Marble UI
← Components

Video Player

Preview: Overlay

Native <video> with custom, keyboard-accessible controls: play, seek, volume, speed, captions, fullscreen.

Import

import { VideoPlayer } from '@marbleui/ui'

Props

<VideoPlayer>

PropTypeDefaultDescription
src *requiredstring—
title *requiredstring—
captions{ src: string; label: string; lang: string; }—WebVTT captions.
classNamestring—
crossOrigin'anonymous' | 'use-credentials'—CORS mode for the media and captions. Opt in when captions (or canvas access) come from another origin that sends CORS headers; set on a host without them, the video fails to load.
posterstring—
variant'bar' | 'overlay''overlay'

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Button · React Aria Slider · React Aria SliderThumb · React Aria SliderTrack. Follow the primitive's docs for the full keyboard map.

Usage notes

Native <video> with its own keyboard-accessible controls: play, seek, volume, playback speed (0.5–2×), captions and fullscreen.

<VideoPlayer
  src="/media/onboarding-tour.mp4"
  poster="/media/onboarding-tour.jpg"
  title="Onboarding tour"
  captions={{ src: '/media/onboarding-tour.en.vtt', label: 'English', lang: 'en' }}
/>
  • title is required and names the player region (“Video: Onboarding tour”). captions takes one WebVTT track; the CC button only appears when it’s set, and captions start off.
  • variant="overlay" (default) shows a center play button and hides the controls during playback until hover or focus. variant="bar" keeps them in a bar under the video.
  • With the player focused, Space or K plays and pauses, ←/→ seek 5 s and M toggles mute. On the seek slider itself, arrows move 1 s and Page Up/Down 10%; it announces the position as “1:05 of 3:20”, and the volume slider as a percentage.
  • The video loads without CORS mode, so media from any host plays. Pass crossOrigin="anonymous" when captions come from another origin (that host must then send CORS headers for the video too). There’s no ref, autoPlay or playback callback.
Example source · show
import { VideoPlayer } from './video-player'

// Public-domain sample from the W3C test suite.
const src = 'https://media.w3.org/2010/05/sintel/trailer.mp4'
const poster = 'https://media.w3.org/2010/05/sintel/poster.png'

export const styles = {
  Overlay: () => <VideoPlayer className="w-[36rem]" src={src} poster={poster} title="Sintel trailer" />,
  Bar: () => <VideoPlayer className="w-[36rem]" src={src} poster={poster} title="Sintel trailer" variant="bar" />,
}

Source: packages/ui/src/video-player/video-player.tsx

Catalog

Category
media
Priority
Pro
Primitive
composed
React Aria
Slider + ToggleButton