Debug logging
Stay organized with collections
Save and categorize content based on your preferences.
By default, ExoPlayer only logs errors. To log player events, the EventLogger
class can be used. The additional logging it provides can be helpful for
understanding what the player is doing, as well as for debugging playback
issues. EventLogger
implements AnalyticsListener
, so registering an instance
with an ExoPlayer
is easy:
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
The easiest way to observe the log is using Android Studio's logcat tab. You
can select your app as debuggable process by the package name (
androidx.media3.demo.main
if using the demo app) and tell the logcat
tab to log only for that app by selecting show only selected application. It's
possible to further filter the logging with the expression
EventLogger|ExoPlayerImpl
, to get only logging from EventLogger
and the
player itself.
An alternative to using Android Studio's logcat tab is to use the console. For
example:
adb logcat EventLogger:* ExoPlayerImpl:* *:s
The ExoPlayerImpl
class delivers two important lines about the player version,
the device and OS the app is running on and the modules of ExoPlayer that have
been loaded:
ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33]
ExoPlayerImpl: Release 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33] [media3.common, media3.datasource, media3.ui, media3.exoplayer, media3.decoder, media3.exoplayer.dash, media3.extractor]
Playback state
Player state changes are logged in lines like these:
EventLogger: playWhenReady [eventTime=0.00, mediaPos=0.00, window=0, true, USER_REQUEST]
EventLogger: state [eventTime=0.01, mediaPos=0.00, window=0, BUFFERING]
EventLogger: state [eventTime=0.93, mediaPos=0.00, window=0, period=0, READY]
EventLogger: isPlaying [eventTime=0.93, mediaPos=0.00, window=0, period=0, true]
EventLogger: playWhenReady [eventTime=9.40, mediaPos=8.40, window=0, period=0, false, USER_REQUEST]
EventLogger: isPlaying [eventTime=9.40, mediaPos=8.40, window=0, period=0, false]
EventLogger: playWhenReady [eventTime=10.40, mediaPos=8.40, window=0, period=0, true, USER_REQUEST]
EventLogger: isPlaying [eventTime=10.40, mediaPos=8.40, window=0, period=0, true]
EventLogger: state [eventTime=20.40, mediaPos=18.40, window=0, period=0, ENDED]
EventLogger: isPlaying [eventTime=20.40, mediaPos=18.40, window=0, period=0, false]
In this example playback starts 0.93 seconds after the player is prepared. The
user pauses playback after 9.4 seconds, and resumes playback one second later at
10.4 seconds. Playback ends ten seconds later at 20.4 seconds. The common
elements within the square brackets are:
[eventTime=float]
: The wall clock time since player creation.
[mediaPos=float]
: The current playback position.
[window=int]
: The current window index.
[period=int]
: The current period in that window.
The final elements in each line indicate the value of the state being reported.
Track information is logged when the available or selected tracks change. This
happens at least once at the start of playback. The example below shows track
logging for an adaptive stream:
EventLogger: tracks [eventTime=0.30, mediaPos=0.00, window=0, period=0,
EventLogger: group [
EventLogger: [X] Track:0, id=133, mimeType=video/avc, bitrate=261112, codecs=avc1.4d4015, res=426x240, fps=30.0, supported=YES
EventLogger: [X] Track:1, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0, supported=YES
EventLogger: [X] Track:2, id=135, mimeType=video/avc, bitrate=1204535, codecs=avc1.4d401f, res=854x480, fps=30.0, supported=YES
EventLogger: [X] Track:3, id=160, mimeType=video/avc, bitrate=112329, codecs=avc1.4d400c, res=256x144, fps=30.0, supported=YES
EventLogger: [ ] Track:4, id=136, mimeType=video/avc, bitrate=2400538, codecs=avc1.4d401f, res=1280x720, fps=30.0, supported=NO_EXCEEDS_CAPABILITIES
EventLogger: ]
EventLogger: group [
EventLogger: [ ] Track:0, id=139, mimeType=audio/mp4a-latm, bitrate=48582, codecs=mp4a.40.5, channels=2, sample_rate=22050, supported=YES
EventLogger: [X] Track:1, id=140, mimeType=audio/mp4a-latm, bitrate=127868, codecs=mp4a.40.2, channels=2, sample_rate=44100, supported=YES
EventLogger: ]
EventLogger: ]
In this example, the player has selected four of the five available video
tracks. The fifth video track is not selected because it exceeds the
capabilities of the device, as indicated by supported=NO_EXCEEDS_CAPABILITIES
.
The player will adapt between the selected video tracks during playback. When
the player adapts from one track to another, it's logged in a line like the one
below:
EventLogger: downstreamFormat [eventTime=3.64, mediaPos=3.00, window=0, period=0, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0]
This log line indicates that the player switched to the 640x360 resolution video
track three seconds into the media.
Decoder selection
In most cases, ExoPlayer renders media using a MediaCodec
acquired from the
underlying platform. When a decoder is initialized, this is logged in lines like
these:
EventLogger: videoDecoderInitialized [0.77, 0.00, window=0, period=0, video, OMX.qcom.video.decoder.avc]
EventLogger: audioDecoderInitialized [0.79, 0.00, window=0, period=0, audio, OMX.google.aac.decoder]
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2024-02-09 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-02-09 UTC."],[],[],null,["# Debug logging\n\nBy default, ExoPlayer only logs errors. To log player events, the `EventLogger`\nclass can be used. The additional logging it provides can be helpful for\nunderstanding what the player is doing, as well as for debugging playback\nissues. `EventLogger` implements `AnalyticsListener`, so registering an instance\nwith an `ExoPlayer` is easy: \n\n### Kotlin\n\n```kotlin\nplayer.addAnalyticsListener(EventLogger())\n```\n\n### Java\n\n```java\nplayer.addAnalyticsListener(new EventLogger());\n```\n\n\u003cbr /\u003e\n\nThe easiest way to observe the log is using Android Studio's [logcat tab](/studio/debug/am-logcat). You\ncan select your app as debuggable process by the package name (\n`androidx.media3.demo.main` if using the demo app) and tell the logcat\ntab to log only for that app by selecting **show only selected application** . It's\npossible to further filter the logging with the expression\n`EventLogger|ExoPlayerImpl`, to get only logging from `EventLogger` and the\nplayer itself.\n\nAn alternative to using Android Studio's logcat tab is to use the console. For\nexample: \n\n adb logcat EventLogger:* ExoPlayerImpl:* *:s\n\n### Player information\n\nThe `ExoPlayerImpl` class delivers two important lines about the player version,\nthe device and OS the app is running on and the modules of ExoPlayer that have\nbeen loaded: \n\n ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33]\n ExoPlayerImpl: Release 59a18ab [AndroidXMedia3/1.0.0-rc02] [flame, Pixel 4, Google, 33] [media3.common, media3.datasource, media3.ui, media3.exoplayer, media3.decoder, media3.exoplayer.dash, media3.extractor]\n\n### Playback state\n\nPlayer state changes are logged in lines like these: \n\n EventLogger: playWhenReady [eventTime=0.00, mediaPos=0.00, window=0, true, USER_REQUEST]\n EventLogger: state [eventTime=0.01, mediaPos=0.00, window=0, BUFFERING]\n EventLogger: state [eventTime=0.93, mediaPos=0.00, window=0, period=0, READY]\n EventLogger: isPlaying [eventTime=0.93, mediaPos=0.00, window=0, period=0, true]\n EventLogger: playWhenReady [eventTime=9.40, mediaPos=8.40, window=0, period=0, false, USER_REQUEST]\n EventLogger: isPlaying [eventTime=9.40, mediaPos=8.40, window=0, period=0, false]\n EventLogger: playWhenReady [eventTime=10.40, mediaPos=8.40, window=0, period=0, true, USER_REQUEST]\n EventLogger: isPlaying [eventTime=10.40, mediaPos=8.40, window=0, period=0, true]\n EventLogger: state [eventTime=20.40, mediaPos=18.40, window=0, period=0, ENDED]\n EventLogger: isPlaying [eventTime=20.40, mediaPos=18.40, window=0, period=0, false]\n\nIn this example playback starts 0.93 seconds after the player is prepared. The\nuser pauses playback after 9.4 seconds, and resumes playback one second later at\n10.4 seconds. Playback ends ten seconds later at 20.4 seconds. The common\nelements within the square brackets are:\n\n- `[eventTime=float]`: The wall clock time since player creation.\n- `[mediaPos=float]`: The current playback position.\n- `[window=int]`: The current window index.\n- `[period=int]`: The current period in that window.\n\nThe final elements in each line indicate the value of the state being reported.\n\n### Media tracks\n\nTrack information is logged when the available or selected tracks change. This\nhappens at least once at the start of playback. The example below shows track\nlogging for an adaptive stream: \n\n EventLogger: tracks [eventTime=0.30, mediaPos=0.00, window=0, period=0,\n EventLogger: group [\n EventLogger: [X] Track:0, id=133, mimeType=video/avc, bitrate=261112, codecs=avc1.4d4015, res=426x240, fps=30.0, supported=YES\n EventLogger: [X] Track:1, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0, supported=YES\n EventLogger: [X] Track:2, id=135, mimeType=video/avc, bitrate=1204535, codecs=avc1.4d401f, res=854x480, fps=30.0, supported=YES\n EventLogger: [X] Track:3, id=160, mimeType=video/avc, bitrate=112329, codecs=avc1.4d400c, res=256x144, fps=30.0, supported=YES\n EventLogger: [ ] Track:4, id=136, mimeType=video/avc, bitrate=2400538, codecs=avc1.4d401f, res=1280x720, fps=30.0, supported=NO_EXCEEDS_CAPABILITIES\n EventLogger: ]\n EventLogger: group [\n EventLogger: [ ] Track:0, id=139, mimeType=audio/mp4a-latm, bitrate=48582, codecs=mp4a.40.5, channels=2, sample_rate=22050, supported=YES\n EventLogger: [X] Track:1, id=140, mimeType=audio/mp4a-latm, bitrate=127868, codecs=mp4a.40.2, channels=2, sample_rate=44100, supported=YES\n EventLogger: ]\n EventLogger: ]\n\nIn this example, the player has selected four of the five available video\ntracks. The fifth video track is not selected because it exceeds the\ncapabilities of the device, as indicated by `supported=NO_EXCEEDS_CAPABILITIES`.\nThe player will adapt between the selected video tracks during playback. When\nthe player adapts from one track to another, it's logged in a line like the one\nbelow: \n\n EventLogger: downstreamFormat [eventTime=3.64, mediaPos=3.00, window=0, period=0, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0]\n\nThis log line indicates that the player switched to the 640x360 resolution video\ntrack three seconds into the media.\n\n### Decoder selection\n\nIn most cases, ExoPlayer renders media using a `MediaCodec` acquired from the\nunderlying platform. When a decoder is initialized, this is logged in lines like\nthese: \n\n EventLogger: videoDecoderInitialized [0.77, 0.00, window=0, period=0, video, OMX.qcom.video.decoder.avc]\n EventLogger: audioDecoderInitialized [0.79, 0.00, window=0, period=0, audio, OMX.google.aac.decoder]"]]