Signatur
Beschreibung
clone() gehört zur WebCodecs API und liefert ein zweites AudioData-Objekt. Es verweist auf dieselbe interne Medienressource wie das Original. Die Audio-Samples werden also nicht kopiert, es entsteht nur ein weiterer Verweis auf denselben Speicher. Damit ist clone() sehr günstig und eignet sich für Echtzeit-Pipelines.
Die Methode braucht man vor allem, wenn ein AudioData-Frame an mehreren Stellen gebraucht wird, zum Beispiel für einen AudioEncoder und gleichzeitig für eine Pegelanzeige. Jeder Verbraucher bekommt seinen eigenen Klon und ruft nach der Arbeit close() auf. Die Ressource wird erst freigegeben, wenn alle Verweise geschlossen sind.
Metadaten wie format, sampleRate, numberOfFrames, numberOfChannels, duration und timestamp übernimmt der Klon unverändert vom Original.
Rückgabewert
AudioData-Objekt, das auf dieselbe Medienressource verweist wie das Original.Beispiele
AudioData erzeugen und klonen
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);
}
const original = new AudioData({
format: 'f32',
sampleRate,
numberOfFrames,
numberOfChannels: 1,
timestamp: 0,
data: samples
});
const copy = original.clone();
console.log(copy.sampleRate, copy.numberOfFrames, copy.timestamp);
// Beide Verweise schließen, damit der Speicher freigegeben wird
original.close();
copy.close();
Einen Frame an Encoder und Pegelanzeige verteilen
const encoder = new AudioEncoder({
output: (chunk) => console.log('Chunk:', chunk.byteLength, 'Bytes'),
error: (e) => console.error(e)
});
encoder.configure({ codec: 'opus', sampleRate: 48000, numberOfChannels: 1 });
const measureLevel = (audioData) => {
const buf = new Float32Array(audioData.numberOfFrames);
audioData.copyTo(buf, { planeIndex: 0 });
const peak = buf.reduce((max, v) => Math.max(max, Math.abs(v)), 0);
audioData.close(); // Klon freigeben
return peak;
};
const handleFrame = (audioData) => {
console.log('Pegel:', measureLevel(audioData.clone()).toFixed(2));
encoder.encode(audioData); // encode() liest die Daten synchron
audioData.close(); // danach kann das Original geschlossen werden
};
Verhalten nach close() des Originals
const data = new AudioData({
format: 'f32', sampleRate: 44100, numberOfFrames: 128,
numberOfChannels: 1, timestamp: 0, data: new Float32Array(128)
});
const clone = data.clone();
data.close();
console.log(data.format); // null – geschlossen
console.log(clone.format); // Klon ist weiter gültig
console.log(clone.numberOfFrames);
clone.close();
try {
data.clone();
} catch (e) {
console.log(e.name);
}
// Wichtig · Fallstricke
- Speicher freigeben: Jeder Klon muss mit
close()geschlossen werden. Die Medienressource bleibt so lange belegt, bis alle Verweise geschlossen sind. Werden Klone vergessen, wächst der Speicherverbrauch in Streams schnell an. - Geschlossene Objekte: Ruft man
clone()auf einem bereits geschlossenenAudioData-Objekt auf, wird eineInvalidStateError-DOMExceptiongeworfen. - Keine echte Kopie:
clone()dupliziert die Samples nicht. Um die Daten unabhängig weiterzuverarbeiten, kopiert man sie mitcopyTo()in einen eigenen Puffer. - Übertragen statt klonen: Beim Versand an einen Worker per
postMessage()kann man das Objekt in die Transfer-Liste aufnehmen. Dann ist vorher kein Klon nötig. - Kompatibilität: Die WebCodecs API ist nur in sicheren Kontexten (HTTPS) verfügbar.
AudioDatawird von Chromium-Browsern und Firefox unterstützt, von Safari aber nicht. Eine Funktionsprüfung wie'AudioData' in windowist sinnvoll. In Window und Dedicated Workers ist die Schnittstelle verfügbar.