Signatur
Beschreibung
Der Konstruktor new AudioData() gehört zur WebCodecs API. Er verpackt einen Block roher PCM-Samples (z. B. aus einem Float32Array oder Int16Array) in ein AudioData-Objekt. Dieses Objekt beschreibt genau, wie die Bytes zu lesen sind: Sample-Format, Abtastrate, Anzahl der Frames und Kanäle sowie den Zeitpunkt im Medienstrom.
Du brauchst AudioData vor allem dann, wenn du selbst erzeugtes oder bearbeitetes Audio an einen AudioEncoder übergeben willst, etwa für die Aufnahme im Browser, Echtzeit-Streaming über WebTransport/WebRTC oder die Umwandlung in Opus/AAC. Auch Objekte, die ein AudioDecoder ausgibt oder ein MediaStreamTrackProcessor liefert, sind AudioData-Instanzen.
Wichtig ist das Speicherlayout: Bei interleaved-Formaten ("f32", "s16" …) liegen die Samples der Kanäle abwechselnd hintereinander (L R L R …). Bei planar-Formaten ("f32-planar" …) stehen zuerst alle Samples von Kanal 0, dann alle von Kanal 1 usw. Der Puffer muss mindestens numberOfFrames × numberOfChannels × Bytes pro Sample groß sein.
Da AudioData Speicher belegt, der oft außerhalb des JavaScript-Heaps liegt, solltest du jedes Objekt mit close() freigeben, sobald es nicht mehr gebraucht wird. Das gilt besonders für Schleifen und Streams.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $init Pflicht | Object | Konfigurationsobjekt mit den folgenden Eigenschaften. | |
| $init.format Pflicht | "u8"|"s16"|"s32"|"f32"|"u8-planar"|"s16-planar"|"s32-planar"|"f32-planar" | Sample-Format der Daten: Datentyp (vorzeichenlos 8 Bit, 16/32 Bit Ganzzahl, 32 Bit Gleitkomma) und Layout (interleaved oder planar). | |
| $init.sampleRate Pflicht | number | Abtastrate in Hz, z. B. 48000. Muss größer als 0 sein. |
|
| $init.numberOfFrames Pflicht | number | Anzahl der Frames (Samples pro Kanal). Muss größer als 0 sein. | |
| $init.numberOfChannels Pflicht | number | Anzahl der Audiokanäle, z. B. 1 (Mono) oder 2 (Stereo). |
|
| $init.timestamp Pflicht | number | Zeitstempel des ersten Frames in Mikrosekunden. | |
| $init.data Pflicht | ArrayBuffer|TypedArray|DataView | Die rohen Audio-Samples. Die Daten werden kopiert, sofern der Puffer nicht in transfer steht. |
|
| $init.transfer | ArrayBuffer[] | [] | Liste von ArrayBuffers, deren Besitz ohne Kopie an das AudioData-Objekt übergeht. Die Puffer werden dabei detached (unbrauchbar). |
Rückgabewert
AudioData-Objekt mit den Eigenschaften format, sampleRate, numberOfFrames, numberOfChannels, timestamp und duration (in Mikrosekunden).Beispiele
Stereo-Sinuston im Format f32-planar erzeugen
const sampleRate = 48000;
const numberOfFrames = 480; // 10 ms
const numberOfChannels = 2;
// Planar: erst alle Samples für links, dann alle für rechts
const samples = new Float32Array(numberOfFrames * numberOfChannels);
for (let i = 0; i < numberOfFrames; i++) {
const value = Math.sin(2 * Math.PI * 440 * (i / sampleRate)) * 0.5;
samples[i] = value; // Kanal 0
samples[numberOfFrames + i] = value; // Kanal 1
}
const audioData = new AudioData({
format: 'f32-planar',
sampleRate,
numberOfFrames,
numberOfChannels,
timestamp: 0,
data: samples,
});
console.log(audioData.format, audioData.numberOfFrames, audioData.duration);
audioData.close();
Interleaved 16-Bit-PCM ohne Kopie übergeben (transfer)
const pcm = new Int16Array(1024 * 2); // Stereo, L R L R ...
for (let i = 0; i < 1024; i++) {
const v = Math.round(Math.sin(i / 10) * 16000);
pcm[i * 2] = v; // links
pcm[i * 2 + 1] = -v; // rechts
}
const audioData = new AudioData({
format: 's16',
sampleRate: 44100,
numberOfFrames: 1024,
numberOfChannels: 2,
timestamp: 0,
data: pcm,
transfer: [pcm.buffer], // Puffer wird übernommen
});
console.log(pcm.byteLength); // Puffer ist jetzt detached
console.log(audioData.allocationSize({ planeIndex: 0 }));
audioData.close();
Mikrofon-ähnliche Blöcke mit AudioEncoder zu Opus kodieren
const sampleRate = 48000;
const frames = 960; // 20 ms pro Block
const chunks = [];
const encoder = new AudioEncoder({
output: (chunk) => chunks.push(chunk),
error: (e) => console.error('Encoder-Fehler:', e),
});
encoder.configure({ codec: 'opus', sampleRate, numberOfChannels: 1, bitrate: 64000 });
let timestamp = 0;
for (let block = 0; block < 50; block++) { // 1 Sekunde
const data = new Float32Array(frames).map(() => Math.random() * 0.1 - 0.05);
const audioData = new AudioData({
format: 'f32', sampleRate, numberOfFrames: frames,
numberOfChannels: 1, timestamp, data,
});
encoder.encode(audioData);
audioData.close(); // sofort freigeben – der Encoder hält eine eigene Referenz
timestamp += (frames / sampleRate) * 1_000_000;
}
await encoder.flush();
console.log(`${chunks.length} Opus-Pakete erzeugt`);