Analytics

ExoPlayer unterstützt eine Vielzahl von Anforderungen an die Wiedergabeanalyse. Letztendlich ist Analytics das Sammeln, Interpretieren, Aggregieren und Zusammenfassen von Daten Wiedergaben. Diese Daten können auf dem Gerät verwendet werden, z. B. für Protokollierung, Fehlerbehebung oder als Grundlage für zukünftige Wiedergabe-Entscheidungen – oder an einen zur Überwachung der Wiedergaben auf allen Geräten.

Ein Analysesystem muss in der Regel zuerst Ereignisse erfassen und dann verarbeiten um sie aussagekräftig zu machen:

  • Ereigniserfassung: Dazu kannst du eine AnalyticsListener auf einem ExoPlayer registrieren. Instanz. Registrierte Analyse-Listener empfangen Ereignisse, sobald sie während Nutzung des Players. Jedes Ereignis ist mit dem entsprechenden Medium verknüpft. das Element in der Playlist sowie die Metadaten zur Wiedergabeposition und zum Zeitstempel.
  • Ereignisverarbeitung: Einige Analysesysteme laden Rohereignisse auf einen Server hoch, wobei alle Ereignisse serverseitig durchgeführt wird. Es ist auch möglich, Ereignisse auf dem und dies könnte einfacher sein oder die Menge an Informationen reduzieren, hochgeladen werden muss. ExoPlayer bietet PlaybackStatsListener, können Sie folgende Verarbeitungsschritte ausführen: <ph type="x-smartling-placeholder">
      </ph>
    1. Ereignisauswertung: Damit sie für Analysezwecke nützlich sind, müssen sie im Kontext einer einzelnen Wiedergabe zu interpretieren ist. Zum Beispiel die Rohdaten einer Änderung des Player-Status in STATE_BUFFERING eine anfängliche Pufferung, einen Puffer oder eine Pufferung nach einer Suche.
    2. Statusverfolgung: In diesem Schritt werden Ereignisse in Zähler umgewandelt. Beispiel: Statusänderungsereignisse können in Zähler umgewandelt werden, die erfassen, wie viel Zeit in jedem Wiedergabestatus verbracht haben. Das Ergebnis ist ein grundlegender Satz von Analysedaten. für eine einzelne Wiedergabe.
    3. Aggregation: Bei diesem Schritt werden die Analysedaten über mehrere Wiedergaben, in der Regel durch Addition von Zählern.
    4. Berechnung zusammenfassender Messwerte: Viele der nützlichsten Messwerte sind die Durchschnittswerte berechnen oder die grundlegenden Analysedatenwerte andere Möglichkeiten haben. Zusammenfassende Messwerte können für eine oder mehrere Wiedergaben.

Ereigniserfassung mit AnalyticsListener

Die vom Player wiedergegebenen Rohdaten werden an AnalyticsListener gemeldet. Implementierungen. Sie können ganz einfach einen eigenen Listener hinzufügen und nur die Methoden, die Sie interessieren:

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

Die EventTime, die an jeden Callback übergeben wird, verknüpft das Ereignis mit einem Medienobjekt. zum Element in der Playlist sowie die Metadaten zur Wiedergabeposition und zum Zeitstempel:

  • realtimeMs: Die tatsächlich verstrichene Zeit des Ereignisses.
  • timeline, windowIndex und mediaPeriodId: Definiert die Playlist und die Element in der Playlist, zu der das Ereignis gehört. Das mediaPeriodId optionale zusätzliche Informationen enthält, z. B. die angeben, ob der -Ereignis zu einer Anzeige im Element gehört.
  • eventPlaybackPositionMs: Wiedergabeposition im Element, wenn das Ereignis auftritt aufgetreten.
  • currentTimeline, currentWindowIndex, currentMediaPeriodId und currentPlaybackPositionMs: Wie oben, aber für das aktuell wiedergegebene Element. Die das aktuell wiedergegebene Element kann sich von dem Element unterscheiden, zu dem das Ereignis gehört. gehört, z. B. wenn das Ereignis der Vorabpufferung des nächsten das abzuspielende Element.

