Un lecteur est le composant de votre application qui facilite la lecture des éléments multimédias.
L'interface Media3 Player définit un plan pour les aspects du fonctionnement généralement gérés par un lecteur. Par exemple :
- Affecter les commandes de lecture, comme la lecture, la pause et la recherche
- Interroger les propriétés du contenu multimédia en cours de lecture, comme la position de lecture
- Gérer une playlist/file d'attente des éléments multimédias
- Configurer les propriétés de lecture, comme la lecture en mode aléatoire, la répétition, la vitesse et le volume
- Afficher la vidéo à l'écran
Media3 fournit également une implémentation de l'interface Player, appelée ExoPlayer.
Une interface commune entre les composants
Plusieurs composants de Media3 implémentent l'interface Player, par exemple :
| Composant | Description et notes sur le comportement |
|---|---|
ExoPlayer |
API de lecteur multimédia et implémentation par défaut de l'interface Player. |
MediaController |
Interagit avec une MediaSession pour envoyer des commandes de lecture. Si vos Player et MediaSession se trouvent dans un Service distinct de l'Activity ou du Fragment où se trouve l'UI de votre lecteur, vous pouvez attribuer votre MediaController en tant que lecteur pour votre UI PlayerView. Les appels de méthode de lecture et de playlist sont envoyés à votre Player via votre MediaSession.
|
MediaBrowser |
En plus du fonctionnement assuré par un MediaController, il interagit avec un MediaLibrarySession pour parcourir le contenu multimédia disponible.
|
SimpleBasePlayer |
Implémentation du Player qui réduit au minimum le nombre de méthodes à implémenter. Utile lorsque vous utilisez un lecteur personnalisé que vous souhaitez connecter à une MediaSession.
|
ForwardingSimpleBasePlayer |
Sous-classe de SimpleBasePlayer conçue pour transférer les opérations de lecture vers un autre Player tout en permettant les mêmes personnalisations cohérentes du comportement que SimpleBasePlayer. Utilisez cette classe pour supprimer ou modifier des opérations de lecture spécifiques.
|
CastPlayer |
Implémentation du Player qui communique avec une application réceptrice Cast. Le comportement dépend de la session Cast sous-jacente.
|
Bien qu'un MediaSession n'implémente pas l'interface Player, il nécessite un Player lors de sa création. Son objectif est de fournir un accès au Player à partir d'autres processus ou threads.
Architecture de lecture Media3
Si vous avez accès à un Player, vous devez appeler ses méthodes directement pour émettre des commandes de lecture. Vous pouvez annoncer votre lecture et accorder le contrôle de la lecture à des sources externes en implémentant une MediaSession. Ces sources externes implémentent un MediaController, ce qui facilite la connexion à une session multimédia et l'envoi de requêtes de commandes de lecture.
Lorsque vous lisez du contenu multimédia en arrière-plan, vous devez loger votre session multimédia et votre lecteur dans un MediaSessionService ou un MediaLibraryService qui s'exécute en tant que service de premier plan. Vous pouvez ainsi séparer votre lecteur de l'Activité de votre application qui contient l'UI pour le contrôle de la lecture. Vous devrez peut-être utiliser un contrôleur multimédia.
Player joue un rôle clé dans l'architecture de Media3.État du lecteur
L'état d'un lecteur multimédia implémentant l'interface Player se compose principalement de quatre catégories d'informations :
- État de la lecture
- Récupérez-le avec
getPlaybackState(). - Les valeurs d'état définies par l'interface sont
STATE_IDLE,STATE_BUFFERING,STATE_READYetSTATE_ENDED.
- Récupérez-le avec
- Playlist des éléments multimédias
- Séquence d'instances
MediaItempour la lecture. - Récupérez-la avec
getCurrentTimeline(). - Les instances
Playerpeuvent fournir des méthodes pour des opérations sur des playlists, comme ajouter ou supprimer unMediaItem, et des méthodes pratiques commegetCurrentMediaItem().
- Séquence d'instances
- Propriétés de lecture/pause, telles que :
playWhenReady: indique si l'utilisateur souhaite que le contenu multimédia soit lu lorsque cela est possible ou reste en pause.- Motif de la suppression de la lecture : indication du motif de la suppression de la lecture, le cas échéant, même si
playWhenReadyest défini surtrue isPlaying: indique si le lecteur est en cours de lecture. La valeur esttrueuniquement si l'état de lecture estSTATE_READY,playWhenReadyesttrueet la lecture n'est pas supprimée.
- Position de lecture, y compris :
- Index de l'élément multimédia actuel : index du
MediaItemactuel dans la playlist. isPlayingAd: indique si une annonce insérée est en cours de lecture.- Position de lecture actuelle :
position de lecture actuelle dans le
MediaItemou l'annonce insérée en cours.
- Index de l'élément multimédia actuel : index du
De plus, l'interface du Player permet d'accéder aux pistes disponibles, aux métadonnées du contenu multimédia, à la vitesse de lecture, au volume et à d'autres propriétés auxiliaires de la lecture.
Écouter les changements
Utilisez un Player.Listener pour écouter les modifications dans un Player. Pour savoir comment créer et utiliser un écouteur, consultez la documentation ExoPlayer sur les événements du lecteur.
Notez que l'interface de l'écouteur n'inclut aucun rappel pour suivre la progression normale de la lecture. Pour surveiller en continu la progression de la lecture, par exemple pour configurer une barre de progression dans l'UI, vous devez interroger la position actuelle à des intervalles appropriés.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
Contrôler la lecture
L'interface Player offre de nombreuses façons de manipuler l'état et de contrôler la lecture :
- Commandes de lecture de base, comme
play(),pause(),prepare()etstop(). - Opérations sur les playlists, comme
addMediaItem()ouremoveMediaItem(). - Recherche pour modifier l'élément ou la position actuels.
- Définition des modes Répéter et du mode aléatoire.
- Mise à jour de vos préférences de sélection des pistes.
- Définition de la vitesse de lecture.
Implémentations du Player personnalisées
Pour créer un lecteur personnalisé, vous pouvez étendre le
SimpleBasePlayer
inclus dans Media3. Cette classe fournit une implémentation de base de l'interface du Player afin de réduire au minimum le nombre de méthodes à implémenter.
Commencez par remplacer la méthode getState(). Cette méthode doit renseigner l'état actuel du lecteur lorsqu'elle est appelée, y compris :
- l'ensemble des commandes disponibles ;
- les propriétés de la lecture, par exemple si le lecteur doit démarrer la lecture lorsque son état est
STATE_READY, l'index de l'élément multimédia en cours de lecture et la position de lecture dans l'élément actuel
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer garantit que State est créé avec une combinaison valide de valeurs d'état. Il gérera également les écouteurs et informera les écouteurs des changements d'état. Si vous devez déclencher manuellement une mise à jour de l'état, appelez invalidateState().
Au-delà de la méthode getState(), vous n'avez besoin d'implémenter que les méthodes utilisées pour les commandes que votre lecteur déclare disponibles. Recherchez la méthode remplaçable du handler qui correspond à la fonctionnalité que vous souhaitez implémenter. Par exemple, remplacez la méthode handleSeek() pour prendre en charge les opérations telles que COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM et COMMAND_SEEK_TO_NEXT_MEDIA_ITEM.
Modifier les implémentations du Player
Au lieu de créer un Player entièrement personnalisé, vous pouvez utiliser un ForwardingSimpleBasePlayer pour modifier l'état et le comportement d'un Player existant. Pour en savoir plus, consultez le guide de la page de personnalisation.