Start · Sprachen · JavaScript · Referenz · AudioData

AudioData

Schnittstelle

Die <code>AudioData</code>-Schnittstelle der WebCodecs API steht für einen Block unkomprimierter Audio-Samples mit Format, Abtastrate, Kanalanzahl und Zeitstempel.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Firefox 130+ (Des Kategorie: webapi

Signatur

interface AudioData

Beschreibung

AudioData ist die rohe, unkomprimierte Audio-Einheit der WebCodecs API. Ein Objekt enthält eine feste Anzahl von Frames (ein Frame = ein Sample pro Kanal) für einen oder mehrere Kanäle, dazu die Metadaten format, sampleRate, numberOfFrames, numberOfChannels, timestamp und duration. Zeitstempel und Dauer werden in Mikrosekunden angegeben.

Solche Objekte entstehen typischerweise als Ausgabe eines AudioDecoder, beim Lesen eines Mikrofon-Tracks über MediaStreamTrackProcessor oder durch direktes Erzeugen mit new AudioData(init). Umgekehrt dienen sie als Eingabe für den AudioEncoder, zum Beispiel um selbst erzeugtes oder bearbeitetes Audio nach Opus oder AAC zu kodieren.

Wichtige Methoden sind:

  • allocationSize(options): berechnet, wie viele Bytes für copyTo() nötig sind.
  • copyTo(destination, options): kopiert die Samples einer Ebene (plane) in einen Puffer, wahlweise mit Umwandlung in ein anderes Format.
  • clone(): erzeugt eine weitere Referenz auf dieselben Mediendaten.
  • close(): gibt den Speicher sofort frei.

Das Sample-Format entscheidet über die Speicheranordnung: Bei interleaved-Formaten ("u8", "s16", "s32", "f32") liegen die Samples aller Kanäle abwechselnd in einer einzigen Ebene. Bei planar-Formaten ("f32-planar" usw.) hat jeder Kanal eine eigene Ebene. AudioData ist transferierbar und lässt sich daher ohne Kopie per postMessage() an Worker weitergeben.

Parameter

Name Typ Default Beschreibung
$init Pflicht Object Initialisierungsobjekt für den Konstruktor new AudioData(init).
$init.format Pflicht "u8"|"s16"|"s32"|"f32"|"u8-planar"|"s16-planar"|"s32-planar"|"f32-planar" Sample-Format und Speicheranordnung (interleaved oder planar).
$init.sampleRate Pflicht number Abtastrate in Hz, z. B. 48000.
$init.numberOfFrames Pflicht number Anzahl der Frames, also der Samples pro Kanal.
$init.numberOfChannels Pflicht number Anzahl der Audiokanäle (1 = mono, 2 = stereo …).
$init.timestamp Pflicht number Startzeitpunkt der Daten in Mikrosekunden.
$init.data Pflicht ArrayBuffer|TypedArray|DataView Puffer mit den Samples. Er muss mindestens numberOfFrames × numberOfChannels × Bytes pro Sample groß sein.
$init.transfer Array<ArrayBuffer> [] Puffer, die ohne Kopie übernommen werden. Danach sind sie beim Aufrufer detached, also nicht mehr nutzbar.

Rückgabewert

Typ
AudioData
Beschreibung
Der Konstruktor gibt ein neues AudioData-Objekt zurück. Die Eigenschaften format, sampleRate, numberOfFrames, numberOfChannels, timestamp und duration (in µs) sind schreibgeschützt. Nach close() ist format gleich null und die übrigen Werte sind 0.

Beispiele

AudioData aus einem erzeugten Sinuston erstellen

const sampleRate = 48000;
const numberOfFrames = 480; // 10 ms
const samples = new Float32Array(numberOfFrames);

for (let i = 0; i < numberOfFrames; i++) {
  samples[i] = Math.sin(2 * Math.PI * 440 * i / sampleRate) * 0.5;
}

const audioData = new AudioData({
  format: 'f32-planar',
  sampleRate,
  numberOfFrames,
  numberOfChannels: 1,
  timestamp: 0,
  data: samples
});

console.log(audioData.format, audioData.duration);
audioData.close();
f32-planar 10000

Decoder-Ausgabe kanalweise auslesen und freigeben

const decoder = new AudioDecoder({
  output: (audioData) => {
    const channels = [];
    for (let ch = 0; ch < audioData.numberOfChannels; ch++) {
      const opts = { planeIndex: ch, format: 'f32-planar' };
      const buffer = new Float32Array(audioData.allocationSize(opts) / 4);
      audioData.copyTo(buffer, opts);
      channels.push(buffer);
    }
    console.log(`${audioData.timestamp} µs, ${channels.length} Kanäle`);
    audioData.close(); // Speicher sofort freigeben!
  },
  error: (e) => console.error('Decoder-Fehler:', e)
});

decoder.configure({ codec: 'opus', sampleRate: 48000, numberOfChannels: 2 });
z. B. "20000 µs, 2 Kanäle"

AudioData in einen Web-Audio-AudioBuffer umwandeln

const toAudioBuffer = (audioData, ctx) => {
  const buffer = ctx.createBuffer(
    audioData.numberOfChannels,
    audioData.numberOfFrames,
    audioData.sampleRate
  );
  for (let ch = 0; ch < audioData.numberOfChannels; ch++) {
    const target = new Float32Array(audioData.numberOfFrames);
    audioData.copyTo(target, { planeIndex: ch, format: 'f32-planar' });
    buffer.copyToChannel(target, ch);
  }
  return buffer;
};

// Verwendung:
// const ctx = new AudioContext();
// const src = ctx.createBufferSource();
// src.buffer = toAudioBuffer(audioData, ctx);
// src.connect(ctx.destination); src.start();

Mikrofon-Samples lesen und in einen Worker übertragen

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const [track] = stream.getAudioTracks();
const processor = new MediaStreamTrackProcessor({ track });
const reader = processor.readable.getReader();
const worker = new Worker('audio-worker.js');

while (true) {
  const { value: audioData, done } = await reader.read();
  if (done) break;
  // Übertragen statt kopieren – im Hauptthread danach nicht mehr verwenden
  worker.postMessage(audioData, [audioData]);
}