API Methods Reference
All public methods on NMVideoPlayer<T>.
Methods follow the overloaded getter/setter pattern: method() reads, method(value) writes.
Factory
nmplayer(id?)
nmplayer(id?: string | number): NMVideoPlayer<VideoPlaylistItem>
nmplayer<T extends VideoPlaylistItem>(id?: string | number): NMVideoPlayer<T>
Creates or retrieves a named player instance.
idis optional. When omitted, the core generates a unique id.- Two calls with the same
idreturn the same instance, with no re-initialization. - The factory is the only entry point. Do not call
new NMVideoPlayer()directly. - Instances persist until
dispose()is called. After dispose, the sameidcreates a fresh instance. - When
setup({ expose: true })is called,window.nmplayeris set to the factory for console access.
const player = nmplayer('main'); // creates or retrieves 'main'
const same = nmplayer('main'); // same instance
player === same; // true
Setup
setup(opts)
setup(opts: VideoPlayerConfig<T>): NMVideoPlayer<T>
Initialize the player. Returns the player for chaining. See Configuration for all options.
ready()
ready(): Promise<void>
Resolves when setup is complete and all plugins’ use() promises have resolved.
dispose()
dispose(): void
Tears down the player: stops playback, disposes all plugins, removes event listeners. The instance is removed from the internal registry.
Transport
play(opts?), pause(opts?), stop(opts?), restart(opts?)
play(opts?: ActionOptions): Promise<void>
pause(opts?: ActionOptions): Promise<void>
stop(opts?: ActionOptions): Promise<void>
restart(opts?: ActionOptions): Promise<void>
togglePlayback(opts?: ActionOptions): Promise<void>
stop() resets position to 0.
restart() seeks to 0 and plays.
togglePlayback() switches between play and pause.
ActionOptions carries source: 'user' | 'remote' | 'plugin', pass { source: 'user' } when triggered by user input.
Queue navigation
next(opts?), previous(opts?)
next(opts?: ActionOptions): Promise<void>
previous(opts?: ActionOptions): Promise<void>
seekToIndex(position, opts?)
seekToIndex(position: number, opts?: ActionOptions): void
Navigate to a playlist item by 1-based ordinal position. seekToIndex(1) loads the first item; seekToIndex(player.queueLength()) loads the last.
Throws RangeError when position is zero, negative, or not an integer.
player.seekToIndex(1); // first item
player.seekToIndex(3); // third item
player.seekToIndex(0); // RangeError — use seekToIndex(1) for the first item
peekNext(), peekPrevious()
peekNext(): T | undefined
peekPrevious(): T | undefined
Current item
item()
item(): T | undefined
Return the currently loaded item.
item(item, opts?)
item(item: T, opts?: ActionOptions): void
Set the current item. The item must be in the queue.
index()
index(): number
Index of the current item.
Returns -1 if nothing is loaded.
load(item, opts?)
load(item: T, opts?: LoadOptions): Promise<void>
Load a single item without requiring it to be in the queue.
Time
time() / time(t, opts?)
time(): number
time(t: number, opts?: ActionOptions): Promise<void>
Get or set the playback position in seconds.
duration()
duration(): number
buffered(), bufferedRanges()
buffered(): number
bufferedRanges(): TimeRanges
seekable()
seekable(): TimeRanges
forward(s?, opts?), rewind(s?, opts?)
forward(s?: number, opts?: ActionOptions): Promise<void>
rewind(s?: number, opts?: ActionOptions): Promise<void>
Skip forward/backward by s seconds.
Default: 5.
seekByPercentage(pct, opts?)
seekByPercentage(pct: number, opts?: ActionOptions): void
Seek to a percentage (0–100) of total duration.
timeData()
timeData(): TimeState
// TimeState: { position: number; duration: number; buffered: number; remaining: number; percentage: number }
Volume
volume() / volume(v)
volume(): number
volume(v: number): void
Get or set volume. Scale: 0–100.
Returns 0 when muted (regardless of stored pre-mute level).
volume(v) clamps to [0, 100] and emits volume.
No-op if cancelled by beforeMutation.
player.volume(80); // 80%
const level = player.volume(); // 80
mute(), unmute(), toggleMute()
mute(): void
unmute(): void
toggleMute(): void
volumeUp(step?: number): void // step default: 5 percentage points
volumeDown(step?: number): void // step default: 5 percentage points
mute() saves the current level so unmute() can restore it exactly.
Both are no-ops when already in the target state.
volumeState()
volumeState(): VolumeState // 'muted' | 'unmuted'
Playback rate
playbackRate() / playbackRate(r)
playbackRate(): number
playbackRate(r: number): void
playbackRates(): number[]
Quality levels
qualityLevels()
qualityLevels(): QualityLevel[]
All available quality levels (from HLS.js after manifest parse).
quality() / quality(idx)
quality(): CurrentQualitySelection | 'auto' // 'auto' = adaptive (ABR) active
quality(idx: number | 'auto'): void // pass 'auto' to re-enable adaptive
The getter returns { index, track } (the level metadata at that index), or the string 'auto' when adaptive bitrate selection is active.
qualityMode()
qualityMode(): QualityState
Audio tracks
audioTracks()
audioTracks(): AudioTrack[]
Available audio tracks exposed by the HLS manifest.
audioTrack() / audioTrack(index)
audioTrack(): CurrentAudioTrackSelection | null
audioTrack(index: number): void
Get the active audio track as { index, track } (null when none is explicitly selected), or set it by index.
cycleAudioTracks()
cycleAudioTracks(): void
Cycle to the next available audio track. Wraps around.
Subtitles
subtitles()
subtitles(): SubtitleTrack[]
All subtitle tracks for the current item.
subtitle() / subtitle(index)
subtitle(): CurrentSubtitleSelection | null
subtitle(index: number | null): void
Get the active subtitle as { index, track } (null when off), or set by index.
Pass null to disable subtitles.
subtitleState()
subtitleState(): SubtitleState // 'on' | 'off'
Whether any subtitle track is currently active.
Checks both the core selection and videoElement.textTracks for backends that toggle native tracks directly.
subtitleStyle() / subtitleStyle(patch)
subtitleStyle(): SubtitleStyle
subtitleStyle(patch: Partial<SubtitleStyle>): void
Read or write subtitle style preferences.
Write merges the patch onto the current style and emits subtitleStyle.
Persistence is the responsibility of preference plugins, and the player only keeps in-memory state.
cycleSubtitles()
cycleSubtitles(): void
Walk: off → track 0 → track 1 → … → last track → off.
Chapters
chapters()
chapters(): Chapter[]
All chapters for the current item. Returns an empty array when no chapters are loaded.
chapter() / chapter(idx)
chapter(): Chapter | null
chapter(idx: number): void
Get the active chapter at time() (returns null when not in any chapter range), or seek to a chapter by index.
seekToChapter(idx, opts?)
seekToChapter(idx: number, opts?: ActionOptions): void
Seek to the start of a chapter by index.
Equivalent to time(chapters()[idx].start).
nextChapter(opts?)
nextChapter(opts?: ActionOptions): void
Advance to the start of the next chapter.
previousChapter(opts?)
previousChapter(opts?: ActionOptions): void
Return to the start of the previous chapter (or the start of the current chapter if more than 10 seconds into it).
Fullscreen / PiP / Theater
fullscreen() / fullscreen(state)
fullscreen(): FullscreenState
fullscreen(state: FullscreenState | boolean): void
FullscreenState is 'on' | 'off'.
Pass true/false or the enum value.
Requires a fullscreen controller in the platform option (wired automatically by browserPlatform).
Throws BrowserPolicyError (core:policy/fullscreenUnsupported) if no controller is configured.
player.fullscreen(true); // enter
player.fullscreen(false); // exit
player.fullscreen(); // FullscreenState.ON | FullscreenState.OFF
toggleFullscreen()
toggleFullscreen(): void
Toggle fullscreen on/off.
Shorthand for fullscreen(!isActive).
pip() / pip(state)
pip(): PipState
pip(state: PipState | boolean): void
PipState is 'on' | 'off'.
Requires a pip controller.
Throws BrowserPolicyError (core:policy/pipUnsupported) if unavailable.
togglePip()
togglePip(): void
theater() / theater(state)
theater(): TheaterState
theater(state: TheaterState | boolean): void
TheaterState is 'on' | 'off'.
Pure player-level state, so the UI plugin reacts via the theater event.
toggleTheater()
toggleTheater(): void
Aspect ratio and stretching
aspectRatio() / aspectRatio(value)
aspectRatio(): 'uniform' | 'fill' | 'exactfit' | 'none'
aspectRatio(value: 'uniform' | 'fill' | 'exactfit' | 'none'): void
| Value | CSS object-fit | Behavior |
|---|---|---|
'uniform' | contain | Letterbox/pillarbox, preserving aspect ratio |
'fill' | fill | Stretch to fill, ignore aspect ratio |
'exactfit' | cover | Cover without bars, may crop |
'none' | none | No scaling |
cycleAspectRatio()
cycleAspectRatio(): void
Cycle through 'uniform' → 'fill' → 'exactfit' → 'none' → 'uniform'.
Emits aspectRatio.
Shuffle and repeat
shuffleState() / shuffleState(state)
shuffleState(): ShuffleState
shuffleState(state: ShuffleState | boolean): void
repeatState() / repeatState(state)
repeatState(): RepeatState
repeatState(state: RepeatState): void
Queue management
All queue methods mirror the music player.
See Music API Methods for the full queue method signatures: queue, queueAppend, queuePrepend, queueInsert, queueRemove, queueRemoveAt, queueMove, queueClear, queueShuffle, queueSort, queueIndexOf, queueLength.
loadQueue(url, parser?)
loadQueue(url: string, parser?: (raw: string) => T[]): Promise<void>
Fetch a URL and replace the queue. Uses the player’s auth pipeline. Optionally supply a custom parser if the response body is not a raw JSON array. The parser receives the raw response body string.
Plugins
addPlugin<P extends Plugin>(Cls: PluginCtorWithId & (new () => P), opts?: P['opts']): NMVideoPlayer<T>
getPlugin<P extends object>(Cls: PluginCtorWithId & (new () => P)): P | undefined
getPluginById<P extends object = object>(id: string): P | undefined
removePlugin<P extends Plugin>(Cls: PluginCtorWithId & (new () => P), opts?: { cascade?: boolean }): void
removePluginById(id: string): void
plugins(): ReadonlyArray<Plugin>
enabledPlugins(): ReadonlyArray<Plugin>
Phase and diagnostics
phase()
phase(): PlayerPhase
Current phase: 'idle' | 'setup' | 'ready' | 'loading' | 'starting' | 'playing' | 'paused' | 'buffering' | 'seeking' | 'ended' | 'stopped' | 'disposing' | 'disposed'.
setupState()
setupState(): SetupState
Snapshot of the setup pipeline state. Useful for debugging plugin init ordering.
dispatching()
dispatching(): ReadonlyArray<string>
Names of all active before* events currently in flight.
Used by plugins that want to block re-entrant mutations.
platform()
platform(): IPlatform
The configured platform bundle (fullscreen, pip, wakeLock, network, visibility controllers).
playState()
playState(): PlayState // 'idle' | 'loading' | 'playing' | 'paused' | 'stopped' | 'error'
bufferState()
bufferState(): BufferState
networkState()
networkState(): NetworkState
visibilityState()
visibilityState(): VisibilityState // 'visible' | 'hidden'
streamState()
streamState(): string
Active stream factory id (e.g. 'hls', 'native').
metrics()
metrics(): PlaybackMetrics
Snapshot of playback metrics.
ttfb, avgBitrate, and decoderStalls are null on the html5 backend, so these counters are structurally unavailable from the HTMLVideoElement API.
droppedFrames is number (from getVideoPlaybackQuality()).
Guard nullable fields before use.
recordMetric(name, value)
recordMetric(name: string, value: number): void
Record a custom counter.
Merged into the metrics() snapshot.
now()
now(): number
Monotonic clock.
Uses options.clockSource() if configured, else Date.now().
Backend
backend()
backend(): IVideoBackend
Returns the active video backend.
Instantiates Html5VideoBackend (or the backendFactory result) on first call.
This is the lowest-level surface, and consumers rarely need it directly.
Stream registration
registerStream(factory, prepend?)
registerStream(factory: IStreamFactory, prepend?: boolean): this
Register a custom stream factory (e.g. DASH, SRT).
Registered factories take priority over the built-ins by default; pass true to register at the lowest priority instead, behind the built-in HLS and native factories.
Returns the player for chaining.
unregisterStream(id)
unregisterStream(id: string): this
Remove a registered stream factory by id.
streams()
streams(): ReadonlyArray<string>
Names of all registered stream factories in priority order.
getStreamFactory(id)
getStreamFactory(id: string): IStreamFactory | undefined
Cue parsers
registerCueParser(parser, prepend?)
registerCueParser(parser: ICueParser, prepend?: boolean): void
Register a custom subtitle/chapter cue parser. Parsers are tried in registration order; the first one that returns a non-null result wins.
unregisterCueParser(id)
unregisterCueParser(id: string): void
resolveCueParser(url)
resolveCueParser(url: string): ICueParser | undefined
Device capabilities
isTv(), isMobile(), isDesktop()
isTv(): boolean
isMobile(): boolean
isDesktop(): boolean
Device type detection. Used internally for buffer cap tiers and ABR constraints.
device()
device(): DeviceCapabilities
Full device capability snapshot: { isTv, isMobile, isDesktop, pipSupported, fullscreenSupported, webLocksSupported, autoplayAllowed, preferred }.
canPlay(profile)
canPlay(profile: {
contentType: string;
width?: number;
height?: number;
bitrate?: number;
framerate?: number;
}): Promise<CanPlayResult>
Query MediaCapabilities.decodingInfo() for a given format profile.
Used internally for HDR-aware ABR.
Returns CanPlayResult with fields { supported: boolean; smooth: boolean; powerEfficient: boolean }.
Bandwidth estimation
bandwidth()
bandwidth(): number
Current estimated bandwidth in bits/sec (from hls.js).
Returns 0 before any segment has loaded.
bandwidthEstimator() / bandwidthEstimator(fn)
bandwidthEstimator(): (() => number) | undefined
bandwidthEstimator(fn: () => number): void
Get or replace the bandwidth estimator function. The estimator is polled by the ABR layer. Supply a custom function to bias quality selection based on your own network signal.
Audio output devices
audioOutputs()
audioOutputs(): Promise<MediaDeviceInfo[]>
Enumerate available audio output devices. Requires the user to have granted device-access permission.
selectAudioOutput()
selectAudioOutput(): Promise<MediaDeviceInfo | null>
Show the browser’s audio output device picker.
Returns the selected device, or null if the user cancelled.
audioOutput() / audioOutput(deviceId)
audioOutput(): Promise<string | null>
audioOutput(deviceId: string): Promise<void>
Get or set the active audio output device id.
Auth
auth() / auth(config)
auth(): Readonly<AuthConfig> | undefined
auth(config: AuthConfig): void
auth(partial: Partial<AuthConfig>): void
Read or merge auth config at runtime.
Pass a full AuthConfig to replace, or a Partial<AuthConfig> to merge only specified fields (e.g. to update a refreshed token).
refreshAuth()
refreshAuth(): Promise<void>
Trigger a manual auth refresh.
Calls auth.refreshOnUnauthenticated() and updates the stored token.
URL
baseUrl() / baseUrl(url)
baseUrl(): string | undefined
baseUrl(url: string): void
Get or set the base URL prepended to relative media source URLs.
Separate from baseImageUrl (which applies to artwork).
resolveUrl(url, category?)
resolveUrl(url: string, category?: UrlCategory): Promise<ResolvedUrl>
Resolve a URL through the configured urlResolver (or the built-in auth.transformUrl + parse default).
Use for URLs that cannot carry Authorization headers (Cast, Worker, CSS), so auth travels via signed URL or query string through the resolver.
UrlCategory values: 'media' | 'subtitle' | 'font' | 'poster' | 'sprite' | 'lyrics' | 'cast' | 'license'.
urlResolver() / urlResolver(fn)
urlResolver(): IUrlResolver | undefined
urlResolver(resolver: IUrlResolver | undefined): void
i18n
t(key, vars?)
t(key: string, vars?: Record<string, string>): string
Translate a key using the configured translator.
Missing keys fall back to the key itself (or the onMissingTranslation handler).
language() / language(lang)
language(): string
language(lang: string): Promise<void>
Get or set the active language (BCP-47).
Setting a new language triggers loadTranslations in all plugins.
addTranslations(bundle)
addTranslations(bundle: Translations): void
Merge a translation bundle ({ en: { key: 'value' }, nl: { ... } }) into the player’s table at runtime.
removeTranslations(prefix, lang?)
removeTranslations(prefix: string, lang?: string): void
Remove all keys with the given prefix from the translation table. Optionally scoped to one language.
translation(lang, key) / translation(lang, key, value)
translation(lang: string, key: string): string | undefined
translation(lang: string, key: string, value: string): void
Low-level per-key read or write.
Plugins use t() instead.
Cast
castState()
castState(): CastState
transferTo(target)
transferTo(target: CastTarget): Promise<void>
// type CastTarget = 'cast' | 'airplay' | 'remote-playback' | 'local'
Hand off playback to a cast target, or pass 'local' to pull playback back.
The CastSenderPlugin must be registered for 'cast'.
CastTarget is exported from @nomercy-entertainment/nomercy-player-core. See Cast and Remote Playback.
Preload and transition strategies
setPreloadStrategy(strategy)
setPreloadStrategy(strategy: IPreloadStrategy): void
Replace the active preload strategy.
Default: VideoPreloadStrategy (preloads 10 s before end).
preloadStrategy()
preloadStrategy(): IPreloadStrategy
setTransitionStrategy(strategy)
setTransitionStrategy(strategy: ITransitionStrategy): void
Replace the transition strategy.
Default: GaplessTransitionStrategy (hard cut, no crossfade).
transitionStrategy()
transitionStrategy(): ITransitionStrategy
Accessibility
announce(text, level?)
announce(text: string, level?: 'polite' | 'assertive'): void
Post a message to the ARIA live region so screen readers announce it.
Default level: 'polite'.
DOM helpers (for plugin authors)
These helpers are composed onto the player so plugin mount() and dispose() implementations can construct DOM without importing from a separate utility path. Application code rarely needs them directly.
createElement(type, id, unique?)
createElement<K extends keyof HTMLElementTagNameMap>(
type: K,
id: string,
unique?: boolean,
): CreateElement<HTMLElementTagNameMap[K]>
Create a DOM element of type, assign id, and return a fluent builder. When unique is true, an existing element with the same id is returned instead of creating a duplicate — useful for singleton overlays that a plugin may construct in mount() and check for on re-mount.
The CreateElement builder exposes .get(), .addClasses(names), .appendTo(parent), and .prependTo(parent).
const overlay = player.createElement('div', 'my-overlay')
.addClasses(['custom-overlay'])
.appendTo(player.container);
createButton(id, label, onClick)
createButton(id: string, label: string, onClick: (e: Event) => void): HTMLButtonElement
Create an accessible <button> pre-wired with type="button", aria-label, title, and a click handler. Ready to insert with no additional setup.
const btn = player.createButton('my-btn', player.t('myPlugin.label'), (e) => {
player.togglePlayback();
});
player.container.appendChild(btn);
createSVG(id, viewBox)
createSVG(id: string, viewBox: string): SVGSVGElement
Create an <svg> element in the SVG namespace with id, viewBox, and xmlns set. Append path or use children on the returned element.
addClasses(el, names)
addClasses<T extends Element>(el: T, names: string[]): AddClasses<T>
Add CSS class names to el (skips empty strings) and return a fluent AddClasses builder. The builder exposes .get(), .appendTo(parent), .prependTo(parent), .addClasses(names), .setAttribute(name, value), and .setProperty(name, value).
removeClasses(el, names)
removeClasses<T extends Element>(el: T, names: string[]): T
Remove CSS class names from el (skips empty strings) and return the element itself.
Back listener
The back event is how the DesktopUiPlugin decides whether to show the back button.
Register a listener for it to signal that a back action is possible:
player.on('back', () => {
router.back();
});
DesktopUiPlugin calls player.hasListeners('back') during ready().
If at least one listener is registered, the back button appears in the top-left corner.
If no listener is registered, the button is not shown.
There is no setBackListener() method, use player.on('back', fn) and player.off('back', fn) directly.
Event API
on<K extends keyof VideoEventMap>(event: K, handler: (payload: VideoEventMap[K]) => void): void
off<K extends keyof VideoEventMap>(event: K, handler: (payload: VideoEventMap[K]) => void): void
once<K extends keyof VideoEventMap>(event: K, handler: (payload: VideoEventMap[K]) => void): void
hasListeners<K extends keyof VideoEventMap>(event: K): boolean
Subscribe to plugin events by string:
player.on('plugin:<id>:<event>', (payload) => { /* ... */ });