Start · Sprachen · JavaScript · Referenz · AudioData.clone()

AudioData.clone()

Methode

Erstellt ein neues <code>AudioData</code>-Objekt, das auf dieselbe Medienressource verweist wie das Original. Die Audiodaten werden dabei nicht kopiert.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Opera 80+, Firefo Kategorie: webapi

Signatur

AudioData.prototype.clone()

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

Typ
AudioData
Beschreibung
Ein neues 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();
48000 480 0

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
};
Pegel: 1.00 Chunk: … Bytes

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);
}
null f32 128 InvalidStateError

// 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 geschlossenen AudioData-Objekt auf, wird eine InvalidStateError-DOMException geworfen.
  • Keine echte Kopie: clone() dupliziert die Samples nicht. Um die Daten unabhängig weiterzuverarbeiten, kopiert man sie mit copyTo() 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. AudioData wird von Chromium-Browsern und Firefox unterstützt, von Safari aber nicht. Eine Funktionsprüfung wie 'AudioData' in window ist sinnvoll. In Window und Dedicated Workers ist die Schnittstelle verfügbar.