0

I am rewriting old Chromecast implementation (web sender + web receiver) from scratch using CAF and I have to use specific external ad library that provides only 1 option for how to implement ads with Google Cast. Documentation of the ad library is very poor not available to public afaik.

When my sender makes load request for media, ads are being loaded and played by receiver before starting the requested media. This causes media session id to change in receivers end but senders media session won't update. Sender is connected for receiver for whole time.

When sender tries to control playback (e.g. play/pause/seek) the receiver throws error:

[cast.receiver.mediamanager] Invalid media session ID: 1 does not match the expected ID: X

Invalid id is always 1 while expected is 1 + amount of ads played

Rundown of steps I have:

Sender application:

  1. connects to receiver
  2. makes load request

Receiver application:

  1. intercepts load request
  2. stores load request for later use
  3. returns null from load request interceptor (effectively ignores load request)
  4. makes ad request
  5. plays preroll ads by calling playerManagaer.load for each of them
  6. loads initial media by calling playerManagaer.load with initially stored load request

My attempts to pause the playback from sender:

remotePlayerController.playOrPause(false)

cast.framework.CastContext.getInstance().getCurrentSession().getMediaSession().pause()

I have also tried to impelent this answer https://stackoverflow.com/a/47928886/16337414 but it doesn't work. I think that difference is that in my case the initial load request is ignored and that's why the senders media session doesn't receive any updateEvents.

Reduced example of sender:

<!Doctype html>
<html lang="en">
  <head>
    <title>CAF Sender</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>

  <body>
    <google-cast-launcher style="display: block; width: 80px; height: 64px;"></google-cast-launcher>

    <script type="text/javascript">
      const source = 'https://example.source'
      const receiverApplicationId = 'XXXXXX'

      let remotePlayerController
      const tryRemotePlayerControllerPause = () => remotePlayerController.playOrPause(false)
      const trySessionPause = () => cast.framework.CastContext.getInstance().getCurrentSession().getMediaSession().pause()
    
      window['__onGCastApiAvailable'] = isAvailable => {
        if(!isAvailable) return

        // Initialize remotePlayerController
        cast.framework.CastContext.getInstance().setOptions({ receiverApplicationId })
        const remotePlayer = new cast.framework.RemotePlayer()
        remotePlayerController = new cast.framework.RemotePlayerController(remotePlayer)

        // Load media on remotePlayerController connected changed
        remotePlayerController.addEventListener(cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, e => {
          if(!e.value) return
          cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(
            new chrome.cast.media.LoadRequest(new chrome.cast.media.MediaInfo(source, 'video/mp4'))
          ).then(
            () => console.log('Remote media loaded'),
            errorCode => console.error('Error occurred while loading remote media, code:' + errorCode)
          )
        })
      }
    </script>
    <script src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
  </body>
</html>

Is there way to update senders media session to match receiver when receiver is the one making the load request?

0 Answers0