# Optimize for Smart Displays

Smart displays are devices with touch functionality to allow Web Receiver
applications to support touch-enabled controls. The Web Receiver SDK provides a
default UI experience with additional customization of the player controls.

This guide explains how to optimize your Web Receiver application when launched
on smart displays and how to customize the player controls.

> [!NOTE]
> **Note:** This customization requires the use of the built-in player UI `cast-media-player` element. The UI state tracking, branding, and other customizations need to be done manually if this element is not used.

## Accessing UI controls

The UI Controls object can be accessed with the following code:

    const controls = cast.framework.ui.Controls.getInstance();

If you are not using a `cast-media-player` element, you need to set
`touchScreenOptimizedApp` property to `true` in [`UiConfig`](https://developers.google.com/cast/docs/reference/web_receiver/cast.framework.ui.UiConfig)
under [`CastReceiverOptions`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.CastReceiverOptions#uiConfig).

    context.start({
      uiConfig: {
        touchScreenOptimizedApp: true
      }
    });

## Default video UI

Default control buttons are assigned to each slot based on [`MetadataType`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages#.MetadataType) and
[`MediaStatus.supportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MediaStatus#supportedMediaCommands).

### MetadataType.Movie, MetadataType.Generic

![](https://developers.google.com/static/cast/images/video_ui.png)

A. [`--playback-logo-image`](https://developers.google.com/cast/docs/caf_receiver_features#styling_the_player)

B. [`MovieMediaMetadata.subtitle`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MovieMediaMetadata#subtitle) or [`GenericMediaMetadata.subtitle`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.GenericMediaMetadata#subtitle).

C. [`MovieMediaMetadata.title`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MovieMediaMetadata#title) or [`GenericMediaMetadata.title`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.GenericMediaMetadata#title).

D. [`MediaStatus.currentTime`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MediaStatus#currentTime)

E. [`MediaInformation.duration`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MediaInformation#duration)

F. [`ControlsSlot.SLOT_SECONDARY_1`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

G. [`ControlsSlot.SLOT_PRIMARY_1`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

H. Play / Pause

I. [`ControlsSlot.SLOT_PRIMARY_2`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

J. [`ControlsSlot.SLOT_SECONDARY_2`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

When the value of `supportedMediaCommands` equals to
[`ALL_BASIC_MEDIA`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages#.Command),
default control layout will display as below:

![](https://developers.google.com/static/cast/images/video_basic_layout.png)

When the value of `supportedMediaCommands` equals to
`ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT`, default control layout will
display as below:

![](https://developers.google.com/static/cast/images/video_queue_layout.png)

When the value of `supportedMediaCommands` equals to
`PAUSE | QUEUE_PREV | QUEUE_NEXT`, default control layout will display as below:

![](https://developers.google.com/static/cast/images/video_no_seek_layout.png)

When text tracks are available, closed caption button would be always shown at
`SLOT_SECONDARY_1`.

![](https://developers.google.com/static/cast/images/video_caption_layout.png)

To dynamically change the value of `supportedMediaCommands` after starting a
receiver context, you can call [`PlayerManager.setSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#setSupportedMediaCommands)
to override the value. Also, you can add new command by using [`addSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#addSupportedMediaCommands)
or remove existing command by using [`removeSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#removeSupportedMediaCommands).

## Default audio UI

### MetadataType.MUSIC_TRACK

![](https://developers.google.com/static/cast/images/audio_ui.png)

A. [`--playback-logo-image`](https://developers.google.com/cast/docs/caf_receiver_features#styling_the_player)

B. [`MusicTrackMediaMetadata.albumName`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#albumName)

C. [`MusicTrackMediaMetadata.title`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#title)

D. [`MusicTrackMediaMetadata.albumArtist`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#albumArtist), [`MusicTrackMediaMetadata.artist`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#artist), or [`MusicTrackMediaMetadata.composer`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#composer)

E. [`MusicTrackMediaMetadata.images[0]`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MusicTrackMediaMetadata#images)

F. [`MediaStatus.currentTime`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MediaStatus#currentTime)

G. [`MediaInformation.duration`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages.MediaInformation#duration)

H. [`ControlsSlot.SLOT_SECONDARY_1`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

I. [`ControlsSlot.SLOT_PRIMARY_1`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

J. Play / Pause

K. [`ControlsSlot.SLOT_PRIMARY_2`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

L. [`ControlsSlot.SLOT_SECONDARY_2`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.ui#.ControlsSlot)

When the value of `supportedMediaCommands` equals to [`ALL_BASIC_MEDIA`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.messages#.Command), default control layout will display as below:

![](https://developers.google.com/static/cast/images/audio_basic_layout.png)

When the value of `supportedMediaCommands` equals to `ALL_BASIC_MEDIA |
QUEUE_PREV | QUEUE_NEXT`, default control layout will display as below:

![](https://developers.google.com/static/cast/images/audio_queue_layout.png)

To dynamically change the value of `supportedMediaCommands` after starting a
Web Receiver context, you can call [`PlayerManager.setSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#setSupportedMediaCommands)
to override the value. Also, you can add new commands by using
[`addSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#addSupportedMediaCommands)
or remove existing commands by using [`removeSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#removeSupportedMediaCommands).

## Customize UI control button layout

Using a custom layout if you want to change buttons in UI controls.

> [!IMPORTANT]
> **Important:** It is required to remove all default buttons before assigning control buttons to slots to prevent conflicts between the custom and default layouts.

    const controls = cast.framework.ui.Controls.getInstance();
    controls.clearDefaultSlotAssignments();

Then, you can assign control buttons to 4 slots by calling `assignButton`.

    controls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_SECONDARY_1,
      cast.framework.ui.ControlsButton.LIKE
    )

    controls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_SECONDARY_2,
      cast.framework.ui.ControlsButton.DISLIKE
    )

And, the custom layout will display as below:

![](https://developers.google.com/static/cast/images/custom_layout.png)

When the assigned button is not supported in `MediaStatus.supportedMediaCommands`,
the button is greyed out. For example, if the `supportedMediaCommands` equals
`ALL_BASIC_MEDIA | QUEUE_NEXT | LIKE | DISLIKE`, then the `QUEUE_PREV`
button is disabled.

![](https://developers.google.com/static/cast/images/custom_layout_disabled.png)

To dynamically change the value of `supportedMediaCommands` after
starting a Web Receiver context, you can call [`PlayerManager.setSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#setSupportedMediaCommands)
to override the value. Also, you can add new commands by using [`addSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#addSupportedMediaCommands)
or remove existing commands by using [`removeSupportedMediaCommands`](https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.PlayerManager#removeSupportedMediaCommands).

## Secondary Image

[Secondary Image](https://developers.google.com/cast/docs/web_receiver/secondary_image) provides Cast
developers the flexibility to add an informational image to the UI for audio
and video applications, to display local channel logos or media format, for
example. This new functionality is provided with very little overhead while
maintaining a consistent UI across different Cast display platforms: Chromecast,
smart displays, and Chromecast with Google TV.