Les applications multimédias contiennent souvent des collections d'éléments multimédias, organisées dans une hiérarchie. Par exemple, les titres d'un album ou les épisodes d'une série TV dans une playlist. Cette hiérarchie d'éléments multimédias est appelée "bibliothèque multimédia".
Un MediaLibraryService
fournit une API standardisée pour diffuser et accéder à votre bibliothèque multimédia. Cela peut être utile, par exemple, lorsque vous ajoutez la prise en charge d'Android Auto à votre application multimédia, qui fournit sa propre UI sécurisée pour le conducteur pour votre bibliothèque multimédia.
Créer un MediaLibraryService
L'implémentation d'un MediaLibraryService
est semblable à l'implémentation d'un MediaSessionService
, à la différence que dans la méthode onGetSession()
, vous devez renvoyer un MediaLibrarySession
au lieu d'un MediaSession
.
Kotlin
class PlaybackService : MediaLibraryService() { var mediaLibrarySession: MediaLibrarySession? = null var callback: MediaLibrarySession.Callback = object : MediaLibrarySession.Callback {...} // If desired, validate the controller before returning the media library session override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession? = mediaLibrarySession // Create your player and media library session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaLibrarySession = MediaLibrarySession.Builder(this, player, callback).build() } // Remember to release the player and media library session in onDestroy override fun onDestroy() { mediaLibrarySession?.run { player.release() release() mediaLibrarySession = null } super.onDestroy() } }
Java
class PlaybackService extends MediaLibraryService { MediaLibrarySession mediaLibrarySession = null; MediaLibrarySession.Callback callback = new MediaLibrarySession.Callback() {...}; @Override public MediaLibrarySession onGetSession(MediaSession.ControllerInfo controllerInfo) { // If desired, validate the controller before returning the media library session return mediaLibrarySession; } // Create your player and media library session in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaLibrarySession = new MediaLibrarySession.Builder(this, player, callback).build(); } // Remember to release the player and media library session in onDestroy @Override public void onDestroy() { if (mediaLibrarySession != null) { mediaLibrarySession.getPlayer().release(); mediaLibrarySession.release(); mediaLibrarySession = null; } super.onDestroy(); } }
N'oubliez pas de déclarer votre Service
et les autorisations requises dans le fichier manifeste :
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
Utilisez un MediaLibrarySession
L'API MediaLibraryService
s'attend à ce que votre bibliothèque multimédia soit structurée sous forme d'arborescence, avec un seul nœud racine et des nœuds enfants qui peuvent être lisibles ou consultables.
Un MediaLibrarySession
étend l'API MediaSession
pour ajouter des API de navigation dans le contenu. Par rapport au rappel MediaSession
, le rappel MediaLibrarySession
ajoute des méthodes telles que :
onGetLibraryRoot()
lorsqu'un client demande la racineMediaItem
d'un arbre de contenuonGetChildren()
lorsqu'un client demande les enfants d'unMediaItem
dans l'arborescence de contenuonGetSearchResult()
lorsqu'un client demande des résultats de recherche à partir de l'arborescence de contenu pour une requête donnée.
Les méthodes de rappel pertinentes incluront un objet LibraryParams
avec des signaux supplémentaires sur le type d'arborescence de contenu qui intéresse une application cliente.
Boutons de commande pour les éléments multimédias
Une application de session peut déclarer des boutons de commande compatibles avec un MediaItem
dans le MediaMetadata
. Cela permet d'attribuer une ou plusieurs entrées CommandButton
à un élément multimédia qu'un contrôleur peut afficher et utiliser pour envoyer facilement la commande personnalisée de l'élément à la session.
Configurer les boutons de commande côté session
Lors de la création de la session, une application de session déclare l'ensemble des boutons de commande qu'une session peut gérer en tant que commandes personnalisées :
Kotlin
val allCommandButtons = listOf( CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setSessionCommand(SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setSessionCommand(SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build(), // possibly more here ) // Add all command buttons for media items supported by the session. val session = MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build()
Java
ImmutableList<CommandButton> allCommandButtons = ImmutableList.of( new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setSessionCommand(new SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setSessionCommand(new SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build()); // Add all command buttons for media items supported by the session. MediaSession session = new MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build();
Lors de la création d'un élément multimédia, une application de session peut ajouter un ensemble d'ID de commandes compatibles qui font référence aux commandes de session des boutons de commande configurés lors de la création de la session :
Kotlin
val mediaItem = MediaItem.Builder() .setMediaMetadata( MediaMetadata.Builder() .setSupportedCommands(listOf(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build()) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setMediaMetadata( new MediaMetadata.Builder() .setSupportedCommands(ImmutableList.of(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build()) .build();
Lorsqu'un contrôleur ou un navigateur se connecte ou appelle une autre méthode de la session Callback
, l'application de session peut inspecter le ControllerInfo
transmis au rappel pour obtenir le nombre maximal de boutons de commande qu'un contrôleur ou un navigateur peut afficher. Le ControllerInfo
transmis à une méthode de rappel fournit un getter permettant d'accéder facilement à cette valeur. Par défaut, la valeur est définie sur 0, ce qui indique que le navigateur ou le contrôleur ne sont pas compatibles avec cette fonctionnalité :
Kotlin
override fun onGetItem( session: MediaLibrarySession, browser: MediaSession.ControllerInfo, mediaId: String, ): ListenableFuture<LibraryResult<MediaItem>> { val settableFuture = SettableFuture.create<LibraryResult<MediaItem>>() val maxCommandsForMediaItems = browser.maxCommandsForMediaItems scope.launch { loadMediaItem(settableFuture, mediaId, maxCommandsForMediaItems) } return settableFuture }
Java
@Override public ListenableFuture<LibraryResult<MediaItem>> onGetItem( MediaLibraryService.MediaLibrarySession session, ControllerInfo browser, String mediaId) { SettableFuture<LibraryResult<MediaItem>> settableFuture = SettableFuture.create(); int maxCommandsForMediaItems = browser.getMaxCommandsForMediaItems(); loadMediaItemAsync(settableFuture, mediaId, maxCommandsForMediaItems); return settableFuture; }
Lors du traitement d'une action personnalisée envoyée pour un élément multimédia, l'application de session peut obtenir l'ID de l'élément multimédia à partir des arguments Bundle
transmis à onCustomCommand
:
Kotlin
override fun onCustomCommand( session: MediaSession, controller: MediaSession.ControllerInfo, customCommand: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { val mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID) return if (mediaItemId != null) handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) else handleCustomCommand(controller, customCommand, args) }
Java
@Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args) { String mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID); return mediaItemId != null ? handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) : handleCustomCommand(controller, customCommand, args); }
Utiliser les boutons de commande comme navigateur ou contrôleur
Du côté de MediaController
, une application peut déclarer le nombre maximal de boutons de commande qu'elle prend en charge pour un élément multimédia lors de la création de MediaController
ou MediaBrowser
:
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync()
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync();
Lorsqu'elle est connectée à la session, l'application de télécommande peut recevoir les boutons de commande compatibles avec l'élément multimédia et pour lesquels la télécommande dispose de la commande disponible accordée par l'application de session :
Kotlin
val commandButtonsForMediaItem: List<CommandButton> = controller.getCommandButtonsForMediaItem(mediaItem)
Java
ImmutableList<CommandButton> commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem);
Pour plus de commodité, un MediaController
peut envoyer des commandes personnalisées spécifiques à un élément multimédia avec MediaController.sendCustomCommand(SessionCommand, MediaItem, Bundle)
:
Kotlin
controller.sendCustomCommand(addToPlaylistButton.sessionCommand!!, mediaItem, Bundle.EMPTY)
Java
controller.sendCustomCommand( checkNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY);