media-cast-button
Accessible Cast toggle button with state reflection and keyboard support
Import
import { CastButton } from '@videojs/react';import '@videojs/html/ui/cast-button';Anatomy
<CastButton /><media-cast-button></media-cast-button>Behavior
Toggles a Google Cast session. Clicking the button while disconnected opens the Cast device picker; clicking while connected ends the session.
The button derives its presentation from availability:
"unsupported"— the HTML custom element receives the nativehiddenattribute; the React component returnsnull."unavailable"— the button remains visible and focusable witharia-disabled="true"anddata-disabled, but does not open the picker. This lets a tooltip explain that no Cast device is reachable."available"— the button is fully interactive unless thedisabledprop is set.
Configurable Cast sessions come from the GoogleCast extension. Add it to the player next to your media element; without it the button drives the browser’s native Remote Playback API instead, which offers no receiver or load-request configuration. See Cast to AirPlay and Chromecast for the complete setup.
Styling
Style based on cast and disabled state:
/* During an active session */
media-cast-button[data-cast-state="connected"] {
color: blue;
}
/* Cast is supported, but no device is reachable */
media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
}React renders a <button> element. Add a className to style it:
/* During an active session */
.cast-button[data-cast-state="connected"] {
color: blue;
}
/* Cast is supported, but no device is reachable */
.cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
}Unsupported buttons are hidden automatically. No availability selector or extra hiding CSS is required.
Accessibility
Renders a <button> with an automatic aria-label:
| Cast state | Default label |
|---|---|
'disconnected' |
“Start casting” |
'connecting' |
“Connecting” |
'connected' |
“Stop casting” |
Override with the label prop. Keyboard activation: Enter / Space.
Examples
Basic Usage
import { CastButton, Container, createPlayer } from '@videojs/react';
import { GoogleCast } from '@videojs/react/extensions/google-cast';
import { HlsJsVideo } from '@videojs/react/media/hlsjs-video';
import { videoFeatures } from '@videojs/react/video';
const { Player } = createPlayer({ features: videoFeatures });
export default function BasicUsage() {
return (
<Player>
<Container className="media-container">
<HlsJsVideo src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" autoPlay muted playsInline loop />
<GoogleCast />
<CastButton
className="media-cast-button"
render={(props, state) => (
<button {...props}>{state.connection === 'connected' ? 'Stop casting' : 'Start casting'}</button>
)}
/>
</Container>
</Player>
);
}
.media-container {
position: relative;
}
.media-container video {
width: 100%;
}
.media-cast-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
filter: grayscale(1);
}
<video-player class="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 class="media-cast-button">
<span class="connected">Stop casting</span>
<span class="disconnected">Start casting</span>
</media-cast-button>
</media-container>
</video-player>
.video-player media-container {
position: relative;
display: block;
}
.video-player media-container video {
width: 100%;
}
.media-cast-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
filter: grayscale(1);
}
.media-cast-button .connected {
display: none;
}
.media-cast-button .disconnected {
display: none;
}
.media-cast-button[data-cast-state="connected"] .connected {
display: inline;
}
.media-cast-button:not([data-cast-state="connected"]) .disconnected {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/extensions/google-cast';
import '@videojs/html/ui/container';
import '@videojs/html/media/hlsjs-video';
import '@videojs/html/ui/cast-button';
API Reference
Props
| Prop | Type | Default | Details |
|---|---|---|---|
disabled | boolean | false | |
| |||
label | object | '' | |
| |||
State
render, className, and style props.| Property | Type | Details |
|---|---|---|
label | { key: string; text: string } | string | |
connection | 'disconnected' | 'connecting' | 'conn... | |
| ||
availability | MediaFeatureAvailability | |
| ||
disabled | boolean | |
| ||
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-cast-state | 'disconnected' | 'connecting' | 'conn... | |
| ||
data-availability | MediaFeatureAvailability | |
| ||
data-disabled | ||
| ||