-
Notifications
You must be signed in to change notification settings - Fork 652
Description
Version
Media3 1.7.1 (same as 1.6.1)
More version details
No response
Devices that reproduce the issue
Pixel 6 running Android 15
Samsung S23 Ultra running Android 14
Pixel 9 emulator running Android 15
Techno Spark 20 Pro running Android 13
Devices that do not reproduce the issue
No
Reproducible in the demo app?
Not tested
Reproduction steps
We have a video-based application with custom ads logic (not IMA). Steps to reproduce describe the simplified logic from our application
Steps to reproduce:
- Start any video playing by ExoPlayer class:
val videoA = MediaItem.fromUri(<any mp4 video url>)
player.addMediaItem(videoA)
player.prepare()
player.play()
- Add some media items to player next to current video (playlist):
val videoB = MediaItem.fromUri(<any mp4 video url>)
val videoC = MediaItem.fromUri(<any mp4 video url>)
player.addMediaItem(videoB)
player.addMediaItem(videoC)
- Apply postroll url to AdPlaybackState and send it to player for current video (in our app we implemented AdsLoader with correct connecting it to mediaSourceFactory etc, but here is only snippet of simplified core logic):
val postrollMediaItem = MediaItem.Builder().setUri(<any mp4 video url>).build()
val adPlaybackState = AdPlaybackState(adsId, C.TIME_END_OF_SOURCE)
.withAdCount(0, 1)
.withAvailableAdMediaItem(0,0, postrollMediaItem)
AdsLoader.EventListener.onAdPlaybackState(adPlaybackState )
-
Wait until almost the very end of the video (for example if video duration is 60.000ms, the position we are interested is ~59.000-59.900ms)
-
At this time moment, clear playlist, apply new video to playlist and switch to next media item (at this moment player.isPlayingAd == false):
// Clears videoB and videoC from player's playlist
player.removeMediaItems(player.currentMediaItemIndex + 1, player.mediaItemCount)
// Setup new playlist as VideoX
val videoX = MediaItem.fromUri(<any mp4 video url>)
player.addMediaItem(videoX)
// Switch to next media item (i.e VideoX)
player.seekToNextMediaItem()
Expected result
Player successfully seek to new next media item (i.e VideoX)
Actual result
Not always, but quite often we get a crash:
java.lang.IllegalStateException
at androidx.media3.common.util.Assertions.checkState(Assertions.java:85)
at androidx.media3.exoplayer.ExoPlayerImpl.maskTimelineAndPosition(ExoPlayerImpl.java:2480)
at androidx.media3.exoplayer.ExoPlayerImpl.removeMediaItemsInternal(ExoPlayerImpl.java:2410)
at androidx.media3.exoplayer.ExoPlayerImpl.removeMediaItems(ExoPlayerImpl.java:674)
at <Our app player wrapper class>.removeMediaItems(just call ExoPlayer's method without specific logic)
at androidx.media3.common.ForwardingPlayer.removeMediaItems(ForwardingPlayer.java:189)
at androidx.media3.session.PlayerWrapper.removeMediaItems(PlayerWrapper.java:594)
at androidx.media3.session.MediaSessionStub.lambda$removeMediaItems$43$androidx-media3-session-MediaSessionStub(MediaSessionStub.java:1298)
at androidx.media3.session.MediaSessionStub$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at androidx.media3.session.MediaSessionStub.lambda$sendSessionResultSuccess$1(MediaSessionStub.java:174)
at androidx.media3.session.MediaSessionStub$$ExternalSyntheticLambda84.run(D8$$SyntheticClass:0)
at androidx.media3.session.MediaSessionStub.lambda$queueSessionTaskWithPlayerCommandForControllerInfo$13(MediaSessionStub.java:344)
at androidx.media3.session.MediaSessionStub$$ExternalSyntheticLambda40.run(D8$$SyntheticClass:0)
at androidx.media3.session.ConnectedControllersManager.lambda$flushCommandQueue$3$androidx-media3-session-ConnectedControllersManager(ConnectedControllersManager.java:295)
at androidx.media3.session.ConnectedControllersManager$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at androidx.media3.session.MediaSessionImpl.lambda$callWithControllerForCurrentRequestSet$3$androidx-media3-session-MediaSessionImpl(MediaSessionImpl.java:355)
at androidx.media3.session.MediaSessionImpl$$ExternalSyntheticLambda21.run(D8$$SyntheticClass:0)
at androidx.media3.common.util.Util.postOrRun(Util.java:800)
at androidx.media3.session.ConnectedControllersManager.flushCommandQueue(ConnectedControllersManager.java:289)
at androidx.media3.session.ConnectedControllersManager.flushCommandQueue(ConnectedControllersManager.java:270)
at androidx.media3.session.MediaSessionStub.lambda$flushCommandQueue$64$androidx-media3-session-MediaSessionStub(MediaSessionStub.java:1692)
at androidx.media3.session.MediaSessionStub$$ExternalSyntheticLambda37.run(D8$$SyntheticClass:0)
at androidx.media3.common.util.Util.postOrRun(Util.java:800)
at androidx.media3.session.MediaSessionStub.flushCommandQueue(MediaSessionStub.java:1690)
at androidx.media3.session.MediaControllerImplBase$FlushCommandQueueHandler.flushCommandQueue(MediaControllerImplBase.java:3646)
at androidx.media3.session.MediaControllerImplBase$FlushCommandQueueHandler.handleMessage(MediaControllerImplBase.java:3639)
at androidx.media3.session.MediaControllerImplBase$FlushCommandQueueHandler.$r8$lambda$TVKiXTCmsW2hn-6HNXqbaigkfJc(Unknown Source:0)
at androidx.media3.session.MediaControllerImplBase$FlushCommandQueueHandler$$ExternalSyntheticLambda0.handleMessage(D8$$SyntheticClass:0)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8705)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
androidx.media3.common.util.Assertions.checkState(Assertions.java:85) fails with check:
checkState(!newPeriodId.isAd());
Additional notes
this crash only happens for postroll (C.TIME_END_OF_SOURCE) advert. Preroll and midroll adverts are works fine without crashes
Media
Any mp4 video url, doesn't depend on specific video
Bug Report
- You will email the zip file produced by
adb bugreportto android-media-github@google.com after filing this issue.