Skip to content
omaris

Data Display

VideoPlayer

A video player with its own chrome.

import { VideoPlayer } from 'omaris'
Learn

Examples

Basic

Its own chrome, with an MD3 wave across the played half of the seek bar. Everything is bindable, so the page can follow along.

Big Buck Bunny
<script lang="ts">	import { VideoPlayer } from 'omaris';​	const SRC =		'https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_5MB.mp4';</script>​<div class="w-full max-w-xl">	<VideoPlayer src={SRC} poster="https://picsum.photos/id/1015/1280/720" title="Big Buck Bunny" /></div>

Chapters and captions

chapters for a clip long enough to skip around in, tracks for one people watch muted or in another language. Both are plain data.

With chapters and captions
<script lang="ts">	import { VideoPlayer } from 'omaris';​	const SRC = 'https://test-videos.co.uk/vids/sintel/mp4/h264/720/Sintel_720_10s_1MB.mp4';​	const CHAPTERS = [		{ time: 0, title: 'Cold open' },		{ time: 4, title: 'The pitch' },		{ time: 8, title: 'Sign-off' }	];​	const TRACKS = [{ src: '/captions-demo.vtt', label: 'English', srclang: 'en', default: true }];</script>​<div class="w-full max-w-xl">	<VideoPlayer		src={SRC}		poster="https://picsum.photos/id/1016/1280/720"		title="With chapters and captions"		chapters={CHAPTERS}		tracks={TRACKS}		start={4}	/></div>

When to use it

Use it for

  • A clip that belongs to the app, like an onboarding video, a lesson or a recording, with chrome that matches the UI. Pass src, poster, title.
  • Long content. chapters mark the scrubber and name the hover bubble; tracks add captions, and with one track the CC button is a switch.
  • Handing the file over: download, and pip where the browser has it.
  • A hero: aspect="21/9", fit="cover", rounded="xl". rounded="none" for a player that fills the page.
  • A page that follows along. paused, currentTime, volume and muted are bindable, and ref is the <video> itself.

Not for

  • Pictures → Image Viewer.
  • A muted background loop with no controls → a plain <video autoplay muted loop playsinline>.
  • A YouTube or Vimeo embed → their <iframe>. This needs a media URL it can play itself.
  • Several clips to flick through → Carousel with a player per slide, one playing at a time.

Do

  • Give it a title. It is the accessible name and the top scrim.
  • Pass a poster, or a cover snippet for a custom one. Otherwise the frame before the first play is black.
  • Pass src as an array to offer several encodings and let the browser choose.
  • Deep-link a moment with start.
  • Leave idleAfter alone. 0 keeps the chrome up, for a kiosk only.

Don't

  • Autoplay with sound. Browsers block it and the player sits paused.
  • Let two players play at once. Pause the other through its paused binding.
  • Set download on content you do not want saved. It is a real link to src.

Quick reference

rounded
  • none
  • md
  • lg (default)
  • xl

Corner style. none is for a player that fills a page.

fit
  • contain (default)
  • cover

How the frame fills the box.

API

VideoPlayer

A video player with its own chrome.

The native controls are a different design system on every platform, so this draws its own: a scrubber whose played half is MD3 Expressive's travelling wave — it rolls while the video plays and flattens the moment you grab it — buffered ranges behind it, chapter marks on top, and a bubble that follows the pointer.

Under the chrome it stays a real <video>: every control is a button, both sliders are <input type="range"> (so keyboard, touch and screen readers work without being re-implemented), and the shortcuts are the ones people already know.

Keys: space/k play, ←/→ ±5s, j/l ±10s, ↑/↓ volume, m mute, c captions, f fullscreen, 0–9 jump to a tenth. Click toggles play, double-click goes fullscreen; on touch, a double tap on either half seeks that way.

import { VideoPlayer } from 'omaris'
<VideoPlayer src="/clip.mp4" poster="/clip.jpg" title="Onboarding" />

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
video
No description in the source yet.
surface
Catches clicks and taps; the controls sit above it.
chrome
Everything that fades out when the player goes idle.
top
Top scrim: title and the actions that belong up there.
title
No description in the source yet.
bottom
Bottom scrim: scrubber, then the control row.
seek
The scrubber's hit area — taller than the track it draws.
track
No description in the source yet.
range
Native range on top of the painted track — free a11y and dragging.
handle
The dot at the play head.
bubble
Time (and chapter) bubble that tracks the pointer.
controls
No description in the source yet.
button
One chrome button.
menu
Speed / captions popover.
menuItem
No description in the source yet.
center
The big centre button, and the seek pills either side of it.
pill
No description in the source yet.

Props

src required
string | VideoSource[]

One URL, or several encodings for the browser to choose from.

poster
string
title
string

Shown in the top scrim, and used as the accessible name.

aspect

Defaults to '16/9'

string | number

16/9 by default. Any CSS aspect ratio, or a number.

rounded

Defaults to 'lg'

VideoPlayerRounded
none
md
lg
xl
fit

Defaults to 'contain'

VideoPlayerFit
contain
cover
start

Defaults to 0

number

Second to open at.

chapters

Defaults to []

VideoChapter[]
tracks

Defaults to []

VideoTrack[]
speeds

Defaults to [0.5, 0.75, 1, 1.25, 1.5, 2]

number[]

Rates the speed menu offers.

pip

Defaults to true

boolean

Offer picture-in-picture, where the browser has it.

fullscreen

Defaults to true

boolean

Offer the fullscreen button.

download

Defaults to false

boolean | string

Offer a download link — true uses src, a string names the file.

idleAfter

Defaults to 2600

number

Hide the chrome after this many ms of stillness. 0 keeps it up.

paused bindable

Defaults to true

boolean

Bindable.

currentTime bindable

Defaults to 0

number

Bindable, in seconds.

volume bindable

Defaults to 1

number

Bindable, 0–1.

muted bindable

Defaults to false

boolean

Bindable.

ref bindable

Defaults to null

HTMLVideoElement | null

Bindable — the underlying <video>.

actions
Snippet

Extra controls, at the end of the control row.

cover
Snippet

Covers the frame before the first play — a custom poster.

class
string
classes
VideoPlayerClasses

Per-part Tailwind overrides. class still covers the root.