media icon indicating copy to clipboard operation
media copied to clipboard

androidx.media3.common.util.Assertions.checkState(Assertions.java:85)

Open JoneyGreat1995 opened this issue 2 months ago • 2 comments

Version

Media3 1.4.0

More version details

api("androidx.media3:media3-exoplayer:1.4.0") api("androidx.media3:media3-session:1.4.0") api("androidx.media3:media3-common:1.4.0")

Devices that reproduce the issue

Customized in-vehicle infotainment system, using Android 13.

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

No

Reproduction steps

1.My multimedia application uses exoPlayer internally, and there's a requirement to switch the player when changing audio sources. Therefore, I'm binding a player to the MediaLibrarySession using: MediaLibrarySession.Builder(this, switchablePlayer, this). The problem tends to occur when the internal audio source switches from Bluetooth to USB update list to exoPlayer:

override fun onUsbPlaylistChanged(playlist: List<MediaItem>) {
    MediaLog.i(TAG, " onUsbPlaylistChanged playlist ${playlist.size}")
    currentMediaList.clear()
    currentMediaList.addAll(playlist)
    exoPlayer?.clearMediaItems()
    exoPlayer?.addMediaItems(currentMediaList)
}

2.when I need Play ,changing the internal player accordingly

fun switchPlayer(newSmartPlayer: SmartPlayer?) {
    MediaLog.d(TAG, "Switching player: ${currentSmartPlayer?.javaClass?.simpleName} → ${newSmartPlayer?.javaClass?.simpleName}")
    currentPlayer?.removeListener(forwardingListener)
    currentSmartPlayer = newSmartPlayer
    currentPlayer = newSmartPlayer?.getPlayer()
    currentPlayer?.addListener(forwardingListener)
    MediaLog.d(TAG, "Player switched, listeners: ${listeners.size}")
    currentPlayer?.currentMediaItem?.let { item ->
        mediaItemChangeCallback?.onMediaItemDataChange(item)
    }
}

3.This player switching is done within SwitchablePlayer.

I will call the play logic.

override fun playMediaByItem(mediaItem: MediaItem) {
    MediaLog.d(TAG, "playMediaByItem: ${mediaItem.mediaMetadata.title}")
    MediaLog.d(TAG, "playMediaByItem: ${mediaItem.mediaId}")
    val index = findMediaIndex(mediaItem)
    if (index >= 0) {
        playMediaAtIndex(index)
    } else {
        MediaLog.w(TAG, "Media not found in playlist: ${mediaItem.mediaId}")
    }
}

private fun playMediaAtIndex(index: Int) {
    if (index >= 0 && index < currentMediaList.size) {
        exoPlayer?.seekToDefaultPosition(index)
        exoPlayer?.prepare()
        exoPlayer?.play()
        MediaLog.d(TAG, "Playing media at index: $index")
    } else {
        MediaLog.w(TAG, "Invalid index: $index, playlist size: ${currentMediaList.size}")
    }
}

Expected result

The usb music media play successfully

Actual result

Playback crashes with the following stack trace
11-03 19:11:19.734  3824  3824 E AndroidRuntime: Process: com.smartlink.multimedia, PID: 3824
11-03 19:11:19.734  3824  3824 E AndroidRuntime: java.lang.IllegalStateException
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.common.util.Assertions.checkState(Assertions.java:85)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.PlayerInfo$Builder.build(PlayerInfo.java:381)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.PlayerInfo.copyWithTimeline(PlayerInfo.java:597)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaUtils.mergePlayerInfo(MediaUtils.java:149)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaControllerImplBase.onPlayerInfoChanged(MediaControllerImplBase.java:2715)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaControllerStub.lambda$onPlayerInfoChangedWithExclusions$9(MediaControllerStub.java:258)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda13.run(Unknown Source:4)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$14(MediaControllerStub.java:374)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda6.run(Unknown Source:4)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:942)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8061)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:703)
11-03 19:11:19.734  3824  3824 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)ra

Media

I will send you the relevant demo via email

Bug Report

  • [x] You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

JoneyGreat1995 avatar Nov 04 '25 02:11 JoneyGreat1995

I think your failure occured here:

https://github.com/androidx/media/blob/bfe5930f7f29c6492d60e3d01a90abd3c138b615/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java#L380-L384

I'm assuming that when you replace the media items, you trigger MediaSessionImpl.PlayerListener.onTimelineChanged -> session.playerInfo.copyWithTimelineAndSessionPositionInfo which then sets the timeline AND builds the PlayerInfo. But then checkState wants the timeline to be empty? Passing onto @marcbaechinger who introduced the check in https://github.com/androidx/media/commit/dee83cc7db73e5a07b4addc9325810643c9ec13d. Perhaps the problem is in the mediaItemIndex instead and we should add an error message to that checkState for easier debugging.

oceanjules avatar Nov 04 '25 11:11 oceanjules

Thank you for your reply. We will address the issue based on the provided solution

Julia @.***> 于2025年11月4日周二 19:30写道:

oceanjules left a comment (androidx/media#2877) https://github.com/androidx/media/issues/2877#issuecomment-3485509221

I think your failure occured here:

https://github.com/androidx/media/blob/bfe5930f7f29c6492d60e3d01a90abd3c138b615/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java#L380-L384

I'm assuming that when you replace the media items, you trigger MediaSessionImpl.PlayerListener.onTimelineChanged -> session.playerInfo.copyWithTimelineAndSessionPositionInfo which then sets the timeline AND builds the PlayerInfo. But then checkState wants the timeline to be empty? Passing onto @marcbaechinger https://github.com/marcbaechinger who introduced the check in dee83cc https://github.com/androidx/media/commit/dee83cc7db73e5a07b4addc9325810643c9ec13d. Perhaps the problem is in the mediaItemIndex instead and we should add an error message to that checkState for easier debugging.

— Reply to this email directly, view it on GitHub https://github.com/androidx/media/issues/2877#issuecomment-3485509221, or unsubscribe https://github.com/notifications/unsubscribe-auth/BR64W7OX7FZHN6DAW3B5TBL33CE5ZAVCNFSM6AAAAACLBQLIMWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTIOBVGUYDSMRSGE . You are receiving this because you authored the thread.Message ID: @.***>

JoneyGreat1995 avatar Nov 05 '25 01:11 JoneyGreat1995