ExoPlayer
ExoPlayer copied to clipboard
STATE_ENDED not reached with Cast extension
First of all i want to congrat you for this amazing extension, it makes cast integration much easier than Google Cast SDK.
Issue description
I want to detect when playback has finished to play next track. I know i could use DynamicConcatenatingMediaSource, but i need a previous process before a track starts, so i'm doing it manually. With SimpleExoPlayerView i get ENDED state when tracks ends, but with cast extension don't, i get IDLE state and "playWhenReady" with "true" value.
If this isn't a bug please tell me how can i detect with cast extension that playback has finished.
Reproduction steps
Connect to Chromecast, playing one video (from an URL) and put a log at onPlayerStateChanged that shows the playback state.
Link to test content
https://www.skillscommons.org/bitstream/handle/taaccct/10109/Operational%20Amplifiers%20(1).mp4
But it happens with any URL i tested.
Version of ExoPlayer being used
2.7.0
Device(s) and version(s) of Android being used
Google Pixel 2 XL, Android 8.1.0 and a Chromecast connected to my TV.
A full bug report captured from the device
I don't get any exception or message, it's just i can't detect when video is over.
A fix for this will be pushed soon. Thanks for reporting!
Great!
@AquilesCanta - I'm not sure which way round, but can one out of this and #4130 be marked a duplicate of the other?
@enigmadevs I had the same issue and as a work around for now, I'm reading directly into the CastSession to determine if the media has ended when I receive a STATE_IDLE.
Something like this:
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
when (playbackState) {
...
Player.STATE_ENDED -> {
// This won't get called but better to keep it for when it gets fixed
onStateEnded()
Player.STATE_IDLE -> {
if (CastContext.getSharedInstance()?.sessionManager?.currentCastSession?.remoteMediaClient?.idleReason == MediaStatus.IDLE_REASON_FINISHED) {
onStateEnded()
} else {
// Regular STATE_IDLE
}
}
}
}
For the record, we wanted to build in a solution like the one shared above, but there was a discussion because Cast player empties the queue when the content ends, which means the state matches the description of both IDLE and ENDED, and the change didn't go through.
We hope we can fix this once we implement masking in CastPlayer, so that the queue will not be empty anymore once we finish playing the content..
As mentioned in issue #9899, I wonder if it's possible to check the MediaStatus for IDLE_REASON_FINISHED (docs) in the fetchPlaybackState function in CastPlayer and send back a STATE_ENDED if it is?
private static int fetchPlaybackState(RemoteMediaClient remoteMediaClient) {
int receiverAppStatus = remoteMediaClient.getPlayerState();
switch (receiverAppStatus) {
case MediaStatus.PLAYER_STATE_BUFFERING:
return STATE_BUFFERING;
case MediaStatus.PLAYER_STATE_PLAYING:
case MediaStatus.PLAYER_STATE_PAUSED:
return STATE_READY;
case MediaStatus.PLAYER_STATE_IDLE: // Can we check the idle reason here?
case MediaStatus.PLAYER_STATE_UNKNOWN:
default:
return STATE_IDLE;
}
}
Assigning to the owner of [Internal ref: b/184443293].
It seems that the problem still persists. I'm using the media3 library. Should I repost this issue in the media3 repo?