Data Display
VideoPlayer
A video player with its own chrome.
import { VideoPlayer } from 'omaris' 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.
<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.
<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.
chaptersmark the scrubber and name the hover bubble;tracksadd captions, and with one track the CC button is a switch. - Handing the file over:
download, andpipwhere 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,volumeandmutedare bindable, andrefis 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 acoversnippet for a custom one. Otherwise the frame before the first play is black. - Pass
srcas an array to offer several encodings and let the browser choose. - Deep-link a moment with
start. - Leave
idleAfteralone.0keeps 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
pausedbinding. - Set
downloadon content you do not want saved. It is a real link tosrc.
Quick reference
rounded nonemdlg(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 nonemdlgxl
fit Defaults to 'contain'
VideoPlayerFit containcover
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 bindableDefaults to true
boolean Bindable.
currentTime bindableDefaults to 0
number Bindable, in seconds.
volume bindableDefaults to 1
number Bindable, 0–1.
muted bindableDefaults to false
boolean Bindable.
ref bindableDefaults 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.