2
votes

I have an important question: I manage stream flow on my receiver but I want to use stop message from my sender for stop the stream. Currently I'm using this sender (https://github.com/googlecast/CastVideos-android) and this receiver (https://github.com/googlecast/CastReferencePlayer) but the problem is that the sender sends me a command to pause and not a stop during the live. In the documentation, side sender Android, I'm reading that the behavior is correct and the receiver must send a media status update message back to the sender and should report the state as MediaStatus.PLAYER_STATE_IDLE with reason MediaStatus.IDLE_REASON_CANCELLED.

Arrived at this point I want to modify the sample receiver and manage the pause like a stop and not like a pause. I want to manage the stop because when the sender click the stop button the receiver must stop the video and the sender must destroy "every player" (player, miniplayer, etc).

So My idea is this:

sampleplayer.CastPlayer.prototype.onPause_ = function() {
  this.log_('onPause');
  this.cancelDeferredPlay_('media is paused');
  var isIdle = this.state_ === sampleplayer.State.IDLE;
  var isDone = this.mediaElement_.currentTime === this.mediaElement_.duration;
  var isUnderflow = this.player_ && this.player_.getState()['underflow'];
  if (isUnderflow) {
    this.log_('isUnderflow');
    this.setState_(sampleplayer.State.BUFFERING, false);
    this.mediaManager_.broadcastStatus(/* includeMedia */ false);
  } else if (!isIdle && !isDone) {
    this.setState_(sampleplayer.State.PAUSED, false);
  } else if(this.isLiveStream) {
    this.log_('onStop');
    this.cancelDeferredPlay_('media is stopped');
    var self = this;
    sampleplayer.transition_(self.element_, sampleplayer.TRANSITION_DURATION_,
        function() {
        self.setState_(sampleplayer.State.IDLE, false);
        self.resetMediaElement_();
        self.mediaManager_.setIdleReason("CANCELLED");
    }); 

    return ;
  }
  this.updateProgress_();
};

As you can see in the third branc, I control a variable that I saved during the load of the video and after I set the state of player to IDLE, reset the mediaElement and finally I send to broadcast the State = IDLE and Reason = CANCELLED. In this way the sender see the message because I look the log but doesn't interpret this.

Now I don't know how to continue and manage this behaviour. Advice are welcome. Thank you.

1

1 Answers

1
votes

Just to make sure my answer is covering your question, let me simplify your questions as the following: when playing a live stream, you want to still see the "stop" button on the sender side but if the user taps on that button, you want to stop the playback and unload the media.

If this is correct, you can achieve that from the sender side as well: CastVideos-android uses CastCompanionLibrary. There are two places that you need to update in that library: in VideoCastManager#togglePlayback() and VideoCastControllerFragment#togglePlayback(). In the former place, you need to update the conditional there to read like the following:

if (isPlaying && isRemoteStreamLive()) {
    stop();
} else if (isPlaying) {
    pause();
} else {
... //leave as is
}

In the latter case, you need to update one of the switch statements:

case MediaStatus.PLAYER_STATE_PLAYING:
    if (mSelectedMedia.getStreamType() == MediaInfo.STREAM_TYPE_LIVE) {
        mCastManager.stop();
        mPlaybackState = MediaStatus.PLAYER_STATE_IDLE;
    } else {
        mCastManager.pause();
        mPlaybackState = MediaStatus.PLAYER_STATE_BUFFERING;
    }
    break;

Basically, you are adding a logic that if the content is playing remotely, "toggling playback" should call stop() rather than pause() when dealing with a live stream.

Note that calling stop() means you are completely unloading your media and you may need to do some additional work to play another media but I haven't tested that since I don't call stop() in the CastVideos app. Also note that I have not tested/tried the above suggestion since I don't have a live stream to play with but I am hoping it would work.