Jetpack Media3 définit une interface Player
qui décrit les fonctionnalités de base
pour la lecture de fichiers audio et vidéo. ExoPlayer
est l'implémentation par défaut
de cette interface dans Media3. Nous vous recommandons d'utiliser ExoPlayer, car il fournit un
un ensemble complet de fonctionnalités couvrant la plupart des cas d'utilisation de la lecture
personnalisable pour gérer tout
cas d'utilisation supplémentaire que vous pourriez avoir. ExoPlayer
élimine la fragmentation de l'appareil et de l'OS afin que votre code fonctionne de manière cohérente.
sur l'ensemble de l'écosystème Android. ExoPlayer inclut:
- Compatibilité avec les playlists
- Compatibilité avec différents streamings progressifs et adaptatifs formats
- Compatibilité avec l'insertion d'annonces côté client et côté serveur
- Compatibilité avec la lecture protégée par DRM
Cette page décrit certaines étapes clés de la création d'une lecture de l'application. Pour en savoir plus, vous pouvez consulter nos guides complets Media3 ExoPlayer
Premiers pas
Pour commencer, ajoutez une dépendance à ExoPlayer, à l'UI et aux modules communs de Jetpack Media3:
implementation "androidx.media3:media3-exoplayer:1.4.0" implementation "androidx.media3:media3-ui:1.4.0" implementation "androidx.media3:media3-common:1.4.0"
Selon votre cas d'utilisation, vous aurez peut-être aussi besoin de modules supplémentaires de Media3,
comme exoplayer-dash
pour lire des flux au format DASH.
Veillez à remplacer 1.4.0
par la version de votre choix
bibliothèque. Consultez les notes de version
pour afficher la dernière version.
Créer un lecteur multimédia
Avec Media3, vous pouvez utiliser l'implémentation incluse de Player
interface standard, ExoPlayer
, ou vous pouvez créer votre propre implémentation personnalisée.
Créer une instance ExoPlayer
Le moyen le plus simple de créer une instance ExoPlayer
est le suivant:
Kotlin
val player = ExoPlayer.Builder(context).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
Vous pouvez créer votre lecteur multimédia dans la méthode de cycle de vie onCreate()
de la
Activity
, Fragment
ou Service
où il se trouve.
Le Builder
inclut
un éventail d'options de personnalisation qui pourraient vous intéresser, telles que:
setAudioAttributes()
pour configurer la gestion du ciblage audiosetHandleAudioBecomingNoisy()
pour configurer le comportement de lecture lorsqu'un périphérique de sortie audio est déconnectésetTrackSelector()
pour configurer la sélection du titre
Media3 fournit un composant d'interface utilisateur PlayerView
que vous pouvez inclure dans le fichier
de mise en page. Ce composant encapsule un élément PlayerControlView
pour la lecture.
SubtitleView
pour afficher les sous-titres et Surface
pour l'affichage.
vidéo.
Préparer le lecteur
Ajouter des éléments multimédias à une playlist pour
grâce à des méthodes telles que
setMediaItem()
et addMediaItem()
.
Appelez ensuite prepare()
pour :
à charger un média
et à acquérir les ressources nécessaires.
N'effectuez pas ces étapes avant que l'application ne soit au premier plan. Si votre
se trouve dans une Activity
ou une Fragment
, cela signifie qu'il doit être préparé
Méthode de cycle de vie onStart()
au niveau d'API 24 ou supérieur, ou onResume()
au niveau d'API 23 et inférieur. Pour un joueur qui se trouve dans un Service
,
vous pouvez le préparer dans onCreate()
.
Contrôler le lecteur
Une fois le lecteur préparé, vous pouvez contrôler la lecture en appelant des méthodes sur le lecteur, par exemple:
play()
etpause()
pour lancer et mettre en pause la lectureseekTo()
pour rechercher une position dans l'élément multimédia actuel.seekToNextMediaItem()
etseekToPreviousMediaItem()
pour parcourir la playlist
Les composants de l'interface utilisateur tels que PlayerView
ou PlayerControlView
seront mis à jour
en conséquence lorsqu'il est associé à un lecteur.
Relâchez le lecteur
La lecture peut nécessiter des ressources limitées, comme la vidéo
des décodeurs. Il est donc important d'appeler release()
sur votre lecteur pour libérer des ressources lorsqu'il n'est plus nécessaire.
Si votre lecteur se trouve dans une Activity
ou une Fragment
, relâchez-le dans la
Méthode de cycle de vie onStop()
au niveau d'API 24 ou supérieur, ou onPause()
au niveau d'API 23 et inférieur. Pour un joueur associé à un Service
, vous pouvez :
le publier dans onDestroy()
.
Gérer la lecture avec une session multimédia
Sur Android, les sessions multimédias offrent une manière standardisée d'interagir avec un contenu multimédia. au-delà des limites des processus. Connecter une session multimédia à votre lecteur vous permet d'annoncer la lecture de vos contenus multimédias en externe et d'en recevoir des commandes provenant de sources externes, par exemple pour s'intégrer commandes multimédias du système sur les mobiles et les grands appareils dotés d'un écran.
Pour utiliser des sessions multimédias, ajoutez une dépendance au module de session Media3:
implementation "androidx.media3:media3-session:1.4.0"
Créer une session multimédia
Vous pouvez créer un MediaSession
après avoir initialisé un lecteur comme suit:
Kotlin
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3 synchronise automatiquement l'état de Player
avec l'état de
MediaSession
Cela fonctionne avec toutes les implémentations de Player
, y compris
ExoPlayer
, CastPlayer
ou un
une implémentation personnalisée.
Accorder le contrôle à d'autres clients
Les applications clientes peuvent implémenter un contrôleur multimédia.
pour contrôler la lecture de votre session multimédia. Pour recevoir ces requêtes, définissez un
callback lorsque
créer votre MediaSession
.
Lorsqu'une manette est sur le point de se connecter à votre session multimédia,
onConnect()
est appelée. Vous pouvez utiliser la ControllerInfo
fournie
décider d'accepter ou non
ou refuser
la demande. Vous trouverez un exemple dans l'application de démonstration de la session Media3.
Une fois connectée, une manette peut envoyer des commandes de lecture à la session. La
délègue ensuite ces commandes au joueur. Lecture et playlist
définies dans l'interface Player
sont automatiquement gérées par
session.
D'autres méthodes de rappel vous permettent, par exemple, de gérer les requêtes pour
commandes de lecture personnalisées
et modifiez la playlist. Ces rappels incluent également un objet ControllerInfo
. Vous pouvez donc
peut déterminer le contrôle des accès à la demande.
Lecture de contenus multimédias en arrière-plan
Pour continuer à lire des contenus multimédias lorsque votre application n'est pas au premier plan, par exemple
pour écouter de la musique, des livres audio ou des podcasts même si l'utilisateur n'a pas votre application
ouvert, votre Player
et votre MediaSession
doivent être encapsulés dans un
service de premier plan. Media3 fournit
MediaSessionService
à cette fin.
Implémenter un MediaSessionService
Créez une classe qui étend MediaSessionService
et instanciez votre
MediaSession
dans la méthode de cycle de vie onCreate()
.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
Dans votre fichier manifeste, votre classe Service
avec un intent MediaSessionService
filtrer et demander l'autorisation FOREGROUND_SERVICE
pour exécuter un premier plan
service:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Enfin, dans la classe que vous avez créée, remplacez la méthode onGetSession()
pour contrôler
l'accès client à votre session multimédia. Renvoyez un MediaSession
pour accepter
requête de connexion, ou renvoyez null
pour refuser la requête.
Kotlin
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
Java
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
Se connecter à l'interface utilisateur
Maintenant que votre session multimédia se trouve dans un Service
distinct de Activity
ou
Fragment
où se trouve l'interface utilisateur de votre lecteur, vous pouvez utiliser un MediaController
pour associer
les uns aux autres. Dans la méthode onStart()
de Activity
ou Fragment
avec votre
UI, créez un SessionToken
pour votre MediaSession
, puis utilisez l'SessionToken
pour créer un MediaController
. La création d'une MediaController
se produit
de manière asynchrone.
Kotlin
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync() controllerFuture.addListener( { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()) }, MoreExecutors.directExecutor() ) }
Java
@Override public void onStart() { SessionToken sessionToken = new SessionToken(this, new ComponentName(this, PlaybackService.class)); ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(this, sessionToken).buildAsync(); controllerFuture.addListener(() -> { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()); }, MoreExecutors.directExecutor()) }
MediaController
implémente l'interface Player
. Vous pouvez donc utiliser la même
telles que play()
et pause()
pour contrôler la lecture. Semblable à d'autres
, n'oubliez pas de libérer le MediaController
lorsqu'il n'est plus
nécessaire, comme la méthode de cycle de vie onStop()
d'un Activity
, en appelant
MediaController.releaseFuture()
Publier une notification
Les services de premier plan sont requis pour publier une notification lorsqu'ils sont actifs. A
MediaSessionService
crée automatiquement un
Notification MediaStyle
pour
sous la forme d'un MediaNotification
.
Pour fournir une notification personnalisée, créez un
MediaNotification.Provider
avec DefaultMediaNotificationProvider.Builder
ou en créant une implémentation
personnalisée de l'interface du fournisseur. Ajoutez votre
à votre MediaSession
avec
setMediaNotificationProvider
Faire la promotion de votre bibliothèque de contenu
Un MediaLibraryService
s'appuie sur un MediaSessionService
en autorisant le client
applications pour parcourir le contenu multimédia fourni par votre application. Les applications clientes implémentent un
MediaBrowser
pour interagir
avec votre MediaLibraryService
.
L'implémentation d'un MediaLibraryService
est semblable à l'implémentation d'une
MediaSessionService
, sauf que dans onGetSession()
, vous devez renvoyer une
MediaLibrarySession
au lieu d'MediaSession
. Par rapport à un
MediaSession.Callback
, le MediaLibrarySession.Callback
inclut d'autres
qui permettent à un client de navigateur de parcourir le contenu proposé par votre
bibliothèque.
Comme pour MediaSessionService
, déclarez MediaLibraryService
dans votre
fichier manifeste et demander l'autorisation FOREGROUND_SERVICE
pour exécuter un premier plan
service:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
L'exemple ci-dessus inclut un filtre d'intent pour MediaLibraryService
et, pour assurer la rétrocompatibilité, l'ancien MediaBrowserService
. La
Un filtre d'intent supplémentaire active les applications clientes à l'aide de l'API MediaBrowserCompat
pour reconnaître votre Service
.
Un MediaLibrarySession
vous permet de diffuser votre bibliothèque de contenus sous forme d'arborescence.
avec une seule racine MediaItem
. Chaque MediaItem
de l'arborescence peut avoir
un nombre illimité de nœuds MediaItem
enfants. Vous pouvez servir une racine différente, ou une
une arborescence différente, en fonction
de la requête de l'application cliente. Par exemple, l’arbre que vous
à un client à la recherche d'une liste d'éléments multimédias recommandés
contiennent la racine MediaItem
et un seul niveau de nœuds enfants MediaItem
;
tandis que l'arborescence vers laquelle vous revenez
vers une autre application cliente peut représenter
bibliothèque complète de contenus.
Créer un MediaLibrarySession
Un MediaLibrarySession
étend l'API MediaSession
pour ajouter des API de navigation de contenu. Par rapport aux
Rappel MediaSession
,
le rappel MediaLibrarySession
ajoute des méthodes telles que:
onGetLibraryRoot()
lorsqu'un client demande la racineMediaItem
d'une arborescence de contenuonGetChildren()
lorsqu'un client demande les enfants d'un élémentMediaItem
dans l'arborescence de contenuonGetSearchResult()
lorsqu'un client demande des résultats de recherche dans l'arborescence de contenu pour une requête
Les méthodes de rappel pertinentes incluront un LibraryParams
objet avec des signaux supplémentaires sur le type d'arborescence de contenu qu'une application cliente
qui vous intéresse.