Oyuncu etkinlikleri

Oynatma etkinliklerini dinleme

Durum değişiklikleri ve oynatma hataları gibi etkinlikler, kayıtlı Player.Listener örneklerine bildirilir. Bu tür etkinlikleri almak için bir dinleyici kaydetmek üzere:

Kotlin

// Add a listener to receive events from the player.
player.addListener(listener)

Java

// Add a listener to receive events from the player.
player.addListener(listener);

Player.Listener, boş varsayılan yöntemlere sahiptir. Bu nedenle yalnızca ilgilendiğiniz yöntemleri uygulamanız gerekir. Yöntemlerin ve ne zaman çağrıldıklarının tam açıklaması için Javadoc'e bakın. En önemli yöntemlerden bazıları aşağıda daha ayrıntılı olarak açıklanmıştır.

Dinleyiciler, tek tek etkinlik geri çağırmalarını veya bir ya da daha fazla etkinlik birlikte gerçekleştiğinde çağrılan genel bir onEvents geri çağırmayı uygulayabilir. Farklı kullanım alanları için hangisinin tercih edilmesi gerektiğiyle ilgili açıklama için Individual callbacks vs onEvents bölümüne bakın.

Oynatma durumu değişiklikleri

Oynatıcı durumundaki değişiklikler, kayıtlı bir Player.Listener içinde onPlaybackStateChanged(@State int state) uygulanarak alınabilir. Oynatıcı, dört oynatma durumundan birinde olabilir:

  • Player.STATE_IDLE: Bu, başlangıç durumu, oynatıcı durdurulduğunda ve oynatma başarısız olduğunda geçerli olan durumdur. Oynatıcı bu durumda yalnızca sınırlı kaynak tutar.
  • Player.STATE_BUFFERING: Oynatıcı, mevcut konumundan hemen oynatmaya başlayamıyor. Bu durumun temel nedeni, daha fazla verinin yüklenmesi gerekmesidir.
  • Player.STATE_READY: Oynatıcı, mevcut konumundan hemen oynatmaya başlayabilir.
  • Player.STATE_ENDED: Oynatıcı, tüm medyaları oynatmayı tamamladı.

Bu durumların yanı sıra, oynatıcıda kullanıcının oynatma isteğini belirtmek için playWhenReady işareti bulunur. Bu işaretle ilgili değişiklikler, onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason) uygulanarak alınabilir.

Aşağıdaki üç koşulun tümü karşılandığında bir oynatıcı oynatılıyor (yani konumu ilerliyor ve kullanıcıya medya sunuluyor) demektir:

  • Oyuncu Player.STATE_READY durumundadır
  • playWhenReady true
  • Oynatma, Player.getPlaybackSuppressionReason tarafından döndürülen bir nedenle engellenmiyor.

Bu özelliklerin tek tek kontrol edilmesi yerine Player.isPlaying çağrılabilir. Bu durumdaki değişiklikler, onIsPlayingChanged(boolean isPlaying) uygulanarak alınabilir:

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
      if (isPlaying) {
        // Active playback.
      } else {
        // Not playing because playback is paused, ended, suppressed, or the player
        // is buffering, stopped or failed. Check player.playWhenReady,
        // player.playbackState, player.playbackSuppressionReason and
        // player.playerError for details.
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onIsPlayingChanged(boolean isPlaying) {
        if (isPlaying) {
          // Active playback.
        } else {
          // Not playing because playback is paused, ended, suppressed, or the player
          // is buffering, stopped or failed. Check player.getPlayWhenReady,
          // player.getPlaybackState, player.getPlaybackSuppressionReason and
          // player.getPlaybackError for details.
        }
      }
    });

Oynatma hataları

Oynatmanın başarısız olmasına neden olan hatalar, kayıtlı bir Player.Listener içinde onPlayerError(PlaybackException error) uygulanarak alınabilir. Bir hata oluştuğunda bu yöntem, oynatma durumu Player.STATE_IDLE olarak değişmeden hemen önce çağrılır. Başarısız olan veya durdurulan oynatmalar, ExoPlayer.prepare çağrılarak yeniden denenebilir.

Bazı Player uygulamalarının, başarısızlık hakkında ek bilgi sağlamak için PlaybackException alt sınıflarının örneklerini ilettiğini unutmayın. Örneğin, ExoPlayer, type, rendererIndex ve ExoPlayer'a özel diğer alanları içeren ExoPlaybackException değerini iletir.

