Live Streaming (alpha)

What's new

The Cast Application Framework (CAF) includes powerful, built-in APIs for building unique live experiences. The recent update to Live support gives developers greater control over live experiences and how they are presented to users.

CAF provides a powerful and flexible out-of-box UX/UI, coupled with APIs that allow developers to create rich live experiences with just a few lines of code. CAF now has built-in support for show start/end times, program metadata, DVR controls, and seekable windows.

This guide demonstrates how to configure a stream to use the new Live Experience, including code and metadata samples for configuring core Live scenarios, along with screenshots demonstrating what each scenario looks like.

Prerequisites

Familiarity with the basics of implementing a CAF Sender and Receiver is required before reviewing this guide. Additionally, to run the code samples you will need access to a live stream that conforms to one of the supported media types for Cast. In general, the Live features will support typical HLS, MPEG-DASH and SmoothStreaming live stream configurations.

There are a few terms used throughout this guide that are helpful to know:

  • Seekable Window - The range of a live stream that users can seek within.
  • Live Edge - The newest part of a live stream available to the player.
  • Play Head - A UI timestamp for the current playback position.

Casting a live stream

The easiest way to configure a live stream to use the new Live Experience is via a LOAD message interceptor in your receiver application. Load interceptors allow you to modify an incoming request from a sender application before that request is acted on by a Cast device. You can also start a Live stream via a sender load request.

The interceptor provides a LoadRequestData object that contains all the important metadata about a load request. To indicate a load request is for a live stream, simply set the streamType on the mediaInformation object to the live streamType.

/*
* This interceptor is called before your content is loaded by a Cast device
*/
playerManager.setMessageInterceptor(
   cast.framework.messages.MessageType.LOAD,
   request => { /* cast.framework.messages.LoadRequestData */
       request.media.streamType = cast.framework.messages.StreamType.LIVE;
   return request;
});

Adding program guide data

Live streams—especially long running streams, like a TV channel—are able to display on-screen guide/programming metadata based off the current playback position in a live stream. Content providers are strongly encouraged to include programming metadata in their receiver applications for a better end user experience.

You can configure the initial guide data for a stream in the LOAD message interceptor, the same way we indicated the stream was a live stream in the previous example. Individual sections or programs in the live stream are represented as MediaMetadata objects which are then stored in a queue. There is a different MediaMetadata class for different types of programs—e.g. TvShowMediaMetadata, MovieMediaMetadata, MusicTrackMediaMetadata, etc.

In the following code snippet, we use the MediaMetadata object to specify the start time of each show with a UNIX Timestamp with the sectionStartAbsoluteTime property. The duration of a program is represented in seconds.

// The metadata 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;

const previousShow = new ...;
const nextShow = new ...;

const containerMetadata = new cast.framework.messages.ContainerMetadata();
containerMetadata.title = 'My TV Channel';
containerMetadata.sections = [previousShow, currentShow, nextShow];

playerManager.getQueueManager().setContainerMetadata(containerMetadata);

Live seekable range

CAF now includes UI elements and controls that allow a user to move their playhead within the stream using the CAF Sender Expanded Controller or touch controls on devices like the Google Home Hub.

The range of time in a stream where a user is able to seek is represented by the LiveSeekableRange object. On the receiver you can access information about the seekable range via PlayerManager.getLiveSeekableRange( ) which returns a LiveSeekableRange object. The main properties on the object to be aware of are:

  • start — the start time—in seconds—of the range relative to the beginning of the stream in seconds.
  • end — the maximum possible time—in seconds—the player can seek to based on available segments, relative to the beginning of the stream.
  • isMovingWindow — a boolean value that indicates if the seekable range moves(i.e. older segments are removed from the manifest) with the stream, this should be true of all live streams.
  • isLiveDone — a boolean value that indicates if the live stream has finished, i.e. no new segments are being generated.

The size of the seekable range, represented as the time between start and end, is determined by the number of segments available in the stream and will move with the stream. For example, if at the start of the stream the seekable range is {start:0, end: 600, isMovingWindow: false, isLiveDone: false}, ten seconds after the stream starts it can become {start: 10, end: 610, isMovingWindow: true, isLiveDone: false}. It is important to note the start/end times in the seekable range are updated based on the time it takes to generate a new segment. Thus if the typical length of a segment for your stream is 10 seconds, the start/end times will be updated about every 10 seconds as well.

If you intend to completely disable the seeking within a stream, you need to remove the seek functionality from the supported media commands on the receiver:

// disable seeking in the LOAD messageInterceptor
playerManager.removeSupportedMediaCommands(cast.framework.messages.Command.SEEK, true);

Removing the supported media command for SEEK signals to sender applications to disable seeking, however on products like the Google Home Hub you must also disable seeking by voice commands, e.g. ‘Ok google, seek backwards 30 seconds.’ The easiest way to do this is by intercepting the seek command.

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)) {
           return null;
       }

       return seekData;
});

If the user pauses a stream long enough that their play head falls outside of the live seekable window, or if seeking is disabled entirely, the stream will restart playback at the live edge of the stream.

Live framework events

There are two events added as part of the new Live features. Each event is passed a LiveStatusEvent object which contains the current live seekable range. Note you cannot update values in an event, for more details see the guide on handling events in CAF.

