Skip to content

Audio Graph

AudioGraphPlugin is the foundation for every Web Audio feature in the player. Register it before EqualizerPlugin, MixerPlugin, SpectrumPlugin, or CanvasPlugin. It creates the AudioContext, connects the backend’s audio output into the Web Audio graph, and owns the signal chain that downstream plugins extend. Without AudioGraphPlugin, the other Web Audio plugins are inert.

Plugin id

'audio-graph'

Import

TypeScript
import { AudioGraphPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins';
import type { AudioGraphOptions, AudioGraphEvents } from '@nomercy-entertainment/nomercy-video-player/plugins';

What it does

On use() the plugin creates (or reuses) an AudioContext and connects the backend’s audio output into the graph. When the backend exposes an outputNode, the plugin reuses that node as the chain source rather than calling createMediaElementSource a second time. Browsers silently stop routing audio if the same media element is wrapped twice. Subsequent plugins extend the chain by calling insertEffect() or the pre() / post() shorthands.

The chain topology looks like this:

5
Backend audio output

The raw audio output produced by the active backend (Html5VideoBackend or WebAudioBackend).

4
Source node

MediaElementSourceNode wrapping the backend output. Created once; reused if the backend already exposes an outputNode.

3
Parallel tap — shared AnalyserNode

Tapped off the source in parallel. Read by SpectrumPlugin and custom visualisers; does not affect the main signal path.

2
preEffects[0..n]

Serial pre-effect nodes inserted via pre() or insertEffect(node, "pre"). Typical use: EQ BiquadFilters.

1
postEffects[0..n] → AudioContext.destination

Serial post-effect nodes inserted via post() or insertEffect(node, "post"). Typical use: MixerPlugin gain and pan. Last node wires to AudioContext.destination.

The AudioContext starts in 'suspended' state per browser autoplay policy. The plugin resumes it on the first 'play' event, which always fires inside or immediately after a user gesture.

Options

OptionTypeDefaultDescription
latencyHintAudioContextLatencyCategory'playback'Latency hint for the AudioContext. Use 'playback' for video and music, 'interactive' when round-trip latency matters.
fftSize256 | 512 | 1024 | 2048 | 4096 | 8192 | 163842048FFT size for the shared AnalyserNode. Higher values give finer frequency resolution at the cost of time resolution.
smoothingnumber0.8Smoothing time constant 0 to 1 for the shared analyser. Higher values make spectrum output lag more behind transients.

Events

EventPayloadDescription
'context:ready'{ sampleRate: number }AudioContext is live and the baseline chain is connected.
'context:closed'voidContext closed on dispose.
'chain:rebuilt'voidEffect list changed; downstream plugins re-link their own nodes.
'unsupported'{ reason: string }AudioContext unavailable in this environment; plugin is inert.

Methods

These are the public methods you call from consumer code or from other plugins via player.getPlugin(AudioGraphPlugin).

TypeScript
import { AudioGraphPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins';

const graph = player.getPlugin(AudioGraphPlugin)!;

// Returns the live AudioContext.
// If called before use(), creates one immediately.
// Throws BrowserPolicyError in non-browser environments.
const audioCtx = graph.context();

// Returns the last node in the effect chain,
// the one wired directly to AudioContext.destination.
const tailNode = graph.outputNode();

// Returns the shared AnalyserNode tapped parallel to the source.
// Created once; SpectrumPlugin and custom visualisers all share it.
const analyser = graph.analyserSource();

// Appends a node to the signal chain and triggers a rebuild.
// position 'pre' places it before post effects (e.g. EQ filters).
// position 'post' places it after all pre effects (default, e.g. master gain).
const gainNode = audioCtx.createGain();

graph.insertEffect(gainNode, 'post');

// Shorthands for insertEffect:
graph.pre(gainNode);
graph.post(gainNode);

// Removes a previously inserted node and triggers a rebuild.
graph.removeEffect(gainNode);

// Manually connects two nodes outside the managed chain.
// All route() pairs are disconnected on dispose.
graph.route(gainNode, audioCtx.destination);

// Disconnects a manual route pair.
graph.unroute(gainNode, audioCtx.destination);

Registration

Register AudioGraphPlugin before any other Web Audio plugin. The required layering order is AudioGraphPlugin first, then EqualizerPlugin, MixerPlugin, SpectrumPlugin, or CanvasPlugin in any order after.

TypeScript
import nmplayer from '@nomercy-entertainment/nomercy-video-player';
import {
AudioGraphPlugin,
EqualizerPlugin,
MixerPlugin,
SpectrumPlugin,
} from '@nomercy-entertainment/nomercy-video-player/plugins';

const player = nmplayer('player')
.addPlugin(AudioGraphPlugin, { latencyHint: 'playback', fftSize: 2048 })
.addPlugin(EqualizerPlugin)
.addPlugin(MixerPlugin)
.addPlugin(SpectrumPlugin)
.setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Films',
playlist: [
{
title: 'Tears of Steel',
url: '/Tears.of.Steel.(2012)/Tears.of.Steel.(2012).NoMercy.m3u8',
},
],
});

player.on('plugin:audio-graph:context:ready', ({ sampleRate }) => {
console.log('AudioContext running at', sampleRate, 'Hz');
});

See also