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 einemExoPlayer
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>
- 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. - 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.
- Aggregation: Bei diesem Schritt werden die Analysedaten über mehrere Wiedergaben, in der Regel durch Addition von Zählern.
- 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.
- 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
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
undmediaPeriodId
: Definiert die Playlist und die Element in der Playlist, zu der das Ereignis gehört. DasmediaPeriodId
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
undcurrentPlaybackPositionMs
: 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 mitEventTime
, zu dem die Bewerbung begonnen hat. Sie können auchPlaybackStats.getPlaybackStateAtTime
, um den Zustand einer bestimmten Mauer zu sehen UhrzeitmediaTimeHistory
: 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 auchPlaybackStats.getMediaTimeMsAtRealtimeMs
verwenden, um die Wiedergabe aufzurufen zu einer gegebenen Ortszeit angezeigt wird.videoFormatHistory
undaudioFormatHistory
: sortierte Listen mit Videos und Audioformate, die bei der Wiedergabe mit demEventTime
verwendet wurden, in dem sie gestartet wurden zu verwenden.fatalErrorHistory
undnonFatalErrorHistory
: sortierte Listen mit schwerwiegenden und schwerwiegenden Fehlern nicht schwerwiegende Fehler mit derEventTime
, 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();