Ereignisverarbeitung mit WiedergabeStatsListener

PlaybackStatsListener ist eine AnalyticsListener, die auf dem Gerät implementiert wird Ereignisverarbeitung. Sie berechnet PlaybackStats mit Zählern und abgeleiteten Metriken wie:

  • Zusammenfassende Messwerte, z. B. die gesamte Wiedergabezeit.
  • Messwerte zur adaptiven Wiedergabequalität, z. B. die durchschnittliche Videoauflösung.
  • Rendering-Qualitätsmesswerte, z. B. die Rate der ausgelassenen Frames.
  • Messwerte zur Ressourcennutzung, z. B. die Anzahl der über das Netzwerk gelesenen Byte.

Eine vollständige Liste der verfügbaren Zählungen und abgeleiteten Messwerte finden Sie in der PlaybackStats Javadoc.

PlaybackStatsListener berechnet die separaten PlaybackStats für jedes Medienelement in der Playlist und jede clientseitige Anzeige, die in diese Elemente eingefügt wurde. Ich kann PlaybackStatsListener einen Callback senden, um darüber informiert zu werden, dass Wiedergaben und verwende das EventTime, das an den Callback übergeben wurde, um zu ermitteln, Wiedergabe beendet. Es ist möglich, die Analysedaten für mehrere Wiedergaben. Es ist auch möglich, das PlaybackStats nach dem Wiedergabesitzung jederzeit über PlaybackStatsListener.getPlaybackStats().

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

Der Konstruktor von PlaybackStatsListener bietet die Option, die vollständige der verarbeiteten Ereignisse. Beachten Sie, dass dadurch ein unbekannter Arbeitsspeicher-Overhead entstehen kann. abhängig von der Wiedergabedauer und der Anzahl der Ereignisse. Daher sehen Sie sollten Sie sie nur aktivieren, wenn Sie Zugriff auf den gesamten Verlauf und nicht nur auf die endgültigen Analysedaten.

Beachten Sie, dass PlaybackStats einen erweiterten Satz von Status verwendet, um nicht nur anzuzeigen, den Zustand der Medien, sondern auch die Absicht des Nutzers, das Video abzuspielen, und detailliertere Informationen darüber, warum die Wiedergabe unterbrochen oder beendet wurde:

Wiedergabestatus Absicht des Nutzers zu spielen Ich habe keine Absicht zu spielen
Vor der Wiedergabe JOINING_FOREGROUND NOT_STARTED, JOINING_BACKGROUND
Aktive Wiedergabe PLAYING
Unterbrochene Wiedergabe BUFFERING, SEEKING PAUSED, PAUSED_BUFFERING, SUPPRESSED, SUPPRESSED_BUFFERING, INTERRUPTED_BY_AD
Endzustände ENDED, STOPPED, FAILED, ABANDONED

Die Absicht des Nutzers zu spielen ist wichtig, um die Zeiten zu unterscheiden, in denen der Nutzer aktiv darauf warten, dass die Wiedergabe nach einer passiven Wartezeit fortgesetzt wird. Beispiel: PlaybackStats.getTotalWaitTimeMs gibt die Gesamtzeit zurück, die im JOINING_FOREGROUND, BUFFERING und SEEKING, aber nicht die Uhrzeit, zu der Wiedergabe wurde angehalten. Gleichermaßen wird PlaybackStats.getTotalPlayAndWaitTimeMs die Gesamtzeit mit der Absicht des Nutzers zurückzugeben, also Wartezeit und die Gesamtzeit im Status PLAYING.

Verarbeitete und interpretierte Ereignisse

