googlecastnew500.png

This codelab will teach you the fundamentals of building a receiver application that takes advantage of the new live features in Cast.

What is Google Cast?

Google Cast allows users to cast content from a mobile device to a TV. Users can then use their mobile device as a remote control for media playback on the TV.

The Google Cast SDK lets you extend your app to control a TV or sound system. The Cast SDK allows you to add the necessary UI components based on the Google Cast Design Checklist.

The Google Cast Design Checklist is provided to make the Cast user experience simple and predictable across all supported platforms.

What are we going to be building?

When you have completed this codelab, you will have built a Cast Receiver that takes advantage of the new Live functionality.

What you'll learn

What you'll need

Experience

How will you use this tutorial?

Read it through only Read it and complete the exercises

How would you rate your experience with building web apps?

Novice Intermediate Proficient

You can download all the sample code to your computer...

Download Source Code

and unpack the downloaded zip file.

To be able to use your receiver with a Cast device it needs to be hosted somewhere where your Cast device can reach it. Should you already have a server available to you that supports https, just skip the following instructions, just remember the URL, you'll need it in the next section.

If you don't have any server available to you, don't fret. You may install node.js, the http-server and ngrok node module.

npm install -g http-server
npm install -g ngrok

Run the server

If you're using http-server, go to your console, and do the following:

cd app-done
http-server

You should then see something like the following:

Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  http://172.19.17.192:8080
Hit CTRL-C to stop the server

Notice the local port used and do the following in a new terminal to expose your local receiver over HTTPS using ngrok:

ngrok http 8080


