---
title: Google Cast
description: Cast playback to Chromecast devices with the Google Cast component, and configure the receiver and load request
---

import FrameworkCase from '@/components/docs/FrameworkCase.astro';
import DocsLink from '@/components/docs/DocsLink.astro';
import DocsLinkCard from '@/components/docs/DocsLinkCard.astro';
import Aside from '@/components/Aside.astro';

Add Google Cast to any Video.js streaming media element (HLS and DASH) by placing the Google Cast component next to it. Pair it with a <DocsLink slug="reference/cast-button">CastButton</DocsLink> and users can move playback to a Chromecast device while the browser stays in control:

<FrameworkCase frameworks={["react"]}>
```tsx title="App.tsx"
import { CastButton, createPlayer } from '@videojs/react';
import { GoogleCast } from '@videojs/react/media/google-cast';
import { HlsJsVideo } from '@videojs/react/media/hlsjs-video';
import { videoFeatures } from '@videojs/react/video';

const Player = createPlayer({ features: videoFeatures });

export default function App() {
  return (
    <Player.Provider>
      <Player.Container>
        <HlsJsVideo
          src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
          autoPlay
          muted
          playsInline
          loop
        />
        <GoogleCast />
        <CastButton />
      </Player.Container>
    </Player.Provider>
  );
}
```
</FrameworkCase>

<FrameworkCase frameworks={["html"]}>
```html title="index.html"
<video-player>
  <media-container>
    <hlsjs-video
      src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
      autoplay
      muted
      playsinline
      loop
    ></hlsjs-video>
    <google-cast></google-cast>
    <media-cast-button></media-cast-button>
  </media-container>
</video-player>
```

Register the `<google-cast>` element by importing `@videojs/html/media/google-cast`.
</FrameworkCase>

The component registers Google Cast with whichever media the player is using, so it works with any of the streaming media elements. The pre-built <DocsLink slug="concepts/skins">skins</DocsLink> include a Cast button already. It appears when a Chromecast device is on the network and stays hidden otherwise.

<Aside type="caution">
Casting needs this component. Without it, <DocsLink slug="reference/cast-button">CastButton</DocsLink> drives the browser's native Remote Playback API rather than a Cast session, so receivers and load requests don't apply.
</Aside>

<Aside type="note">
Cast only works in Chromium-based browsers (Chrome, Edge, and others built on Blink). On other browsers, `remotePlaybackAvailability` is `'unsupported'`.
</Aside>

## How Cast works

Cast uses a **sender / receiver** model:

- **Sender**: the browser tab. It sends the receiver a load request with the source URL and metadata, then issues playback commands (play, pause, seek, volume).
- **Receiver**: the Chromecast device running a receiver application, either Google's default media receiver or a custom one you configure.

### Session lifecycle

A Cast session moves through three states, exposed by the <DocsLink slug="reference/feature-remote-playback">Remote Playback</DocsLink> feature:

| State | Meaning |
|---|---|
| `'disconnected'` | No active session |
| `'connecting'` | Device picked; session starting |
| `'connected'` | Session active; receiver has the media |

While `connected`, the media element's `play`, `pause`, `currentTime`, `volume`, `muted`, and `playbackRate` all forward to the Cast receiver. Local playback is suspended.

### The lazy-loaded SDK

Video.js injects the Cast SDK (`cast_sender.js`) as a `<script>` tag the first time a Google Cast component is added in a Chromium browser. Browsers that can't cast — and players without the component — never load the SDK.

Set `disableRemotePlayback` on the media element to opt out of remote playback entirely:

<FrameworkCase frameworks={["react"]}>
```tsx
<HlsJsVideo disableRemotePlayback />
```
</FrameworkCase>

<FrameworkCase frameworks={["html"]}>
```html
<hlsjs-video disableremoteplayback></hlsjs-video>
```
</FrameworkCase>

## Configure Cast

By default, the receiver loads the same source the browser plays through Google's [Default Media Receiver](https://developers.google.com/cast/docs/web_sender/integrate#default_media_web_receiver). Point Cast at your own receiver app, send a different source, attach custom data to the load request, or override the stream type through the component's options:

<FrameworkCase frameworks={["react"]}>
```tsx
<HlsJsVideo src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" />
<GoogleCast
  receiver="YOUR_APP_ID"
  src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
  contentType="application/x-mpegURL"
/>
```
</FrameworkCase>

<FrameworkCase frameworks={["html"]}>
```html
<hlsjs-video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"></hlsjs-video>
<google-cast
  receiver="YOUR_APP_ID"
  src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
  content-type="application/x-mpegURL"
></google-cast>
```
</FrameworkCase>

The <DocsLink slug="reference/google-cast">GoogleCast reference</DocsLink> documents every option. HLS sources need no extra receiver setup: Video.js detects the segment format and configures the load request, and the Default Media Receiver plays HLS natively.

## Read Cast state

Cast session state lives in the <DocsLink slug="reference/feature-remote-playback">Remote Playback</DocsLink> feature slice. Subscribe with `selectRemotePlayback`:

<FrameworkCase frameworks={["react"]}>
```tsx
import { selectRemotePlayback, usePlayer } from '@videojs/react';

function CastStatus() {
  const remotePlayback = usePlayer(selectRemotePlayback);
  if (!remotePlayback) return null;

  return <span>{remotePlayback.remotePlaybackState}</span>;
}
```
</FrameworkCase>

<FrameworkCase frameworks={["html"]}>
```ts
import { PlayerController, playerContext, selectRemotePlayback } from '@videojs/html';

class CastStatus extends HTMLElement {
  readonly #remotePlayback = new PlayerController(this, playerContext, selectRemotePlayback);
}
```
</FrameworkCase>

## Browser availability

The Remote Playback feature reports availability as `'available'` (a device is on the network), `'unavailable'` (no device found), or `'unsupported'` (the browser can't cast). A <DocsLink slug="reference/cast-button">CastButton</DocsLink> handles the presentation for you: it hides itself when Cast is unsupported, and shows a disabled state when Cast is supported but no device is reachable. See its reference for the data attributes and styling hooks.

## See also

<DocsLinkCard slug="reference/google-cast">GoogleCast reference</DocsLinkCard>
<DocsLinkCard slug="reference/cast-button">CastButton component reference</DocsLinkCard>
<DocsLinkCard slug="reference/feature-remote-playback">Remote Playback feature reference</DocsLinkCard>
