Signatur
Beschreibung
decodeAudioData() nimmt die Rohbytes einer kompletten Audiodatei entgegen, die zuvor per fetch(), XMLHttpRequest oder FileReader bzw. Blob.arrayBuffer() geladen wurden, und wandelt sie in einen AudioBuffer mit unkomprimierten PCM-Samples um. Den Puffer kannst du anschließend über einen AudioBufferSourceNode abspielen oder direkt analysieren, etwa für Wellenform-Darstellungen.
Die Methode liefert ein Promise zurück. Die älteren Callback-Parameter successCallback und errorCallback werden aus Gründen der Abwärtskompatibilität weiterhin unterstützt, in neuem Code solltest du aber async/await verwenden. Die Samples werden automatisch auf die sampleRate des Kontexts umgerechnet (resampled).
Die Methode eignet sich für kurze bis mittellange Clips, die du exakt, mit wenig Verzögerung und mehrfach abspielen willst: Soundeffekte, Samples für Spiele oder Instrumente. Für lange Musikstücke oder Streams ist ein <audio>-Element zusammen mit createMediaElementSource() meist besser geeignet, weil decodeAudioData() die gesamte Datei unkomprimiert im Speicher ablegt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $arrayBuffer Pflicht | ArrayBuffer | Die vollständigen, kodierten Audiodaten, z. B. MP3, WAV, AAC, OGG/Opus oder FLAC. Der Puffer wird dabei übertragen (detached) und ist danach leer. | |
| $successCallback | (decodedData: AudioBuffer) => void | Veraltete Callback-Variante: Wird mit dem dekodierten AudioBuffer aufgerufen. |
|
| $errorCallback | (error: DOMException) => void | Veraltete Callback-Variante: Wird bei einem Dekodierfehler mit einer DOMException aufgerufen, meist EncodingError. |
Rückgabewert
AudioBuffer erfüllt wird. Wenn das Format nicht unterstützt wird oder die Daten beschädigt sind, wird es mit einer DOMException abgelehnt, meist EncodingError.Beispiele
Soundeffekt laden und abspielen
const ctx = new AudioContext();
const loadSound = async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.arrayBuffer();
return ctx.decodeAudioData(data);
};
const playSound = (buffer) => {
const source = ctx.createBufferSource();
source.buffer = buffer;
source.connect(ctx.destination);
source.start();
};
const button = document.querySelector('#play');
const clickBufferPromise = loadSound('/sounds/click.mp3');
button.addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Sperre aufheben
const buffer = await clickBufferPromise;
console.log(`Dauer: ${buffer.duration.toFixed(2)} s, Kanäle: ${buffer.numberOfChannels}`);
playSound(buffer);
});
Vom Nutzer gewählte Datei dekodieren (mit Fehlerbehandlung)
const ctx = new AudioContext();
const input = document.querySelector('input[type=file]');
input.addEventListener('change', async () => {
const file = input.files[0];
if (!file) return;
try {
const data = await file.arrayBuffer();
const buffer = await ctx.decodeAudioData(data);
console.log(`${file.name}: ${buffer.duration.toFixed(1)} s @ ${buffer.sampleRate} Hz`);
} catch (err) {
console.error(`Dekodierung fehlgeschlagen (${err.name}): ${err.message}`);
}
});
Mehrere Samples parallel vorladen
const ctx = new AudioContext();
const urls = {
kick: '/samples/kick.wav',
snare: '/samples/snare.wav',
hihat: '/samples/hihat.wav'
};
const loadAll = async () => {
const entries = await Promise.all(
Object.entries(urls).map(async ([name, url]) => {
const data = await (await fetch(url)).arrayBuffer();
return [name, await ctx.decodeAudioData(data)];
})
);
return Object.fromEntries(entries);
};
const samples = await loadAll();
console.log(Object.keys(samples));
Wiederverwendung des ArrayBuffers: vorher kopieren
const ctx = new AudioContext();
const data = await (await fetch('/sounds/beep.ogg')).arrayBuffer();
// Kopie übergeben, damit das Original erhalten bleibt
const buffer = await ctx.decodeAudioData(data.slice(0));
console.log(data.byteLength > 0, buffer.length);
// Wichtig · Fallstricke
- Der ArrayBuffer wird geleert (detached): Nach dem Aufruf hat er die
byteLength0. Wenn du die Rohdaten noch brauchst, übergib eine Kopie mitbuffer.slice(0). - Nur vollständige Dateien: Die Methode kann keine Stream-Fragmente dekodieren. Die Daten müssen eine komplette, gültige Datei mit Header sein. Für Streaming eignen sich
MediaSourceoder WebCodecs (AudioDecoder). - Formatunterstützung ist browserabhängig: MP3, WAV und AAC funktionieren praktisch überall. Bei OGG/Vorbis und Opus hatte Safari lange Lücken. Prüfe das im Zweifel vorab mit
HTMLAudioElement.canPlayType(). - Speicherbedarf: Das Ergebnis liegt als unkomprimiertes 32-Bit-Float-PCM vor. Eine Minute Stereo bei 48 kHz belegt rund 23 MB. Lange Dateien daher besser über
<audio>abspielen. - Resampling: Die Daten werden auf die
sampleRatedes Kontexts umgerechnet. Brauchst du die Originalrate, erzeuge einenOfflineAudioContextmit passender Rate. - Autoplay: Dekodieren funktioniert auch in einem Kontext mit Zustand
suspended. Zum Abspielen musst du aber meist nach einer Nutzerinteraktionctx.resume()aufrufen. - Veraltete Callbacks: Sehr alte Safari-Versionen (vor 14.1) unterstützen nur die Callback-Variante. Zum Absichern kannst du beide Mechanismen kombinieren.
- CORS: Audiodateien von fremden Domains müssen passende CORS-Header senden, sonst schlägt schon
fetch()fehl.