Aşağıdaki örnekte, HTTP ağ iletişimi sorunu nedeniyle oynatmanın başarısız olduğu durumun nasıl tespit edileceği gösterilmektedir:

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onPlayerError(error: PlaybackException) {
      val cause = error.cause
      if (cause is HttpDataSourceException) {
        // An HTTP error occurred.
        val httpError = cause
        // It's possible to find out more about the error both by casting and by querying
        // the cause.
        if (httpError is InvalidResponseCodeException) {
          // Cast to InvalidResponseCodeException and retrieve the response code, message
          // and headers.
        } else {
          // Try calling httpError.getCause() to retrieve the underlying cause, although
          // note that it may be null.
        }
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onPlayerError(PlaybackException error) {
        @Nullable Throwable cause = error.getCause();
        if (cause instanceof HttpDataSourceException) {
          // An HTTP error occurred.
          HttpDataSourceException httpError = (HttpDataSourceException) cause;
          // It's possible to find out more about the error both by casting and by querying
          // the cause.
          if (httpError instanceof HttpDataSource.InvalidResponseCodeException) {
            // Cast to InvalidResponseCodeException and retrieve the response code, message
            // and headers.
          } else {
            // Try calling httpError.getCause() to retrieve the underlying cause, although
            // note that it may be null.
          }
        }
      }
    });

Oynatma listesi geçişleri

Oynatıcı, oynatma listesindeki yeni bir medya öğesine her geçtiğinde, kayıtlı Player.Listener nesnelerinde onMediaItemTransition(MediaItem mediaItem, @MediaItemTransitionReason int reason) çağrılır. Nedeni, bunun otomatik bir geçiş mi, arama mı (örneğin, player.next() arandıktan sonra), aynı öğenin tekrarı mı yoksa oynatma listesi değişikliğinden mi (örneğin, şu anda oynatılan öğe kaldırılırsa) kaynaklandığını gösterir.

Meta veri

player.getCurrentMediaMetadata()'dan döndürülen meta veriler birçok nedenden dolayı değişebilir: oynatma listesi geçişleri, akış içi meta veri güncellemeleri veya mevcut MediaItem'nın oynatma sırasında güncellenmesi.

Meta veri değişiklikleriyle ilgileniyorsanız (ör. mevcut başlığı gösteren bir kullanıcı arayüzünü güncellemek için) onMediaMetadataChanged dinleyebilirsiniz.

Oynatma konumu değiştiriliyor

Player.seekTo yöntemlerinin çağrılması, kayıtlı Player.Listener örneklerine yönelik bir dizi geri çağırmayla sonuçlanır:

  1. reason=DISCONTINUITY_REASON_SEEK ile onPositionDiscontinuity. Bu, Player.seekTo numarası arandığında doğrudan sonuç olarak gösterilir. Geri çağırma işlevinde, arama işleminden önceki ve sonraki konum için PositionInfo alanları bulunur.
  2. Aramayla ilgili herhangi bir anlık durum değişikliğiyle onPlaybackStateChanged Böyle bir değişiklik olmayabileceğini unutmayın.

Bireysel geri aramalar ve onEvents

Dinleyiciler, onIsPlayingChanged(boolean isPlaying) gibi tek tek geri çağırma işlevlerini ve genel onEvents(Player player, Events events) geri çağırma işlevini kullanabilir. Genel geri çağırma, Player nesnesine erişim sağlar ve birlikte gerçekleşen events kümesini belirtir. Bu geri çağırma, her zaman tek tek etkinliklere karşılık gelen geri çağırmalardan sonra çağrılır.

Kotlin

override fun onEvents(player: Player, events: Player.Events) {
  if (
    events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) ||
      events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)
  ) {
    uiModule.updateUi(player)
  }
}

Java

@Override
public void onEvents(Player player, Events events) {
  if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED)
      || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) {
    uiModule.updateUi(player);
  }
}

