Chromecast
Sends playback to a Chromecast, with the player's controls driving the receiver.
import { chromecast } from "react-video-kit/chromecast";Adds 1.8 KB to a player3.2 KB on its ownSource
Adds a Cast button to the controls once the Cast SDK reports a device. While casting, the player's controls drive the receiver. Most readers won't have a device, so the demo says what you'd need and shows the current status.
The Cast button joins the controls once the Cast SDK reports a device. To see it, you need a browser the SDK supports, such as Chrome, and a Cast device on the same network.
Cast status: no device found
"use client";import { useEffect, useRef, useState } from "react";import { chromecast } from "react-video-kit/chromecast";import type { Player } from "react-video-kit/core";import { VideoPlayer } from "react-video-kit/player";const plugins = [chromecast({ title: "First light" })];export default function Chromecast() { const player = useRef<Player>(null); const [status, setStatus] = useState("no device found"); useEffect(() => { const current = player.current; if (!current) return; return current.subscribe(() => { const { available, active, device } = current.plugin(chromecast).state(); setStatus(active ? `casting to ${device ?? "a device"}` : available ? "device found" : "no device found"); }); }, []); return ( <div className="flex flex-col gap-3"> <VideoPlayer ref={player} src="/media/sample-720.mp4" poster="/media/poster.jpg" plugins={plugins} load="visible" /> <div className="flex flex-col gap-1 text-sm text-current opacity-80"> <p> The Cast button joins the controls once the Cast SDK reports a device. To see it, you need a browser the SDK supports, such as Chrome, and a Cast device on the same network. </p> <p>Cast status: {status}</p> </div> </div> );}Usage
import { chromecast } from "react-video-kit/chromecast";import { VideoPlayer } from "react-video-kit/player";const plugins = [chromecast({ title: "First light" })];<VideoPlayer src="/video.mp4" plugins={plugins} />;title is what the receiver shows. It can be a function of the source. receiverId picks a custom receiver app instead of Google's default one:
chromecast({ receiverId: "ABCD1234", title: (source) => source.src.split("/").pop(),});How the Cast SDK loads
The SDK isn't in your bundle. When the player mounts in a Chromium browser, the plugin adds a script tag for https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1, unless that script or cast.framework is already on the page. load="visible" doesn't delay it.
Chromium browsers, which are the ones with window.chrome, request the script whether or not the viewer ever casts. Other browsers make no request. If the SDK reports that Cast isn't available, or never loads, the plugin goes no further and the button never appears. To load the SDK from somewhere else, such as a proxy, set sdkUrl:
chromecast({ sdkUrl: "/vendor/cast_sender.js" });Build your own control
toggle opens the device picker, or ends the session if there is one. It has to run from a click or key press.
"use client";import { useCommands, useVideoState } from "react-video-kit";import { chromecast } from "react-video-kit/chromecast";function CastControl() { const available = useVideoState(chromecast, (state) => state.available); const active = useVideoState(chromecast, (state) => state.active); const device = useVideoState(chromecast, (state) => state.device); const { toggle } = useCommands(chromecast); if (!available && !active) return null; return <button onClick={() => toggle()}>{active ? `Stop casting to ${device}` : "Cast"}</button>;}VideoPlayer places CastButton and CastingOverlay through slots. In your own layout, render them yourself.
What the receiver gets
When a session starts, the plugin sends:
- The source's URL, made absolute. The receiver fetches it directly, so it has to be reachable from the device.
- A content type: the source's
type, or one worked out from.m3u8or.mpd, or elsevideo/mp4. - The
title, if there is one. - The current position, so playback carries on from there, with autoplay on.
It doesn't send DRM configuration, caption tracks, or speed.
DRM
The default receiver can't play DRM content. The plugin never passes your drm configuration to the receiver, so a custom receiver has to get its licences some other way.
Behaviour
- The button renders while a device is available or a session is active.
availablestarts from the SDK's current cast state, so devices found before the player mounted count, and follows its events after that. - When a session starts, the local video pauses, the player's
providerbecomeschromecast, and the root hasdata-casting.CastingOverlaynames the device, or says "Chromecast" if it has no name. - Play, pause, seek, volume, and mute go to the receiver. Time, duration, and buffering come back from it.
- The receiver can't change speed, so
capabilities.rateis false while casting and the speed menu disappears until the session ends. Captions stay on this device. - The player reports whatever's casting as on-demand, including live streams.
- A new source during a session goes to the receiver with its own
title, and the session stays connected. - When the session ends, the player returns to the local video at the receiver's position, paused.
- If the first load fails on the receiver, the plugin ends the session. A failed load after a source change is ignored.
- The SDK's auto-join policy is
ORIGIN_SCOPED. A resumed session gets the same handover as a new one. - The Cast context belongs to the page, so every player with this plugin reacts to the same session. Use it on one player per page.
API
Options
| Option | Type | Description |
|---|---|---|
| receiverId? | string | A custom receiver's ID. Defaults to Google's default receiver. |
| sdkUrl? | string | Where to load the Cast SDK from. |
| title? | string | ((source: SourceObject) => string | undefined) | The title the receiver shows. |
State
Read it with useVideoState(chromecast, (state) => …).
| Field | Type | Description |
|---|---|---|
| available | boolean | True when the Cast SDK reports a device to cast to. |
| active | boolean | True while playback is on a Cast receiver. |
| device | string | null | The name of the receiver in use, or null if there's none or it has no name. |
Commands
Call them with useCommands(chromecast).
| Command | Type | Description |
|---|---|---|
| toggle | () => void | Opens the device picker, or ends the session if one is running. Must run from a click or key press. |
Parts
| Part | Description |
|---|---|
| CastButton | Renders nothing until a device is available. |
| CastingOverlay | Says where playback went, over the video that's no longer playing. |