IAudioBackend
Concrete contract every audio backend implements.
The player calls these methods; plugins tap outputNode() and analyserSource() to build effect chains.
import type { IAudioBackend } from '@nomercy-entertainment/nomercy-music-player/adapters/audio-backend';
kind
readonly kind: AudioBackendKind // 'audio-element' | 'webaudio'
Discriminates the backend type.
Use .kind to branch; do not compare the return value of player.backend() as a string.
const backend = player.backend();
if (backend.kind === 'webaudio') {
// WebAudioBackend-specific code
}
Lifecycle
load(url, opts?)
load(url: string, opts?: { preload: 'auto' | 'metadata' | 'none' }): Promise<void>
Load and preload a media URL. Resolves when the backend is ready to play.
unload()
unload(): void
Detach the current source. Does not dispose the backend.
dispose()
dispose(): void
Tear down the backend: pause, disconnect all nodes, release all resources.
After dispose(), the backend must not be used.
Transport
play()
play(): Promise<void>
Start or resume playback.
pause()
pause(): void
Pause playback.
stop()
stop(): void
Stop playback and reset position to 0.
Time
currentTime()
currentTime(): number
currentTime(seconds: number): void
Get or set the current playback position in seconds.
duration()
duration(): number
Total duration in seconds. May return NaN or 0 before metadata loads.
buffered()
buffered(): number
Seconds of audio buffered ahead of the current position.
bufferedRanges()
bufferedRanges(): TimeRanges
All buffered time ranges.
seekable()
seekable(): TimeRanges
Seekable time ranges.
playbackRate()
playbackRate(): number
playbackRate(rate: number): void
Get or set the playback rate.
Volume
volume()
volume(): number
volume(level: number): void
Get or set the volume (0–1 scale at the backend level; the player converts from its 0–100 scale).
mute()
mute(): void
Silence output without changing the stored volume.
unmute()
unmute(): void
Restore output.
State
state()
state(): BackendState
BackendState values: 'idle' | 'loading' | 'ready' | 'playing' | 'paused' | 'error'
Effect chain
outputNode(ctx)
outputNode(ctx: AudioContext): AudioNode
The output node of the backend’s audio graph. Connect your processing chain here.
analyserSource(ctx)
analyserSource(ctx: AudioContext): AudioNode
A tap node suitable for AnalyserNode connection (spectrum, waveform visualization).
Does not interrupt the main signal path.
Raw access
mediaElement()
mediaElement(): HTMLMediaElement
The underlying <audio> element.
Used by Cast SDKs and other integrations that need direct element access.
Capture
captureStream()
captureStream(): MediaStream
MediaStream of the audio output.
Use for recording, WebRTC, or piping to <video>.
Audio output routing
setSinkId(deviceId)
setSinkId(deviceId: string): Promise<void>
Route audio to a specific output device.
getSinkId()
getSinkId(): string
Id of the current output device.
DRM (planned v2.1)
mediaKeys()
mediaKeys(): MediaKeys | undefined
setMediaKeys(keys)
setMediaKeys(keys: MediaKeys): Promise<void>
outputProtectionState()
outputProtectionState(): 'unrestricted' | 'restricted' | 'unsupported'
Loader backpressure
pauseLoader()
pauseLoader(): void
Signal the backend to pause segment fetching (used by LiveTranscodingPlugin to drain the buffer before refilling).
resumeLoader()
resumeLoader(): void
loaderState()
loaderState(): 'running' | 'paused'
Crossfade
supportsCrossfade()
supportsCrossfade(): boolean
Whether this backend supports parallel playback for crossfade.
Both built-in backends return true.
Custom backends that cannot allocate a second handle should return false.
loadSecondary(url)
loadSecondary(url: string): Promise<void>
Allocate the secondary playback handle and load url into it without affecting primary playback.
primeSecondary(seekMs?)
primeSecondary(seekMs?: number): Promise<void>
Pre-roll the secondary to position seekMs (default 0).
Waits for canplay before resolving.
crossfade(durationMs)
crossfade(durationMs: number): Promise<void>
Ramp primary gain → 0 and secondary gain → current volume over durationMs.
At completion, secondary becomes primary and the old primary is disposed.
disposeSecondary()
disposeSecondary(): void
Tear down the secondary handle. Idempotent.
secondaryGain()
secondaryGain(): number
secondaryGain(value: number): void
Read or write the secondary’s gain (0–1). Returns 0 when no secondary is allocated.
Events
on(event, fn)
on<E extends BackendEvent>(event: E, fn: (data?: BackendEventPayload[E]) => void): void
off<E extends BackendEvent>(event: E, fn: (data?: BackendEventPayload[E]) => void): void
Backend events are forwarded to the player’s event bus by the player’s wiring layer.
Subscribe to player-level events (player.on(...)) rather than backend-level events directly.
BackendEvent values: 'loadstart' | 'loadedmetadata' | 'canplay' | 'play' | 'playing' | 'pause' | 'ended' | 'timeupdate' | 'waiting' | 'stalled' | 'ratechange' | 'encrypted' | 'error' | 'backend:loading' | 'backend:loaded'
backend:loading payload: { url: string; kind: AudioBackendKind }.
backend:loaded payload: { url: string; kind: AudioBackendKind; duration: number }.
All DOM-bridge events carry the original Event object.
See also
- AudioElementBackend, implementation details
- WebAudioBackend, implementation details
- Advanced: Writing an Audio Backend, implementing this interface