Aşağıdaki durumlarda bağımsız etkinlikler tercih edilmelidir:

  • Dinleyici, değişikliklerin nedenlerini merak ediyor. Örneğin, onPlayWhenReadyChanged veya onMediaItemTransition için sağlanan nedenler.
  • Dinleyici yalnızca geri çağırma parametreleri aracılığıyla sağlanan yeni değerlere göre hareket eder veya geri çağırma parametrelerine bağlı olmayan başka bir şeyi tetikler.
  • Dinleyici uygulaması, yöntem adında etkinliği neyin tetiklediğine dair net ve okunabilir bir göstergeyi tercih eder.
  • Dinleyici, tüm bireysel etkinlikler ve durum değişiklikleri hakkında bilgi sahibi olması gereken bir analiz sistemine rapor gönderir.

Aşağıdaki durumlarda genel onEvents(Player player, Events events) tercih edilmelidir:

  • Dinleyici, birden fazla etkinlik için aynı mantığı tetiklemek istiyor. Örneğin, hem onPlaybackStateChanged hem de onPlayWhenReadyChanged için kullanıcı arayüzünü güncelleme.
  • Dinleyicinin, başka etkinlikleri tetiklemek için Player nesnesine erişmesi gerekir. Örneğin, medya öğesi geçişinden sonra arama yapma.
  • Dinleyici, ayrı geri çağırma işlevleri aracılığıyla bildirilen birden fazla durum değerini birlikte veya Player getter yöntemleriyle birlikte kullanmayı planlıyor. Örneğin, onTimelineChanged içinde sağlanan Timeline ile Player.getCurrentWindowIndex() kullanmak yalnızca onEvents geri çağırma işlevi içinde güvenlidir.
  • Dinleyici, etkinliklerin mantıksal olarak birlikte gerçekleşip gerçekleşmediğiyle ilgilenir. Örneğin, bir medya öğesi geçişi nedeniyle onPlaybackStateChanged yerine STATE_BUFFERING.

Bazı durumlarda dinleyicilerin, tek tek geri aramaları genel onEvents geri aramasıyla birleştirmesi gerekebilir. Örneğin, medya öğesi değişikliği nedenlerini onMediaItemTransition ile kaydetmek için bu birleştirme işlemi yapılabilir. Ancak yalnızca tüm durum değişiklikleri onEvents içinde birlikte kullanılabildiğinde işlem yapılabilir.

AnalyticsListener kullanılıyor

ExoPlayer kullanılırken addAnalyticsListener aranarak oynatıcıya AnalyticsListener kaydedilebilir. AnalyticsListener uygulamaları, analiz ve günlük kaydı amaçları için yararlı olabilecek ayrıntılı etkinlikleri dinleyebilir. Daha fazla bilgi için lütfen Analytics sayfasını inceleyin.

EventLogger kullanılıyor

EventLogger, günlük kaydı amacıyla doğrudan kitaplık tarafından sağlanan bir AnalyticsListener'dır. Tek bir satırla yararlı ek günlük kaydını etkinleştirmek için EventLogger öğesini ExoPlayer öğesine ekleyin:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

Daha fazla ayrıntı için hata ayıklama günlüğü sayfasına bakın.

Belirtilen oynatma konumlarında etkinlik tetikleme

Bazı kullanım alanlarında, etkinliklerin belirli oynatma konumlarında tetiklenmesi gerekir. Bu özellik, PlayerMessage kullanılarak desteklenir. PlayerMessage, ExoPlayer.createMessage kullanılarak oluşturulabilir. PlayerMessage.setPosition kullanılarak yürütülmesi gereken oynatma konumu ayarlanabilir. İletiler varsayılan olarak oynatma iş parçacığında yürütülür ancak bu, PlayerMessage.setLooper kullanılarak özelleştirilebilir. PlayerMessage.setDeleteAfterDelivery, mesajın belirtilen oynatma konumu her karşılaşıldığında (arama ve tekrar modları nedeniyle bu durum birden çok kez gerçekleşebilir) mı yoksa yalnızca ilk kez mi yürütüleceğini kontrol etmek için kullanılabilir. PlayerMessage yapılandırıldıktan sonra PlayerMessage.send kullanılarak planlanabilir.

Kotlin

player
  .createMessage { messageType: Int, payload: Any? -> }
  .setLooper(Looper.getMainLooper())
  .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120000)
  .setPayload(customPayloadData)
  .setDeleteAfterDelivery(false)
  .send()

Java

player
    .createMessage(
        (messageType, payload) -> {
          // Do something at the specified playback position.
        })
    .setLooper(Looper.getMainLooper())
    .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120_000)
    .setPayload(customPayloadData)
    .setDeleteAfterDelivery(false)
    .send();