Cast Media Browse (CMB) is a feature that lets smart display users discover and engage with your audio or video content catalog. CMB does so by enhancing the Web Receiver with a streamlined browsing experience that is specially tuned for smart displays.
CMB defines standardized templates that deliver a consistent browsing experience that follows smart display UI conventions. Developers supply data to populate these standardized templates. Templates support both audio and video content or a mix of both.
Entry points
There are two entry points for CMB, from which a user can browse and select content using touch or voice control.
In-player browse
Swipe up during playback to choose from a list of application-supplied content:
Video
Audio
Landing page browse
When a Web Receiver with the cast-media-player
element is running on Smart
Displays, it shows CMB while in the IDLE state.
Video and Audio
Populating content
Developers are responsible for populating the template for each entry point with data for each content item. The content used to populate In-Player Browse can be different than the content used to populate Landing Page Browse.
Use In-Player Browse to display items that relate to the content a user is currently playing, or items of a playlist. Live TV providers could also use this entry point to populate a list of channels for easy access.
Use Landing Page Browse to raise awareness of new original content, content that is currently live, or content that might be of further interest to your user.
Enable Media Browse
Provide a list of media contents for browsing by calling setBrowseContent
:
const controls = cast.framework.ui.Controls.getInstance(); controls.setBrowseContent(BrowseContent);
The Media Browse UI is updated immediately after calling this method.
Safe area height
When CMB is enabled, the height of the Cast SDK UI safe area changes, and you
might need to update your existing Web Receiver UI. Use
getSafeAreaHeight
to determine the height of the safe area.
// Media Browse UI enabled controls.setBrowseContent(BrowseContent); console.log(controls.getSafeAreaHeight()); // 338px on Google Nest Hub // Media Browse UI disabled controls.setBrowseContent(null); console.log(controls.getSafeAreaHeight()); // 408px on Google Nest Hub
Remove Media Browse
To remove the Media Browse UI, use null
with setBrowseContent
:
controls.setBrowseContent(null);
Customize Media Browse
Browsing content
Use
BrowseContent
to customize the title of the Media Browse UI and update items:
Use
BrowseItem
to display title, subtitle, duration, and image for each item in the Media
Browse UI:
Aspect ratio
Use targetAspectRatio
to select the best aspect ratio for your image assets. Three aspect ratios are
supported by the Web Receiver SDK:
Aspect Ratio | Example |
---|---|
SQUARE_1_TO_1 |
|
PORTRAIT_2_TO_3 |
|
LANDSCAPE_16_TO_9 |
Messages
When a user selects one of the items from the Media Browse UI, the Web Receiver
SDK sends a LOAD
message to the application according to
the values of the selected BrowseItem
.
Sample code
const controls = cast.framework.ui.Controls.getInstance();
const item1 = new cast.framework.ui.BrowseItem();
item1.title = 'Title 1';
item1.subtitle = 'Subtitle 1';
item1.duration = 300;
item1.imageType = cast.framework.ui.BrowseImageType.MUSIC_TRACK;
item1.image = new cast.framework.messages.Image('1.jpg');
item1.entity = 'example://gizmos/1';
const item2 = new cast.framework.ui.BrowseItem();
item2.title = 'Title 2';
item2.subtitle = 'Subtitle 2';
item2.duration = 100;
item2.imageType = cast.framework.ui.BrowseImageType.MUSIC_TRACK;
item2.image = new cast.framework.messages.Image('2.jpg');
item2.entity = 'example://gizmos/2';
const items = [item1, item2];
const browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = items;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
// Media browse
controls.setBrowseContent(browseContent);
});
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
if (loadRequestData.media && loadRequestData.media.entity) {
// Load by entity
loadRequestData.media.contentId = entityToId(loadRequestData.media.entity);
loadRequestData.media.contentUrl = entityToUrl(loadRequestData.media.entity);
}
return loadRequestData;
});