Debugging Cast Receiver Apps

googlecastnew500.png

This codelab will teach you how to add the Cast Debug Logger to your Cast-enabled Receiver app.

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 or desktop Chrome Browser as a remote control for media playback on the TV.

The Google Cast SDK allows your app to control Google Cast enabled devices (e.g. a TV or sound system). The Cast SDK provides you with 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 a HTML5 app that acts as your very own custom receiver capable of displaying video content on Cast-enabled devices.

What you'll learn

  • How to get set up for receiver development.
  • How to integrate the Debug Logger into your Cast Receiver.

What you'll need

  • The latest Google Chrome browser.
  • node.js, npm, the http-server and ngrok module
  • A Google Cast device such as a Chromecast or Android TV configured with internet access.
  • A TV or monitor with HDMI input.

Experience

  • You should have previous Cast experience and understand how a Cast Receiver works.
  • You will need to have previous web development knowledge.
  • You will also need previous knowledge of watching TV :)

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

How would you rate your experience with watching TV?

Novice Intermediate Proficient

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

Download Source

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.

d8b39f5d33d33db4.png

Click "Add new application"

e8c19e57b85c7d.png

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

bf364a7d382e3c58.png

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.

a446325da6ebd627.png

Click on "Add new Device"

a21355793a3f4cd5.png

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.

Google_Chrome_logo_icon.png

While we wait for our new receiver application to be ready for testing let's see what a sample completed receiver app looks like. The receiver we're going to build will be capable of playing back media using adaptive bitrate streaming (we'll be using sample content encoded for Dynamic Adaptive Streaming over HTTP (DASH)).

In your browser, open the Command and Control (CaC) Tool.

7dbd91a75140c46f.png

  1. You should see our CaC Tool.
  2. Use the default "CC1AD845" receiver ID and click the "Set App ID" button.
  3. Click the Cast button at the top left and select your Google Cast device.

a02db8244a963fd6.png

  1. Navigate to the "Load Media" tab at the top.

acd63df355a0493.png

  1. Click the "Load by Content" button to play a sample video.
  2. The video will start playing on your Google Cast device to show what basic receiver functionality looks like using the Default Receiver.

We need to add support for Google Cast to the start app you downloaded. Here are some Google Cast terminology that we will be using in this codelab:

  • a sender app runs on a mobile device or laptop,
  • a receiver app runs on the Google Cast device.

Now you're ready to build on top of the starter project using your favorite text editor:

  1. Select the android_studio_folder.pngapp-start directory from your sample code download.
  2. Open up js/receiver.js and index.html

Note, as you're working through this codelab, http-server should be picking up changes you make. If you notice it doesn't, try killing and restarting http-server.

App Design

The receiver app initializes the Cast session and will stand-by until a LOAD request (ie. the command to playback a piece of media) from a sender arrives.

The app consists of one main view, defined in index.html and one JavaScript file called js/receiver.js containing all the logic to make our receiver work.

index.html

This html file contains all of the UI for our receiver app.

receiver.js

This script manages all of the logic for our receiver app.

Frequently Asked Questions

Cast Receiver SDK provides another option for developers to easily debug your receiver app by using the CastDebugLogger API.

Initialization

Include the following script in the <head> tag your receiver app right after the CAF Receiver SDK script, in index.html:

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

In js/receiver.js at the top of the file and below the playerManager, get the CastDebugLogger instance and enable the logger:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);

When the debug logger is enabled, you will see an overlay displaying DEBUG MODE will show on the receiver.

d9cb99e7742fc240.png

Log Player Events

Using CastDebugLogger you can easily log player events that are fired by CAF Receiver SDK and use different logger levels to log the event data. The loggerLevelByEvents config takes cast.framework.events.EventType and cast.framework.events.category to specify the events to be logged.

Add the following below the castDebugLogger to log when the player CORE events are triggered or a mediaStatus change is broadcasted:

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

Log Messages and Custom Tags

The CastDebugLogger API allows you to create log messages that appear on the receiver debug overlay with different colors. Use the following log methods, listed in order from highest to lowest priority:

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

For each log method, the first parameter should be a custom tag and the second parameter is the log message. The tag can be any string that you find helpful.

To show logs in action, add logs to your LOAD interceptor.

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Load content from playable URL if populated
      if(request.media.contentUrl) {
        castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);
        return resolve(request);
      }

      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://tse-summit.firebaseio.com/content.json?orderBy=%22$key%22&equalTo=%22'+ request.media.contentId + '%22')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

You can control which messages appear on the debug overlay by setting the log level in loggerLevelByTags for each custom tag. For example, enabling a custom tag with log level cast.framework.LoggerLevel.DEBUG would display all messages added with error, warn, info, and debug log messages. Another example is that enabling a custom tag with WARNING level would only display error and warn log messages.

The loggerLevelByTags config is optional. If a custom tag is not configured for its logger level, all log messages will display on the debug overlay.

Add the following below the CORE event logger:

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

The Cast Debug Logger provides a debug overlay on the receiver to show your custom log messages. Use showDebugLogs to toggle the debug overlay and clearDebugLogs to clear log messages on the overlay.

Add the following to preview the debug overlay on your receiver.

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);

// Show debug overlay
castDebugLogger.showDebugLogs(true);

// Clear log messages on debug overlay
// castDebugLogger.clearDebugLogs();

356c6ac94318539c.png

Overview

The Command and Control (CaC) Tool helps to capture your logs and control the debug overlay.

There are two ways to connect your receiver to the CaC Tool:

Start a new Cast connection:

  1. Open the CaC Tool, set receiver App ID, and click on the Cast button to cast to the receiver.
  2. Cast a separate sender app to the same receiver App ID.
  3. Load media from the sender app and log messages will show on the tool.

Join an existing Cast session:

  1. Get the running Cast session id using receiver SDK or sender SDK. From the receiver side, enter the following to get session id in the Chrome Remote Debugger console:
cast.framework.CastReceiverContext.getInstance().getApplicationData().sessionId;

Or you can get the session id from a connected web sender, use the following method:

cast.framework.CastContext.getInstance().getCurrentSession().getSessionId();
  1. Input the session id on the CaC Tool and click the RESUME button.
  2. The Cast button should be connected and start showing log messages on the tool.

Things to Try

Next we will use the CaC Tool to see logs on your sample receiver.

Open the CaC Tool and set the receiver App ID to your sample app.

7dbd91a75140c46f.png

Click on the Cast button and select your device to open your receiver. Navigate to the "Load Media" tab and click the "Load by Content" button to load the sample media.

ccd8cc258d0c1522.png

A sample video should now be playing on your device. You should start seeing your logs from the previous steps start to display in the "Log Messages" tab at the bottom of the tool.

cd24a07430d5b689.png

Try exploring the following features to investigate logs and control the receiver:

  • Click the MEDIA INFO or MEDIA STATUS tab to see the media information and media status.
  • Click the SHOW OVERLAY button to see a debug overlay on receiver.
  • Use the CLEAR CACHE AND STOP button to reload the receiver app and cast again.

You now know how to add the Cast Debug Logger to your Cast-enabled Receiver ap using the latest Cast Receiver SDK.

Take a look at developer guide for more details: Cast Debug Logger, Command and Control (CaC) Tool

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