Start · Sprachen · JavaScript · Referenz · OfflineAudioContext.resume()

OfflineAudioContext.resume()

Methode

Setzt das Offline-Rendering eines per <code>suspend()</code> angehaltenen <code>OfflineAudioContext</code> fort und gibt ein Promise zurück.

seit JavaScript Web Audio API; in allen modernen Browsern (Chrome, Kategorie: webapi

Signatur

OfflineAudioContext.prototype.resume()

Beschreibung

resume() setzt die Zeit in einem OfflineAudioContext fort, der zuvor mit suspend(suspendTime) angehalten wurde. Ein Offline-Kontext berechnet Audio so schnell wie möglich in einen Puffer, nicht in Echtzeit. Mit suspend() und resume() kannst du diese Berechnung an genau festgelegten Zeitpunkten anhalten. Dann kannst du den Audio-Graphen umbauen und das Rendering danach fortsetzen.

Typische Einsätze sind:

  • Graph ändern: an festen Stellen Knoten verbinden oder trennen und Parameter setzen, zum Beispiel Effekte umschalten oder Quellen hinzufügen.
  • Fortschritt anzeigen: in regelmäßigen Abständen anhalten, den Fortschritt melden und weiterrendern.
  • Dinge vorbereiten: teure Aufgaben wie das Dekodieren weiterer Dateien erledigen, bevor das Rendering weiterläuft.

Anders als bei AudioContext.resume() kann ein Offline-Kontext nur fortgesetzt werden, wenn das Rendering schon mit startRendering() gestartet wurde. Das Promise von resume() wird erfüllt, sobald der Kontext wieder rendert. Das eigentliche Ergebnis, also der fertige AudioBuffer, kommt weiterhin aus dem Promise von startRendering().

Rückgabewert

Typ
Promise<void>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald das Rendering weiterläuft. Es wird mit einem InvalidStateError (DOMException) abgelehnt, wenn das Rendering noch nicht gestartet wurde oder der Kontext bereits geschlossen ist bzw. fertig gerendert hat.

Beispiele

Frequenz an einem festen Zeitpunkt ändern

const ctx = new OfflineAudioContext({ numberOfChannels: 1, length: 44100 * 2, sampleRate: 44100 });

const osc = new OscillatorNode(ctx, { frequency: 440 });
osc.connect(ctx.destination);
osc.start();

// Anhalten bei 1 Sekunde vormerken – vor startRendering()!
ctx.suspend(1).then(async () => {
  console.log('Angehalten bei', ctx.currentTime.toFixed(3), 's');
  osc.frequency.value = 880; // Graph während der Pause ändern
  await ctx.resume();
  console.log('Rendering läuft weiter');
});

const buffer = await ctx.startRendering();
console.log('Fertig:', buffer.duration, 's');
Angehalten bei 1.000 s Rendering läuft weiter Fertig: 2 s

Fortschrittsanzeige beim Offline-Export

const renderWithProgress = async (ctx, step = 0.5, onProgress) => {
  const total = ctx.length / ctx.sampleRate;
  for (let t = step; t < total; t += step) {
    ctx.suspend(t).then(() => {
      onProgress(Math.round((ctx.currentTime / total) * 100));
      return ctx.resume();
    });
  }
  return ctx.startRendering();
};

const ctx = new OfflineAudioContext(2, 44100 * 2, 44100);
const osc = new OscillatorNode(ctx);
osc.connect(ctx.destination);
osc.start();

const result = await renderWithProgress(ctx, 0.5, (p) => console.log(`${p} %`));
console.log('Samples:', result.length);
25 % 50 % 75 % Samples: 88200

Fehler: resume() vor startRendering()

const ctx = new OfflineAudioContext(1, 44100, 44100);

try {
  await ctx.resume();
} catch (err) {
  console.log(err.name); // Rendering wurde noch nicht gestartet
}
InvalidStateError

// Wichtig · Fallstricke

  • Erst rendern, dann fortsetzen: Wenn du resume() vor startRendering() aufrufst, wird das Promise mit InvalidStateError abgelehnt. Nach dem Ende des Renderings passiert dasselbe.
  • suspend() vorher vormerken: Rufe suspend(time) in der Regel vor startRendering() auf. Weil das Offline-Rendering sehr schnell läuft, ist ein späterer Zeitpunkt sonst womöglich schon vorbei. Zeitpunkte, die kleiner als currentTime oder mindestens so groß wie die Gesamtdauer sind, werden abgelehnt.
  • Zeitpunkte werden gerundet: Die Pausenzeit wird auf ein Vielfaches des Render-Blocks gerundet (128 Frames). currentTime kann deshalb leicht vom angefragten Wert abweichen. Wenn zwei suspend()-Aufrufe auf denselben Block fallen, wird der zweite abgelehnt.
  • Vergessenes resume(): Ohne resume() bleibt der Kontext dauerhaft angehalten. Das Promise von startRendering() wird dann nie erfüllt.
  • Kompatibilität: Alte Safari-Versionen mit webkitOfflineAudioContext unterstützen suspend() und resume() nicht. Prüfe die Unterstützung bei Bedarf mit typeof ctx.resume === 'function'.