Event Description
LIVE_ENDED Triggered when a live stream ends. At this point the end value in the LiveSeekableRange will stop updating; users will still be able to view content within the live seekable range. For the full event details see: cast.framework.events.EventType.LIVE_ENDED
LIVE_IS_MOVING_WINDOW_CHANGED Triggered when the seekable range of a live stream changes from a fixed window to a moving window, or vice versa. For a live stream this will happen when the player detects the manifest is removing earlier segments. For full event details see:cast.framework.events.EventType.LIVE_IS_MOVING_WINDOW_CHANGED

Live stream scenarios

There are eight possible types of scenarios for live streaming, each of which are configured by setting three core settings: if the stream has a start time; an end time; and if users allowed to seek within the live stream’s seekable window—see Adding Program Guide Data for how to configure those values.

Below are descriptions—including screenshots—of the scenarios supported by CAF. The variables T1 and T2 are used to represent the timestamp on the left and right of the UI respectively.

Start time End time Seekable T1 T2
Scenario 1 No No No Play Head Not Shown
Scenario 2 No No Yes Play Head Not Shown
Scenario 3 No Yes No Play Head Not Shown
Scenario 4 No Yes Yes Play Head Not Shown
Scenario 5 Yes No No Show Start TIme Play Head
Scenario 6 Yes No Yes Show Start TIme Play Head
Scenario 7 Yes Yes No Show Start Time Show End Time
Scenario 8 Yes Yes Yes Show Start Time Show End Time

Scenario one

Start time End time Seekable T1 T2
No No No Play head Not Shown

Scenario one has no start or end time and users are unable to seek within the stream. It is worth noting that in this scenario, when a user stops a stream playback will resume not from when they paused the stream but the current live edge of the stream.

Scenario seven

A TV Showing Chromecast's Live UI for Scenario 7 with Clock Time A mobile phone showing the Live UI for Scenario 7 with Clock Time

Start time End time Seekable T1 T2
Yes Yes No Play Head Program Duration

The stream has a start time and end time but is not seekable. Two timestamps in the UI, T1 and T2, represent the current playhead time and total program duration respectively. If a user pauses/resumes playback the stream will resume at the live edge of the stream. In the above example the red section of the seek bar represents the portion of the stream since the user started watching.

Scenario eight

A TV Showing Chromecast's Live UI for Scenario 8 with Clock Time A mobile phone showing the Live UI for Scenario 8 with Clock Time

Start time End time Seekable T1 T2
Yes Yes Yes Play Head Program Duration

The stream has a start time, end time, and is seekable. Two timestamps in the UI, T1 and T2, represent the current playhead time and total program duration respectively. If a user pauses/resumes playback the stream will resume at the time they paused if it is within the seekable window—the area in red on the seek bar represents where a user can seek back to and the area in white represents where they can seek forward to.

Configuring a scenario

Configuring a stream as a specific Live Scenario is done in three parts:

  1. Set Stream Type - Mark the stream as being a live stream.
  2. Add Program Guide Data - Set a start time and duration in the MediaMetadata object.
  3. Configure Seek Functionality - Enable or disable seeking.

Playback behavior

While paused the UI will continue to have its playback metadata updated—this includes playback head and live edge times. Upon resumption of the stream there are a few behaviors to be aware of that vary based on the configuration of the stream.

Seekable streams

  • Upon resumption of a seekable stream:
    • The live edge shall be updated to the live location and the seekable range will be adjusted accordingly.
    • If the playhead jumps past the current show, the scrub bar will be updated with the metadata from the new show (including start time and end time if available).
    • If a seekable window limit of length ‘X’ is in effect, the seekable range will extent back to at most ‘X’, or to the beginning of the show—whichever is smaller.
    • User pauses for a while and the seek window expires; playback will remain paused. When the user chooses to exit pause state, playback shall resume at the earliest point (far left) of the seekable window.

Non-seekable streams

  • Upon resumption of a non-seekable stream:
    • In this case, playback will resume at the live edge.
    • If the live edge jumps past the current show, the scrub bar should be updated with the metadata from the new show (including start time and end time if available).

API surface changes & customizing Live UI

CAF has powerful, built-in support for creating custom user interfaces instead of using the out-of-the-box UI. However it is important to follow the Cast UX Design Checklist when customizing the interface.

Receiver

On the receiver, new fields have been added to the PlayerData object to allow developers to extend their custom interfaces for live streams:

  • isLive - a flag that indicates if the current stream is a live stream, as opposed to VOD.
  • liveSeekableRange - the seekable range to be shown on screen demarcating the DVR window.
  • mediaStartAbsoluteTime - when the section started in absolute time(UNIX Epoch).
  • sectionStartTimeInMedia - section start time in seconds relative to the media start time.
  • sectionDuration - section duration in seconds.

Additionally there are two new events that are being introduced as part of Live, you should take into account if customizing the UI.

Android SDK

As part of the new Live functionality, the use of the Android Seekbar Widget in the UIMediaController has been deprecated, instead use CastSeekBar.

Next Steps

This concludes the features that you can add to your CAF Receiver. You can now build a sender app on iOS, Android, or Chrome.