Analytics

ExoPlayer, çeşitli oynatma analizi ihtiyaçlarını destekler. Analizler, oynatmalardan elde edilen verileri toplama, yorumlama, toplama ve özetleme ile ilgilidir. Bu veriler cihazda kullanılabilir (örneğin, günlüğe kaydetme, hata ayıklama veya gelecekteki oynatma kararlarını bilgilendirmek için) ya da tüm cihazlardaki oynatmaları izlemek için bir sunucuya raporlanabilir.

Bir analiz sisteminin genellikle önce etkinlikleri toplaması ve ardından anlamlı hale getirmek için daha fazla işlemesi gerekir:

  • Etkinlik toplama: Bu işlem, bir ExoPlayer örneğine AnalyticsListener kaydedilerek yapılabilir. Kayıtlı analiz işleyicileri, oynatıcı kullanılı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, tüm etkinlik işlemlerinin sunucu tarafında gerçekleştirildiği ham etkinlikleri bir sunucuya yükler. Cihazdaki etkinlikler de işlenebilir. Bu işlem daha basit olabilir veya yüklenmesi gereken bilgi miktarını azaltabilir. ExoPlayer, aşağıdaki işleme adımlarını gerçekleştirmenize olanak tanıyan PlaybackStatsListener sağlar:
    1. Etkinlik yorumlama: Analizde yararlı olması için etkinliklerin tek bir oynatma bağlamında yorumlanması gerekir. Örneğin, oynatıcı durumunun STATE_BUFFERING olarak değiştiği ham etkinlik, ilk arabelleğe alma işlemine, yeniden arabelleğe almaya veya bir aramadan sonra gerçekleşen arabelleğe almaya karşılık gelebilir.
    2. Durum izleme: Bu adım, etkinlikleri sayaçlara dönüştürür. Örneğin, durum değişikliği etkinlikleri, her oynatma durumunda ne kadar süre harcandığını izleyen sayaçlara dönüştürülebilir. Sonuçta, tek bir oynatma için temel bir analiz verisi değerleri grubu elde edilir.
    3. Toplama: Bu adım, genellikle sayaçlar toplanarak birden fazla oynatmadaki analiz verilerini birleştirir.
    4. Özet metriklerin hesaplanması: En yararlı metriklerin çoğu, ortalamaları hesaplayan veya temel analiz veri değerlerini başka şekillerde birleştiren metriklerdir. Özet metrikler tek veya birden fazla oynatma için hesaplanabilir.

AnalyticsListener ile etkinlik koleksiyonu

Oynatıcıdan gelen ham oynatma etkinlikleri AnalyticsListeneruygulamaları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ğırma işlevine iletilen EventTime, etkinliği oynatma listesindeki bir medya öğesiyle, oynatma konumuyla ve zaman damgası meta verileriyle ilişkilendirir:

  • realtimeMs: Etkinliğin duvar saati zamanı.
  • timeline, windowIndex ve mediaPeriodId: Oynatma listesini ve etkinliğin ait olduğu oynatma listesindeki öğ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 konumu.
  • currentTimeline, currentWindowIndex, currentMediaPeriodId ve currentPlaybackPositionMs: Yukarıda olduğu gibi, şu anda oynatılan öğe içindir. Oynatılan öğe, etkinliğin ait olduğu öğeden farklı olabilir. Örneğin, etkinlik oynanacak bir sonraki öğenin önceden arabelleğe alınmasıyla ilgiliyse.

PlaybackStatsListener ile etkinlik işleme

PlaybackStatsListener, cihaz üzerinde etkinlik işleme uygulayan bir AnalyticsListener'tır. Aşağıdakiler dahil olmak üzere sayaçlar ve türetilmiş metriklerle PlaybackStats'ü hesaplar:

  • Özet metrikler (ör. toplam oynatma süresi).
  • Uyarlanabilir oynatma kalitesi metrikleri (ör. ortalama video çözünürlüğü).
  • Oluşturma kalitesi metrikleri (ör. atlanan kare oranı).
  • Ağ üzerinden okunan bayt sayısı gibi kaynak kullanım metrikleri.

Mevcut sayıları ve türetilmiş metriklerin tam listesini PlaybackStats Javadoc'da bulabilirsiniz.

PlaybackStatsListener, oynatma listesindeki her medya öğesi ve bu öğelere eklenen her istemci tarafı reklam için ayrı PlaybackStats hesaplar. Biten oynatmalar hakkında bilgi almak için PlaybackStatsListener için bir geri çağırma sağlayabilir ve geri çağırma işlevine iletilen EventTime değerini kullanarak hangi oynatmanın tamamlandığını belirleyebilirsiniz. Birden fazla oynatma için analiz verilerini toplamak mümkündür. PlaybackStatsListener.getPlaybackStats() kullanarak mevcut oynatma oturumu için PlaybackStats'ü istediğiniz zaman 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 öğesinin 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, işlenen etkinliklerin tam geçmişine erişmeniz gerekiyorsa bu özelliği etkinleştirmeniz gerekir.

