WebAudioBackend
Web Audio pipeline backend.
Routes all audio through a AudioContext graph.
Crossfade uses GainNode.gain.linearRampToValueAtTime for sample-accurate ramps.
Kind: 'webaudio'
Activation
player.setup({ backend: 'webaudio' });
Or switch at runtime:
await player.backend('webaudio');
Audio graph
The backend constructs a graph rooted at the AudioContext:
Source node. Always wraps the <audio> element via createMediaElementSource(), for both HLS and non-HLS sources.
Controls playback volume and executes crossfade ramps via linearRampToValueAtTime.
Tap point for AudioGraphPlugin effect chains. Connect custom analyser or effect nodes here.
Final sink routed to the device speakers or headphones.
When AudioGraphPlugin is registered, it connects its effect chain between the outputNode() and AudioContext.destination.
Source node
WebAudioBackend always routes through a <audio> element and wraps it with createMediaElementSource().
This applies to both HLS streams and direct file URLs (MP3, AAC, FLAC, OGG).
hls.js attaches to the same <audio> element, so there is no separate code path per format.
Crossfade implementation
crossfade(durationMs):
- Primary
GainNode.gainramps from current volume to 0 vialinearRampToValueAtTime - Secondary
GainNode.gainramps from 0 to current volume vialinearRampToValueAtTime - Both ramps complete at
AudioContext.currentTime + durationMs / 1000 - At completion, the secondary becomes the primary; the old primary is disconnected and its buffer released
Accuracy: Sample-accurate. No RAF loop, no jitter.
Volume changes are smoothed with GainNode.gain.setTargetAtTime (time constant 10 ms) to prevent clicks on mute/unmute or abrupt volume changes.
iOS considerations
On iOS and in some mobile Chrome contexts, AudioContext creation may be suspended until a user gesture.
If audioContext().state === 'suspended', call audioContext().resume() inside a user interaction handler before starting playback.
Graph access
const audioCtx = player.audioContext(); // AudioContext | undefined
if (audioCtx) {
const analyser = audioCtx.createAnalyser();
const backend = player.backend();
backend.outputNode(audioCtx).connect(analyser);
analyser.connect(audioCtx.destination);
}
See also
- Backends overview, when to choose
audio-elementvswebaudio - IAudioBackend, full interface reference
- AudioElementBackend, default, less accurate alternative
- Advanced: Equalizer Customization, building on the Web Audio graph