#API
createPlayer() and createPlayerCore() return a Player:
import { createPlayer } from 'composable-video-player';
const player = createPlayer({ container: 'player', source: 'https://example.com/video.mp4' });
player.on('time', (t) => console.log(t));
player.command('setVolume', 0.5);
player.select((s) => s.status, (status, prev) => console.log(prev, '→', status));
#Properties
| Property | Type | Description |
|---|---|---|
id |
string |
The container's id. If the container had none, the player assigns vp1, vp2, …. |
state |
Readonly<PlayerState> |
Current state snapshot (see State). Treat it as read-only. |
container |
HTMLElement |
The element you passed in. |
root |
HTMLElement |
The player's root element (.vp-root), the place for CSS variables and classes. |
video |
HTMLVideoElement |
The underlying <video>. Prefer commands over mutating it directly, so state and events stay in sync. |
#Methods
| Method | Description |
|---|---|
play(): Promise<void> |
Start playback. Resolves or rejects like HTMLMediaElement.play() (for example with NotAllowedError when autoplay is blocked). |
pause(): void |
Pause. |
seek(t: number | string): void |
Seek to t seconds, or relative with '+10' / '-10'. |
load(source: SourceInput): void |
Load a new source (string, SourceSpec, or playlist). Does not start playback. |
command(name, ...args) |
Run any command by name, fully typed. Returns the command's result (play returns a promise) or undefined for unknown commands. |
on(name, cb): () => void |
Subscribe to an event. Returns an unsubscribe function. |
once(name, cb): () => void |
Subscribe for one call. |
off(name, cb): void |
Unsubscribe. |
select(selector, cb, opts?): () => void |
Watch a derived value of the state. cb(value, prev) runs whenever selector(state) changes (compared with Object.is unless opts.equals is given). opts.immediate: true also calls it right away. Returns an unsubscribe function. |
api(cmd: string, arg?: unknown): unknown |
The PlayerJS-style string API (api('seek', '+10'), api('time')). See PlayerJS compatibility. |
destroy(): void |
Emit destroy, dispose the UI and plugins, stop and detach the media, and remove the player's DOM from the container. Calls after destroy() are ignored with a warning. |
play(), pause(), seek(), and load() are shortcuts for the matching commands.
#Timing of init and the first new
createPlayer() emits init and starts loading options.source before it returns. A listener added after createPlayer() therefore misses init and the first new event. If you need them, handle them in a plugin, or create the player without source and call player.load() after subscribing:
const player = createPlayer({ container: 'player' });
player.on('new', ({ spec }) => console.log('loading', spec.qualities.length, 'qualities'));
player.load('https://example.com/video.mp4');
#Commands
player.command(name, ...args) runs a command from the API, so it does not emit the user* events (those are reserved for UI, hotkeys, and Media Session). Plugins can intercept any command with ctx.commands.before() (see Plugins).
#Core commands
| Command | Arguments | Description |
|---|---|---|
load |
input: SourceInput |
Load a source or playlist. |
reload |
— | Reload the last good source and resume from the current position. |
play |
— | Play. Returns Promise<void>. |
pause |
— | Pause. |
toggle |
— | Play or pause. At the end it restarts from 0. |
stop |
— | Pause, rewind to 0, and emit stop. |
seek |
t: number | string |
Absolute seconds, or relative '+N' / '-N'. Clamped to [0, duration]. Ignored for live streams. |
setVolume |
v: number | string |
0–1, or relative '+0.1' / '-0.1'. Clamped. A volume above 0 also unmutes. |
mute / unmute / toggleMute |
— | Mute control. |
setRate |
r: number |
Playback rate, clamped to 0.0625–16. Values ≤ 0 are ignored. |
setLoop |
b: boolean |
Loop the video. |
setTitle |
s: string |
Change the title. |
setPoster |
url: string |
Change the poster. |
fullscreen / exitFullscreen / toggleFullscreen |
— | Fullscreen control. Browsers only allow entering fullscreen from a user gesture. |
setQuality |
i: number |
Index into state.qualities. |
setAudioTrack |
i: number |
Index into state.audioTracks. |
setControlsLocked |
b: boolean |
true keeps the controls visible (the idle hide rule stops applying). |
showControls |
— | Show the controls as if the user had moved the pointer. They hide again after idleTimeout. |
toggleMenu |
— | Open or close the settings menu. |
layout |
node: LayoutNode |
Replace the UI with a new layout tree at runtime. |
destroy |
— | Same as player.destroy(). |
#Commands added by default plugins
| Command | Plugin | Arguments | Description |
|---|---|---|---|
setSpeedIndex |
speed | index: number |
Set the rate to state.speeds[index]. |
setTextTrack |
subtitles | index: number |
Select a subtitle track. -1 turns subtitles off. |
toggleSubtitles |
subtitles | — | Off, or back on to the last used track. |
addSubtitle |
subtitles | label: string, url: string, select?: boolean |
Add a track to the current source. select makes it active. |
setThumbnails |
thumbnails | url: string |
Load a thumbnails VTT. '' clears. |
next / prev |
playlist | — | Play the next or previous item (wraps when playlistLoop is on). |
playItem |
playlist | idOrIndex: string | number, autoplay?: boolean |
Play an item by id (checked first) or flat index. autoplay defaults to true. |
push |
playlist | items: PlaylistItem[] |
Append items. |
setPlaylist |
playlist | input: string | PlaylistItem[] |
Replace the playlist (JSON string, URL, or array). |
togglePlaylist |
playlist | — | Open or close the playlist panel. |
setAutonext |
playlist | on: boolean |
Toggle autonext. |
setPlaylistLoop |
playlist | on: boolean |
Toggle playlist wrap-around. |
setCuid |
memory | id: string |
Change the position-memory id (applies to the next load). |
Running a command whose plugin is not installed logs a warning and returns undefined.
#Events
player.on(name, cb). The payload type is inferred from PlayerEvents.
| Event | Payload | When |
|---|---|---|
init |
— | The player is constructed (plugins and layout ready), before the initial load. |
new |
{ spec: SourceSpec; selection: { quality, audio, start } } |
A new source starts loading. |
metadata |
{ duration: number } |
The media's metadata loaded and the start position was applied. |
start |
— | First playing since the last load. |
play |
— | Playback started (media play event). |
userplay |
— | Play triggered by the user (UI, hotkeys, Media Session). |
pause |
— | Paused (not emitted for pauses caused by loading, errors, or the end). |
userpause |
— | Pause triggered by the user. |
stop |
— | The stop command ran. |
end |
— | Reached the end of the media, or the end option's stop point. |
finish |
— | Emitted right after end (PlayerJS alias). |
time |
number |
Current time on every timeupdate (about 4 times per second). |
quartile |
25 | 50 | 75 | 100 |
Each quarter of the duration, once per source. |
duration |
number |
The duration changed to a finite value. |
seek |
number |
A seek completed (seeked), with the new time. |
userseek |
number |
The user seeked (timeline, hotkeys, Media Session), with the target time. |
line |
number |
The user released the timeline at this time (emitted just before the seek). |
volume |
number |
Volume changed. |
mute / unmute |
— | Muted state changed. |
speed |
number |
Playback rate changed. |
quality |
string |
Quality changed (label). |
audiotrack |
string |
Audio track changed (label). |
subtitle |
string |
Subtitle track changed (label, or 'off'). |
fullscreen / exitfullscreen |
— | Entered or left fullscreen. |
resize |
{ width: number; height: number } |
The player root changed size (not emitted for the initial size). |
ui |
0 | 1 |
Controls hidden (0) or shown (1). |
buffering |
— | Playback stalled waiting for data. |
buffered |
— | Recovered from buffering. |
loaderror |
{ url: string; error: PlayerError } |
A URL in the fallback chain failed, a subtitle/thumbnail/playlist fetch failed, or load() received invalid input. Not necessarily fatal. |
error |
PlayerError |
Fatal playback error (state.status === 'error'). |
playlist |
PlaylistItem[] (typed unknown) |
A playlist was set or extended. |
next / previous |
— | next / prev moved to another item. |
destroy |
— | The player is being destroyed. |
UI-internal events, used by components and not forwarded to PlayerJS listeners:
| Event | Payload | When |
|---|---|---|
ui:timeline-hover |
{ time, x, rootX, width } |
Pointer moves over the timeline. x is relative to the timeline, rootX to the player root. |
ui:timeline-leave |
— | Pointer left the timeline. |
ui:menu |
{ open: boolean } |
Settings menu opened or closed. |
ui:drag |
{ active: boolean } |
A slider or timeline drag started or ended. |
PLAYERJS_EVENTS (exported) lists the public event names.
#State
player.state (and ctx.store.get() in plugins) is a PlayerState. Every change creates a new object, so select() with plain selectors is cheap.
| Field | Type | Description |
|---|---|---|
status |
'idle' | 'loading' | 'ready' | 'playing' | 'paused' | 'ended' | 'error' |
Lifecycle: idle → loading → ready → playing/paused → ended. Any load can end in error. |
started |
boolean |
Playback has started since the last load. |
currentTime |
number |
Seconds. |
duration |
number |
Seconds. 0 when unknown or live. |
buffered |
number |
End of the buffered range containing currentTime, in seconds. |
live |
boolean |
The source is a live stream (infinite duration). |
waiting |
boolean |
Buffering. |
volume |
number |
0–1. |
muted |
boolean |
|
rate |
number |
Playback rate. |
fullscreen |
boolean |
|
userActive |
boolean |
The user recently interacted (controls shown). |
controlsLocked |
boolean |
Controls are pinned visible (setControlsLocked). |
width / height |
number |
Size of the player root in px. |
url |
string |
The URL currently being played (the one in the fallback chain that is in use). |
qualities |
{ label: string; height?: number; bitrate?: number }[] |
Available qualities (from the source, or HLS variants plus auto). |
quality |
number |
Index into qualities. |
audioTracks |
{ label: string; lang?: string }[] |
Available audio tracks. |
audioTrack |
number |
Index into audioTracks. |
textTracks |
{ label: string; lang?: string }[] |
Available subtitle tracks. |
textTrack |
number |
Index into textTracks, -1 = off. |
preferredSubtitle |
string | null |
Remembered subtitle label or 'off' (written by memory, read by subtitles). |
title |
string |
|
poster |
string |
|
loop |
boolean |
|
error |
{ kind: ErrorKind; message: string } | null |
Last fatal error. |
markers |
TimelineMarker[] |
Ticks drawn on the timeline: { time: number; label?: string }. Owned by plugins and not reset on load. See markers. |
Fields added by default plugins:
| Field | Plugin | Type | Description |
|---|---|---|---|
speeds |
speed | number[] |
Speeds offered in the menu. |
playlist |
playlist | { items, flat, index, open } | undefined |
The playlist tree, its flattened list ({ item, index, depth }[]), the current flat index, and whether the panel is open. |
autonext |
playlist | boolean |
|
playlistLoop |
playlist | boolean |
|
cuid |
memory | string | undefined |
Current position-memory id. |
#Utilities
The package also exports helpers used by the built-in UI. They are useful in custom components:
| Export | Description |
|---|---|
formatTime(seconds, reference?) |
m:ss, or h:mm:ss when reference (usually the duration) is at least an hour. |
h(tag, attrs?, ...children) |
Small DOM element builder (class, attributes, children). |
iconEl(svg) / parseSvg(svg) |
Build a sanitized SVG icon element from a markup string. |
createIconButton(ui, className, onClick) |
Button with setIcon(name) and setLabel(i18nKey). |
createSlider(ui, { className, label, onInput, step? }) |
Accessible horizontal 0–1 slider (the volume control uses it). |
defaultIcons, dictionaries, defaultLayout, BUILTIN_COMPONENTS |
Built-in icons, UI strings, layout tree, and component factories. |
html5Provider(), hasNativeHls() |
The built-in <video> provider and the native HLS check. |
pickQuality, DEFAULT_SPEEDS, shouldRestorePosition |
Plugin helpers. |
mapPlayerjsOptions(opts, log) |
Converts PlayerJS options to PlayerOptions. |