Medya oturumları, ses veya video oynatıcıyla etkileşim kurmanın evrensel bir yolunu sunar. Media3'te varsayılan oynatıcı, Player arayüzünü uygulayan ExoPlayer sınıfıdır. Medya oturumunu oynatıcıya bağlamak, uygulamanın medya oynatmayı harici olarak tanıtmasına ve harici kaynaklardan oynatma komutları almasına olanak tanır.
Komutlar, kulaklıktaki oynatma düğmesi veya TV uzaktan kumandası gibi fiziksel düğmelerden gelebilir. Ayrıca, medya kumandası olan istemci uygulamalarından da gelebilir. Örneğin, Gemini veya Google Asistan gibi yapay zeka asistanlarına "duraklat" talimatı verilebilir. Medya oturumu, bu komutları medya uygulamasının oynatıcısına iletir.
Medya oturumu ne zaman seçilir?
MediaSession uyguladığınızda kullanıcıların oynatmayı kontrol etmesine izin verirsiniz:
- Kulaklık aracılığıyla. Kullanıcıların medyayı oynatmak veya duraklatmak ya da sonraki veya önceki parçaya gitmek için kulaklıklarında kullanabileceği düğmeler veya dokunma etkileşimleri vardır.
- Gemini veya Google Asistan gibi asistan yapay zekalarla konuşarak. Yaygın bir kullanım şekli, cihazda o anda oynatılan medyayı duraklatmak için "Ok Google, duraklat" demektir.
- Wear OS kol saatleri üzerinden. Bu sayede, telefonda oynatılan içeriklerde en yaygın oynatma kontrollerine daha kolay erişilebilir.
- Medya kontrolleri aracılığıyla. Bu bantta, çalışan her medya oturumu için kontroller gösterilir.
- TV'de. Fiziksel oynatma düğmeleri, platform oynatma kontrolü ve güç yönetimi ile işlemlere izin verir (örneğin, TV, ses çubuğu veya A/V alıcısı kapanırsa ya da giriş değiştirilirse uygulamada oynatma durdurulmalıdır).
- Android Auto medya kontrolleri aracılığıyla Bu sayede, sürüş sırasında oynatma kontrollerini güvenli bir şekilde kullanabilirsiniz.
- Oynatmayı etkilemesi gereken diğer tüm harici işlemler.
Bu, birçok kullanım alanı için idealdir. Özellikle aşağıdaki durumlarda MediaSession kullanmayı kesinlikle düşünmelisiniz:
- Film veya canlı TV gibi uzun video içerikleri yayınlıyorsanız.
- Podcast'ler veya müzik oynatma listeleri gibi uzun ses içerikleri yayınlıyorsanız
- TV uygulaması geliştiriyorsunuz.
Ancak tüm kullanım alanları MediaSession için uygun değildir. Aşağıdaki durumlarda yalnızca Player kullanmak isteyebilirsiniz:
- Harici kontrol veya arka planda oynatma gerektirmeyen kısa içerikler gösteriyorsanız.
- Tek bir etkin video yoktur. Örneğin, kullanıcı bir listede gezinirken ekranda aynı anda birden fazla video gösterilir.
- Kullanıcınızın harici oynatma kontrollerine ihtiyaç duymadan aktif olarak izlemesini beklediğiniz tek seferlik bir tanıtım veya açıklama videosu oynatıyorsunuz.
- İçeriğiniz gizlilik açısından hassas ve harici işlemlerin medya meta verilerine erişmesini istemiyorsunuz (ör. tarayıcıda gizli mod).
Kullanım alanınız yukarıda listelenenlerden hiçbirine uymuyorsa uygulamanızın, kullanıcı içerikle aktif olarak etkileşimde bulunmadığında oynatmaya devam etmesini isteyip istemediğinizi düşünün. Cevabınız evetse MediaSession seçeneğini tercih etmeniz daha iyi olabilir. Cevabınız hayırsa bunun yerine Player kullanmanız daha iyi olabilir.
Medya oturumu oluşturma
Medya oturumu, yönettiği oynatıcıyla birlikte çalışır. Context ve Player nesnesiyle bir medya oturumu oluşturabilirsiniz. Medya oturumunu ve ilişkili oynatıcısını barındıran Activity veya Fragment öğesinin onStart() ya da onResume() yaşam döngüsü yöntemi veya Service öğesinin onCreate() yöntemi gibi gerektiğinde bir medya oturumu oluşturup başlatmanız gerekir.
Medya oturumu oluşturmak için bir Player başlatın ve bunu şu şekilde MediaSession.Builder öğesine sağlayın:
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();
Otomatik durum işleme
Media3 kitaplığı, oynatıcının durumunu kullanarak medya oturumunu otomatik olarak günceller. Bu nedenle, oyuncudan oturuma eşlemeyi manuel olarak yapmanız gerekmez.
Bu, oynatıcıdan bağımsız olarak bir PlaybackState oluşturup sürdürmeniz gereken platform medya oturumundan farklıdır (ör. hataları belirtmek için).
Benzersiz oturum kimliği
Varsayılan olarak MediaSession.Builder, oturum kimliği olarak boş bir dize içeren bir oturum oluşturur. Bir uygulamanın yalnızca tek bir oturum örneği oluşturması amaçlanıyorsa bu yeterlidir. Bu, en yaygın durumdur.
Bir uygulama aynı anda birden fazla oturum örneğini yönetmek istiyorsa her oturumun oturum kimliğinin benzersiz olmasını sağlamalıdır. Oturum kimliği, MediaSession.Builder.setId(String id) ile oturum oluşturulurken ayarlanabilir.
Uygulamanızın IllegalStateException: Session ID must be unique. ID= hata mesajıyla IllegalStateException nedeniyle kilitlendiğini görürseniz daha önce aynı kimlikle oluşturulmuş bir örnek yayınlanmadan önce beklenmedik bir şekilde oturum oluşturulmuş olabilir. Oturumların bir programlama hatası nedeniyle sızdırılmasını önlemek için bu tür durumlar algılanır ve bir istisna oluşturularak bildirilir.
Diğer istemcilere kontrol izni verme
Medya oturumu, oynatmayı kontrol etmenin anahtarıdır. Harici kaynaklardan gelen komutları, medyanızı oynatma işini yapan oynatıcıya yönlendirmenizi sağlar. Bu kaynaklar, kulaklık veya TV uzaktan kumandasındaki oynat düğmesi gibi fiziksel düğmeler ya da Gemini veya Google Asistan'a "duraklat" talimatı vermek gibi dolaylı komutlar olabilir. Benzer şekilde, bildirim ve kilit ekranı kontrolleri için Android sistemine veya oynatmayı saat kadranından kontrol edebilmek için Wear OS kol saatine erişim izni vermek isteyebilirsiniz. Harici istemciler, medya uygulamanıza oynatma komutları vermek için medya kumandası kullanabilir. Medya oturumunuz bu komutları alır ve medya oynatıcıya iletir.
Bir kumanda medya oturumunuza bağlanmak üzereyken oturum onConnectAsync() yöntemini çağırır. İsteği kabul etmek veya reddetmek için sağlanan ControllerInfo kullanabilirsiniz. Bağlantı isteğini kabul etme örneği için Özel komutları bildirme ve işleme başlıklı makaleyi inceleyin.
Bağlantı kurulduktan sonra kumanda, oturuma oynatma komutları gönderebilir. Oturum, bu komutları oynatıcıya iletir. Player arayüzünde tanımlanan oynatma ve oynatma listesi komutları, oturum tarafından otomatik olarak işlenir.
Diğer geri çağırma yöntemleri, örneğin özel komutlar ve oynatma listesini değiştirme isteklerini işlemenize olanak tanır. Bu geri çağırmalar da benzer şekilde bir ControllerInfo nesnesi içerir. Böylece her isteğe nasıl yanıt vereceğinizi denetleyici bazında değiştirebilirsiniz.
Oynatma listesini değiştirme
Medya oturumu, Oynatma listeleri için ExoPlayer kılavuzunda açıklandığı gibi oynatıcısının oynatma listesini doğrudan değiştirebilir.
Denetleyiciler, COMMAND_SET_MEDIA_ITEM veya COMMAND_CHANGE_MEDIA_ITEMS erişimine sahipse oynatma listesini değiştirebilir.
Oynatma listesine yeni öğeler eklerken oynatıcı, öğelerin oynatılabilmesi için genellikle tanımlanmış URI'ye sahip MediaItem örnekleri gerektirir. Varsayılan olarak, yeni eklenen öğeler, tanımlanmış bir URI'leri varsa player.addMediaItem gibi oynatıcı yöntemlerine otomatik olarak yönlendirilir.
Oynatıcıya eklenen MediaItem örneklerini özelleştirmek istiyorsanız onAddMediaItems() öğesini geçersiz kılabilirsiniz. Bu adım, tanımlı bir URI olmadan medya isteyen denetleyicileri desteklemek istediğinizde gereklidir. Bunun yerine, MediaItem genellikle istenen medyayı açıklamak için aşağıdaki alanlardan birini veya daha fazlasını ayarlar:
MediaItem.mediaId: Medyayı tanımlayan genel bir kimlik.MediaItem.RequestMetadata.mediaUri: Özel bir şema kullanabilen ve oynatıcı tarafından doğrudan oynatılması gerekmeyen bir istek URI'si.MediaItem.RequestMetadata.searchQuery: Metin tabanlı bir arama sorgusu (ör. Gemini veya Google Asistan'dan).MediaItem.mediaMetadata: "Başlık" veya "sanatçı" gibi yapılandırılmış meta veriler.
Tamamen yeni oynatma listeleri için daha fazla özelleştirme seçeneği istiyorsanız onSetMediaItems() yöntemini de geçersiz kılabilirsiniz. Bu yöntem, oynatma listesindeki başlangıç öğesini ve konumunu tanımlamanıza olanak tanır. Örneğin, istenen tek bir öğeyi tüm oynatma listesine genişletebilir ve oynatıcıya, başlangıçta istenen öğenin dizininde başlaması talimatını verebilirsiniz. Bu özelliğin kullanıldığı onSetMediaItems() için örnek bir uygulama görmek istiyorsanız oturum demo uygulamasına bakın.
Medya düğmesi tercihlerini yönetme
Her denetleyici (ör. Sistem Kullanıcı Arayüzü, Android Auto veya Wear OS), kullanıcıya hangi düğmelerin gösterileceğine kendisi karar verebilir. Kullanıcıya göstermek istediğiniz oynatma kontrollerini belirtmek için MediaSession üzerinde medya düğmesi tercihlerini belirtebilirsiniz. Bu tercihler, her biri kullanıcı arayüzündeki bir düğme için tercih tanımlayan sıralı bir CommandButton örneği listesinden oluşur.
Komut düğmelerini tanımlama
CommandButton örnekleri, medya düğmesi tercihlerini tanımlamak için kullanılır. Her düğme, istenen kullanıcı arayüzü öğesinin üç yönünü tanımlar:
- Görsel görünümü tanımlayan simge.
CommandButton.Builderoluşturulurken simge, önceden tanımlanmış sabitlerden birine ayarlanmalıdır. Bunun gerçek bir Bitmap veya resim kaynağı olmadığını unutmayın. Genel bir sabit, denetleyicilerin kendi kullanıcı arayüzlerinde tutarlı bir görünüm ve tarz için uygun bir kaynak seçmesine yardımcı olur. Önceden tanımlanmış simge sabitlerinden hiçbiri kullanım alanınıza uymuyorsa bunun yerinesetCustomIconResIdkullanabilirsiniz. - Kullanıcı düğmeyle etkileşimde bulunduğunda tetiklenen işlemi tanımlayan Command (Komut).
Player.CommandiçinsetPlayerCommand, önceden tanımlanmış veya özelSessionCommandiçinsetSessionCommandkullanabilirsiniz. - Düğmenin kumanda kullanıcı arayüzünde nereye yerleştirileceğini tanımlayan Slot (Yuva). Bu alan isteğe bağlıdır ve Simge ile Komut'a göre otomatik olarak ayarlanır. Örneğin, bir düğmenin varsayılan "taşma" alanı yerine kullanıcı arayüzünün "ileri" gezinme alanında gösterilmesi gerektiğini belirtmenize olanak tanır.
Kotlin
val button = CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD_15) .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) .setSlots(CommandButton.SLOT_FORWARD) .build()
Java
CommandButton button = new CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD_15) .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) .setSlots(CommandButton.SLOT_FORWARD) .build();
Medya düğmesi tercihleri çözümlenirken aşağıdaki algoritma uygulanır:
- Medya düğmesi tercihlerindeki her
CommandButtoniçin düğmeyi izin verilen ilk kullanılabilir yuvaya yerleştirin. - Merkezi, ileri ve geri yuvalardan herhangi biri düğmeyle doldurulmamışsa bu yuva için varsayılan düğmeler ekleyin.
Kullanıcı arayüzü görüntüleme kısıtlamalarına bağlı olarak medya düğmesi tercihlerinin nasıl çözümleneceğine dair bir önizleme oluşturmak için CommandButton.DisplayConstraints kullanabilirsiniz.
Medya düğmesi tercihlerini ayarlama
Medya düğmesi tercihlerini ayarlamanın en kolay yolu, MediaSession oluşturulurken listeyi tanımlamaktır. Alternatif olarak, bağlı her kumandanın medya düğmesi tercihlerini özelleştirmek için MediaSession.Callback.onConnectAsync() değerini geçersiz kılabilirsiniz.
Kotlin
val mediaSession = MediaSession.Builder(context, player) .setMediaButtonPreferences(ImmutableList.of(likeButton, favoriteButton)) .build()
Java
MediaSession mediaSession = new MediaSession.Builder(context, player) .setMediaButtonPreferences(ImmutableList.of(likeButton, favoriteButton)) .build();
Kullanıcı etkileşiminden sonra medya düğmesi tercihlerini güncelleme
Oynatıcınızla etkileşimi işledikten sonra kumanda kullanıcı arayüzünde gösterilen düğmeleri güncellemek isteyebilirsiniz. Bunun tipik bir örneği, kendisiyle ilişkili işlemi tetikledikten sonra simgesini ve işlemini değiştiren açma/kapatma düğmesidir. Medya düğmesi tercihlerini güncellemek için MediaSession.setMediaButtonPreferences kullanarak tüm kumandaların veya belirli bir kumandanın tercihlerini güncelleyebilirsiniz:
Kotlin
// Handle "favoritesButton" action, replace by opposite button mediaSession.setMediaButtonPreferences(ImmutableList.of(likeButton, removeFromFavoritesButton))
Java
// Handle "favoritesButton" action, replace by opposite button mediaSession.setMediaButtonPreferences(ImmutableList.of(likeButton, removeFromFavoritesButton));
Özel komutlar ekleme ve varsayılan davranışı özelleştirme
Mevcut oynatıcı komutları, özel komutlarla genişletilebilir. Ayrıca, varsayılan davranışı değiştirmek için gelen oynatıcı komutlarını ve medya düğmelerini de kesebilirsiniz.
Özel komutları bildirme ve işleme
Medya uygulamaları, örneğin medya düğmesi tercihlerinde kullanılabilecek özel komutlar tanımlayabilir. Örneğin, kullanıcının bir medya öğesini favori öğeler listesine kaydetmesine olanak tanıyan düğmeler ekleyebilirsiniz. MediaController özel komutlar gönderir ve MediaSession.Callback bunları alır.
Özel komutları tanımlamak için bağlı her kumandada kullanılabilir özel komutları ayarlamak üzere MediaSession.Callback.onConnectAsync() değerini geçersiz kılmanız gerekir.
Kotlin
private class CustomMediaSessionCallback : MediaSession.Callback { // Configure commands available to the controller in onConnect() override fun onConnectAsync( session: MediaSession, controller: ControllerInfo, ): ListenableFuture<ConnectionResult> { val sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(SessionCommand(SAVE_TO_FAVORITES, Bundle.EMPTY)) .build() return Futures.immediateFuture( AcceptedResultBuilder(session, controller) .setAvailableSessionCommands(sessionCommands) .build() ) } }
Java
private static class CustomMediaSessionCallback implements MediaSession.Callback { // Configure commands available to the controller in onConnect() @Override public ListenableFuture<ConnectionResult> onConnectAsync( MediaSession session, ControllerInfo controller) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS .buildUpon() .add(new SessionCommand(SAVE_TO_FAVORITES, new Bundle())) .build(); return Futures.immediateFuture( new AcceptedResultBuilder(session, controller) .setAvailableSessionCommands(sessionCommands) .build()); } }
MediaController cihazından özel komut istekleri almak için Callback sınıfındaki onCustomCommand() yöntemini geçersiz kılın.
Kotlin
private class CustomCallback : MediaSession.Callback { // ... override fun onCustomCommand( session: MediaSession, controller: ControllerInfo, customCommand: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { if (customCommand.customAction == SAVE_TO_FAVORITES) { // Do custom logic here saveToFavorites(session.player.currentMediaItem) return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } // ... return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } }
Java
private static class CustomCallback implements MediaSession.Callback { // ... @Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args) { if (customCommand.customAction.equals(SAVE_TO_FAVORITES)) { // Do custom logic here saveToFavorites(session.getPlayer().getCurrentMediaItem()); return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } // ... return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } }
Callback yöntemlerine iletilen MediaSession.ControllerInfo nesnesinin packageName özelliğini kullanarak hangi medya kumandasının istekte bulunduğunu takip edebilirsiniz. Bu sayede, sistemden, kendi uygulamanızdan veya diğer istemci uygulamalarından gelen belirli bir komuta yanıt olarak uygulamanızın davranışını özelleştirebilirsiniz.
Varsayılan oynatıcı komutlarını özelleştirme
Tüm varsayılan komutlar ve durum işleme, MediaSession üzerindeki Player öğesine devredilir. Player arayüzünde tanımlanan bir komutun (ör. play() veya seekToNext()) davranışını özelleştirmek için Player öğenizi MediaSession öğesine iletmeden önce bir ForwardingSimpleBasePlayer içine sarmalayın:
Kotlin
val forwardingPlayer = object : ForwardingSimpleBasePlayer(player) { // Customizations } val mediaSession = MediaSession.Builder(context, forwardingPlayer).build()
Java
ForwardingSimpleBasePlayer forwardingPlayer = new ForwardingSimpleBasePlayer(player) { // Customizations }; MediaSession mediaSession = new MediaSession.Builder(context, forwardingPlayer).build();
ForwardingSimpleBasePlayer hakkında daha fazla bilgi için Özelleştirme ile ilgili ExoPlayer kılavuzuna bakın.
Oynatıcı komutunu isteyen denetleyiciyi tanımlama
Bir Player yöntemine yapılan çağrı MediaController tarafından başlatıldığında, kaynağı MediaSession.controllerForCurrentRequest ile tanımlayabilir ve mevcut istek için ControllerInfo değerini alabilirsiniz:
Kotlin
private class CallerAwarePlayer(player: Player) : ForwardingSimpleBasePlayer(player) { private lateinit var session: MediaSession override fun handleSeek( mediaItemIndex: Int, positionMs: Long, seekCommand: Int, ): ListenableFuture<*> { Log.d( "caller", "seek operation from package ${session.controllerForCurrentRequest?.packageName}", ) return super.handleSeek(mediaItemIndex, positionMs, seekCommand) } }
Java
private static final class CallerAwarePlayer extends ForwardingSimpleBasePlayer { private MediaSession session; public CallerAwarePlayer(Player player) { super(player); } @Override protected ListenableFuture<?> handleSeek(int mediaItemIndex, long positionMs, int seekCommand) { Log.d( "caller", "seek operation from package: " + session.getControllerForCurrentRequest().getPackageName()); return super.handleSeek(mediaItemIndex, positionMs, seekCommand); } }
Medya düğmesi kullanımını özelleştirme
Medya düğmeleri, Android cihazlarda ve diğer çevre birimlerinde bulunan donanım düğmeleridir (ör. Bluetooth mikrofonlu kulaklıktaki oynat/duraklat düğmesi). Media3, oturuma ulaştıklarında medya düğmesi etkinliklerini sizin için işler ve oturum oynatıcıda uygun Player yöntemini çağırır.
Gelen tüm medya düğmesi etkinliklerini ilgili Player yönteminde işlemeniz önerilir. Daha gelişmiş kullanım alanları için medya düğmesi etkinlikleri MediaSession.Callback.onMediaButtonEvent() içinde kesilebilir.
Hata işleme ve raporlama
Bir oturumun oluşturduğu ve denetleyicilere bildirdiği iki tür hata vardır. Önemli hatalar, oturum oynatıcısının oynatmayı kesintiye uğratan teknik bir oynatma hatası bildirdiğini gösterir. Önemli hatalar, meydana geldiklerinde denetleyiciye otomatik olarak bildirilir. Önemli olmayan hatalar, oynatmayı kesintiye uğratmayan ve uygulama tarafından denetleyicilere manuel olarak gönderilen teknik olmayan veya politikayla ilgili hatalardır.
Önemli oynatma hataları
Oynatıcı tarafından oturuma önemli bir oynatma hatası bildirilir ve ardından Player.Listener.onPlayerError(PlaybackException) ve Player.Listener.onPlayerErrorChanged(@Nullable PlaybackException) üzerinden çağrı yapmak için denetleyicilere bildirilir.
Böyle bir durumda, oynatma durumu STATE_IDLE olarak değiştirilir ve MediaController.getPlayerError(), geçişe neden olan PlaybackException değerini döndürür. Denetleyici, hatanın nedeni hakkında bilgi edinmek için PlaybackException.errorCode öğesini inceleyebilir.
Özel oynatıcı hatası ayarlama
Oynatıcı tarafından bildirilen önemli hatalara ek olarak, bir uygulama MediaSession.setPlaybackException(PlaybackException) kullanarak MediaSession düzeyinde özel bir PlaybackException ayarlayabilir. Bu izin, uygulamanın bağlı kumandalara hata durumu sinyali göndermesine olanak tanır. İstisna, tüm bağlı denetleyiciler veya belirli bir ControllerInfo için ayarlanabilir.
Bir uygulama bu API'yi kullanarak PlaybackException ayarladığında:
Bağlı
MediaControllerörneklere bildirim gönderilir. DenetleyicidekiListener.onPlayerError(PlaybackException)veListener.onPlayerErrorChanged(@Nullable PlaybackException)geri çağırmaları, sağlanan istisnayla çağrılır.MediaController.getPlayerError()yöntemi, uygulama tarafından ayarlananPlaybackExceptiondeğerini döndürür.Etkilenen denetleyicilerin oynatma durumu
Player.STATE_IDLEolarak değişir.Mevcut komutlar kaldırılır ve yalnızca
COMMAND_GET_TIMELINEgibi okuma komutları (daha önce verilmişse) kalır. Örneğin,Timelinedurumu, istisna denetleyiciye uygulandığında dondurulur. Oynatıcının durumunu değiştirmeye çalışan komutlar (ör.COMMAND_PLAY), ilgili denetleyicinin oynatma istisnası uygulama tarafından kaldırılana kadar kaldırılır.
Daha önce ayarlanmış özel bir PlaybackException değerini temizlemek ve normal oynatıcı durumu raporlamasını geri yüklemek için bir uygulama MediaSession.setPlaybackException(/* playbackException= */ null) veya MediaSession.setPlaybackException(ControllerInfo,
/* playbackException= */ null) yöntemini çağırabilir.
Önemli hataları özelleştirme
Kullanıcıya yerelleştirilmiş ve anlamlı bilgiler sağlamak için gerçek oynatıcıdan gelen önemli bir oynatma hatasının hata kodunu, hata mesajını ve hata eklerini özelleştirebilirsiniz. Bunun için oturumu oluştururken ForwardingSimpleBasePlayer kullanın:
Kotlin
val session = MediaSession.Builder(context, ErrorForwardingPlayer(context, player)).build()
Java
MediaSession session = new MediaSession.Builder(context, new ErrorForwardingPlayer(context, player)).build();
ForwardingSimpleBasePlayer alt sınıfınız, hatayı yakalamak ve hata kodunu, mesajı veya ekstraları özelleştirmek için getState() yöntemini geçersiz kılabilir. Aynı şekilde, orijinal oynatıcıda bulunmayan yeni hatalar da oluşturabilirsiniz:
Kotlin
private class ErrorForwardingPlayer(private val context: Context, player: Player) : ForwardingSimpleBasePlayer(player) { override fun getState(): State { var state = super.getState() if (state.playerError != null) { state = state.buildUpon().setPlayerError(customizePlaybackException(state.playerError!!)).build() } return state } private fun customizePlaybackException(error: PlaybackException): PlaybackException { val buttonLabel: String val errorMessage: String when (error.errorCode) { PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW -> { buttonLabel = context.getString(R.string.err_button_label_restart_stream) errorMessage = context.getString(R.string.err_msg_behind_live_window) } else -> { buttonLabel = context.getString(R.string.err_button_label_ok) errorMessage = context.getString(R.string.err_message_default) } } val extras = Bundle() extras.putString("button_label", buttonLabel) return PlaybackException(errorMessage, error.cause, error.errorCode, extras) } }
Java
private static class ErrorForwardingPlayer extends ForwardingSimpleBasePlayer { private final Context context; public ErrorForwardingPlayer(Context context, Player player) { super(player); this.context = context; } @Override protected State getState() { State state = super.getState(); if (state.playerError != null) { state = state.buildUpon().setPlayerError(customizePlaybackException(state.playerError)).build(); } return state; } private PlaybackException customizePlaybackException(PlaybackException error) { String buttonLabel; String errorMessage; switch (error.errorCode) { case PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW: buttonLabel = context.getString(R.string.err_button_label_restart_stream); errorMessage = context.getString(R.string.err_msg_behind_live_window); break; default: buttonLabel = context.getString(R.string.err_button_label_ok); errorMessage = context.getString(R.string.err_message_default); break; } Bundle extras = new Bundle(); extras.putString("button_label", buttonLabel); return new PlaybackException(errorMessage, error.getCause(), error.errorCode, extras); } }
Önemli olmayan hatalar
Teknik bir istisnadan kaynaklanmayan önemli olmayan hatalar, bir uygulama tarafından tüm denetleyicilere veya belirli bir denetleyiciye gönderilebilir:
Kotlin
val sessionError = SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired), ) // Option 1: Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError) // Option 2: Sending a nonfatal error to the media notification controller only // to set the error code and error message in the playback state of the platform // media session. mediaSession.mediaNotificationControllerInfo?.let { mediaSession.sendError(it, sessionError) }
Java
SessionError sessionError = new SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired)); // Option 1: Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError); // Option 2: Sending a nonfatal error to the media notification controller only // to set the error code and error message in the playback state of the platform // media session. ControllerInfo mediaNotificationControllerInfo = mediaSession.getMediaNotificationControllerInfo(); if (mediaNotificationControllerInfo != null) { mediaSession.sendError(mediaNotificationControllerInfo, sessionError); }
Medya bildirim denetleyicisine önemli olmayan bir hata gönderildiğinde hata kodu ve hata mesajı, platform medya oturumuna kopyalanır ancak PlaybackState.state, STATE_ERROR olarak değiştirilmez.
Önemli olmayan hataları alma
MediaController, MediaController.Listener.onError uygulayarak önemli olmayan bir hata alır:
Kotlin
val future = MediaController.Builder(context, sessionToken) .setListener( object : MediaController.Listener { override fun onError(controller: MediaController, sessionError: SessionError) { // Handle nonfatal error. } } ) .buildAsync()
Java
MediaController.Builder future = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public void onError(MediaController controller, SessionError sessionError) { // Handle nonfatal error. } });