Video Player
Themed controls over a real video: chapters on the seek bar, a thumbnail while scrubbing, captions, speed, picture-in-picture and full screen.
c2-video-player puts themed controls over a real <video>, the way Loom and YouTube draw them: the seek bar split into chapters, a thumbnail while you scrub, captions, speed, picture-in-picture and full screen. The video stays yours, with its sources and caption tracks, so every native feature keeps working.
Import
import '@c2n/components/video-player'Usage
Speed
Speed
The video
Put a <video> inside the player, with its <source> and <track> children, and leave its controls off. The player draws the controls and never writes an attribute on the video, so several sources, captions, crossorigin and an HLS or DASH library attached to the element all keep working. For a single file, src and poster render the player’s own video. media gives the video element, for example to hand to a c2-transcript:
const player = document.querySelector('c2-video-player')!
document.querySelector('c2-transcript')!.media = player.mediaChapters and thumbnails
The seek bar shows the buffered range and the played part, split into one segment per chapter. Chapters come from chapters ([{ "start": 0, "title": "Intro" }, …]) or from a <track kind="chapters">; chapter-change fires as playback enters one, and the time shows the chapter’s title.
Hovering or dragging over the bar shows the time and the chapter. With thumbnails it also shows a frame: give it the URL of a WebVTT file whose cues name an image or a region of a sprite, the format most video platforms export:
WEBVTT
00:00.000 --> 00:02.000
tour-thumbs.jpg#xywh=0,0,160,90Or set it to a function of the time that returns a URL or { url, x, y, w, h }.
Controls
Play and pause, the time, volume with mute, the captions button (it turns the last track on and off), a settings menu with the speed and the caption track, picture-in-picture where the browser has it, and full screen, which covers the whole player so the controls stay. While the video plays, the controls hide 2.5 s after the pointer stops and come back on any movement, on focus and on pause. A big play button covers the poster until the first play, a spinner shows while the video waits for data, and an error panel says what went wrong, with a button to try again. Below 420 px the volume slider, the chapter name and picture-in-picture give way.
Captions are the browser’s own: the player turns the text tracks on and off and the video draws the cues.
Keyboard and accessibility
While focus is in the player: Space or K plays and pauses, ← and → seek 5 s, J and L seek 10 s, ↑ and ↓ change the volume, M mutes, C toggles captions, F toggles full screen, 0–9 jump to that tenth of the video, Home and End go to the start and the end. The seek bar is a slider read as “1:23 of 4:56, Dashboards”, and every control is a button named by what it does. The host is a group named by label, and matches :state(playing), :state(fullscreen) and :state(idle) while the controls are hidden.