Start · Sprachen · JavaScript · Referenz · OfflineAudioCompletionEvent.renderedBuffer

OfflineAudioCompletionEvent.renderedBuffer

Eigenschaft

Schreibgeschützte Eigenschaft, die den <code>AudioBuffer</code> mit dem fertig gerenderten Audio eines <code>OfflineAudioContext</code> enthält.

seit JavaScript Baseline: alle modernen Browser (Web Audio API) Kategorie: webapi

Signatur

OfflineAudioCompletionEvent.renderedBuffer

Beschreibung

Die Eigenschaft renderedBuffer des OfflineAudioCompletionEvent liefert einen AudioBuffer mit dem Ergebnis des Offline-Renderings. Das Event (Typ complete) wird am OfflineAudioContext ausgelöst, sobald startRendering() den gesamten Audiograph bis zur festgelegten Länge durchgerechnet hat.

Ein OfflineAudioContext gibt nichts über die Lautsprecher aus, sondern rendert so schnell wie möglich in den Speicher. Gebraucht wird das z. B. zum Exportieren von Audio (etwa als WAV), zum Vorberechnen von Effekten, zum Erzeugen von Wellenform-Vorschauen oder für eine Analyse ohne Echtzeitwiedergabe.

Der zurückgegebene Puffer hat genau die Kanalanzahl, Länge (in Sample-Frames) und Abtastrate, die du im Konstruktor des OfflineAudioContext angegeben hast. Du kannst ihn direkt in einem AudioBufferSourceNode eines normalen AudioContext abspielen oder mit getChannelData() die Rohdaten auslesen.

In modernem Code wird meist das Promise von startRendering() genutzt, das denselben AudioBuffer liefert. Die Event-Variante mit oncomplete bzw. addEventListener("complete", …) ist aber weiterhin gültig und für älteren Code wichtig.

Rückgabewert

Typ
AudioBuffer
Beschreibung
Der gerenderte Audiopuffer mit den Eigenschaften numberOfChannels, length, sampleRate und duration entsprechend der Konfiguration des OfflineAudioContext.

Beispiele

Oszillator offline rendern und über das complete-Event auslesen

// 2 Sekunden Stereo bei 44,1 kHz
const offlineCtx = new OfflineAudioContext(2, 44100 * 2, 44100);

const osc = offlineCtx.createOscillator();
osc.frequency.value = 440;
osc.connect(offlineCtx.destination);
osc.start();

offlineCtx.addEventListener('complete', (event) => {
  const buffer = event.renderedBuffer;
  console.log(buffer.numberOfChannels, buffer.length, buffer.sampleRate, buffer.duration);
});

offlineCtx.startRendering();
2 88200 44100 2

Gerendertes Ergebnis in einem normalen AudioContext abspielen (oncomplete)

const liveCtx = new AudioContext();
const offlineCtx = new OfflineAudioContext(1, 44100, 44100);

const osc = offlineCtx.createOscillator();
const gain = offlineCtx.createGain();
gain.gain.setValueAtTime(1, 0);
gain.gain.linearRampToValueAtTime(0, 1); // Ausblenden über 1 s
osc.connect(gain).connect(offlineCtx.destination);
osc.start();

offlineCtx.oncomplete = ({ renderedBuffer }) => {
  const source = liveCtx.createBufferSource();
  source.buffer = renderedBuffer;
  source.connect(liveCtx.destination);
  source.start(); // muss nach einer Nutzerinteraktion erfolgen
};

offlineCtx.startRendering();

Spitzenpegel des gerenderten Puffers analysieren

const analysePeak = async (audioData) => {
  const decodeCtx = new AudioContext();
  const decoded = await decodeCtx.decodeAudioData(audioData);

  const offlineCtx = new OfflineAudioContext(
    decoded.numberOfChannels, decoded.length, decoded.sampleRate
  );
  const src = offlineCtx.createBufferSource();
  src.buffer = decoded;
  src.connect(offlineCtx.destination);
  src.start();

  return new Promise((resolve) => {
    offlineCtx.oncomplete = (event) => {
      const samples = event.renderedBuffer.getChannelData(0);
      let peak = 0;
      for (const s of samples) peak = Math.max(peak, Math.abs(s));
      resolve(peak);
    };
    offlineCtx.startRendering();
  });
};

const response = await fetch('/audio/sample.mp3');
console.log('Peak:', await analysePeak(await response.arrayBuffer()));
Peak: 0.98 (Beispielwert)

// Wichtig · Fallstricke

  • Schreibgeschützt: Die Eigenschaft selbst lässt sich nicht neu zuweisen. Die Sample-Daten des Puffers (über getChannelData()) kannst du aber verändern.
  • Promise statt Event: startRendering() gibt in modernen Browsern ein Promise<AudioBuffer> zurück. Das complete-Event wird trotzdem ausgelöst. Wenn du beides nutzt, landet dasselbe Ergebnis in zwei Handlern.
  • Nur einmal rendern: Ein OfflineAudioContext kann nur einmal gerendert werden. Ein zweiter Aufruf von startRendering() führt zu einem InvalidStateError.
  • Speicherbedarf: Lange Aufnahmen mit vielen Kanälen verbrauchen viel Speicher. Die Größe beträgt ungefähr Kanäle × Länge × 4 Byte (Float32). Zehn Minuten Stereo bei 48 kHz sind etwa 230 MB.
  • Stille: Wenn keine Quelle gestartet oder nichts mit destination verbunden wurde, enthält der Puffer nur Nullen.
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt. Ältere Safari-Versionen brauchten das Präfix webkitOfflineAudioContext und kannten die Promise-Variante nicht. Dort ist das Event der einzige Weg an das Ergebnis.