Sender

The Chromecast component builds on the Google Web Sender SDK for sender-side functionality. It’s compatible with receiver apps built using PRESTOplay’s receiver-side functionality. You can also pair it with a different receiver app based on the Google Web Receiver SDK, though some features may not work.

Load the PRESTOplay SDK and its Cast component:

import { clpp } from "@castlabs/prestoplay";
import "@castlabs/prestoplay/cl.cast";

Load the Google Web Sender SDK:

<script src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Use the clpp.cast.onReady callback to wait until the Cast component and the underlying Google Web Sender SDK are ready, then use CastProxy to implement casting:

const player = new clpp.Player(...);

clpp.cast.onReady(() => {
  const proxy = new clpp.cast.CastProxy(player, '<your_receiver_app_id>');
});

Check whether casting is available by calling CastProxy.canCast and listen for clpp.events.CAST_STATUS_CHANGED for changes:

let canCast = proxy.canCast();
player.on(clpp.events.CAST_STATUS_CHANGED, () => {
  canCast = proxy.canCast();
});

Casting requires a Chromecast target device on the same Wi-Fi network, a correct receiver app ID, and a published receiver app.

Basic example:

<script src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
<video id="video"></video>
<button id="castButton" disabled>Cast</button>
<script type="module">
  import { clpp } from "@castlabs/prestoplay";
  import "@castlabs/prestoplay/cl.cast";

  const player = new clpp.Player('video', {
    license: 'your-license-key',
  });

  // Load and play content
  player.open({
    source: 'https://demo.cf.castlabs.com/media/prestodash/Manifest.mpd',
    muted: true,
    autoplay: true,
  });

  clpp.cast.onReady(() => {
    const proxy = new clpp.cast.CastProxy(player, '<your_receiver_app_id>');

    const castButton = document.getElementById('castButton');

    // Update button state based on cast availability
    castButton.disabled = !proxy.canCast();
    player.on(clpp.events.CAST_STATUS_CHANGED, () => {
      castButton.disabled = !proxy.canCast();
      castButton.textContent = proxy.isCasting() ? 'Stop Casting' : 'Cast';
    });

    castButton.addEventListener('click', () => {
      if (proxy.isCasting()) {
        // Stop casting
        proxy.forceDisconnect();
      } else {
        // Start casting
        proxy.cast();
      }
    });
  });
</script>

During casting, control remote playback on the receiver app from the sender by calling Player methods — the sender acts as a remote control for the receiver.

Events

Player fires these Chromecast-related events:

  • clpp.events.CASTING_STARTED — casting has started.

  • clpp.events.CASTING_ENDED — casting has ended.

  • clpp.events.CAST_STATUS_CHANGED — any cast status change (session started or ended, Cast API availability, receiver connection, and so on).

Limitations of the sender

The Chromecast Sender SDK has limitations that keep some Player APIs from working while casting.

Track management

As on the receiver, video tracks and renditions can’t be listed or switched while casting. These TrackManager APIs aren’t usable:

const tm = player.getTrackManager();
tm.getVideoTracks(); // empty array (DASH) or array containing only one item (HLS)
tm.getVideoRendition(); // null (DASH) or active rendition (HLS)
tm.getVideoTrack(); // null (DASH) or active track (HLS)
tm.setVideoTrack(track); // does nothing

Audio track and subtitle management work as expected.

Rendering UI

To render a play/pause button during a casting session, listen for the state change event, since that’s when Player.isPaused changes. Standard video play and pause events aren’t available here because playback happens in the receiver app:

player.on(clpp.events.STATE_CHANGED, function () {
  renderPlayButton();
});
Next topic: Messaging
Previous topic: Receiver app