Analytics

ExoPlayer, oynatma analiziyle ilgili çok çeşitli ihtiyaçları destekler. Sonuç olarak analiz, oynatmalardan elde edilen verileri toplama, yorumlama, birleştirme ve özetleme sürecidir. Bu veriler cihazda kullanılabilir (ör. günlük kaydı, hata ayıklama veya gelecekteki oynatma kararlarını bildirmek için) ya da tüm cihazlardaki oynatmaları izlemek için bir sunucuya bildirilebilir.

Analiz sistemlerinin genellikle önce etkinlikleri toplaması, ardından bunları 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şleyiciler, oynatıcı kullanılırken gerçekleşen etkinlikleri 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, ham etkinlikleri bir sunucuya yükler ve tüm etkinlik işleme işlemleri sunucu tarafında gerçekleştirilir. Etkinlikleri cihazda işlemek de mümkündür. Bu yöntem 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: Etkinliklerin analiz amacıyla kullanılabilmesi için 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, yeniden arabelleğe alma veya arama işleminden sonra gerçekleşen arabelleğe alma işlemine 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 zaman harcandığını izleyen sayaçlara dönüştürülebilir. Sonuç, tek bir oynatma için temel bir analiz verisi değerleri kümesidir.
    3. Toplama: Bu adım, genellikle sayaçları toplayarak birden fazla oynatmadaki analiz verilerini birleştirir.
    4. Ö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.

AnalyticsListener ile etkinlik toplama

Oynatıcıdan gelen ham oynatma etkinlikleri AnalyticsListener uygulamalarına bildirilir. Kendi dinleyicinizi 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 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 öğe içindeki bir reklama ait olup olmadığını gösterir.
  • eventPlaybackPositionMs: Etkinlik gerçekleştiğinde öğedeki oynatma konumu.
  • currentTimeline, currentWindowIndex, currentMediaPeriodId ve currentPlaybackPositionMs: Daha önce açıklandığı gibi, ancak o anda oynatılan öğe için. Şu anda oynatılan öğe, etkinliğin ait olduğu öğeden farklı olabilir. Örneğin, etkinlik oynatılacak bir sonraki öğenin önceden arabelleğe alınmasına karşılık geliyorsa.

PlaybackStatsListener ile etkinlik işleme

PlaybackStatsListener, cihaz üzerinde etkinlik işleme uygulayan bir AnalyticsListener. PlaybackStats hesaplaması yapar. Bu hesaplamada, aşağıdakiler gibi sayaçlar ve türetilmiş metrikler kullanılır:

  • Ö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ı)

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

PlaybackStatsListener, oynatma listesindeki her bir medya öğesi ve bu öğelere eklenen her bir istemci tarafı reklam için ayrı ayrı PlaybackStats hesaplar. Tamamlanan oynatmalar hakkında bilgi almak için PlaybackStatsListener yöntemine bir geri çağırma 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. PlaybackStatsListener.getPlaybackStats() kullanarak istediğiniz zaman geçerli oynatma oturumu için PlaybackStats sorgulaması 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 bunun bilinmeyen bir bellek ek yüküne neden olabileceğini unutmayın. Bu nedenle, yalnızca nihai analiz verileri yerine 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 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 kümesi kullanır:

Oynatma durumu Kullanıcının oynama niyeti Oynama niyetim yok
Oynatmadan önce JOINING_FOREGROUND NOT_STARTED, JOINING_BACKGROUND
Etkin oynatma PLAYING
Kesintili oynatma BUFFERING, SEEKING PAUSED, PAUSED_BUFFERING, SUPPRESSED, SUPPRESSED_BUFFERING, INTERRUPTED_BY_AD
Bitiş durumları ENDED, STOPPED, FAILED, ABANDONED

Kullanıcının oynatma niyeti, kullanıcının oynatmanın devam etmesini aktif olarak beklediği zamanları pasif bekleme sürelerinden ayırt etmek açısından ö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ığı süreyi döndürmez. Benzer şekilde, PlaybackStats.getTotalPlayAndWaitTimeMs, kullanıcının oynama niyetinde olduğu toplam süreyi, yani toplam etkin bekleme süresini ve PLAYING durumunda geçirilen toplam süreyi döndürür.

İşlenen ve yorumlanan etkinlikler

PlaybackStatsListener ile keepHistory=true kullanarak işlenen ve yorumlanan etkinlikleri kaydedebilirsiniz. Oluşturulan PlaybackStats aşağıdaki etkinlik listelerini içerir:

  • playbackStateHistory: Geçerli olmaya başladıkları EventTime ile birlikte genişletilmiş oynatma durumlarının sıralı listesi. Belirli bir saatteki durumu aramak için PlaybackStats.getPlaybackStateAtTime seçeneğini de kullanabilirsiniz.
  • mediaTimeHistory: Medyanın hangi bölümlerinin ne zaman oynatıldığını yeniden oluşturmanıza olanak tanıyan duvar saati zamanı ve medya zamanı çiftlerinin geçmişi. Belirli bir gerçek saatte oynatma konumunu bulmak için PlaybackStats.getMediaTimeMsAtRealtimeMs yöntemini de kullanabilirsiniz.
  • videoFormatHistory ve audioFormatHistory: Oynatma sırasında kullanılan video ve ses biçimlerinin, kullanılmaya başlandıkları EventTime ile birlikte sıralı listeleri.
  • fatalErrorHistory ve nonFatalErrorHistory: Oluştukları EventTime ile birlikte önemli ve önemli olmayan hataların 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 birlikte olsa bile PlaybackStatsListener kullanıyorsanız otomatik olarak toplanır. Son 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 birleştirme

PlaybackStats.merge işlevini çağırarak birden fazla PlaybackStats öğesini birleştirebilirsiniz. Oluşturulan PlaybackStats, birleştirilen tüm oynatmaların birleştirilmiş verilerini içerir. Bu raporun, birleştirilemeyecekleri için tek tek oynatma etkinliklerinin geçmişini içermeyeceğini unutmayın.

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

Hesaplanmış özet metrikler

PlaybackStats, temel analiz verilerinin yanı sıra ö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());

İleri düzey konular

Analiz verilerini oynatma meta verileriyle ilişkilendirme

Tek tek oynatmalar için analiz verileri toplarken oynatma analiz verilerini, oynatılan medyayla ilgili meta verilerle ilişkilendirmek isteyebilirsiniz.

Medyaya özgü meta verileri MediaItem.Builder.setTag ile ayarlamanız önerilir. Medya etiketi, ham etkinlikler için bildirilen EventTime öğesinin ve PlaybackStats tamamlandığında bildirilen öğenin bir parçasıdır. Bu nedenle, ilgili analiz verileri işlenirken 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 gerekiyorsa bu etkinlikleri kendi veri yapınıza kaydetmeniz ve daha sonra raporlanan PlaybackStats ile birleştirmeniz gerekir. İşinize yarayacaksa ö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 sınıfını genişletebilirsiniz.

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();
}

Özellik bayraklarını ve Canary modunu izleme

A/B testi yaparken veya yeni Media3 optimizasyonlarının etkisini değerlendirirken oynatma analizi verilerini etkin özellik bayrakları ve Canary modu ile ilişkilendirebilirsiniz.

Flags.getLogString sorgulayabilir veya Flags.getEnabledOverrides ve Flags.getDisabledOverrides kullanarak belirli işaret geçersiz kılma işlemlerini inceleyerek işaret durumlarını özel analiz yüklerinize veya oturum meta verilerinize dahil edebilirsiniz.