ExoPlayer, çok çeşitli oynatma analizi ihtiyaçlarını destekler. Sonuç olarak analiz, oynatmalardan gelen verilerin toplanması, yorumlanması, birleştirilmesi ve özetlenmesiyle ilgilidir. Bu veriler cihazda (örneğin günlüğe kaydetme, hata ayıklama veya gelecekteki oynatma kararlarını şekillendirmek amacıyla) kullanılabilir ya da tüm cihazlardaki oynatmaları izlemek için bir sunucuya bildirilebilir.
Analiz sistemlerinin genellikle önce etkinlikleri toplaması ve ardından daha anlamlı hale getirmek için bunları işlemesi gerekir:
- Etkinlik toplama:
Bu işlem,
ExoPlayer
örneğine birAnalyticsListener
kaydedilerek yapılabilir. Kayıtlı analiz dinleyicileri, oynatıcıyı kullanırken gerçekleşen etkinlikleri alır. Her etkinlik, oynatma konumu ve zaman damgası meta verilerinin yanı sıra oynatma listesindeki ilgili medya öğesiyle ilişkilendirilir. - Etkinlik işleme: Bazı analiz sistemleri, ham etkinlikleri bir sunucuya yükler. Tüm etkinlik işlemleri sunucu tarafında gerçekleştirilir. Etkinliklerin cihazda işlenmesi de mümkündür ve bu işlem daha basit olabilir ya da yüklenmesi gereken bilgi miktarını azaltabilir. ExoPlayer, aşağıdaki işleme adımlarını gerçekleştirmenizi sağlayan
PlaybackStatsListener
özelliğini sunar:- Etkinlik yorumlaması: Analiz açısından faydalı olması için etkinliklerin tek bir oynatma bağlamında yorumlanması gerekir. Örneğin, oyuncu durumunun
STATE_BUFFERING
olarak değişmesinin ham etkinliği, aramadan sonra gerçekleşen ilk arabelleğe alma, yeniden arabelleğe alma veya arabelleğe alma işlemine karşılık gelebilir. - Durum izleme: Bu adım etkinlikleri sayaçlara dönüştürür. Örneğin, durum değişikliği etkinlikleri, her bir oynatma durumunda ne kadar zaman harcandığını izleyen sayaçlara dönüştürülebilir. Sonuçta, tek bir oynatma için temel bir analiz veri değerleri grubu elde edilir.
- Toplama: Bu adım, genellikle sayaçlar toplanarak birden fazla oynatmadaki analiz verilerini birleştirir.
- Özet metriklerin hesaplanması: En faydalı metriklerin çoğu, ortalamaları hesaplayan veya temel analiz veri değerlerini başka şekillerde birleştiren metriklerdir. Özet metrikler, bir veya birden fazla oynatma için hesaplanabilir.
- Etkinlik yorumlaması: Analiz açısından faydalı olması için etkinliklerin tek bir oynatma bağlamında yorumlanması gerekir. Örneğin, oyuncu durumunun
AnalyticsListener ile etkinlik toplama
Oynatıcıdan gelen ham oynatma etkinlikleri AnalyticsListener
uygulamaya bildirilir. Kendi işleyicinizi kolayca ekleyebilir ve yalnızca ilgilendiğiniz yöntemleri geçersiz kılabilirsiniz:
Kotlin
exoPlayer.addAnalyticsListener( object : AnalyticsListener { override fun onPlaybackStateChanged( eventTime: EventTime, @Player.State state: Int ) {} override fun onDroppedVideoFrames( eventTime: EventTime, droppedFrames: Int, elapsedMs: Long, ) {} } )
Java
exoPlayer.addAnalyticsListener( new AnalyticsListener() { @Override public void onPlaybackStateChanged( EventTime eventTime, @Player.State int state) {} @Override public void onDroppedVideoFrames( EventTime eventTime, int droppedFrames, long elapsedMs) {} });
Her geri çağırmaya aktarılan EventTime
, etkinliği oynatma listesindeki bir medya öğesinin yanı sıra oynatma konumu ve zaman damgası meta verileriyle ilişkilendirir:
realtimeMs
: Etkinliğin gerçek saati.timeline
,windowIndex
vemediaPeriodId
: Oynatma listesini ve oynatma listesinde etkinliğin ait olduğu öğeyi tanımlar.mediaPeriodId
, isteğe bağlı ek bilgiler içerir (örneğin, etkinliğin öğedeki bir reklama ait olup olmadığını belirtir).eventPlaybackPositionMs
: Etkinlik gerçekleştiğinde öğenin oynatma konumudur.currentTimeline
,currentWindowIndex
,currentMediaPeriodId
vecurrentPlaybackPositionMs
: Yukarıdaki gibidir ancak şu anda oynatılan öğe için geçerlidir. Şu anda oynatılan öğe, etkinliğin ait olduğu öğeden farklı olabilir. Örneğin, etkinlik, oynatılacak sonraki öğenin önceden arabelleğe alınmasına karşılık geliyorsa.
PlaybackStatsListener ile etkinlik işleme
PlaybackStatsListener
, cihaz üzerinde etkinlik işlemeyi uygulayan bir AnalyticsListener
'dir. PlaybackStats
işlemini, sayaçlar ve aşağıdakiler gibi türetilmiş metriklerle hesaplar:
- Toplam oynatma süresi gibi özet metrikler.
- Ortalama video çözünürlüğü gibi uyarlanabilir oynatma kalitesi metrikleri.
- Atlanan karelerin hızı gibi kalite metrikleri oluşturma.
- Ağda okunan bayt sayısı gibi kaynak kullanım metrikleri.
Kullanılabilir sayıların ve türetilen metriklerin tam listesini PlaybackStats
Javadoc'ta bulabilirsiniz.
PlaybackStatsListener
, oynatma listesindeki her bir medya öğesi ve bu öğelere eklenen her bir istemci tarafı reklam için ayrı PlaybackStats
hesaplar. Sona eren oynatmalar hakkında bilgi almak için PlaybackStatsListener
için bir geri çağırma sağlayabilir ve hangi oynatmanın sona erdiğini belirlemek için geri çağırmaya iletilen EventTime
parametresini kullanabilirsiniz. Birden çok oynatma için analiz verileri toplanabilir. Ayrıca, PlaybackStatsListener.getPlaybackStats()
kullanarak dilediğiniz zaman mevcut oynatma oturumu için PlaybackStats
sorgusunu sorgulayabilirsiniz.
Kotlin
exoPlayer.addAnalyticsListener( PlaybackStatsListener(/* keepHistory= */ true) { eventTime: EventTime?, playbackStats: PlaybackStats?, -> // Analytics data for the session started at `eventTime` is ready. } )
Java
exoPlayer.addAnalyticsListener( new PlaybackStatsListener( /* keepHistory= */ true, (eventTime, playbackStats) -> { // Analytics data for the session started at `eventTime` is ready. }));
PlaybackStatsListener
oluşturucusu, işlenen etkinliklerin tüm geçmişini saklama seçeneği sunar. Bu işlemin, oynatmanın uzunluğuna ve etkinlik sayısına bağlı olarak bilinmeyen bir bellek ek yüküne neden olabileceğini unutmayın. Bu nedenle, yalnızca nihai analiz verilerine değil, yalnızca işlenen etkinliklerin tüm geçmişine erişmeniz gerektiğinde bu özelliği etkinleştirmeniz gerekir.
PlaybackStats
cihazının yalnızca medyanın durumunu değil, aynı zamanda kullanıcının oynatma niyetini ve oynatmanın neden kesintiye uğradığı ya da sonlandırıldığı gibi daha ayrıntılı bilgileri belirtmek için genişletilmiş bir durum grubu kullandığını unutmayın:
Oynatma durumu | Kullanıcı oynamak istiyor | Oynamak istemiyorum |
---|---|---|
Oynatmadan önce | JOINING_FOREGROUND |
NOT_STARTED , JOINING_BACKGROUND |
Etkin oynatma | PLAYING |
|
Oynatma kesintiye uğradı | BUFFERING , SEEKING |
PAUSED , PAUSED_BUFFERING , SUPPRESSED , SUPPRESSED_BUFFERING , INTERRUPTED_BY_AD |
Bitiş eyaletleri | ENDED , STOPPED , FAILED , ABANDONED |
Kullanıcının oynatma niyetinde olduğu anlar, etkin bir şekilde oynatmanın devam etmesini beklediği zamanları pasif bekleme sürelerinden ayırt etmek için önemlidir. Örneğin PlaybackStats.getTotalWaitTimeMs
, JOINING_FOREGROUND
, BUFFERING
ve SEEKING
durumlarında harcanan toplam süreyi döndürür, ancak oynatmanın duraklatıldığı zamanı döndürmez. Benzer şekilde PlaybackStats.getTotalPlayAndWaitTimeMs
, kullanıcının oyun oynama niyetine sahip toplam süreyi, yani toplam etkin bekleme süresini ve PLAYING
durumunda harcanan toplam süreyi döndürür.
İşlenen ve yorumlanan etkinlikler
keepHistory=true
ile PlaybackStatsListener
kullanarak işlenen ve yorumlanan etkinlikleri kaydedebilirsiniz. Sonuçta elde edilen PlaybackStats
aşağıdaki etkinlik listelerini içerir:
playbackStateHistory
: Uygulanmaya başlandığıEventTime
ile birlikte genişletilmiş oynatma durumlarının sıralı listesi. Belirli bir gerçek saatteki durumu aramak içinPlaybackStats.getPlaybackStateAtTime
özelliğini de kullanabilirsiniz.mediaTimeHistory
: Medyanın hangi bölümlerinin hangi zamanda oynatıldığını yeniden oluşturmanıza olanak tanıyan gerçek zamanlı saat ve medya zaman çiftleri geçmişi. Belirli bir gerçek zamandaki oynatma konumunu bulmak içinPlaybackStats.getMediaTimeMsAtRealtimeMs
öğesini de kullanabilirsiniz.videoFormatHistory
veaudioFormatHistory
: Kullanıma sunulduklarıEventTime
ile oynatma sırasında kullanılan video ve ses biçimlerinin sıralı listeleri.fatalErrorHistory
venonFatalErrorHistory
: Önemli ve önemli olmayan hataların, meydana geldikleriEventTime
ile sıralanmış listeleri. Önemli hatalar, oynatmanın sonlandırılmasına yol açan hatalardır. Öte yandan, önemli olmayan hatalar kurtarılabilir.
Tek oynatmalık analiz verileri
Bu veriler, keepHistory=false
ile bile PlaybackStatsListener
kullanıyorsanız otomatik olarak toplanır. Son değerler, PlaybackStats
Javadoc'ta bulabileceğiniz herkese açık alanlar ve getPlaybackStateDurationMs
tarafından döndürülen oynatma durumu süreleridir. Size kolaylık sağlaması için belirli oynatma durumu kombinasyonlarının süresini döndüren getTotalPlayTimeMs
ve getTotalWaitTimeMs
gibi yöntemler de bulabilirsiniz.
Kotlin
Log.d( "DEBUG", "Playback summary: " + "play time = " + playbackStats.totalPlayTimeMs + ", rebuffers = " + playbackStats.totalRebufferCount )
Java
Log.d( "DEBUG", "Playback summary: " + "play time = " + playbackStats.getTotalPlayTimeMs() + ", rebuffers = " + playbackStats.totalRebufferCount);
Birden fazla oynatmanın analiz verilerini birleştirme
PlaybackStats.merge
yöntemini çağırarak birden fazla PlaybackStats
öğesini birleştirebilirsiniz. Sonuçta elde edilen PlaybackStats
, birleştirilen tüm oynatmaların toplu verilerini içerir. Oynatma etkinliklerinin tek tek geçmişini içermeyeceğini unutmayın. Bunlar birleştirilemez.
PlaybackStatsListener.getCombinedPlaybackStats
, bir PlaybackStatsListener
kullanım ömrü boyunca toplanan tüm analiz verilerinin toplu görünümünü elde etmek için kullanılabilir.
Hesaplanmış özet metrikleri
PlaybackStats
, özet metriklerini hesaplamak için temel analiz verilerine ek olarak birçok yöntem sunar.
Kotlin
Log.d( "DEBUG", "Additional calculated summary metrics: " + "average video bitrate = " + playbackStats.meanVideoFormatBitrate + ", mean time between rebuffers = " + playbackStats.meanTimeBetweenRebuffers )
Java
Log.d( "DEBUG", "Additional calculated summary metrics: " + "average video bitrate = " + playbackStats.getMeanVideoFormatBitrate() + ", mean time between rebuffers = " + playbackStats.getMeanTimeBetweenRebuffers());
İleri düzey konular
Analiz verilerini oynatma meta verileriyle ilişkilendirme
Ayrı ayrı oynatmalar için analiz verilerini toplarken oynatma analiz verilerini, oynatılan medyayla ilgili meta verilerle ilişkilendirmek isteyebilirsiniz.
Medyaya özel meta verileri MediaItem.Builder.setTag
ile ayarlamanız önerilir.
Medya etiketi, ham etkinlikler için bildirilen ve PlaybackStats
tamamlandığında bildirilen EventTime
kapsamında yer alır. Bu sayede, ilgili analiz verileri işlenirken kolayca alınabilir:
Kotlin
PlaybackStatsListener(/* keepHistory= */ false) { eventTime: EventTime, playbackStats: PlaybackStats -> val mediaTag = eventTime.timeline .getWindow(eventTime.windowIndex, Timeline.Window()) .mediaItem .localConfiguration ?.tag // Report playbackStats with mediaTag metadata. }
Java
new PlaybackStatsListener( /* keepHistory= */ false, (eventTime, playbackStats) -> { Object mediaTag = eventTime.timeline.getWindow(eventTime.windowIndex, new Timeline.Window()) .mediaItem .localConfiguration .tag; // Report playbackStats with mediaTag metadata. });
Özel analiz etkinliklerini raporlama
Analiz verilerine özel etkinlikler eklemeniz gerekirse bu etkinlikleri kendi veri yapınıza kaydetmeniz ve daha sonra raporlanan PlaybackStats
etkinliğiyle birleştirmeniz gerekir. İşe yararsa özel etkinlikleriniz için EventTime
örnekleri oluşturabilmek ve bunları aşağıdaki örnekte gösterildiği gibi önceden kayıtlı işleyicilere göndermek amacıyla DefaultAnalyticsCollector
kapsamını genişletebilirsiniz.
Kotlin
private interface ExtendedListener : AnalyticsListener { fun onCustomEvent(eventTime: EventTime) } private class ExtendedCollector : DefaultAnalyticsCollector(Clock.DEFAULT) { fun customEvent() { val eventTime = generateCurrentPlayerMediaPeriodEventTime() sendEvent(eventTime, CUSTOM_EVENT_ID) { listener: AnalyticsListener -> if (listener is ExtendedListener) { listener.onCustomEvent(eventTime) } } } } // Usage - Setup and listener registration. val player = ExoPlayer.Builder(context).setAnalyticsCollector(ExtendedCollector()).build() player.addAnalyticsListener( object : ExtendedListener { override fun onCustomEvent(eventTime: EventTime?) { // Save custom event for analytics data. } } ) // Usage - Triggering the custom event. (player.analyticsCollector as ExtendedCollector).customEvent()
Java
private interface ExtendedListener extends AnalyticsListener { void onCustomEvent(EventTime eventTime); } private static class ExtendedCollector extends DefaultAnalyticsCollector { public ExtendedCollector() { super(Clock.DEFAULT); } public void customEvent() { AnalyticsListener.EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime(); sendEvent( eventTime, CUSTOM_EVENT_ID, listener -> { if (listener instanceof ExtendedListener) { ((ExtendedListener) listener).onCustomEvent(eventTime); } }); } } // Usage - Setup and listener registration. ExoPlayer player = new ExoPlayer.Builder(context).setAnalyticsCollector(new ExtendedCollector()).build(); player.addAnalyticsListener( (ExtendedListener) eventTime -> { // Save custom event for analytics data. }); // Usage - Triggering the custom event. ((ExtendedCollector) player.getAnalyticsCollector()).customEvent();