diff --git a/site/src/content/docs/concepts/accessibility.mdx b/site/src/content/docs/concepts/accessibility.mdx index 745bf0c6..0ad60a6a 100644 --- a/site/src/content/docs/concepts/accessibility.mdx +++ b/site/src/content/docs/concepts/accessibility.mdx @@ -30,6 +30,14 @@ All interactive components support keyboard control. For example, buttons activa Interactive elements are focusable when enabled and leave the [tab order](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) when disabled. Popover triggers link to their popups with `aria-controls` and `aria-expanded`. +The player container is focusable and labeled: it takes `role="group"`, `tabindex="0"`, and an `aria-label` you can override. Keyboard users can tab to the player as a whole, and screen readers announce it as a named group. + +## Status announcements + +The player announces confirmed state changes through a visually hidden live region (`role="status"`), so screen reader users hear when playback starts or pauses, captions turn on or off, fullscreen, picture-in-picture, playback rate, or volume change, and where a seek lands. + +Announcements follow confirmed state from the player store rather than requested changes, so routine time updates never reach the live region. Rapid volume and seek changes are grouped into a single announcement, and the player stays quiet while one of its sliders has focus, since the slider already announces its own value. State the store tracks is covered for you; a custom control that tracks its own state needs its own live region. + ## Captions and subtitles The text tracks feature supports captions and subtitles. Closed captions in the U.S. are governed by the [FCC](https://www.fcc.gov/) under the [CVAA](https://www.fcc.gov/consumers/guides/21st-century-communications-and-video-accessibility-act-cvaa), which requires both captioning and viewer control over caption appearance (font, size, color, opacity, and edge style). Non-compliance carries legal risk. The [WebKit Caption Display Settings explainer](https://github.com/WebKit/explainers/tree/main/CaptionDisplaySettings) tracks how browsers are bringing these customization preferences into the web platform natively. diff --git a/site/src/content/docs/concepts/cast.mdx b/site/src/content/docs/concepts/cast.mdx index 9b6ccf70..fe194366 100644 --- a/site/src/content/docs/concepts/cast.mdx +++ b/site/src/content/docs/concepts/cast.mdx @@ -73,8 +73,8 @@ Cast only works in Chromium-based browsers (Chrome, Edge, and others built on Bl 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: Google's default media receiver, or a custom one you configure. +- **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 @@ -86,7 +86,7 @@ A Cast session moves through three states, exposed by the -Pass Cast options as props of the `GoogleCast` component. - - - -Set Cast options as attributes on the `` element. Object-valued options (like `customData`) are properties only. - - -### Custom receiver application ID - -By default, Video.js casts to Google's [Default Media Receiver](https://developers.google.com/cast/docs/web_sender/integrate#default_media_web_receiver) (`CC1AD845`). To use your own receiver app, set `receiver`: - - -```tsx - - // [!code focus] -``` - - - -```html - - -``` - - -### Custom data on load - -Send extra data (auth tokens, user IDs) to the receiver with each load request via `customData`. The receiver app reads it from the load request's `customData` field: - - -```tsx - - // [!code focus] -``` - - - -```ts -const googleCast = document.querySelector('google-cast'); -googleCast.customData = { token: 'abc123', userId: 'u_789' }; // [!code focus] -``` - - -### Cast a different source - -By default the receiver loads the same URL the browser plays. Set `src` (and optionally `contentType`) to send the receiver a different one — for example, cast an HLS stream while the browser plays an MP4: +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: ```tsx @@ -170,31 +125,14 @@ By default the receiver loads the same URL the browser plays. Set `src` (and opt ```html ``` -### HLS on the receiver - -When the Cast source is an HLS playlist, Video.js inspects the playlist, detects the segment format (TS or fMP4), and sets `hlsSegmentFormat` / `hlsVideoSegmentFormat` on the Cast load request. The default media receiver plays HLS natively; no extra configuration needed. - -Set `streamType` to tell the receiver whether the stream is `'on-demand'` or `'live'`. When unset, it falls back to the player's `streamType`: - - -```tsx - - // [!code focus] -``` - - - -```html - - -``` - +The GoogleCast reference 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 @@ -225,40 +163,10 @@ class CastStatus extends HTMLElement { ## 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). The `CastButton` keeps this raw value in `data-availability`, but handles presentation for you: - -- When Cast is unsupported, the HTML custom element receives the native `hidden` attribute and the React component returns `null`. -- When Cast is supported but no device is reachable, the button remains visible with `aria-disabled="true"` and `data-disabled`. - -Use `data-disabled` to style the visible, non-interactive state: - - -```css -media-cast-button[data-disabled] { - cursor: not-allowed; - opacity: 0.5; -} -``` - - - -`CastButton` renders a `