Signatur
Beschreibung
Mit createScriptProcessor() erstellst du einen ScriptProcessorNode. Über ihn kannst du Audio-Samples direkt in JavaScript bearbeiten. Immer wenn ein Puffer mit bufferSize Samples voll ist, löst der Knoten das Ereignis audioprocess aus. Das zugehörige AudioProcessingEvent enthält einen inputBuffer (Eingangsdaten) und einen outputBuffer (in den du die bearbeiteten Daten schreibst).
Typische Einsatzzwecke sind eigene Effekte wie Verzerrung, Bitcrusher oder Rauschgeneratoren, Pegelmessung (RMS/VU-Meter) und das Mitschneiden roher PCM-Daten, zum Beispiel für den WAV-Export oder die Spracherkennung.
Wichtig: Die Methode gilt als veraltet. Der Callback läuft im Haupt-Thread. Dadurch kommt es zu Latenz, und sobald die Oberfläche stark ausgelastet ist, knackt oder stockt das Audio. Für neuen Code solltest du AudioWorkletNode verwenden: Er verarbeitet das Audio in einem eigenen Audio-Thread. createScriptProcessor() kommt nur noch für Altprojekte oder schnelle Prototypen infrage.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $bufferSize | number | 0 | Puffergröße in Sample-Frames. Erlaubt sind 256, 512, 1024, 2048, 4096, 8192 und 16384. Bei 0 wählt der Browser einen passenden Wert. Kleine Werte bedeuten wenig Latenz, aber mehr Aufrufe und damit mehr Aussetzer-Risiko. |
| $numberOfInputChannels | number | 2 | Anzahl der Eingangskanäle (maximal 32). Sie darf nur dann 0 sein, wenn numberOfOutputChannels nicht ebenfalls 0 ist. |
| $numberOfOutputChannels | number | 2 | Anzahl der Ausgangskanäle (maximal 32). Sie darf nur dann 0 sein, wenn numberOfInputChannels nicht ebenfalls 0 ist. |
Rückgabewert
ScriptProcessorNode, der über das Ereignis audioprocess Audioblöcke zur Bearbeitung liefert.Beispiele
Weißes Rauschen erzeugen
const ctx = new AudioContext();
// 0 Eingänge, 1 Ausgang: reiner Generator
const noise = ctx.createScriptProcessor(4096, 0, 1);
noise.onaudioprocess = (event) => {
const out = event.outputBuffer.getChannelData(0);
for (let i = 0; i < out.length; i++) {
out[i] = Math.random() * 2 - 1;
}
};
noise.connect(ctx.destination);
// Nach 2 Sekunden stoppen
setTimeout(() => noise.disconnect(), 2000);
Lautstärke halbieren (einfacher Effekt)
const ctx = new AudioContext();
const audio = document.querySelector('audio');
const source = ctx.createMediaElementSource(audio);
const processor = ctx.createScriptProcessor(2048, 2, 2);
processor.addEventListener('audioprocess', ({ inputBuffer, outputBuffer }) => {
for (let ch = 0; ch < outputBuffer.numberOfChannels; ch++) {
const input = inputBuffer.getChannelData(ch);
const output = outputBuffer.getChannelData(ch);
for (let i = 0; i < input.length; i++) {
output[i] = input[i] * 0.5;
}
}
});
source.connect(processor).connect(ctx.destination);
Mikrofonpegel (RMS) messen
const meter = async () => {
const ctx = new AudioContext();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mic = ctx.createMediaStreamSource(stream);
const processor = ctx.createScriptProcessor(1024, 1, 1);
processor.onaudioprocess = (e) => {
const data = e.inputBuffer.getChannelData(0);
let sum = 0;
for (const s of data) sum += s * s;
const rms = Math.sqrt(sum / data.length);
console.log(`Pegel: ${(rms * 100).toFixed(1)} %`);
};
mic.connect(processor);
// Verbindung zum Ziel nötig, sonst feuert audioprocess in Chrome nicht
processor.connect(ctx.destination);
};
meter();
// Wichtig · Fallstricke
- Veraltet: Die Spezifikation hat
ScriptProcessorNodedurchAudioWorkletersetzt. Die Methode funktioniert zwar noch in allen gängigen Browsern, kann aber langfristig entfernt werden. - Leistung: Der Callback läuft im Haupt-Thread. Aufwendige DOM-Arbeit, Garbage Collection oder lange Aufgaben führen deshalb zu Knacksern. Im Callback solltest du keine Objekte anlegen und kein DOM verändern.
- Eine ungültige
bufferSizelöst einenIndexSizeErroraus. Dasselbe gilt, wenn beide Kanalzahlen0sind oder eine davon größer als 32 ist. - In Chromium-Browsern feuert
audioprocessnur, wenn der Knoten (direkt oder indirekt) mitctx.destinationverbunden ist. - Wegen der Autoplay-Richtlinien startet ein
AudioContextoft im Zustandsuspended. Rufectx.resume()daher nach einer Nutzeraktion auf. - Ältere WebKit-Versionen verlangten die Angabe von
bufferSize. Gib den Wert explizit an, wenn du alte Browser unterstützen musst.