ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

STATE_ENDED not reached with Cast extension

Open enigmadevs opened this issue 7 years ago • 8 comments

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.

enigmadevs avatar Mar 09 '18 07:03 enigmadevs

A fix for this will be pushed soon. Thanks for reporting!

AquilesCanta avatar Mar 12 '18 12:03 AquilesCanta

Great!

enigmadevs avatar Mar 12 '18 12:03 enigmadevs

@AquilesCanta - I'm not sure which way round, but can one out of this and #4130 be marked a duplicate of the other?

ojw28 avatar Jun 24 '19 15:06 ojw28

@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
                }
        }
    }
}

JulienArzul avatar Sep 25 '19 22:09 JulienArzul

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..

AquilesCanta avatar Sep 26 '19 09:09 AquilesCanta

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;
    }
  }

mikescamell avatar Jan 26 '22 11:01 mikescamell

Assigning to the owner of [Internal ref: b/184443293].

AquilesCanta avatar Jan 27 '22 08:01 AquilesCanta

It seems that the problem still persists. I'm using the media3 library. Should I repost this issue in the media3 repo?

ziem avatar Oct 12 '23 10:10 ziem