ExoPlayer, çok çeşitli oynatma analizi ihtiyaçlarını destekler. Sonuç olarak, analizler oynatmalardan elde edilen verileri toplama, yorumlama, toplama ve özetleme ile ilgilidir. Bu veriler cihazda (ör. günlük kaydı, hata ayıklama veya gelecekteki oynatma kararlarını bildirme için) kullanılabilir ya da tüm cihazlardaki oynatmaları izlemek için bir sunucuya bildirilebilir.
Bir analiz sisteminin anlamlı hale getirmek için önce etkinlikleri toplaması, ardından da daha fazla işlemesi gerekir:
- Etkinlik toplama:
Bu işlem,
ExoPlayerörneğineAnalyticsListenerkaydedilerek yapılabilir. Kayıtlı analiz işleyicileri, oynatıcı kullanılırken etkinlikler gerçekleştiğinde bunları alır. Her etkinlik, oynatma listesindeki ilgili medya öğesinin yanı sıra oynatma konumu ve zaman damgası meta verileriyle ilişkilendirilir. - Etkinlik işleme:
Bazı analiz sistemleri, tüm etkinlik işleme sunucu tarafında gerçekleştirilecek şekilde ham etkinlikleri bir sunucuya yükler. Etkinlikleri cihazda işlemek de mümkündür. Bu işlem daha basit olabilir veya yüklenmesi gereken bilgi miktarını azaltabilir. ExoPlayer,
PlaybackStatsListenersağlar. Bu özellik, aşağıdaki işleme adımlarını uygulamanıza olanak tanır:- Etkinlik yorumlama: Etkinliklerin analiz amacıyla yararlı olması için tek bir oynatma bağlamında yorumlanması gerekir. Örneğin, oynatıcı durumunun
STATE_BUFFERINGolarak değişmesiyle ilgili ham etkinlik; ilk arabelleğe alma, yeniden arabelleğe alma veya arama işleminden sonra gerçekleşen arabelleğe alma ile ilişkili olabilir. - Durum izleme: Bu adımda etkinlikler sayaca dönüştürülür. Örneğin, durum değişikliği etkinlikleri, her oynatma durumunda ne kadar zaman harcandığını izleyen sayaçlara dönüştürülebilir. Sonuç, tek bir oynatma için temel bir analiz verileri değerleri kümesidir.
- Toplama: Bu adımda, genellikle sayaçlar toplanarak birden fazla oynatmadaki Analytics verileri birleştirilir.
- Özet metriklerin hesaplanması: En faydalı metriklerin çoğu, ortalamaları hesaplayan veya temel analiz verisi değerlerini başka şekillerde birleştiren metriklerdir. Özet metrikler tek veya birden fazla oynatma için hesaplanabilir.
- Etkinlik yorumlama: Etkinliklerin analiz amacıyla yararlı olması için tek bir oynatma bağlamında yorumlanması gerekir. Örneğin, oynatıcı durumunun
AnalyticsListener ile etkinlik toplama
Oynatıcıdan gelen ham oynatma etkinlikleri, AnalyticsListener
uygulamalarına bildirilir. Kendi dinleyicinizi 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 iletilen EventTime, etkinliği oynatma listesindeki bir medya öğesiyle, oynatma konumu ve zaman damgası meta verileriyle ilişkilendirir:
realtimeMs: Etkinliğin gerçek saat zamanı.timeline,windowIndexvemediaPeriodId: Oynatma listesini ve etkinliğin ait olduğu oynatma listesindeki öğeyi tanımlar.mediaPeriodIdisteğe bağlı ek bilgiler içerir. Örneğin, etkinliğin öğe içindeki bir reklama ait olup olmadığını belirtir.eventPlaybackPositionMs: Etkinlik gerçekleştiğinde öğedeki oynatma konumu.currentTimeline,currentWindowIndex,currentMediaPeriodIdvecurrentPlaybackPositionMs: Yukarıdakiyle aynıdır 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 bir sonraki öğenin önbelleğe alınmasına karşılık geliyorsa.
PlaybackStatsListener ile etkinlik işleme
PlaybackStatsListener, cihaz üzerinde etkinlik işlemeyi uygulayan bir AnalyticsListener'dir. Aşağıdakiler gibi sayaçlar ve türetilmiş metriklerle PlaybackStats değerini hesaplar:
- Özet metrikler (ör. toplam oynatma süresi)
- Uyarlanabilir oynatma kalitesi metrikleri (ör. ortalama video çözünürlüğü)
- Oluşturma kalitesi metrikleri (ör. bırakılan karelerin oranı)
- Kaynak kullanım metrikleri (ör. ağ üzerinden okunan bayt sayısı).
Kullanılabilir sayıların ve türetilmiş metriklerin tam listesini PlaybackStats Javadoc'ta bulabilirsiniz.
PlaybackStatsListener, oynatma listesindeki her medya öğesi ve bu öğelere yerleştirilen her istemci tarafı reklam için ayrı PlaybackStats hesaplar. Tamamlanan oynatmalar hakkında bilgi almak için PlaybackStatsListener geri çağırması sağlayabilir ve hangi oynatmanın tamamlandığını belirlemek için geri çağırmaya iletilen EventTime değerini kullanabilirsiniz. Birden fazla oynatma için analiz verilerini toplamak mümkündür. Ayrıca, PlaybackStatsListener.getPlaybackStats() kullanarak mevcut oynatma oturumu için PlaybackStats sorgusu da yapabilirsiniz.
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 tam geçmişini saklama seçeneği sunar. Oynatma süresine ve etkinlik sayısına bağlı olarak bilinmeyen bir bellek ek yükü oluşabileceğini unutmayın. Bu nedenle, yalnızca son analiz verilerine değil, işlenen etkinliklerin tam geçmişine erişmeniz gerekiyorsa bu özelliği etkinleştirmeniz gerekir.
PlaybackStats, yalnızca medyanın durumunu değil, aynı zamanda kullanıcının oynatma isteğini ve oynatmanın neden kesintiye uğradığı veya sona erdiği gibi daha ayrıntılı bilgileri de belirtmek için genişletilmiş bir durum kümesi kullandığını unutmayın:
| Oynatma durumu | Kullanıcının oynama niyeti | Oynama niyeti yok |
|---|---|---|
| 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ş durumları | ENDED, STOPPED, FAILED, ABANDONED |
Kullanıcının oynatma isteği, kullanıcının oynatmanın devam etmesini aktif olarak beklediği zamanları pasif bekleme sürelerinden ayırt etmek için önemlidir. Örneğin, PlaybackStats.getTotalWaitTimeMs, JOINING_FOREGROUND, BUFFERING ve SEEKING durumlarında geçirilen toplam süreyi döndürür ancak oynatma duraklatıldığında geçen süreyi döndürmez. Benzer şekilde, PlaybackStats.getTotalPlayAndWaitTimeMs, oynama kullanıcı niyetiyle geçen toplam süreyi (yani toplam etkin bekleme süresi ve PLAYING durumunda harcanan toplam süre) döndürür.
İşlenmiş ve yorumlanmış etkinlikler
İşlenen ve yorumlanan etkinlikleri PlaybackStatsListener
ile keepHistory=true kullanarak kaydedebilirsiniz. Sonuç olarak elde edilen PlaybackStats, aşağıdaki etkinlik listelerini içerir:
playbackStateHistory: Uygulanmaya başladıklarıEventTimeile birlikte, genişletilmiş oynatma durumlarının sıralı listesi. Belirli bir duvar saati zamanındaki durumu aramak içinPlaybackStats.getPlaybackStateAtTimeda kullanabilirsiniz.mediaTimeHistory: Medyanın hangi bölümlerinin hangi zamanda oynatıldığını yeniden oluşturmanıza olanak tanıyan, duvar saati zamanı ve medya zamanı çiftlerinin geçmişi. Ayrıca, belirli bir saatteki oynatma konumunu aramak içinPlaybackStats.getMediaTimeMsAtRealtimeMssimgesini de kullanabilirsiniz.videoFormatHistoryveaudioFormatHistory: Oynatma sırasında kullanılan video ve işitsel biçimlerin sıralı listeleri veEventTimeile kullanıma başlama zamanları.fatalErrorHistoryvenonFatalErrorHistory: Kritik ve kritik olmayan hataların,EventTimeile birlikte sıralı listeleri. Önemli hatalar oynatmayı sonlandıran hatalardır. Önemli olmayan hatalar ise kurtarılabilir.
Tek oynatma analiz verileri
Bu veriler, PlaybackStatsListener'yı keepHistory=false ile birlikte kullansanız bile 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. Kolaylık sağlaması için belirli oynatma durumu kombinasyonlarının süresini döndüren getTotalPlayTimeMs ve getTotalWaitTimeMs gibi yöntemleri 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 oynatma işleminin analiz verilerini toplama
PlaybackStats işlevini çağırarak birden fazla PlaybackStats.merge işlevini birleştirebilirsiniz. Sonuçta elde edilen PlaybackStats, birleştirilen tüm oynatmalara ait toplanmış verileri içerir. Bu raporun, tek tek oynatma etkinliklerinin geçmişini içermeyeceğini unutmayın. Bunun nedeni, bu etkinliklerin toplanamamasıdır.
PlaybackStatsListener.getCombinedPlaybackStats, PlaybackStatsListener'ün 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, temel analiz verilerine ek olarak özet metrikleri hesaplamak için 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());
Gelişmiş konular
Analiz verilerini oynatma meta verileriyle ilişkilendirme
Tek tek oynatmalara ilişkin analiz verilerini toplarken oynatma analiz verilerini, oynatılan medya hakkındaki meta verilerle ilişkilendirmek isteyebilirsiniz.
MediaItem.Builder.setTag ile medyaya özel meta veriler ayarlamanız önerilir.
Medya etiketi, EventTime için bildirilen ham etkinliklerin ve PlaybackStats tamamlandığında bildirilen etkinliklerin bir parçasıdır. Bu nedenle, ilgili Analytics 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ızda kaydetmeniz ve daha sonra bildirilen PlaybackStats ile birleştirmeniz gerekir. Gerekirse özel etkinlikleriniz için EventTime örnekleri oluşturabilmek ve bunları aşağıdaki örnekte gösterildiği gibi halihazırda kayıtlı dinleyicilere gönderebilmek için DefaultAnalyticsCollector değerini uzatabilirsiniz.
Kotlin
@OptIn(UnstableApi::class) private interface ExtendedListener : AnalyticsListener { fun onCustomEvent(eventTime: EventTime) } @OptIn(UnstableApi::class) private class ExtendedCollector : DefaultAnalyticsCollector(Clock.DEFAULT) { fun customEvent() { val eventTime = super.generateCurrentPlayerMediaPeriodEventTime() super.sendEvent(eventTime, CUSTOM_EVENT_ID) { listener: AnalyticsListener -> if (listener is ExtendedListener) { listener.onCustomEvent(eventTime) } } } } @OptIn(UnstableApi::class) fun useExtendedAnalyticsCollector(context: Context) { // 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
@OptIn(markerClass = UnstableApi.class) private interface ExtendedListener extends AnalyticsListener { void onCustomEvent(EventTime eventTime); } @OptIn(markerClass = UnstableApi.class) 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); } }); } } @OptIn(markerClass = UnstableApi.class) public static void useExtendedAnalyticsCollector(Context context) { // 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(); }