ExoPlayer는 다양한 재생 분석 요구사항을 지원합니다. 결국 애널리틱스는 데이터를 수집, 해석, 집계 및 요약하는 것입니다. 있습니다. 이 데이터는 기기(예: 알 수 있게 하거나 또는 향후 재생 결정을 알리는 데 사용되거나 모든 기기의 재생을 모니터링할 수 있습니다.
일반적으로 분석 시스템은 이벤트를 먼저 수집한 다음 처리해야 합니다. 더욱 의미 있게 만들 수 있습니다.
- 이벤트 수집:
ExoPlayer
에AnalyticsListener
를 등록하면 됩니다. 인스턴스를 만들 수 있습니다 등록된 애널리틱스 리스너는 이벤트 발생 시 이벤트를 수신합니다. 지정할 수 있습니다. 각 이벤트는 해당 미디어와 연결됩니다. 재생 위치 및 타임스탬프 메타데이터도 확인할 수 있습니다. - 이벤트 처리:
일부 애널리틱스 시스템은 모든 이벤트와 함께 원시 이벤트를 서버에 업로드
kube-apiserver와 통신하는
역할을 합니다 또한 서버에서 이벤트를
그렇게 하는 것이 훨씬 간단할 수도 있고, 이동 중에 받는 정보의 양을
업로드해야 합니다. ExoPlayer는
PlaybackStatsListener
를 제공합니다. 를 사용하면 다음 처리 단계를 수행할 수 있습니다. <ph type="x-smartling-placeholder">- </ph>
- 이벤트 해석: 분석 목적으로 유용하려면
단일 재생 컨텍스트에서 해석됩니다. 예를 들어 원시
플레이어 상태가
STATE_BUFFERING
로 변경되는 이벤트는 탐색 후에 발생하는 초기 버퍼링, 리버퍼링 또는 버퍼링이 있을 수 있습니다. - 상태 추적: 이 단계는 이벤트를 카운터로 변환합니다. 예를 들어 상태 변경 이벤트는 현재 상태와 남은 시간을 추적하는 카운터로 각 재생 상태에서 소비될 수 있습니다 그 결과 기본적인 분석 데이터 세트는 값을 설정할 수 있습니다.
- 집계: 이 단계에서는 여러 분석 데이터를 일반적으로 카운터를 더하는 방식으로 이루어집니다.
- 요약 측정항목 계산: 가장 유용한 측정항목 대부분은 평균을 계산하거나 기본 분석 데이터 값을 결합하는 사용할 수 있습니다 요약 측정항목은 하나 또는 여러 개를 기준으로 계산할 수 있습니다. 있습니다.
- 이벤트 해석: 분석 목적으로 유용하려면
단일 재생 컨텍스트에서 해석됩니다. 예를 들어 원시
플레이어 상태가
AnalyticsListener를 사용한 이벤트 수집
플레이어의 원시 재생 이벤트가 AnalyticsListener
에 보고됩니다.
있습니다. 손쉽게 자체 리스너를 추가하고
관심 있는 방법:
Kotlin
exoPlayer.addAnalyticsListener( object : AnalyticsListener { override fun onPlaybackStateChanged( eventTime: EventTime, @Player.State state: Int ) {} override fun onDroppedVideoFrames( eventTime: EventTime, droppedFrames: Int, elapsedMs: Long, ) {} } )
자바
exoPlayer.addAnalyticsListener( new AnalyticsListener() { @Override public void onPlaybackStateChanged( EventTime eventTime, @Player.State int state) {} @Override public void onDroppedVideoFrames( EventTime eventTime, int droppedFrames, long elapsedMs) {} });
각 콜백에 전달되는 EventTime
는 이벤트를 미디어에 연결합니다.
재생목록의 항목뿐 아니라 재생 위치 및 타임스탬프 메타데이터도 보여줍니다.
realtimeMs
: 이벤트의 벽시계 시간입니다.timeline
,windowIndex
,mediaPeriodId
: 재생목록 및 이벤트가 속한 재생목록의 항목을 찾습니다.mediaPeriodId
선택적 추가 정보를 포함합니다. 예를 들어 이벤트가 항목 내 광고에 속하는지 확인합니다.eventPlaybackPositionMs
: 이벤트가 발생했을 때 항목의 재생 위치 수 있습니다.currentTimeline
,currentWindowIndex
,currentMediaPeriodId
및currentPlaybackPositionMs
: 위와 같지만 현재 재생 중인 항목에 적용됩니다. 이 현재 재생 중인 항목은 이벤트가 재생된 항목과 다를 수 있습니다. 예를 들어 이벤트가 다음 있습니다.
PlaybackStatsListener를 통한 이벤트 처리
PlaybackStatsListener
는 기기 내를 구현하는 AnalyticsListener
입니다.
이벤트를 처리합니다. 카운터 및 파생 함수를 사용하여 PlaybackStats
를 계산합니다.
측정항목:
- 요약 측정항목(예: 총 재생 시간)
- 적응형 재생 품질 측정항목(예: 평균 동영상 해상도)
- 품질 측정항목 렌더링(예: 드롭된 프레임 속도)
- 리소스 사용량 측정항목(예: 네트워크를 통해 읽은 바이트 수)
사용 가능한 개수 및 파생 측정항목의 전체 목록은
PlaybackStats
Javadoc
PlaybackStatsListener
는 각 미디어 항목에 대해 별도의 PlaybackStats
를 계산합니다.
이러한 항목에 삽입된 각 클라이언트측 광고도 포함됩니다. 나
PlaybackStatsListener
에 콜백을 제공하여 완료에 관해 알릴 수 있습니다.
콜백에 전달된 EventTime
를 사용하여
재생이 완료됩니다. 여러 목적에 대해 애널리틱스 데이터를 집계하여
여러 번 재생할 수 있습니다 PlaybackStats
에서
현재 재생 세션을 언제든지
PlaybackStatsListener.getPlaybackStats()
입니다.
Kotlin
exoPlayer.addAnalyticsListener( PlaybackStatsListener(/* keepHistory= */ true) { eventTime: EventTime?, playbackStats: PlaybackStats?, -> // Analytics data for the session started at `eventTime` is ready. } )
자바
exoPlayer.addAnalyticsListener( new PlaybackStatsListener( /* keepHistory= */ true, (eventTime, playbackStats) -> { // Analytics data for the session started at `eventTime` is ready. }));
PlaybackStatsListener
의 생성자는 전체
이벤트 기록입니다. 이로 인해 알 수 없는 메모리 오버헤드가 발생할 수 있습니다.
이벤트 수에 따라 달라집니다. 따라서
처리 과정 전체 기록에 액세스해야 하는 경우에만
최종 분석 데이터가 아닌 이벤트로 전송됩니다.
PlaybackStats
는 확장된 상태 집합을 사용하여
미디어의 상태뿐 아니라 사용자의 재생 의도와
재생이 중단되거나 종료된 이유 등의 정보를 포함합니다.
재생 상태 | 사용자의 플레이 의도 | 플레이할 생각이 없음 |
---|---|---|
재생 전 | JOINING_FOREGROUND |
JOINING_BACKGROUND NOT_STARTED |
활성 재생 | PLAYING |
|
재생 중단됨 | SEEKING BUFFERING |
PAUSED , PAUSED_BUFFERING , SUPPRESSED , SUPPRESSED_BUFFERING , INTERRUPTED_BY_AD |
종료 상태 | ENDED , STOPPED , FAILED , ABANDONED |
사용자가 플레이하고자 했던 시간을 구별하는 데
수동적 대기 시간에서 재생이 계속되기를 적극적으로 기다리는 중입니다. 예를 들어
PlaybackStats.getTotalWaitTimeMs
는
JOINING_FOREGROUND
, BUFFERING
, SEEKING
상태이지만 시간이
재생이 일시중지되었습니다. 마찬가지로 PlaybackStats.getTotalPlayAndWaitTimeMs
는
사용자가 플레이할 의도가 있는 전체 시간, 즉 총 활성 시간인
대기 시간 및 PLAYING
상태에서 소요된 총 시간입니다.
처리되고 해석된 이벤트
PlaybackStatsListener
를 사용하여 처리 및 해석된 이벤트를 기록할 수 있습니다.
keepHistory=true
. 결과 PlaybackStats
에는 다음이 포함됩니다.
이벤트 목록:
playbackStateHistory
: 확장 재생 상태의 순서가 지정된 목록이며 적용하기 시작한EventTime
또한PlaybackStats.getPlaybackStateAtTime
: 지정된 월에서 상태 조회 확인할 수 있습니다.mediaTimeHistory
: 벽시계 시간 및 미디어 시간 쌍의 기록을 통해 미디어의 어떤 부분이 언제 재생되었는지 재구성할 수 있습니다. 다음과 같은 작업을 할 수 있습니다.PlaybackStats.getMediaTimeMsAtRealtimeMs
를 사용하여 재생을 찾습니다. 특정 벽시계 시간의 위치를 나타냅니다.videoFormatHistory
및audioFormatHistory
: 동영상 및 재생을 시작한EventTime
로 재생하는 동안 사용된 오디오 형식 있습니다.fatalErrorHistory
및nonFatalErrorHistory
: 심각한 문제 및 발생한EventTime
의 치명적이지 않은 오류를 반환합니다. 치명적인 오류는 치명적이지 않은 오류는 복구 가능할 수도 있습니다.
단일 재생 분석 데이터
이 데이터는 PlaybackStatsListener
을(를) 사용하면 자동으로 수집됩니다.
keepHistory=false
. 최종 값은
PlaybackStats
Javadoc에서 찾을 수 있으며, 재생 상태 지속 시간도
getPlaybackStateDurationMs
에서 반환함 편의를 위해
getTotalPlayTimeMs
및 getTotalWaitTimeMs
와 같은 메서드는
특정 재생 상태 조합의 지속 시간을 측정합니다.
Kotlin
Log.d( "DEBUG", "Playback summary: " + "play time = " + playbackStats.totalPlayTimeMs + ", rebuffers = " + playbackStats.totalRebufferCount )
자바
Log.d( "DEBUG", "Playback summary: " + "play time = " + playbackStats.getTotalPlayTimeMs() + ", rebuffers = " + playbackStats.totalRebufferCount);
여러 재생에 대한 분석 데이터 집계
다음을 호출하여 여러 PlaybackStats
를 결합할 수 있습니다.
PlaybackStats.merge
입니다. 결과 PlaybackStats
에는 집계된
데이터를 생성합니다. 포드의 이전 기록은 포함되지 않습니다.
집계할 수 없기 때문입니다.
PlaybackStatsListener.getCombinedPlaybackStats
를 사용하면
전체 기간 동안 수집된 모든 애널리틱스 데이터를
PlaybackStatsListener
입니다.
계산된 요약 측정항목
PlaybackStats
는 기본 애널리틱스 데이터 외에도 다양한 메서드를 제공합니다.
요약 측정항목을 계산합니다.
Kotlin
Log.d( "DEBUG", "Additional calculated summary metrics: " + "average video bitrate = " + playbackStats.meanVideoFormatBitrate + ", mean time between rebuffers = " + playbackStats.meanTimeBetweenRebuffers )
자바
Log.d( "DEBUG", "Additional calculated summary metrics: " + "average video bitrate = " + playbackStats.getMeanVideoFormatBitrate() + ", mean time between rebuffers = " + playbackStats.getMeanTimeBetweenRebuffers());
고급 주제
분석 데이터를 재생 메타데이터와 연결
개별 재생에 대한 분석 데이터를 수집할 때는 재생 분석 데이터를 재생 중인 미디어에 대한 메타데이터와 연결 합니다.
MediaItem.Builder.setTag
로 미디어별 메타데이터를 설정하는 것이 좋습니다.
미디어 태그는 원시 이벤트에 관해 보고되는 EventTime
의 일부이며
PlaybackStats
가 완료되었으므로
해당되는 분석 데이터:
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. }
자바
new PlaybackStatsListener( /* keepHistory= */ false, (eventTime, playbackStats) -> { Object mediaTag = eventTime.timeline.getWindow(eventTime.windowIndex, new Timeline.Window()) .mediaItem .localConfiguration .tag; // Report playbackStats with mediaTag metadata. });
맞춤 분석 이벤트 보고
애널리틱스 데이터에 맞춤 이벤트를 추가해야 하는 경우
보고되는 데이터와 결합하여
PlaybackStats
후입니다. 도움이 된다면 DefaultAnalyticsCollector
를 연장할 수 있습니다.
맞춤 이벤트에 대한 EventTime
인스턴스를 생성하고
이미 등록된 리스너에 전달합니다.
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();