Jetpack Media3 définit une interface Player qui décrit les fonctionnalités de base pour la lecture de fichiers vidéo et audio. ExoPlayer est l'implémentation par défaut de cette interface dans Media3. Nous vous recommandons d'utiliser ExoPlayer, car il offre un ensemble complet de fonctionnalités qui couvrent la plupart des cas d'utilisation de lecture. De plus, il est personnalisable pour gérer tous les cas d'utilisation supplémentaires que vous pourriez avoir. Par ailleurs, ExoPlayer ignore la fragmentation des appareils et de l'OS afin que votre code fonctionne de manière cohérente dans l'ensemble de l'écosystème Android. ExoPlayer inclut les particularités suivantes :
- Prise en charge des playlists
- Prise en charge de différents formats de streaming progressif et adaptatif formats
- Prise en charge de l'insertion d'annonces côté client et côté serveur ad insertion
- Prise en charge de la lecture de contenus protégés par DRM
Cette page vous présente certaines des étapes clés de la création d'une application de lecture. Pour en savoir plus, consultez nos guides complets sur Media3 ExoPlayer.
Premiers pas
Pour commencer, ajoutez une dépendance aux modules ExoPlayer, UI et Common de Jetpack Media3 :
Kotlin
implementation("androidx.media3:media3-exoplayer:1.11.0")
implementation("androidx.media3:media3-ui:1.11.0")
implementation("androidx.media3:media3-common:1.11.0")
Groovy
implementation "androidx.media3:media3-exoplayer:1.11.0"
implementation "androidx.media3:media3-ui:1.11.0"
implementation "androidx.media3:media3-common:1.11.0"
Selon votre cas d'utilisation, vous aurez peut-être également besoin de modules Media3 supplémentaires, tels que exoplayer-dash, pour lire en streaming au format DASH.
Veillez à remplacer 1.11.0 par la version que vous souhaitez utiliser pour la bibliothèque. Vous pouvez consulter les notes de version pour connaître la dernière
version.
Créer un lecteur multimédia
Avec Media3, vous pouvez utiliser l'implémentation incluse de l'Player
interface, ExoPlayer, ou créer votre propre implémentation personnalisée.
Créer une instance d'ExoPlayer
Voici la méthode la plus simple pour créer une instance ExoPlayer :
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 l'Activity, du Fragment ou du Service dans lequel il se trouve.
Le Builder inclut un éventail d'options de personnalisation qui peuvent vous intéresser, telles que :
setAudioAttributes()pour configurer la gestion de la priorité audiosetHandleAudioBecomingNoisy()pour configurer le comportement de lecture lorsqu'un périphérique de sortie audio est déconnectésetTrackSelector()pour configurer la sélection des pistes
Media3 fournit un composant d'interface utilisateur PlayerView que vous pouvez inclure dans le fichier de mise en page de votre application. Ce composant encapsule un PlayerControlView pour les commandes de lecture, un SubtitleView pour afficher les sous-titres et une Surface pour le rendu vidéo.
Préparer le lecteur
Ajoutez des éléments multimédias à une playlist pour la lecture avec des méthodes telles que
setMediaItem() et addMediaItem(). Ensuite, appelez prepare() pour commencer
à charger les contenus multimédias et acquérir les ressources nécessaires.
Vous ne devez pas effectuer ces étapes tant que l'application n'est pas au premier plan. Si votre lecteur se trouve dans un état Activity ou Fragment, cela signifie qu'il est en cours de préparation dans la méthode de cycle de vie onStart() au niveau d'API 24 et supérieur, ou dans la méthode de cycle de vie onResume() au niveau d'API 23 et inférieur. Pour un lecteur qui se trouve dans un Service,
vous pouvez le préparer dans onCreate(). Consultez l'atelier de programmation ExoPlayer pour obtenir un exemple d'implémentation des méthodes de cycle de vie.
Contrôler le lecteur
Une fois le lecteur préparé, vous pouvez contrôler la lecture en appelant des méthodes sur le lecteur, telles que :
play()etpause()pour démarrer et mettre en pause la lectureseekTo()pour rechercher une position dans l'élément multimédia actuelseekToNextMediaItem()etseekToPreviousMediaItem()pour parcourir la playlist
Les composants d'interface utilisateur tels que PlayerView ou PlayerControlView sont mis à jour en conséquence lorsqu'ils sont liés à un lecteur.
Libérer le lecteur
La lecture peut nécessiter des ressources qui sont en quantité limitée, comme des décodeurs vidéo
. Il est donc important d'appeler release() sur votre lecteur pour libérer des ressources
lorsque le lecteur n'est plus nécessaire.
Si votre lecteur se trouve dans un état Activity ou Fragment, libérez-le dans la méthode de cycle de vie onStop() au niveau d'API 24 et supérieur, ou dans la méthode onPause() au niveau d'API 23 et inférieur. Pour un lecteur qui se trouve dans un Service, vous pouvez le libérer dans onDestroy(). Consultez l'atelier de programmation ExoPlayer pour obtenir un exemple d'implémentation des méthodes de cycle de vie.
Gérer la lecture avec une session multimédia
Sur Android, les sessions multimédias offrent un moyen standardisé d'interagir avec un lecteur multimédia au-delà des limites des processus. En connectant une session multimédia à votre lecteur , vous pouvez annoncer votre lecture multimédia en externe et recevoir des commandes de lecture depuis des sources externes, par exemple pour l'intégrer aux commandes multimédias système sur les appareils mobiles et à grand écran.
Pour utiliser des sessions multimédias, ajoutez une dépendance au module Media3 Session :
Kotlin
implementation("androidx.media3:media3-session:1.11.0")
Groovy
implementation "androidx.media3:media3-session:1.11.0"
Créer une session multimédia
Vous pouvez créer une 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 du Player avec l'état de la MediaSession. Cela fonctionne avec n'importe quelle Player implémentation, y compris
ExoPlayer, CastPlayer ou 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 objet de rappel lors de la création de votre
MediaSession.
Lorsqu'un contrôleur est sur le point de se connecter à votre session multimédia, la onConnect()
méthode est appelée. Vous pouvez utiliser le ControllerInfo fourni pour décider
d'accepter ou de refuser la requête. Pour en voir un exemple, consultez l'application de démonstration Media3
Session.
Une fois connecté, un contrôleur peut envoyer des commandes de lecture à la session. La session délègue ensuite ces commandes au lecteur. Les commandes de lecture et de playlist définies dans l'interface Player sont automatiquement gérées par la session.
D'autres méthodes de rappel vous permettent de gérer, par exemple, les requêtes de commandes de lecture personnalisées et la modification de la playlist. Ces rappels incluent également un ControllerInfo objet afin que vous puissiez déterminer le contrôle des accès pour chaque
requête.
Lire des 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
lire de la musique, des livres audio ou des podcasts même lorsque l'utilisateur n'a pas ouvert votre application
), vos Player et MediaSession doivent être encapsulés dans un service
de premier plan. Media3 fournit l'interface MediaSessionService à cette fin.
Implémenter un MediaSessionService
Créez une classe qui étend MediaSessionService et instanciez votre
MediaSession dans la onCreate() méthode de cycle de vie.
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, déclarez votre Service classe avec un MediaSessionService
filtre d'intent et demandez l'autorisation FOREGROUND_SERVICE pour exécuter un
service de premier plan :
<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 du client à votre session multimédia. Renvoyez MediaSession pour accepter la requête de connexion ou null pour la refuser.
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 à votre UI
Maintenant que votre session multimédia se trouve dans un Service distinct de l'Activity ou du Fragment où se trouve l'UI de votre lecteur, vous pouvez utiliser un MediaController pour les lier. Dans la méthode onStart() de l'Activity ou du Fragment avec votre UI, créez un SessionToken pour votre MediaSession, puis utilisez le SessionToken pour créer un MediaController. La création d'un MediaController s'effectue 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 les mêmes méthodes, telles que play() et pause(), pour contrôler la lecture. Comme pour les autres
composants, n'oubliez pas de libérer le MediaController lorsqu'il n'est plus
nécessaire dans la méthode de cycle de vie onStop() d'un état Activity, en appelant
MediaController.releaseFuture().
Publier une notification
Les services de premier plan doivent publier une notification lorsqu'ils sont actifs. Un
MediaSessionService crée automatiquement une MediaStyle notification
pour vous 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 fournisseur à votre
MediaSession avec setMediaNotificationProvider.
Annoncer votre bibliothèque de contenus
Un MediaLibraryService s'appuie sur un MediaSessionService en permettant aux applications clientes de 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 à celle d'un
MediaSessionService, sauf que dans onGetSession(), vous devez renvoyer un
MediaLibrarySession au lieu d'un MediaSession. Par rapport à un MediaSession.Callback, le MediaLibrarySession.Callback inclut des méthodes supplémentaires qui permettent à un client de navigateur de parcourir le contenu proposé par votre service de bibliothèque.
Comme pour le MediaSessionService, déclarez le MediaLibraryService dans votre fichier manifeste et demandez l'autorisation FOREGROUND_SERVICE pour exécuter un service de premier plan :
<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 le MediaLibraryService et, pour la rétrocompatibilité, l'ancien MediaBrowserService. Le filtre d'intent supplémentaire permet aux applications clientes utilisant l'API MediaBrowserCompat de reconnaître votre Service.
Un MediaLibrarySession vous permet de diffuser votre bibliothèque de contenus dans une structure arborescente, avec un seul racine MediaItem. Chaque MediaItem de l'arborescence peut comporter un nombre quelconque de nœuds enfants MediaItem. Vous pouvez diffuser une racine ou un arbre différents en fonction de la requête de l'application cliente. Par exemple, l'arborescence que vous renvoyez à un client qui recherche une liste d'éléments multimédias recommandés peut ne contenir que la racine MediaItem et un seul niveau de nœuds enfants MediaItem, tandis que l'arborescence que vous renvoyez à une autre application cliente peut représenter une bibliothèque de contenus plus complète.
Créer un MediaLibrarySession
Un MediaLibrarySession étend l'API MediaSession pour ajouter des API de navigation dans le contenu. Par rapport au MediaSession rappel, le MediaLibrarySession
rappel ajoute des méthodes telles que :
onGetLibraryRoot()lorsque le client demande la racineMediaItemd'une arborescence de contenuonGetChildren()lorsque le client demande les enfants d'unMediaItemdans l'arborescence de contenuonGetSearchResult()lorsque le client demande les résultats de recherche de l'arborescence de contenu pour une requête donnée
Les méthodes de rappel pertinentes incluent un LibraryParams objet avec
des signaux supplémentaires sur le type d'arborescence de contenu qui intéresse une application cliente.