This guide explains how to migrate a Cast Receiver v2 app to the latest Web Receiver app.
The new Cast Application Framework (CAF) SDK, also known as Web Receiver v3, is a major upgrade from the Receiver v2 SDK. The Web Receiver SDK provides an easy, streamlined SDK for developing media Web Receiver applications.
The Web Receiver provides an API that is more consistent with the new CAF sender APIs. It provides full integration of a player (MPL and Shaka) and full implementation and support for the Cast media and Google Assistant voice commands. CAF SDK also provides a default UI that can be easily styled using CSS, and a data binding service to simplify UI implementation.
Why migrate?
By migrating a Receiver v2 application to Web Receiver, a lot of code that deals with the player can be eliminated, so you can concentrate on writing application-specific business logic.
CAF seamlessly integrates MPL and Shaka players to support a wider range of content types including—HTTP Live Streaming (TS and CMAF), MPEG-DASH, Smooth Streaming and types supported by the Media Element source property (MP3, MP4, Icecast, etc...). For a complete list see Supported Media for Google Cast. Currently CAF does not support a user-provided player.
Migrating to CAF will add the support for voice control with Google Assistant. Any new Google Assistant voice command will automatically be supported when using CAF.
In addition to supporting new media commands—like "change tracks by language” and "change playback rate”—CAF also provides better queueing, built-in ads support, and better live support.
What changed?
The Web Receiver API tries to follow the conventions that were introduced by CAF senders for Android and iOS, and is quite different from v2.
The Web Receiver is using a new namespace
cast.framework
instead of cast.receiver
namespace for all exposed APIs. Many of
the data objects that were used by v2 are the same in CAF and are exposed under
the
cast.framework.messages
namespace (they were mostly under cast.receiver.media
).
The following v2 services are replaced by corresponding CAF services:
CastReceiverManager
class is replaced byCastReceiverContext
which is a singleton that manages the cast session, senders, sending custom messages, and global system events. TheCastReceiverOptions
can be used to provide global application options (such as queue, receiver version, playback config, etc.) to the context.MediaManager
class is replaced byPlayerManager
which is a property of theCastReceiverContext
singleton, and it manages the media session, media requests, Google Assistant voice requests (CommandAndControlManager
in v2), and fires media events. Configuration for the players (cast.player.api.Host
in MPL) is provided byPlaybackConfig
, which can be provided globally or per load request.
The PlayerManager
also exposes the new sub-manager classes:
TextTracksManager
- manage media text tracks.AudioTracksManager
- manage audio tracks.QueueManager
- manage the queue.BreakManager
- manage ads.
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
// Set global options.
const options = new cast.framework.CastReceiverOptions();
options.versionCode = DEVELOPERS_APP_VERSION;
context.start(options);
Receiver business logic
Receiver v2 exposed event handlers (such as CastReceiverManager.onReady
or
MediaManager.onLoad
) to add business logic. In CAF the event handlers are
replaced by event listeners
(CastReceiverContext.addEventListener
)
and message interceptors
(PlayerManager.setMessageInterceptor
).
Web Receiver can have multiple event listeners for an event (the listener
does not affect the event), and one interceptor per message. The interceptor
can update the request or handle it (return a modified request, a success
message, or error message), and can be an async handler that returns a promise.
The load request interceptor is the most common place to add application-specific logic. For load requests from a sender, the load interceptor can convert the content ID to content URL. The load interceptor is also being called for preload and precache requests if no explicit interceptor was provided for preload or precache.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
// Resolve entity to content id
if (request.media.entity && !request.media.contentId) {
return getMediaByEntity(request.media.entity).then(
media => {
request.media.contentId = media.url;
return request;
});
}
return request;
});
The v2 customized media status handler is also replaced with a message
interceptor for the media status message. Web Receiver apps that do not want to
expose the media URL in the media status can provide a URL resolver
(PlayerManager.setMediaUrlResolver
),
which provides the media URL for a load request. That URL is used by CAF
internally and is not provided in the media status.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.MEDIA_STATUS,
status => {
// Disable seek.
status.supportedMediaCommands &=
~cast.framework.messages.Command.SEEK
return status;
});
Events
Web Receiver provides an extensive set of events both from
CastReceiverContext
and
PlayerManager
.
Web Receiver apps can have multiple listeners on any event, and
can also provide one listener to multiple events. (See
cast.framework.events.category
for some groups of events.)
The events cover any user request, playback progress, player processing, and any low-level media element event (CAF does not expose the media element itself).
The Web Receiver app can add event listeners to act upon (for example, add text tracks definition when load completes), or for analytics.
// Log all media commands
playerManager.addEventListener(
cast.framework.events.category.REQUEST,
event => logEvent(event.type));
Custom message bus
CAF does not expose the message bus in the API, instead it provides
CastReceiverContext.addCustomMessageListener
to add a message listener for a specific namespace (only one per namespace) and
CastReceiverContext.sendCustomMessage
to send a message on a namespace. All namespaces need to be declared before
starting the Web Receiver (that is, before calling
CastReceiverContext.start
).
The namespaces can be declared by
adding a message listener to them or can be provided as a start option in
CastReceiverOptions.customNamespaces
.
const options = new cast.framework.CastReceiverOptions();
options.customNamespaces = {
CUSTOM_NS: cast.framework.system.MessageType.JSON
};
context.start(options);
context.sendCustomMessage(CUSTOM_NS, {
type: 'status'
message: 'Playing'
});
Default UI
CAF provides a default Web Receiver UI that displays a playback progress bar and
media metadata as needed. The default UI is provided as a custom element
(<cast-media-player>
)
that can be styled with CSS-like styling.
<style>
cast-media-player { --splash-image: url("splash.png"); }
</style>
<cast-media-player></cast-media-player>
For more customization, a Web Receiver app can implement its own UI. The
Web Receiver provides the
cast.framework.ui.PlayerDataBinder
class to help bind a UI object to the Web Receiver playback state.