Skip to content

Overview

Every player instance emits events from BaseEventMap. Subscribe with player.on(name, handler), unsubscribe with player.off(name, handler), subscribe once with player.once(name, handler). Library-specific maps (MusicEventMap, VideoEventMap) extend BaseEventMap with domain-only events and may narrow payload types for shared events.

Setup lifecycle

Ordered sequence: beforeSetupsetupStartconfigResolvedpluginsRegisteringpluginsRegisteredstreamsReadyauthReadyplaylistResolvingplaylistReadymediaReadyready.

EventPayloadWhen
beforeSetupvoidBefore any setup work begins
setupStart{ container: HTMLElement }Setup phase entered
configResolved{ config: BasePlayerConfig }Options normalised
pluginsRegisteringvoidPlugin registration loop begins
pluginsRegisteredvoidAll plugins’ use() settled
streamsReadyvoidStream factories registered
authReadyvoidAuth config resolved
playlistResolving{ url: string }Remote playlist URL fetch began
playlistReady{ length: number }Playlist loaded (or empty on failure)
playlistError{ url, error, code }Remote playlist fetch or parse failed
mediaReadyvoidFirst item loaded into backend
readyvoidPlayer is fully ready

Error events (each stage emits <stage>Error: PlayerErrorEvent on failure): setupStartError, configResolvedError, pluginsRegisteringError, pluginsRegisteredError, streamsReadyError, authReadyError, playlistResolveError, mediaReadyError

Play-path lifecycle

Every before* event is cancellable (preventDefault()), delayable (delay(promise)), and stops propagation on request (stopImmediatePropagation()).

EventPayloadWhen
beforePlayBeforeEvent<ActionOptions>Before play() executes
playingvoidBackend confirms media is actively rendering (after buffering resolves)
firstFramevoidFirst video/audio frame presented
playActionOptionsPlay dispatched; phase entering starting
playPrevented{ reason, cause? }beforePlay was prevented
beforePauseBeforeEvent<ActionOptions>Before pause() executes
pauseActionOptionsPaused
pausePrevented{ reason, cause? }beforePause was prevented
beforeStopBeforeEvent<ActionOptions>Before stop() executes
stopActionOptionsStopped
stopPrevented{ reason, cause? }beforeStop was prevented
beforeNextBeforeEvent<ActionOptions>Before next() executes
nextActionOptionsAdvanced to next item
nextPrevented{ reason, cause? }beforeNext was prevented
beforePreviousBeforeEvent<ActionOptions>Before previous() executes
previousActionOptionsWent back to previous item
previousPrevented{ reason, cause? }beforePrevious was prevented
beforeLoadBeforeEvent<{ item, source? }>Before load(item) executes
loadPrevented{ reason, cause? }beforeLoad was prevented
endedvoidCurrent item ended naturally

playing fires when the backend confirms media is rendering, equivalent to the HTML playing event. It fires after buffering resolves, not just on the play() call. Wired by the per-library backend.

Seek events

EventPayloadWhen
beforeSeekBeforeEvent<{ time, source? }>Before any seek executes
seek{ time, source? }Seek dispatched; backend receiving new position
seeked{ time }Seek settled, backend has confirmed the new position
seekPrevented{ reason, cause? }beforeSeek was prevented

seek fires at dispatch time. seeked fires after the backend repositions.

Mutation guards

EventPayloadWhen
beforeMutationBeforeEvent<{ method, args, phase, dispatchStack }>Before a mutating method executes (when guards are active)
mutationPrevented{ method, reason, cause? }beforeMutation was prevented

Phase transitions

EventPayloadWhen
phase{ from: PlayerPhase; to: PlayerPhase }Player moves between lifecycle phases

Time and progress

EventPayloadWhen
time{ time: number }Every animation frame during playback
duration{ duration: number }Backend resolves the total duration
progress{ time, duration, percentage }Throttled, at most every progressIntervalMs (default 5 s)

Use progress instead of time for server-side watch-position saves. time fires on every frame.

Volume and mode state

EventPayloadWhen
volume{ level: number }Volume changed (0–100)
mute{ muted: boolean }Mute toggled
repeat{ state: 'off' | 'all' | 'one' }Repeat mode changed
shuffle{ state: 'off' | 'on' }Shuffle mode changed

Queue events

EventPayloadWhen
queueBasePlaylistItem[]Queue replaced
queue:append{ items, from: number }Items appended
queue:prepend{ items }Items prepended
queue:insert{ items, index }Items inserted
queue:remove{ id, index, item }Item removed
queue:move{ from, to }Item moved
queue:clear{ previousLength }Queue cleared
queue:shufflevoidQueue randomly reordered
queue:sortvoidQueue sorted
queue:exhaustedvoidnext() reached the end with no next item and repeat is 'off'
current{ item: BasePlaylistItem | undefined; index: number }Active item cursor moved

