Start · Sprachen · JavaScript · Referenz · BaseAudioContext.decodeAudioData()

BaseAudioContext.decodeAudioData()

Methode

Dekodiert asynchron Audiodaten (z. B. MP3, WAV, OGG) aus einem <code>ArrayBuffer</code> in einen abspielbaren <code>AudioBuffer</code>.

seit JavaScript Baseline: alle modernen Browser (Promise-Variante Kategorie: webapi

Signatur

BaseAudioContext.prototype.decodeAudioData(arrayBuffer, successCallback, errorCallback)

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

Typ
Promise<AudioBuffer>
Beschreibung
Ein Promise, das mit dem dekodierten 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);
});
Dauer: 0.35 s, Kanäle: 2

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}`);
  }
});
song.wav: 183.4 s @ 48000 Hz

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));
["kick", "snare", "hihat"]

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);
true 22050

// Wichtig · Fallstricke

  • Der ArrayBuffer wird geleert (detached): Nach dem Aufruf hat er die byteLength 0. Wenn du die Rohdaten noch brauchst, übergib eine Kopie mit buffer.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 MediaSource oder 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 sampleRate des Kontexts umgerechnet. Brauchst du die Originalrate, erzeuge einen OfflineAudioContext mit passender Rate.
  • Autoplay: Dekodieren funktioniert auch in einem Kontext mit Zustand suspended. Zum Abspielen musst du aber meist nach einer Nutzerinteraktion ctx.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.