Sie können verarbeitete und interpretierte Ereignisse mit PlaybackStatsListener aufzeichnen mit keepHistory=true. Die resultierende PlaybackStats enthält den folgende Ereignislisten:

  • playbackStateHistory: Eine sortierte Liste erweiterter Wiedergabestatus mit EventTime, zu dem die Bewerbung begonnen hat. Sie können auch PlaybackStats.getPlaybackStateAtTime, um den Zustand einer bestimmten Mauer zu sehen Uhrzeit
  • mediaTimeHistory: Ein Verlauf von Echtzeit- und Medienzeitpaaren ermöglicht um zu rekonstruieren, welche Teile der Medien zu welchem Zeitpunkt abgespielt wurden. Sie können Du kannst auch PlaybackStats.getMediaTimeMsAtRealtimeMs verwenden, um die Wiedergabe aufzurufen zu einer gegebenen Ortszeit angezeigt wird.
  • videoFormatHistory und audioFormatHistory: sortierte Listen mit Videos und Audioformate, die bei der Wiedergabe mit dem EventTime verwendet wurden, in dem sie gestartet wurden zu verwenden.
  • fatalErrorHistory und nonFatalErrorHistory: sortierte Listen mit schwerwiegenden und schwerwiegenden Fehlern nicht schwerwiegende Fehler mit der EventTime, zu der sie aufgetreten sind. Schwerwiegende Fehler sind die die Wiedergabe beendet haben. Nicht schwerwiegende Fehler ließen sich möglicherweise beheben.

Analysedaten für einzelne Wiedergaben

Diese Daten werden automatisch erhoben, wenn Sie PlaybackStatsListener verwenden, auch mit keepHistory=false. Die endgültigen Werte sind die öffentlichen Felder, die Sie im PlaybackStats-Javadoc und die Dauer des Wiedergabestatus von getPlaybackStateDurationMs zurückgegeben. Der Einfachheit halber finden Sie wie getTotalPlayTimeMs und getTotalWaitTimeMs, die den Parameter Wiedergabestatuskombinationen angezeigt.

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

Analysedaten mehrerer Wiedergaben aggregieren

Sie können mehrere PlaybackStats kombinieren, indem Sie PlaybackStats.merge. Die resultierende PlaybackStats enthält die aggregierten Daten aller zusammengeführten Wiedergaben. Der Verlauf von einzelne Wiedergabeereignisse zu erfassen, da diese nicht zusammengefasst werden können.

Mit PlaybackStatsListener.getCombinedPlaybackStats kann Folgendes abgerufen werden: aggregierte Ansicht aller Analytics-Daten, die während der Lebensdauer einer PlaybackStatsListener.

Berechnete zusammenfassende Messwerte

Zusätzlich zu den grundlegenden Analysedaten bietet PlaybackStats viele Methoden zusammenfassende Metriken berechnet.

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

Erweiterte Themen

Analysedaten mit Wiedergabemetadaten verknüpfen

Wenn du Analysedaten für einzelne Wiedergaben erhebst, kannst du die Analysedaten der Wiedergabe mit Metadaten zu den Medien verknüpfen, gespielt haben.

Es empfiehlt sich, medienspezifische Metadaten mit MediaItem.Builder.setTag festzulegen. Das Media-Tag ist Teil des EventTime, das für Rohereignisse gemeldet wird. PlaybackStats abgeschlossen sind, sodass sie bei der Verarbeitung der entsprechenden Analytics-Daten:

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

Berichte zu benutzerdefinierten Analytics-Ereignissen erstellen

Wenn Sie den Analysedaten benutzerdefinierte Ereignisse hinzufügen müssen, müssen Sie diese Ereignisse in Ihrer eigenen Datenstruktur zu erstellen und mit den gemeldeten Ereignissen zu kombinieren. PlaybackStats später. Sie können DefaultAnalyticsCollector bei Bedarf verlängern um EventTime Instanzen für Ihre benutzerdefinierten Ereignisse zu generieren und an die bereits registrierten Listener übergeben, wie im folgenden Beispiel gezeigt.

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