Backlog events

EventPayloadWhen
backlogBasePlaylistItem[]Backlog replaced
backlog:append{ items }Items added to backlog
backlog:remove{ id, index, item }Item removed from backlog
backlog:clear{ previousLength }Backlog cleared

Media track events

EventPayloadWhen
subtitle{ track: number | null }Subtitle track selection changed
subtitleCue{ cues: SubtitleCue[]; language?: string }Active subtitle cues changed
subtitleStyleSubtitleStyleSubtitle style written
audioTrack{ id: number | null }Audio track selection changed
chapter{ index, title }Chapter seeked via seekToChapter
chapters{ chapters: ReadonlyArray<Chapter> }Chapter list resolved for active item
qualityState{ state: 'auto' | 'manual' }Quality selection mode changed
audioTrackState{ state: 'default' | 'manual' }Audio track selection mode changed
level-switched{ level: number }HLS adaptive level switched

Backend events

EventPayloadWhen
backend:changed{ kind: string }Active backend swapped
backend:loading{ url, kind }Backend started loading
backend:loaded{ url, kind, duration }Backend finished loading
backend:error{ error, kind }Backend encountered an error
backend:stalled{ time }Playback stalled
backend:ratechange{ rate }Playback rate changed
backend:waitingvoidBackend is waiting for data

Stream events

EventPayloadWhen
stream:manifest-loaded{ url }HLS manifest loaded
stream:level-switched{ level, label }Stream variant switched
stream:fragment-loaded{ url, durationMs }Segment fetched
stream:level-considered{ candidate, decided, reason }ABR candidate evaluated
stream:error{ details, fatal }Stream-level error
stream:encrypted{ initData, initDataType }Encrypted stream detected

Network and visibility

EventPayloadWhen
network:onlinevoidNetwork came online
network:offlinevoidNetwork went offline
network:slow{ rttMs: number | undefined }Online but downlink < 1.5 Mbps. Fires only on transition from not-slow to slow, not on every heartbeat. rttMs is undefined on Firefox and Safari (no Network Information API).
visibility:visiblevoidTab became visible
visibility:hiddenvoidTab was hidden

Auth events

EventPayloadWhen
auth:refreshed{ tokenAcquiredAt: number }Token refreshed successfully
auth:failed{ error }Token refresh failed

Cast events

EventPayloadWhen
castState{ state: CastState }Cast session state changed

Preload and transition events

EventPayloadWhen
preloadStart{ item, assets }Prefetch began for next item
preloadProgress{ item, loaded, total }Individual asset fetched
preloadComplete{ item }All preload assets fetched
preloadError{ item, error }One or more assets failed (non-fatal)
transitionStart{ outgoing, incoming }Transition window began
transitionProgress{ outgoing, incoming, fraction }Per-frame progress [0..1]
transitionComplete{ from, to }Transition done
transitionCancelled{ reason }Transition aborted

Cue tracker events

EventPayloadWhen
cue:enterCueEventPayloadPlayback entered a cue’s time range
cue:exitCueEventPayloadPlayback exited a cue’s time range

Plugin lifecycle events

EventPayloadWhen
plugin:installed{ id, version }Plugin registered successfully
plugin:enabled{ id }Plugin enabled
plugin:disabled{ id, reason? }Plugin disabled
plugin:opts:changed{ id, opts }Plugin options updated
plugin:disposed{ id }Plugin removed
plugin:failed{ id, error }Plugin use() threw or timed out
plugin:errorPlayerErrorEventPlugin emitted an error
plugin:warningPlayerErrorEventPlugin emitted a warning

Error severity events

EventPayloadWhen
fatalPlayerErrorEventUnrecoverable error, player shutting down
errorPlayerErrorEventRecoverable error
warningPlayerErrorEventObservability only
infoPlayerErrorEventInformational

Metrics and activity

EventPayloadWhen
playback:metricsPlaybackMetricsPeriodic metrics snapshot (every metricsIntervalMs, default 10 s)
fetch:start{ url, pluginId? }Authenticated fetch began
fetch:retry{ url, attempt, reason, delayMs, pluginId? }Fetch retrying after 401 or network error
fetch:complete{ url, ok, status?, durationMs, pluginId? }Fetch completed
activity{ active: boolean }User activity state changed (pointer/touch/key)
listeners-changed{ name, count }Listener count for a named event changed
disposevoidPlayer disposed

See also