Media Browse

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

Media Browse Entry - In Player Video 1 Media Browse Entry - In Player Video 2

Audio

Media Browse Entry - In Player Audio 1 Media Browse Entry - In Player Audio 2

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

Media Browse Entry - Landing Page Video Media Browse Entry - Landing Page 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:

Media Browse - Browse Content

A. BrowseContent.title

B. BrowseContent.items

Use BrowseItem to display title, subtitle, duration, and image for each item in the Media Browse UI:

Media Browse - Browse Item

A. BrowseItem.image

B. BrowseItem.duration

C. BrowseItem.title

D. BrowseItem.subtitle

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 Media Browse - Square Aspect Ratio
PORTRAIT_2_TO_3 Media Browse - Portrait Aspect Ratio
LANDSCAPE_16_TO_9 Media Browse - Landscape Aspect Ratio

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;
  });