Oyuncu etkinlikleri

Oynatma etkinliklerini dinleme

Durum değişiklikleri ve oynatma hataları gibi etkinlikler, kayıtlı Player.Listener örneklerine raporlanır. Bir işleyiciyi bu tür etkinlikleri almak üzere kaydetmek için:

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 için varsayılan yöntemler boş olduğundan yalnızca ilgilendiğiniz yöntemleri uygulamanız gerekir. Yöntemlerin ve çağrıldıkları zamanların tam açıklaması için Javadoc'a bakın. En önemli yöntemlerden bazıları aşağıda ayrıntılı olarak açıklanmıştır.

İşleyiciler tek tek etkinlik geri çağırmalarını veya bir veya daha fazla etkinlik birlikte gerçekleştikten sonra çağrılan genel bir onEvents geri çağırmasını uygulama arasında seçim yapabilir. Farklı kullanım alanlarında hangilerinin tercih edilmesi gerektiğinin açıklaması için Individual callbacks vs onEvents adresine bakın.

Oynatma durumundaki değişiklikler

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

  • Player.STATE_IDLE: Başlangıçtaki durum, oynatıcının durdurulduğu ve oynatmanın başarısız olduğu durumdur. Oynatıcı bu durumda yalnızca sınırlı kaynaklara sahip olur.
  • Player.STATE_BUFFERING: Oyuncu mevcut konumundan hemen oynatamaz. Bu durum, çoğunlukla daha fazla verinin yüklenmesi gerektiği için yaşanır.
  • Player.STATE_READY: Oyuncu mevcut konumundan hemen oynatabilir.
  • Player.STATE_ENDED: Oynatıcı tüm medya içeriğini oynatmayı bitirdi.

Bu durumlara ek olarak oyuncu, kullanıcının oyun oynama niyetini belirtmek için playWhenReady işareti kullanır. Bu işaretteki değişiklikler onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason) uygulanarak alınabilir.

Aşağıdaki koşulların üçü de karşılandığında bir oynatıcı oynamakta (yani konumu ilerlemektedir ve medya kullanıcıya sunulmaktadır):

  • Oynatıcı Player.STATE_READY durumunda
  • playWhenReady, true başlayacak
  • Player.getPlaybackSuppressionReason tarafından döndürülen bir nedenden dolayı oynatma engellenmemiştir

Bu özellikleri tek tek kontrol etmek 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 öğesine onPlayerError(PlaybackException error) uygulanarak alınabilir. Bir hata oluştuğunda, oynatma durumu Player.STATE_IDLE moduna geçmeden hemen önce bu yöntem çağrılır. Başarısız olan veya durdurulan oynatmalar, ExoPlayer.prepare çağrısı yapılarak yeniden denenebilir.

Bazı Player uygulamalarının, hata hakkında ek bilgi sağlamak için PlaybackException alt sınıfları örneklerini ilettiğini unutmayın. Örneğin ExoPlayer, type,rendererIndex ve ExoPlayer'a özgü diğer alanlara sahip ExoPlaybackException aracını geçer.

Aşağıdaki örnekte, HTTP ağ sorunu nedeniyle oynatmanın başarısız olduğu zamanların nasıl algılanacağı 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 geçiş yaptığında onMediaItemTransition(MediaItem mediaItem, @MediaItemTransitionReason int reason), kayıtlı Player.Listener nesneleri çağrılır. Bunun nedeni bunun otomatik bir geçiş mi, arama (örneğin, player.next() çağrısından sonra), aynı öğenin tekrarlanması ya da bir oynatma listesi değişikliğinden (örneğin, o anda oynatılan öğe kaldırılmışsa) kaynaklanıp kaynaklanmadığını belirtir.

Meta veri

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

Geçerli başlığı gösteren bir kullanıcı arayüzünü güncellemek gibi meta veri değişiklikleriyle ilgileniyorsanız onMediaMetadataChanged dilini dinleyebilirsiniz.

Oynatma konumu değiştiriliyor

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

  1. reason=DISCONTINUITY_REASON_SEEK ile onPositionDiscontinuity. Bu, Player.seekTo çağrısının doğrudan sonucudur. Geri çağırmanın aramadan önceki ve sonraki konum için PositionInfo alanı vardır.
  2. Aramayla ilgili acil durum değişikliği içeren onPlaybackStateChanged. Böyle bir değişiklik olmayabileceğini unutmayın.

onEvents ile karşılaştırıldığında bağımsız geri aramalar

İşleyiciler, onIsPlayingChanged(boolean isPlaying) ve genel onEvents(Player player, Events events) geri çağırması gibi bağımsız geri çağırmaları uygulama arasında seçim yapabilir. Genel geri çağırma, Player nesnesine erişim sağlar ve birlikte gerçekleşen events grubunu belirtir. Bu geri çağırma, her zaman bağımsız 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 ayrı etkinlikler tercih edilmelidir:

  • Dinleyici değişikliklerin nedenleriyle ilgilenir. Örneğin, onPlayWhenReadyChanged veya onMediaItemTransition için sağlanan nedenler.
  • İşleyici yalnızca geri çağırma parametreleri aracılığıyla sağlanan yeni değerler üzerinde işlem yapar veya geri çağırma parametrelerine bağlı olmayan başka bir şeyi tetikler.
  • İşleyici uygulaması, yöntem adında etkinliği neyin tetiklediğinin net ve okunabilir bir göstergesini tercih eder.
  • İşleyici, tüm bağımsız olaylar ve durum değişiklikleri hakkında bilgi sahibi olması gereken bir analiz sistemine rapor verir.

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

  • İşleyici, birden fazla etkinlik için aynı mantığı tetiklemek ister. Örneğin, hem onPlaybackStateChanged hem de onPlayWhenReadyChanged için kullanıcı arayüzünü güncelleme.
  • İşleyicinin daha fazla etkinlik (örneğin, bir medya öğesi geçişinden sonra arama) tetiklemek için Player nesnesine erişmesi gerekir.
  • İşleyici, birlikte ayrı geri çağırmalarla veya Player getter yöntemleriyle birlikte raporlanan birden çok durum değerini kullanmayı amaçlar. Örneğin, Player.getCurrentWindowIndex() işlevinin onTimelineChanged içinde sağlanan Timeline ile birlikte kullanılması, yalnızca onEvents geri araması sırasında güvenlidir.
  • Dinleyici, olayların mantıksal olarak birlikte gerçekleşip gerçekleşmediğini merak eder. Örneğin, bir medya öğesi geçişi nedeniyle onPlaybackStateChanged-STATE_BUFFERING.

Bazı durumlarda, dinleyicilerin bağımsız geri çağırmaları genel onEvents geri çağırmasıyla birleştirmesi gerekebilir (örneğin, medya öğesi değişiklik nedenlerini onMediaItemTransition ile kaydetmek için) ancak yalnızca tüm durum değişiklikleri onEvents içinde birlikte kullanılabilir olduğunda işlem yapmalıdır.

AnalyticsListener kullanılıyor

ExoPlayer kullanılırken addAnalyticsListener çağrısı yapılarak oynatıcıya AnalyticsListener kaydedilebilir. AnalyticsListener uygulamaları, analiz ve günlük kaydı için yararlı olabilecek ayrıntılı etkinlikleri dinleyebilir. Daha fazla ayrıntı için lütfen analiz sayfasını inceleyin.

EventLogger kullanılıyor

EventLogger, günlük kaydı amacıyla doğrudan kitaplık tarafından sağlanan bir AnalyticsListener'dir. Tek bir satırla faydalı ek günlük kaydı sağlamak için ExoPlayer öğesine EventLogger ekleyin:

Kotlin

player.addAnalyticsListener(EventLogger())

Java

player.addAnalyticsListener(new EventLogger());

Daha fazla bilgi için hata ayıklama günlük kaydı sayfasını inceleyin.

Belirtilen oynatma konumlarında etkinlik tetikleme

Bazı kullanım alanları, etkinliklerin belirtilen oynatma konumlarında tetiklenmesini gerektirir. Bu, PlayerMessage ile desteklenir. PlayerMessage, ExoPlayer.createMessage ile oluşturulabilir. Yürütülmesi gereken oynatma konumu, PlayerMessage.setPosition kullanılarak ayarlanabilir. Mesajlar varsayılan olarak oynatma iş parçacığında yürütülür ancak PlayerMessage.setLooper kullanılarak özelleştirilebilir. PlayerMessage.setDeleteAfterDelivery, belirtilen oynatma konumuyla her karşılaşıldığında (bu, arama ve tekrarlama modları nedeniyle birden çok kez olabilir) mesajın 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();