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şlayacakPlayer.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:
reason=DISCONTINUITY_REASON_SEEK
ileonPositionDiscontinuity
. Bu,Player.seekTo
çağrısının doğrudan sonucudur. Geri çağırmanın aramadan önceki ve sonraki konum içinPositionInfo
alanı vardır.- 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
veyaonMediaItemTransition
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 deonPlayWhenReadyChanged
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şlevininonTimelineChanged
içinde sağlananTimeline
ile birlikte kullanılması, yalnızcaonEvents
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();