ExoPlayer hỗ trợ nhiều nhu cầu phân tích quá trình phát. Cuối cùng, phân tích liên quan đến việc thu thập, diễn giải, tổng hợp và tóm tắt dữ liệu khỏi các lượt phát. Bạn có thể dùng dữ liệu này trên thiết bị, ví dụ: ghi nhật ký, gỡ lỗi hoặc để thông báo các quyết định phát lại trong tương lai—hoặc báo cáo cho máy chủ để theo dõi lượt phát trên tất cả thiết bị.
Hệ thống phân tích thường cần thu thập sự kiện trước rồi mới xử lý các sự kiện đó để chúng có ý nghĩa:
- Thu thập sự kiện:
Bạn có thể thực hiện việc này bằng cách đăng ký
AnalyticsListener
trênExoPlayer
thực thể. Trình nghe số liệu phân tích đã đăng ký sẽ nhận được các sự kiện xảy ra trong khoảng thời gian mức sử dụng trình phát. Mỗi sự kiện được liên kết với nội dung nghe nhìn tương ứng trong danh sách phát, cũng như vị trí phát và siêu dữ liệu về dấu thời gian. - Xử lý sự kiện:
Một số hệ thống phân tích tải sự kiện thô lên máy chủ, trong đó chứa tất cả các sự kiện
quá trình xử lý được thực hiện ở phía máy chủ. Bạn cũng có thể xử lý các sự kiện trên
thiết bị của bạn và làm như vậy có thể đơn giản hơn hoặc giảm lượng thông tin mà
cần được tải lên. ExoPlayer cung cấp
PlaybackStatsListener
cho phép bạn thực hiện các bước xử lý sau:- Diễn giải sự kiện: Để hữu ích cho mục đích phân tích, các sự kiện cần phải có
cần được diễn giải trong ngữ cảnh của một lần phát. Ví dụ: dữ liệu thô
sự kiện thay đổi trạng thái của người chơi thành
STATE_BUFFERING
có thể tương ứng với lưu vào bộ đệm ban đầu, tạo bộ đệm lại hoặc lưu vào bộ đệm xảy ra sau khi tua. - Theo dõi trạng thái: Bước này chuyển đổi sự kiện thành bộ đếm. Ví dụ: các sự kiện thay đổi trạng thái có thể được chuyển đổi thành bộ đếm theo dõi thời gian dành cho mỗi trạng thái phát. Kết quả là tập hợp dữ liệu phân tích cơ bản cho một lần phát.
- Tổng hợp: Bước này kết hợp dữ liệu phân tích trên nhiều lượt phát, thường bằng cách thêm bộ đếm.
- Tính toán các chỉ số tóm tắt: Nhiều chỉ số hữu ích nhất là tính toán giá trị trung bình hoặc kết hợp các giá trị dữ liệu phân tích cơ bản trong những cách khác. Bạn có thể tính các chỉ số tóm tắt cho một hoặc nhiều chỉ số lượt phát.
- Diễn giải sự kiện: Để hữu ích cho mục đích phân tích, các sự kiện cần phải có
cần được diễn giải trong ngữ cảnh của một lần phát. Ví dụ: dữ liệu thô
sự kiện thay đổi trạng thái của người chơi thành
Thu thập sự kiện bằng AnalyticsListener
Các sự kiện phát nội dung thô từ trình phát sẽ được báo cáo cho AnalyticsListener
thực tế. Bạn có thể dễ dàng thêm trình nghe của riêng mình và chỉ ghi đè
mà bạn quan tâm:
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) {} });
EventTime
được truyền đến mỗi lệnh gọi lại sẽ liên kết sự kiện với một nội dung nghe nhìn
mục trong danh sách phát, cũng như siêu dữ liệu về vị trí phát và dấu thời gian:
realtimeMs
: Thời gian trên đồng hồ treo tường của sự kiện.timeline
,windowIndex
vàmediaPeriodId
: Xác định danh sách phát và mục trong danh sách phát có chứa sự kiện.mediaPeriodId
chứa thông tin bổ sung không bắt buộc, ví dụ: cho biết liệu sự kiện thuộc về một quảng cáo trong mục.eventPlaybackPositionMs
: Vị trí phát trong mục khi sự kiện đã xảy ra.currentTimeline
,currentWindowIndex
,currentMediaPeriodId
vàcurrentPlaybackPositionMs
: Như trên nhưng dành cho nội dung hiện đang phát. Chiến lược phát hành đĩa đơn nội dung đang phát có thể khác với nội dung mà sự kiện chuyển đến chẳng hạn như nếu sự kiện tương ứng với việc lưu vào bộ đệm trước của mục được phát.
Xử lý sự kiện bằng PlaybackStatsListener
PlaybackStatsListener
là một AnalyticsListener
triển khai trên thiết bị
xử lý sự kiện. Hàm này tính PlaybackStats
, cùng với bộ đếm và kết quả
các chỉ số bao gồm:
- Các chỉ số tóm tắt, ví dụ như tổng thời gian phát.
- Chỉ số chất lượng phát thích ứng, ví dụ như độ phân giải trung bình của video.
- Chỉ số chất lượng kết xuất hình ảnh, ví dụ như tỷ lệ khung hình bị rớt.
- Chỉ số sử dụng tài nguyên, ví dụ như số byte đọc qua mạng.
Bạn sẽ thấy danh sách đầy đủ các chỉ số phát sinh và số lượng hiện có trong
PlaybackStats
Javadoc.
PlaybackStatsListener
tính toán PlaybackStats
riêng cho từng mục nội dung đa phương tiện
trong danh sách phát và cả quảng cáo phía máy khách được chèn trong các mục này. Bạn
có thể thực hiện lệnh gọi lại đến PlaybackStatsListener
để được thông báo về việc đã hoàn tất
lượt phát lại và sử dụng EventTime
được truyền đến lệnh gọi lại để xác định
đã phát xong. Bạn có thể tổng hợp dữ liệu phân tích để
nhiều lần phát. Bạn cũng có thể truy vấn PlaybackStats
cho
phiên phát hiện tại bất kỳ lúc nào bằng cách sử dụng
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. }));
Hàm khởi tạo của PlaybackStatsListener
cung cấp lựa chọn để giữ lại toàn bộ
nhật ký của các sự kiện được xử lý. Xin lưu ý rằng việc này có thể gây hao tổn bộ nhớ không xác định
tuỳ thuộc vào thời lượng phát và số lượng sự kiện. Do đó, bạn
chỉ nên bật chế độ này nếu bạn cần truy cập vào toàn bộ nhật ký xử lý
thay vì chỉ dựa vào dữ liệu phân tích cuối cùng.
Lưu ý PlaybackStats
sử dụng một nhóm trạng thái mở rộng để cho biết không chỉ
trạng thái của nội dung đa phương tiện, cũng như ý định phát của người dùng và
chẳng hạn như lý do vì sao quá trình phát bị gián đoạn hoặc kết thúc:
Trạng thái phát | Ý định chơi của người dùng | Không có ý định chơi |
---|---|---|
Trước khi phát | JOINING_FOREGROUND |
NOT_STARTED , JOINING_BACKGROUND |
Đang phát | PLAYING |
|
Quá trình phát bị gián đoạn | BUFFERING , SEEKING |
PAUSED , PAUSED_BUFFERING , SUPPRESSED , SUPPRESSED_BUFFERING , INTERRUPTED_BY_AD |
Trạng thái kết thúc | ENDED , STOPPED , FAILED , ABANDONED |
Ý định chơi của người dùng là yếu tố quan trọng để phân biệt thời điểm người dùng
chủ động đợi tiếp tục phát từ thời gian chờ thụ động. Ví dụ:
PlaybackStats.getTotalWaitTimeMs
trả về tổng thời gian dành cho
Các trạng thái JOINING_FOREGROUND
, BUFFERING
và SEEKING
, nhưng không phải thời điểm khi
đã tạm dừng phát. Tương tự, PlaybackStats.getTotalPlayAndWaitTimeMs
sẽ
trả về tổng thời gian mà người dùng có ý định chơi, tức là tổng thời gian hoạt động
thời gian chờ và tổng thời gian ở trạng thái PLAYING
.
Sự kiện đã xử lý và diễn giải
Bạn có thể ghi lại các sự kiện đã xử lý và diễn giải bằng cách dùng PlaybackStatsListener
cùng với keepHistory=true
. PlaybackStats
thu được sẽ chứa
danh sách sự kiện sau:
playbackStateHistory
: Danh sách theo thứ tự các trạng thái phát mở rộng vớiEventTime
mà họ bắt đầu đăng ký. Bạn cũng có thể sử dụngPlaybackStats.getPlaybackStateAtTime
để tra cứu trạng thái của một bức tường cụ thể giờ đồng hồ.mediaTimeHistory
: Lịch sử các cặp thời gian nội dung đa phương tiện và thời gian theo đồng hồ treo tường cho phép bạn muốn tạo lại phần nào của nội dung đa phương tiện đã được phát vào thời điểm đó. Bạn có thể Bạn cũng có thể dùngPlaybackStats.getMediaTimeMsAtRealtimeMs
để tra cứu nội dung phát tại một thời điểm nhất định trên đồng hồ treo tường.videoFormatHistory
vàaudioFormatHistory
: Danh sách video và video theo thứ tự các định dạng âm thanh được dùng trong quá trình phát bằngEventTime
lúc chúng bắt đầu phát. để sử dụng.fatalErrorHistory
vànonFatalErrorHistory
: Danh sách theo thứ tự các mục quan trọng và lỗi không nghiêm trọng vớiEventTime
nơi sự cố xảy ra. Lỗi nghiêm trọng là những lỗi đã kết thúc phát lại, trong khi các lỗi không nghiêm trọng có thể khôi phục được.
Dữ liệu phân tích một lượt phát
Dữ liệu này sẽ tự động được thu thập nếu bạn sử dụng PlaybackStatsListener
, thậm chí
cùng với keepHistory=false
. Giá trị cuối cùng là các trường công khai mà bạn có thể
tìm trong PlaybackStats
Javadoc và thời lượng trạng thái phát
được trả về bởi getPlaybackStateDurationMs
. Để thuận tiện, bạn cũng sẽ tìm thấy
các phương thức như getTotalPlayTimeMs
và getTotalWaitTimeMs
trả về
thời lượng của các tổ hợp trạng thái phát cụ thể.
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);
Dữ liệu phân tích tổng hợp về nhiều lần phát
Bạn có thể kết hợp nhiều PlaybackStats
với nhau bằng cách gọi
PlaybackStats.merge
PlaybackStats
thu được sẽ chứa dữ liệu tổng hợp
dữ liệu của tất cả các lượt phát đã hợp nhất. Lưu ý rằng tài khoản này sẽ không chứa lịch sử của
sự kiện phát riêng lẻ vì hệ thống không thể tổng hợp những sự kiện này.
Bạn có thể dùng PlaybackStatsListener.getCombinedPlaybackStats
để lấy
chế độ xem tổng hợp của tất cả dữ liệu phân tích
được thu thập trong toàn bộ thời gian
PlaybackStatsListener
Các chỉ số tóm tắt được tính toán
Ngoài dữ liệu phân tích cơ bản, PlaybackStats
còn cung cấp nhiều phương thức
để tính toán các chỉ số tóm tắt.
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());
Chủ đề nâng cao
Liên kết dữ liệu phân tích với siêu dữ liệu phát
Khi thu thập dữ liệu phân tích cho từng lượt phát riêng lẻ, bạn nên: liên kết dữ liệu phân tích phát lại với siêu dữ liệu về phương tiện đang được đã phát.
Bạn nên đặt siêu dữ liệu dành riêng cho nội dung nghe nhìn bằng MediaItem.Builder.setTag
.
Thẻ nội dung đa phương tiện nằm trong EventTime
được báo cáo cho các sự kiện thô và thời điểm
PlaybackStats
đã hoàn tất nên có thể dễ dàng truy xuất khi xử lý
dữ liệu phân tích tương ứng:
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. });
Báo cáo sự kiện phân tích tuỳ chỉnh
Trong trường hợp cần thêm sự kiện tuỳ chỉnh vào dữ liệu phân tích, bạn cần lưu
những sự kiện này trong cấu trúc dữ liệu của riêng bạn và kết hợp chúng với dữ liệu được báo cáo
Sau PlaybackStats
. Nếu việc này hữu ích, bạn có thể mở rộng DefaultAnalyticsCollector
để có thể tạo EventTime
phiên bản cho các sự kiện tùy chỉnh và gửi
chúng cho trình nghe đã đăng ký như trong ví dụ sau.
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();