Medya uygulamaları genellikle hiyerarşik olarak düzenlenmiş medya öğesi koleksiyonları içerir. Örneğin, bir albümdeki şarkılar veya oynatma listesindeki TV bölümleri. Medya öğelerinin bu hiyerarşisi medya kitaplığı olarak bilinir.
MediaLibraryService
, medya kitaplığınızı yayınlamak ve kitaplığınıza erişmek için standartlaştırılmış bir API sağlar. Bu, örneğin medya uygulamanıza Android Auto desteği eklerken faydalı olabilir. Bu destek, medya kitaplığınız için sürücüye güvenli kendi kullanıcı arayüzünü sağlar.
MediaLibraryService
oluşturma
MediaLibraryService
uygulamak, MediaSessionService
uygulamaya benzer. Tek fark, onGetSession()
yönteminde MediaSession
yerine MediaLibrarySession
döndürmeniz gerektiğidir.
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(); } }
Service
ve gerekli izinlerinizi manifest dosyasında da belirtmeyi unutmayın:
<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" />
<!-- For targetSdk 34+ -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
MediaLibrarySession
kullanın
MediaLibraryService
API, medya kitaplığınızın tek bir kök düğüm ve oynatılabilir veya gezilebilir alt düğümler içeren bir ağaç biçiminde yapılandırılmasını bekler.
MediaLibrarySession
, içeriklere göz atma API'leri eklemek için MediaSession
API'yi genişletir. MediaSession
geri çağırma yöntemine kıyasla MediaLibrarySession
geri çağırma yöntemi aşağıdaki gibi yöntemler ekler:
onGetLibraryRoot()
Bir istemci, içerik ağacının kökünüMediaItem
istediğindeonGetChildren()
istemci, içerik ağacındaki birMediaItem
öğesinin alt öğelerini istediğindeonGetSearchResult()
Müşteri belirli bir sorgu için içerik ağacından arama sonuçları istediğinde
Alakalı geri çağırma yöntemleri, istemci uygulamasının ilgilendiği içerik ağacı türü hakkında ek sinyaller içeren bir LibraryParams
nesnesi içerir.
Medya öğeleri için komut düğmeleri
Oturum uygulamaları, MediaMetadata
içinde MediaItem
tarafından desteklenen komut düğmeleri tanımlayabilir. Bu sayede, bir kontrol cihazının görüntüleyebileceği ve öğenin özel komutunu oturuma kolay bir şekilde göndermek için kullanabileceği bir medya öğesine bir veya daha fazla CommandButton
girişi atayabilirsiniz.
Oturum tarafında komut düğmelerini ayarlama
Oturum uygulaması, oturumu oluştururken oturumun özel komutlar olarak işleyebileceği komut düğmelerini tanımlar:
Kotlin
val allCommandButtons = listOf( CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setDisplayName("Add to playlist") .setIconResId(R.drawable.playlist_add) .setSessionCommand(SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setIconResId(R.drawable.radio) .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("Add to playlist") .setIconUri(Uri.parse("http://www.example.com/icon/playlist_add")) .setSessionCommand(new SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName("Radio station") .setIconUri(Uri.parse("http://www.example.com/icon/radio")) .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();
Bir medya öğesi oluştururken oturum uygulaması, oturum oluşturulurken ayarlanan komut düğmelerinin oturum komutlarına atıfta bulunan bir dizi desteklenen komut kimliği ekleyebilir:
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();
Bir kontrol cihazı veya tarayıcı oturuma bağlandığında ya da oturumun başka bir yöntemini çağrdığında Callback
oturum uygulaması, bir kontrol cihazının veya tarayıcının görüntüleyebileceği maksimum komut düğmesi sayısını almak için geri çağırma işlevine iletilen ControllerInfo
öğesini inceleyebilir. Bir geri çağırma yöntemine iletilen ControllerInfo
, bu değere kolayca erişmek için bir alıcı sağlar. Varsayılan olarak değer 0 olarak ayarlanır. Bu, tarayıcının veya denetleyicinin bu özelliği desteklemediğini gösterir:
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; }
Oturum uygulaması, bir medya öğesi için gönderilen özel bir işlemi işlerken Bundle
içine iletilen onCustomCommand
bağımsız değişkenlerinden medya öğesi kimliğini alabilir:
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); }
Komut düğmelerini tarayıcı veya kumanda olarak kullanma
MediaController
tarafında, bir uygulama MediaController
veya MediaBrowser
öğesini oluştururken bir medya öğesi için desteklediği maksimum komut düğmesi sayısını belirtebilir:
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync()
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync();
Denetleyici uygulaması, oturuma bağlıyken medya öğesi tarafından desteklenen ve denetleyicinin oturum uygulaması tarafından verilen kullanılabilir komuta sahip olduğu komut düğmelerini alabilir:
Kotlin
val commandButtonsForMediaItem: List<CommandButton> = controller.getCommandButtonsForMediaItem(mediaItem)
Java
ImmutableList<CommandButton> commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem);
Kolaylık sağlamak için MediaController
, MediaController.sendCustomCommand(SessionCommand, MediaItem, Bundle)
ile medya öğesine özel özel komutlar gönderebilir:
Kotlin
controller.sendCustomCommand(addToPlaylistButton.sessionCommand!!, mediaItem, Bundle.EMPTY)
Java
controller.sendCustomCommand( checkNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY);