React Video Thumbnail Previews
On this page
The vtt-controls module, @react-av/vtt-controls, provides a set of components for interacting with chapter and storyboard VTT files.
npm i @react-av/core @react-av/vtt-core @react-av/vtt @react-av/vtt-controls @radix-ui/react-select
This package is still very barebones and is still in active development, like most of the other packages.
CaptionTrackSelectRoot and CaptionTrackSelectItems
Compose a caption language picker with Radix Select. CaptionTrackSelectRoot connects the selection to the current player’s caption tracks. CaptionTrackSelectItems lists “Off” and one item per subtitles or captions track, using its label, then its srclang, then “Track N”. Choosing a language shows only that track; choosing “Off” hides captions, including while paused or before the first playback.
Use Radix’s trigger, value, content and viewport to control the layout and styling. Give the trigger an accessible name. Place the portal inside Media.Container so the menu remains visible in fullscreen.
import { useState } from 'react';
import * as Select from '@radix-ui/react-select';
import * as Media from '@react-av/core';
import { Track } from '@react-av/vtt';
import { CaptionTrackSelectRoot, CaptionTrackSelectItems } from '@react-av/vtt-controls';
function Player() {
const [container, setContainer] = useState(null);
return (
<Media.Root>
<Media.Container ref={setContainer}>
<Media.Video src="https://media.w3.org/2010/05/sintel/trailer_hd.mp4" />
<CaptionTrackSelectRoot>
<Select.Trigger aria-label="Captions" className="caption-trigger">
<Select.Value />
<Select.Icon />
</Select.Trigger>
<Select.Portal container={container}>
<Select.Content position="popper" className="caption-menu">
<Select.Viewport>
<CaptionTrackSelectItems className="caption-item" />
</Select.Viewport>
</Select.Content>
</Select.Portal>
</CaptionTrackSelectRoot>
</Media.Container>
<Track src="https://example.com/english.vtt" srclang="en" label="English" default />
<Track src="https://example.com/french.vtt" srclang="fr" label="Français" />
</Media.Root>
);
}
CaptionTrackSelectRootProps accepts Radix Select root props except value and defaultValue: the visible caption track owns the value. disabled, open, onOpenChange and other root props work as usual. onValueChange runs after the caption changes, with "off" or the track’s zero-based index as a string. Use useMediaCaptionTracks when you need the track object.
CaptionTrackSelectItemsProps accepts Radix Select item props except value and children, and applies them to every generated item. Set offLabel to translate “Off”. Style highlighted items with [data-highlighted] and the selected item with [data-state="checked"]. Put refs and trigger event handlers on the Radix primitives; the root does not render an element.
useMediaCaptionTracks()
Build a custom caption menu without Radix. This hook can also keep other caption controls in sync with the picker.
Returns: { tracks, selected, select } where tracks is the list of subtitle and caption TextTracks, selected is the track that is showing or null, and select(track) shows only the given track, or hides all of them when passed null.
StoryboardThumbnail
Displays a storyboard thumbnail for the media provided a timestamp and the id of the storyboard VTT file.
It is a HTMLImageElement and accepts all the props that an HTMLImageElement accepts except for src. Additionally, it has a timestamp prop that is the time in seconds of the thumbnail and a storyboardId prop of the text track to be used.
import * as Media from '@react-av/core';
import { Track } from '@react-av/vtt';
import { StoryboardThumbnail } from '@react-av/vtt-controls';
() => (
<Media.Root>
<Media.Container>
<Media.Video src="https://media.w3.org/2010/05/sintel/trailer_hd.mp4" />
</Media.Container>
<Track
src="https://example.com/storyboard.vtt"
kind="metadata"
label="Storyboard"
id="storyboard"
/>
<StoryboardThumbnail
timestamp={10}
storyboardId="storyboard"
/>
</Media.Root>
)