Start · Sprachen · JavaScript · Referenz · AudioData.numberOfFrames

AudioData.numberOfFrames

Eigenschaft

Schreibgeschützte Eigenschaft, die die Anzahl der Frames (Samples pro Kanal) in einem <code>AudioData</code>-Objekt als Ganzzahl liefert.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Safari 26+ (teilw Kategorie: webapi

Signatur

AudioData.numberOfFrames

Beschreibung

AudioData.numberOfFrames gibt an, wie viele Frames ein AudioData-Objekt enthält. Ein Frame ist ein Zeitpunkt, an dem für jeden Kanal genau ein Sample vorliegt. Bei Stereo-Audio mit 1024 Frames gibt es also 1024 Samples pro Kanal, insgesamt 2048 Samples.

Die Eigenschaft wird vor allem gebraucht, um Puffergrößen für AudioData.prototype.copyTo() zu berechnen, die Dauer eines Audio-Blocks zu bestimmen (numberOfFrames / sampleRate) oder decodierte Blöcke aus einem AudioDecoder weiterzuverarbeiten, z. B. in einem AudioBuffer für die Web Audio API.

Der Wert wird beim Erzeugen des Objekts festgelegt (über das Init-Feld numberOfFrames des Konstruktors oder durch den Decoder). Nach dem Aufruf von close() liefert die Eigenschaft 0.

Rückgabewert

Typ
number
Beschreibung
Eine nicht-negative Ganzzahl (unsigned long) mit der Anzahl der Frames. Nach close() ist der Wert 0.

Beispiele

AudioData erzeugen und Frames auslesen

const sampleRate = 48000;
const numberOfChannels = 2;
const numberOfFrames = 1024;

// Planar-Float32: alle Samples von Kanal 0, danach Kanal 1
const samples = new Float32Array(numberOfFrames * numberOfChannels);

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

console.log(audioData.numberOfFrames);
console.log(`Dauer: ${(audioData.numberOfFrames / audioData.sampleRate * 1000).toFixed(2)} ms`);

audioData.close();
console.log(audioData.numberOfFrames);
1024 Dauer: 21.33 ms 0

Puffergröße für copyTo() berechnen

const copyChannel = (audioData, planeIndex) => {
  // Bei planaren Formaten enthält jede Ebene numberOfFrames Samples
  const size = audioData.allocationSize({ planeIndex, format: 'f32-planar' });
  const buffer = new Float32Array(size / Float32Array.BYTES_PER_ELEMENT);
  audioData.copyTo(buffer, { planeIndex, format: 'f32-planar' });
  console.log(buffer.length === audioData.numberOfFrames);
  return buffer;
};

const data = new AudioData({
  format: 'f32-planar', sampleRate: 44100, numberOfChannels: 1,
  numberOfFrames: 512, timestamp: 0, data: new Float32Array(512),
});
const left = copyChannel(data, 0);
data.close();
true

Decodierte Blöcke in einen AudioBuffer übertragen

const ctx = new AudioContext();

const decoder = new AudioDecoder({
  output: (audioData) => {
    const buffer = ctx.createBuffer(
      audioData.numberOfChannels,
      audioData.numberOfFrames,
      audioData.sampleRate
    );
    for (let ch = 0; ch < audioData.numberOfChannels; ch++) {
      const channel = new Float32Array(audioData.numberOfFrames);
      audioData.copyTo(channel, { planeIndex: ch, format: 'f32-planar' });
      buffer.copyToChannel(channel, ch);
    }
    audioData.close(); // Ressourcen sofort freigeben

    const source = ctx.createBufferSource();
    source.buffer = buffer;
    source.connect(ctx.destination);
    source.start();
  },
  error: (e) => console.error('Decoder-Fehler:', e),
});

decoder.configure({ codec: 'opus', sampleRate: 48000, numberOfChannels: 2 });

// Wichtig · Fallstricke

  • Frames ≠ Samples: numberOfFrames zählt Samples pro Kanal. Bei interleaved-Formaten (z. B. 'f32') enthält der Puffer numberOfFrames * numberOfChannels Werte – Größen daher immer über allocationSize() ermitteln.
  • Nach close() liefert die Eigenschaft 0; Werte, die man später noch braucht, vorher speichern.
  • Die Eigenschaft ist schreibgeschützt; Zuweisungen werden ignoriert (im Strict Mode TypeError).
  • Wer die Dauer braucht, kann alternativ AudioData.duration (Mikrosekunden) nutzen.
  • Kompatibilität: Die WebCodecs API ist nur in sicheren Kontexten (HTTPS) verfügbar und wird nicht von allen Browsern vollständig unterstützt – vorher mit 'AudioData' in globalThis prüfen. Auch in Dedicated Workers verfügbar.