PlaybackStats'ün yalnızca medyanın durumunu değil, aynı zamanda kullanıcının oynatma niyetini ve oynatmanın neden kesintiye uğradığı veya sona erdiği gibi daha ayrıntılı bilgileri belirtmek için genişletilmiş bir durum grubu kullandığını unutmayın:

Oynatma durumu Kullanıcının oynama niyeti Oyun 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 oynama niyeti, oynatmanın devam etmesini aktif olarak beklediği süreleri pasif bekleme sürelerinden ayırmak 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 oynama niyetiyle toplam süreyi döndürür. Bu, toplam aktif bekleme süresi ve PLAYING durumunda harcanan toplam süreyi ifade eder.

İşlenen ve yorumlanan etkinlikler

PlaybackStatsListener ile keepHistory=true kullanarak işlenmiş ve yorumlanmış etkinlikleri kaydedebilirsiniz. Elde edilen PlaybackStats, aşağıdaki etkinlik listelerini içerir:

  • playbackStateHistory: Genişletilmiş oynatma durumlarının, geçerli olmaya başladıkları EventTime ile birlikte sıralı listesi. Belirli bir saatte durumu kontrol etmek için PlaybackStats.getPlaybackStateAtTime simgesini de kullanabilirsiniz.
  • mediaTimeHistory: Gerçek zamanlı süre ve medya zamanı çiftlerinin geçmişi, medyanın hangi bölümlerinin ne zaman oynatıldığını yeniden oluşturmanıza olanak tanır. Belirli bir gerçek hayatta oynatma konumunu aramak için PlaybackStats.getMediaTimeMsAtRealtimeMs öğesini de kullanabilirsiniz.
  • videoFormatHistory ve audioFormatHistory: Oynatma sırasında kullanılan video ve ses biçimlerinin, kullanılmaya başladıkları EventTime ile birlikte sıralı listeleri.
  • fatalErrorHistory ve nonFatalErrorHistory: Kritik ve kritik olmayan hataların, oluştukları EventTime ile birlikte sıralı listeleri. Önemli hatalar oynatmayı sonlandıran hatalardır. Önemli olmayan hatalar ise kurtarılabilir olabilir.

Tek oynatma analiz verileri

Bu veriler, keepHistory=false ile bile PlaybackStatsListener kullanıldığında otomatik olarak toplanır. Nihai değerler, PlaybackStats Javadoc'da bulabileceğiniz herkese açık alanlar ve getPlaybackStateDurationMs tarafından döndürülen oynatma durumu süreleridir. Kolaylık sağlamak 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 toplama

PlaybackStats.merge işlevini çağırarak birden fazla PlaybackStats öğesini birleştirebilirsiniz. Elde edilen PlaybackStats, birleştirilen tüm oynatma işlemlerinin toplu verilerini içerir. Bu rapor, tekil oynatma etkinliklerinin geçmişini içermez çünkü bu etkinlikler toplu olarak görüntülenemez.

PlaybackStatsListener.getCombinedPlaybackStats, bir PlaybackStatsListener'ün kullanım süresi boyunca toplanan tüm analiz verilerinin toplu bir görünümünü elde etmek için kullanılabilir.

Hesaplanmış özet metrikler

PlaybackStats, temel analiz verilerine ek olarak özet metrikleri hesaplamak için birçok yöntem sağlar.

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 analizi verilerini oynatılan medyayla ilgili meta verilerle ilişkilendirmek isteyebilirsiniz.

Medyaya özgü meta verileri MediaItem.Builder.setTag ile ayarlamanızı öneririz. Medya etiketi, ham etkinlikler için raporlanan ve PlaybackStats tamamlandığında EventTime değerinin bir parçasıdır. Bu nedenle, ilgili analiz verilerini işlerken 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

Analytics verilerine özel etkinlikler eklemeniz gerekirse bu etkinlikleri kendi veri yapınıza kaydetmeniz ve daha sonra raporlanan PlaybackStats ile birleştirmeniz gerekir. Faydalı olacağını düşünüyorsanız özel etkinlikleriniz için EventTime örnekleri oluşturmak ve bunları aşağıdaki örnekte gösterildiği gibi kayıtlı dinleyicilere göndermek üzere DefaultAnalyticsCollector'ü 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();