Il existe deux façons de se connecter à une application multimédia :
MediaControllerMediaBrowser
MediaController
Un contrôleur multimédia interagit avec une session multimédia pour interroger et contrôler la lecture d'une application multimédia. Dans Media3, l'API MediaController implémente l'interface Player. Voici quelques exemples d'applications clientes qui utilisent un contrôleur multimédia :
- Commandes multimédias du système Android
- Application associée Android Wear OS
- Android Auto et Automotive OS
- Assistants vocaux, comme l'Assistant Google
- L'application de test du contrôleur multimédia
Un contrôleur multimédia peut également être utile dans une application multimédia, par exemple si le lecteur et la session multimédia se trouvent dans un Service distinct de l'Activity ou du Fragment avec l'UI.
Créer un MediaController
Pour créer un MediaController, commencez par créer un SessionToken pour le MediaSession correspondant. La méthode onStart() de votre Activity ou Fragment peut être un bon emplacement pour cela.
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
L'utilisation de ce SessionToken pour créer un MediaController connecte le contrôleur à la session donnée. Cette opération s'effectue de manière asynchrone. Vous devez donc écouter le résultat et l'utiliser lorsqu'il est disponible.
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() controllerFuture.addListener( { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken).buildAsync(); controllerFuture.addListener( () -> { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor());
Utiliser un MediaController
MediaController implémente l'interface Player. Vous pouvez donc utiliser les commandes définies dans l'interface pour contrôler la lecture du MediaSession connecté.
Autrement dit, l'appel de play() sur un MediaController envoie la commande au MediaSession connecté, qui délègue ensuite la commande à son Player sous-jacent.
Vous pouvez ajouter un Player.Listener au contrôleur pour écouter les modifications de l'
Player état. Pour en savoir plus sur l'utilisation d'un
Player.Listener, consultez le guide sur les événements du lecteur.
L'interface MediaController.Listener définit des rappels supplémentaires pour les événements et les commandes personnalisées du MediaSession connecté. Par exemple,
onCustomCommand() lorsque la session envoie une commande personnalisée,
onAvailableSessionCommandsChanged() lorsque la session modifie les commandes de session disponibles ou onDisconnected() lorsque le contrôleur est déconnecté
de la session.
Un MediaController.Listener peut être défini lors de la création du contrôleur avec un Builder :
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken) .setListener( object : MediaController.Listener { override fun onCustomCommand( controller: MediaController, command: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { // Handle custom command. return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } override fun onDisconnected(controller: MediaController) { // Handle disconnection. } } ) .buildAsync()
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public ListenableFuture<SessionResult> onCustomCommand( MediaController controller, SessionCommand command, Bundle args) { // Handle custom command. return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } @Override public void onDisconnected(MediaController controller) { // Handle disconnection. } }) .buildAsync();
Comme pour les autres composants, n'oubliez pas de libérer le MediaController lorsqu'il n'est plus nécessaire, par exemple dans la méthode onStop() d'une Activity ou d'un Fragment.
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
La libération du contrôleur envoie toujours toutes les commandes en attente à la session et ne se dissocie du service de session qu'une fois ces commandes traitées ou après un délai d'inactivité, selon la première de ces deux options.
MediaBrowser
Un MediaBrowser s'appuie sur les fonctionnalités offertes par un MediaController pour permettre également de parcourir la bibliothèque multimédia proposée par le MediaLibraryService d'une application multimédia.
Créer un MediaBrowser
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync() browserFuture.addListener( { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).buildAsync(); browserFuture.addListener( () -> { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor());
Utiliser un MediaBrowser
Pour commencer à parcourir la bibliothèque de contenu de l'application multimédia, récupérez d'abord le nœud racine avec getLibraryRoot() :
Kotlin
// Get the library root to start browsing the library tree. val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null) rootFuture.addListener( { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor(), )
Java
// Get the library root to start browsing the library tree. ListenableFuture<LibraryResult<MediaItem>> rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null); rootFuture.addListener( () -> { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor());
Vous pouvez ensuite parcourir la bibliothèque multimédia en récupérant les enfants d'un MediaItem dans la bibliothèque avec getChildren(). Par exemple, pour récupérer les enfants du nœud racine MediaItem :
Kotlin
// Get the library root to start browsing the library tree. val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null) childrenFuture.addListener( { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor(), )
Java
ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null); childrenFuture.addListener( () -> { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor());
Afficher les commandes de lecture d'une autre application multimédia
Lorsque vous affichez des commandes d'UI avec des boutons pour une autre application multimédia, il est important de respecter les préférences de boutons multimédias déclarées de cette application.
Pour résoudre les préférences de l'application avec les contraintes et les exigences de votre UI, utilisez CommandButton.DisplayConstraints. Vous pouvez définir les limites et
les restrictions de votre UI, et la resolve() méthode
fournit une liste définitive de boutons à afficher avec leur icône, leur position et
l'action prévue. Si un utilisateur clique sur l'un de ces boutons, vous pouvez utiliser CommandButton.executeAction pour déclencher l'action associée dans l'application multimédia.
Kotlin
// Get media button preferences from media app val mediaButtonPreferences = controller.getMediaButtonPreferences() // Declare constraints of UI (example: limit overflow button to one) val displayConstraints = DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build() // Resolve media app preferences with constraints val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller) // Display buttons in UI for (button in resolvedButtons) { generateUiButton( uiPosition = button.slots[0], icon = getIconRes(button.icon), onClick = { button.executeAction(controller) }, ) }
Java
// Get media button preferences from media app List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences(); // Declare constraints of UI (example: limit overflow button to one) DisplayConstraints displayConstraints = new DisplayConstraints.Builder() .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1) .build(); // Resolve media app preferences with constraints List<CommandButton> resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller); // Display buttons in UI for (CommandButton button : resolvedButtons) { generateUiButton( /* uiPosition= */ button.slots.get(0), /* icon= */ getIconRes(button.icon), /* onClick= */ () -> button.executeAction(controller)); }