Skip to content
FrameworkStyle

Show timeline thumbnail previews

Preview frames along the timeline while the user scrubs, powered by a storyboard track.

Show preview frames along the timeline while the user scrubs, like YouTube’s seek previews.

Add a kind="metadata" track labeled thumbnails whose cues reference storyboard images, then put a slider thumbnail inside the TimeSlider. Scrubbing shows the frame under the pointer; the thumbnail reads the pointer time from the slider, so it takes no props.

import { Container, createPlayer, Slider, TimeSlider } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';

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

export default function BasicUsage() {
  return (
    <Player>
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline loop crossOrigin="anonymous">
          <track kind="metadata" label="thumbnails" src="https://image.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/storyboard.vtt" default />
        </Video>
        <TimeSlider.Root className="media-time-slider">
          <TimeSlider.Track className="media-slider-track">
            <TimeSlider.Fill className="media-slider-fill" />
          </TimeSlider.Track>
          <Slider.Thumbnail className="media-slider-thumbnail" />
        </TimeSlider.Root>
      </Container>
    </Player>
  );
}

How it works

  • Previews come from a storyboard: a kind="metadata" text track labeled thumbnails whose WebVTT cues map time ranges to image URLs (optionally with sprite coordinates). The text track feature exposes these as thumbnailCues and thumbnailTrackSrc.
  • The slider thumbnail renders the storyboard frame for the slider’s pointer position. While the pointer is over the slider, the slider sets data-pointing and the --media-slider-pointer CSS variable; the demo’s CSS uses them to reveal the preview and position it over the pointer.
  • To render a storyboard frame outside the slider — a fixed preview for a chapter list, for example — use the standalone Thumbnail component with an explicit time.

Each cue’s text is an image URL. An optional #xywh=x,y,w,h fragment crops one frame out of a sprite sheet:

WEBVTT

00:00:00.000 --> 00:00:05.000
storyboard.jpg#xywh=0,0,256,160

00:00:05.000 --> 00:00:10.000
storyboard.jpg#xywh=256,0,256,160

Availability and constraints

  • Thumbnails require a storyboard asset generated alongside the media; the player doesn’t extract frames from the video itself.
  • Cross-origin storyboards need CORS headers, and crossOrigin on the media element for the track to load.
  • Cues load asynchronously. The track appears before its cues are parsed, so previews fill in when the track finishes loading.
  • Storyboard images download on demand; oversized sprite sheets hurt seek-preview responsiveness more than they help quality.

Troubleshooting

Thumbnails don’t appear while scrubbing

Confirm the storyboard track is kind="metadata" with label="thumbnails" and has the default attribute — the browser leaves a non-default track disabled and never loads its cues. Then confirm the VTT loads (network panel) and cross-origin assets have CORS headers with crossOrigin set on the media element.

Thumbnails are blurry or slow

Regenerate the storyboard with a larger frame size, or split giant sprite sheets into smaller images.