ExoPlayer répond à de nombreux besoins d'analyse de lecture. En fin de compte, l’analytique consiste à collecter, à interpréter, à agréger et à résumer des données des lectures. Ces données peuvent être utilisées sur l'appareil, par exemple pour la journalisation ou le débogage, ou d'éclairer les futures décisions de lecture, ou de signaler pour contrôler les lectures sur tous les appareils.
Un système d'analyse doit généralement collecter les événements, puis les traiter pour les rendre plus intéressantes:
- Collecte de l'événement:
Pour ce faire, enregistrez un
AnalyticsListener
sur unExoPlayer
. Compute Engine. Les écouteurs d'analyse enregistrés reçoivent les événements au fur et à mesure qu'ils se produisent du lecteur. Chaque événement est associé au média correspondant de la playlist, ainsi que les métadonnées de position et de code temporel de la lecture. - Traitement des événements:
Certains systèmes d'analyse importent
des événements bruts sur un serveur,
et le traitement côté serveur. Il est également possible de traiter des événements
d'un appareil, ce qui peut être plus simple ou réduire la quantité d'informations
doit être importée. ExoPlayer fournit
PlaybackStatsListener
, qui vous permet d'effectuer les étapes de traitement suivantes: <ph type="x-smartling-placeholder">- </ph>
- Interprétation des événements: pour être utiles à des fins d'analyse, les événements doivent
à interpréter lors d'une seule lecture. Par exemple, les données brutes
l'événement de changement d'état du lecteur sur
STATE_BUFFERING
peut correspondre à mise en mémoire tampon initiale, remise en mémoire tampon ou mise en mémoire tampon après une recherche. - Suivi de l'état: cette étape convertit les événements en compteurs. Par exemple : Les événements de changement d'état peuvent être convertis en compteurs qui suivent la durée dans chaque état de lecture. Vous obtenez ainsi un ensemble de données d'analyse de base pour une seule lecture.
- Agrégation: cette étape combine les données d'analyse de plusieurs généralement en ajoutant des compteurs.
- Calcul des métriques récapitulatives: la plupart des métriques les plus utiles sont ceux qui calculent les moyennes ou combinent les valeurs des données analytiques de base dans d'autres manières. Les métriques récapitulatives peuvent être calculées pour une ou plusieurs lectures.
- Interprétation des événements: pour être utiles à des fins d'analyse, les événements doivent
à interpréter lors d'une seule lecture. Par exemple, les données brutes
l'événement de changement d'état du lecteur sur
Collecte d'événements avec AnalyticsListener
Les événements de lecture bruts du lecteur sont signalés à AnalyticsListener
mises en œuvre. Vous pouvez facilement ajouter votre propre écouteur et remplacer uniquement les
méthodes qui vous intéressent:
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) {} });
L'élément EventTime
transmis à chaque rappel associe l'événement à un élément multimédia
de la playlist, ainsi que les métadonnées relatives à la position de lecture et au code temporel:
realtimeMs
: heure de l'événementtimeline
,windowIndex
etmediaPeriodId
: définit la playlist et les éléments de la playlist à laquelle l'événement appartient.mediaPeriodId
contient des informations supplémentaires facultatives, indiquant par exemple si le appartient à une annonce dans l'élément.eventPlaybackPositionMs
: position de lecture de l'élément lorsque l'événement s'est produit.currentTimeline
,currentWindowIndex
,currentMediaPeriodId
etcurrentPlaybackPositionMs
: comme indiqué ci-dessus, mais pour l'élément en cours de lecture. La l'élément en cours de lecture peut être différent de celui auquel l'événement si l'événement correspond à la mise en mémoire tampon préalable du prochain à lire.
Traitement des événements avec PlaybackStatsListener
PlaybackStatsListener
est un AnalyticsListener
qui implémente sur l'appareil.
lors du traitement des événements. Elle calcule PlaybackStats
, avec des compteurs et des valeurs dérivées
y compris:
- Métriques récapitulatives, par exemple la durée de lecture totale.
- Métriques adaptatives sur la qualité de la lecture, par exemple la résolution vidéo moyenne.
- Métriques de qualité de rendu, telles que le taux d'images perdues.
- Métriques d'utilisation des ressources, par exemple le nombre d'octets lus sur le réseau.
Vous trouverez une liste complète des décomptes disponibles et des métriques dérivées dans la
Javadoc PlaybackStats
.
PlaybackStatsListener
calcule des PlaybackStats
distincts pour chaque élément multimédia
de la playlist, ainsi que chaque annonce côté client insérée à l'intérieur de ces éléments. Toi
peut rappeler à PlaybackStatsListener
pour être informé de l'avancement
et utilise le EventTime
transmis au rappel pour identifier les
lecture terminée. Il est possible d'agréger les données d'analyse pour
plusieurs lectures. Il est également possible d'interroger PlaybackStats
pour obtenir
la session de lecture en cours à tout moment en utilisant
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. }));
Le constructeur de PlaybackStatsListener
permet de conserver l'intégralité
l'historique des événements traités. Notez que cela peut entraîner une surcharge de mémoire inconnue
en fonction de la durée de la lecture et du nombre d'événements. Par conséquent, vous
ne l'activez que si vous avez besoin d'accéder à l'historique complet
les événements, et pas seulement
aux données d'analyse finales.
Notez que PlaybackStats
utilise un ensemble étendu d'états pour indiquer non seulement
l'état des contenus multimédias, mais aussi l'intention de l'utilisateur de les lire,
des informations telles que la raison pour laquelle la lecture a été interrompue ou terminée:
État de lecture | Intention de l'utilisateur de jouer | Je n'ai pas l'intention de jouer |
---|---|---|
Avant la lecture | JOINING_FOREGROUND |
NOT_STARTED , JOINING_BACKGROUND |
Lecture active | PLAYING |
|
Lecture interrompue | BUFFERING , SEEKING |
PAUSED , PAUSED_BUFFERING , SUPPRESSED , SUPPRESSED_BUFFERING , INTERRUPTED_BY_AD |
États de fin | ENDED , STOPPED , FAILED , ABANDONED |
L'intention de l'utilisateur de jouer est importante
pour distinguer les moments où l'utilisateur
dans l'attente active de la poursuite de la lecture à partir des temps d'attente passifs. Par exemple :
PlaybackStats.getTotalWaitTimeMs
renvoie le temps total passé dans la
JOINING_FOREGROUND
, BUFFERING
et SEEKING
, mais pas le moment où
la lecture a été mise en pause. De même, PlaybackStats.getTotalPlayAndWaitTimeMs
renvoie la durée totale de jeu dont l'utilisateur a l'intention de jouer, c'est-à-dire la durée totale
le temps d'attente et le temps total passé à l'état PLAYING
.
Événements traités et interprétés
Vous pouvez enregistrer des événements traités et interprétés à l'aide de PlaybackStatsListener
avec keepHistory=true
. Le PlaybackStats
obtenu contient le
les listes d'événements suivantes:
playbackStateHistory
: liste numérotée des états de lecture étendue avec laEventTime
à laquelle il a commencé à postuler. Vous pouvez également utiliserPlaybackStats.getPlaybackStateAtTime
pour rechercher l'état sur un mur donné l'heure de l'horloge.mediaTimeHistory
: historique de l'heure de l'horloge murale et de l'heure du média permettant de reconstituer quelles parties du média ont été lues et à quel moment. Vous pouvez Utilisez aussiPlaybackStats.getMediaTimeMsAtRealtimeMs
pour rechercher la lecture à une heure donnée.videoFormatHistory
etaudioFormatHistory
: listes ordonnées de vidéos et formats audio utilisés lors de la lecture avec leEventTime
à partir duquel ils ont commencé à utiliser.fatalErrorHistory
etnonFatalErrorHistory
: listes numérotées d'erreurs fatales et des erreurs non fatales avec leEventTime
où elles se sont produites. Les erreurs fatales sont ceux qui ont mis fin à la lecture, alors que les erreurs non fatales auraient pu être récupérées.
Données d'analyse pour les lectures uniques
Ces données sont collectées automatiquement si vous utilisez PlaybackStatsListener
, même
avec keepHistory=false
. Les valeurs finales sont les champs publics que vous pouvez
que vous trouverez dans le Javadoc PlaybackStats
et les durées d'état de lecture
renvoyé par getPlaybackStateDurationMs
. Pour plus de commodité, vous trouverez également
comme getTotalPlayTimeMs
et getTotalWaitTimeMs
, qui renvoient le
la durée de combinaisons
d'états de lecture spécifiques.
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);
Regrouper les données d'analyse de plusieurs lectures
Vous pouvez combiner plusieurs PlaybackStats
en appelant
PlaybackStats.merge
Le PlaybackStats
obtenu contient les données agrégées
les données de toutes les lectures fusionnées. Notez qu'il ne contiendra pas l'historique
des événements de lecture individuels, car ils ne peuvent pas être agrégés.
PlaybackStatsListener.getCombinedPlaybackStats
permet d'obtenir une
une vue agrégée de toutes les données d'analyse collectées au cours de la durée de vie
PlaybackStatsListener
Métriques récapitulatives calculées
En plus des données d'analyse de base, PlaybackStats
propose de nombreuses méthodes
pour calculer des métriques récapitulatives.
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());
Rubriques avancées
Associer des données d'analyse aux métadonnées de lecture
Si vous collectez des données d'analyse pour des lectures individuelles, vous pouvez associer les données d'analyse de lecture aux métadonnées concernant le contenu multimédia joué.
Nous vous recommandons de définir des métadonnées spécifiques aux contenus multimédias avec MediaItem.Builder.setTag
.
La balise média fait partie du EventTime
rapporté pour les événements bruts et quand
PlaybackStats
sont terminés, et peuvent donc être facilement récupérés lors de la gestion
données analytiques correspondantes:
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. });
Créer des rapports sur des événements d'analyse personnalisés
Si vous devez ajouter des événements personnalisés aux données d'analyse, vous devez enregistrer
ces événements dans votre propre structure de données et les combiner avec les
PlaybackStats
plus tard. Si cela peut vous aider, vous pouvez prolonger DefaultAnalyticsCollector
afin de pouvoir générer des instances EventTime
pour vos événements personnalisés et envoyer
aux écouteurs déjà enregistrés, comme illustré dans l'exemple suivant.
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();