This will setup an ngrok tunnel to your local HTTP server, assigning you a globally available HTTPS secured endpoint you can use in the next step (https://116ec943.eu.ngrok.io):

ngrok by @inconshreveable                                                                                                                                                                                                                                     (Ctrl+C to quit)

Session Status         online
Version                2.2.4
Web Interface          http://127.0.0.1:8080
Forwarding             http://116ec943.eu.ngrok.io -> localhost:8080
Forwarding             https://116ec943.eu.ngrok.io -> localhost:8080

You should keep both ngrok and http-server running for the duration of the codelab. Any changes you make locally will be instantly available.

You must register your application to be able to run a custom receiver, as built in this codelab, on Chromecast devices. After you've registered your application, you'll receive an application ID that your sender application must use to perform API calls, such as to launch a receiver application.

Click "Add new application"

Select "Custom Receiver", this is what we're building.

Enter the details of your new receiver, be sure to use the URL you ended up with

in the last section. Make a note of the Application ID assigned to your brand new receiver.

You must also register your Google Cast device so that it may access your receiver application before you publish it. Once you publish your receiver application, it will be available to all Google Cast devices. For the purpose of this codelab it's advised to work with an unpublished receiver application.

Click on "Add new Device"

Enter the serial number printed on the back of your Cast device and give it a descriptive name. You can also find your serial number by casting your screen in Chrome when accessing Google Cast SDK Developer Console

It will take 5-15 minutes for your receiver and device to be ready for testing. After waiting 5-15 minutes you must reboot your Cast device.

Before starting this codelab, it may be helpful to review the live developer guide which provides an overview of the new live functionality.

For our sender, we will use the CAF Receiver Debugging Tool to initiate a Cast session. The receiver is designed to automatically start playing a live stream.

The receiver is composed of two files. A basic html file called receiver.html that initializes the Cast context, and a placeholder for the Cast media player. You won't need to modify this file. There is also a file called receiver.js, which will contain all our logic for the receiver.

To begin, open the web sender in Chrome. Enter the Receiver Application ID you were given on the Cast SDK Developer Console and click ‘Set''.

In the receiver we need to add some logic to tell the Cast Application Framework (CAF) that the stream is live. Happily this only requires a single line of code. Add the following line of code to the load interceptor in receiver.js:

request.media.streamType = cast.framework.messages.StreamType.LIVE;

Setting the stream type to LIVE enables CAF's live UI. In this scenario this means when the stream is joined, CAF will automatically jump to the live edge of the stream. We haven't set any program guide data yet, so the scrub bar will represent the full length of the seekable-range of a stream.

Save your changes to receiver.js and initiate a Cast session on the web sender by right clicking anywhere on the page and selecting ‘Cast'. The live stream should begin playing immediately.

CAF's new support for live content now includes support for displaying program guide data on screen in receiver and sender applications. Content providers are strongly encouraged to include programming metadata in their receiver applications for a better end user experience, especially for long running live streams like TV Channels.

You can now provide CAF with the metadata for multiple programs in a single stream. By setting start timestamps and durations on MediaMetadata objects, the receiver will automatically update the metadata shown on senders and receivers based on the player's current location in the stream.

// A sample metadata object for a single tv show
const currentShow = new cast.framework.messages.TvShowMediaMetadata();
currentShow.episode = 15;
currentShow.seriesTitle = 'The Odyssey';
currentShow.title = 'Scylla and Charybdis';
currentShow.sectionStartAbsoluteTime = toUnixTimestamp('9:00 PM');
currentShow.sectionDuration = HOUR_IN_SECONDS;

For this codelab we will use a sample metadata service to provide the metadata for our live stream. To create a listing of program metadata, we first need to create a container. A container holds a list of MediaMetadata objects for a single media stream. Each MediaMetadata object represents a single section in the container. When the playhead is within the bounds of a given section, its metadata will be automatically copied over to the media status. Add the following code to the receiver.js file to download the sample metadata from our service and provide the container to CAF:

/**
 * Gets the current program guide data from our Google Cloud Function
 * @return {cast.framework.messages.MediaMetadata[]} Latest program guide data
 */
function loadGuideData() {
  return fetch(LIVE_MEDIA_METADATA_SERVICE_URI)
      .then((response) => response.json())
      .then(function(data) {
        const containerMetadata =
          new cast.framework.messages.ContainerMetadata();
        containerMetadata.sections = data;

        playerManager.getQueueManager().setContainerMetadata(containerMetadata);
      });
}

Additionally, add a call to the function for loading the guide data in the load interceptor:

loadGuideData();

Save the receiver.js file and initiate a Cast session. You should see the program start time, end time, and title all displayed on screen.

A new media status message will be sent from the receiver to all senders when the playhead transitions to a new section in the container. Thus it might make sense to update the container metadata in a media status interceptor so you can always have up-to-date program information. In our sample service we return the current program metadata, as well as the metadata for the next two programs. To update the metadata for a stream, simply create a new container and call setContainerMetadata as in the example above.

Most video streams are composed of segments that hold a range of video frames. Unless otherwise specified, CAF will allow users to seek within these segments. To disable seeking, we need to add two snippets of code to our receiver.

In the load interceptor, remove the SEEK supported media command. This disables seeking on all mobile sender and touch interfaces.

playerManager.removeSupportedMediaCommands(cast.framework.messages.Command.SEEK, true);

Next, we need to disable voice commands from letting viewers skip around in the stream, e.g. ‘Ok Google, skip back 60 seconds.' To disable seeking by voice, we will add a seek interceptor. This interceptor gets called every time a seek request is made. If the SEEK supported media command is disabled, the interceptor will reject the seek request. Add the following code snippet to the receiver.js file:

/**
 * Seek a seek interceptor is called whenever CAF receives a request to seek to
 * a different location in media. This interceptor can be used to modify that
 * seek request or disable seeking completely.
 * @param {cast.framework.messages.MessageType.SEEK} The message to intercept.
 */
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SEEK,
    (seekData) => {
      // if the SEEK supported media command is disabled, block seeking
      if (!(playerManager.getSupportedMediaCommands() &
      cast.framework.messages.Command.SEEK)) {
        castDebugLogger.info(TAG, 'Seek blocked.');
        return null;
      }

      return seekData;
    }
);

Save the receiver.js file and initiate a Cast session. You should no longer be able to seek within the live stream.

You now know how to create a custom receiver application using the latest Cast Receiver SDK.

Take a look at our sample apps on GitHub: github.com/googlecast.