Start · Sprachen · JavaScript · Referenz · new AudioWorkletNode()

new AudioWorkletNode()

Methode

Erstellt einen <code>AudioWorkletNode</code>, der Audiodaten über einen zuvor registrierten <code>AudioWorkletProcessor</code> im Audio-Rendering-Thread verarbeitet.

seit JavaScript Baseline: alle modernen Browser (Chrome 66+, Firef Kategorie: webapi

Signatur

new AudioWorkletNode(context, name, options)

Beschreibung

Der Konstruktor AudioWorkletNode() erzeugt einen AudioNode, dessen Signalverarbeitung von einer eigenen JavaScript-Klasse übernommen wird. Diese Klasse erbt von AudioWorkletProcessor und läuft im Audio-Rendering-Thread, also getrennt vom Haupt-Thread. Dadurch ist eine latenzarme, unterbrechungsfreie Verarbeitung möglich. Der AudioWorklet ersetzt den veralteten ScriptProcessorNode.

Vor dem Aufruf muss das Modul mit dem Prozessor über audioContext.audioWorklet.addModule(url) geladen werden. Darin wird die Prozessorklasse mit registerProcessor(name, klasse) unter einem Namen registriert. Genau dieser Name wird dem Konstruktor als zweites Argument übergeben.

Über das Optionsobjekt legst du Folgendes fest:

  • die Anzahl der Ein- und Ausgänge,
  • die Kanalanzahl der Ausgänge,
  • die Startwerte der AudioParams, die der Prozessor über static get parameterDescriptors() deklariert,
  • beliebige serialisierbare Daten (processorOptions), die der Konstruktor des Prozessors erhält.

Haupt-Thread und Prozessor kommunizieren über node.port, einen MessagePort.

Parameter

Name Typ Default Beschreibung
$context Pflicht BaseAudioContext Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehören soll.
$name Pflicht string Der Name, unter dem der Prozessor im Worklet-Modul mit registerProcessor() registriert wurde.
$options AudioWorkletNodeOptions {} Optionales Objekt mit: numberOfInputs (Standard 1), numberOfOutputs (Standard 1), outputChannelCount (Array mit einer Kanalanzahl pro Ausgang), parameterData (Objekt mit Startwerten der AudioParams), processorOptions (beliebige, per structured clone übertragbare Daten) sowie die allgemeinen AudioNode-Optionen channelCount, channelCountMode und channelInterpretation.

Rückgabewert

Typ
AudioWorkletNode
Beschreibung
Ein neuer AudioWorkletNode mit den Eigenschaften port (MessagePort) und parameters (AudioParamMap). Er lässt sich wie jeder andere AudioNode verbinden.

Beispiele

Prozessor registrieren (Datei gain-processor.js)

// gain-processor.js – läuft im AudioWorkletGlobalScope
class GainProcessor extends AudioWorkletProcessor {
  static get parameterDescriptors() {
    return [{ name: 'gain', defaultValue: 1, minValue: 0, maxValue: 2 }];
  }

  process(inputs, outputs, parameters) {
    const input = inputs[0];
    const output = outputs[0];
    const gain = parameters.gain;
    for (let ch = 0; ch < input.length; ch++) {
      for (let i = 0; i < input[ch].length; i++) {
        // gain hat Länge 1 (konstant) oder 128 (automatisiert)
        const g = gain.length > 1 ? gain[i] : gain[0];
        output[ch][i] = input[ch][i] * g;
      }
    }
    return true; // Prozessor aktiv halten
  }
}

registerProcessor('gain-processor', GainProcessor);

Knoten erzeugen und in den Audiograph einbinden

const ctx = new AudioContext();
await ctx.audioWorklet.addModule('gain-processor.js');

const gainNode = new AudioWorkletNode(ctx, 'gain-processor', {
  parameterData: { gain: 0.5 },
  outputChannelCount: [2]
});

const osc = new OscillatorNode(ctx, { frequency: 440 });
osc.connect(gainNode).connect(ctx.destination);
osc.start();

// AudioParam zeitgesteuert automatisieren
const gain = gainNode.parameters.get('gain');
gain.linearRampToValueAtTime(0, ctx.currentTime + 2);
console.log(gain.value);
0.5

processorOptions und Kommunikation über port

// meter-processor.js
class MeterProcessor extends AudioWorkletProcessor {
  constructor(options) {
    super();
    this.interval = options.processorOptions.interval;
    this.frames = 0;
  }
  process(inputs) {
    const data = inputs[0][0];
    if (data) {
      this.frames += data.length;
      if (this.frames >= this.interval) {
        const rms = Math.sqrt(data.reduce((s, v) => s + v * v, 0) / data.length);
        this.port.postMessage({ rms });
        this.frames = 0;
      }
    }
    return true;
  }
}
registerProcessor('meter-processor', MeterProcessor);

// main.js
const ctx = new AudioContext();
await ctx.audioWorklet.addModule('meter-processor.js');
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = ctx.createMediaStreamSource(stream);

const meter = new AudioWorkletNode(ctx, 'meter-processor', {
  numberOfOutputs: 0,
  processorOptions: { interval: 4096 }
});
meter.port.onmessage = ({ data }) => console.log('Pegel:', data.rms.toFixed(3));
source.connect(meter);
Pegel: 0.042 Pegel: 0.057 …

// Wichtig · Fallstricke

  • Reihenfolge: Wird der Konstruktor aufgerufen, bevor das Promise von addModule() erfüllt ist, oder ist der Name nicht registriert, wirft er einen NotSupportedError (in älteren Browsern InvalidStateError).
  • Sicherer Kontext: audioWorklet gibt es nur unter HTTPS bzw. localhost. Das Modul unterliegt CORS und CSP (script-src/worker-src).
  • Ungültige Optionen: Sind numberOfInputs und numberOfOutputs beide 0, entsteht ein NotSupportedError. Passt die Länge von outputChannelCount nicht zu numberOfOutputs, gibt es einen IndexSizeError.
  • Autoplay-Regeln: Ein AudioContext startet oft im Zustand suspended. Rufe ctx.resume() nach einer Nutzerinteraktion auf.
  • Performance: process() wird alle 128 Samples aufgerufen. Erzeuge darin keine Objekte, sende keine Nachrichten in hoher Frequenz und vermeide aufwendige Berechnungen, sonst entstehen Knackser (Buffer-Underruns). Die Rückgabe false erlaubt dem Browser, den Knoten zu entsorgen.
  • processorOptions werden per structured clone kopiert. Funktionen und DOM-Objekte lassen sich nicht übertragen. Für große Datenmengen eignen sich SharedArrayBuffer (setzt Cross-Origin-Isolation voraus) oder übertragbare Objekte über port.
  • Browser: Safari unterstützt die Schnittstelle erst ab Version 14.1. Für sehr alte Browser bleibt nur der veraltete ScriptProcessorNode als Ersatz.