Start · Sprachen · JavaScript · Referenz · AudioContext.suspend()

AudioContext.suspend()

Methode

Hält den Zeitfortschritt eines <code>AudioContext</code> an, gibt die Audio-Hardware vorübergehend frei und senkt so CPU- und Akkuverbrauch.

seit JavaScript Baseline: alle modernen Browser (Chrome 41+, Firef Kategorie: webapi

Signatur

AudioContext.prototype.suspend()

Beschreibung

suspend() pausiert einen AudioContext vollständig: currentTime läuft nicht weiter, der Audio-Graph wird nicht mehr verarbeitet und der Browser kann die Verbindung zur Audio-Hardware freigeben. Die Methode gibt ein Promise zurück, das erfüllt wird, sobald der Kontext tatsächlich angehalten ist. Danach steht state auf "suspended" und es wird ein statechange-Ereignis ausgelöst.

Das ist sinnvoll, wenn eine Anwendung eine Zeit lang keinen Ton ausgibt, etwa ein Spiel im Pausenmenü, ein Synthesizer ohne gedrückte Tasten oder ein Tab im Hintergrund. Anders als beim Stummschalten über einen GainNode wird die Verarbeitung dabei wirklich gestoppt. Das spart Rechenleistung und Akku.

Mit AudioContext.resume() läuft der Kontext genau an der Stelle weiter, an der er angehalten wurde. Alle Knoten, Verbindungen und geplanten Ereignisse bleiben erhalten. Wer den Kontext endgültig beenden und alle Ressourcen freigeben will, verwendet stattdessen close().

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald der Kontext angehalten ist. Es wird mit einer InvalidStateError-DOMException abgelehnt, wenn der Kontext bereits geschlossen ist (state === "closed").

Beispiele

Wiedergabe per Button pausieren und fortsetzen

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

const button = document.querySelector('#toggle');

button.addEventListener('click', async () => {
  if (ctx.state === 'running') {
    await ctx.suspend();
    button.textContent = 'Fortsetzen';
  } else if (ctx.state === 'suspended') {
    await ctx.resume();
    button.textContent = 'Pause';
  }
  console.log('Status:', ctx.state);
});
Status: suspended Status: running

currentTime bleibt während der Pause stehen

const ctx = new AudioContext();
await ctx.resume(); // nach einer Nutzerinteraktion aufrufen

await new Promise((r) => setTimeout(r, 1000));
await ctx.suspend();
const t1 = ctx.currentTime;

await new Promise((r) => setTimeout(r, 2000));
const t2 = ctx.currentTime;

console.log(t1 === t2); // Zeit ist eingefroren
true

Kontext anhalten, wenn der Tab in den Hintergrund wechselt

const ctx = new AudioContext();

document.addEventListener('visibilitychange', async () => {
  try {
    if (document.hidden && ctx.state === 'running') {
      await ctx.suspend();
    } else if (!document.hidden && ctx.state === 'suspended') {
      await ctx.resume();
    }
  } catch (err) {
    console.error('Statuswechsel fehlgeschlagen:', err.name);
  }
});

ctx.addEventListener('statechange', () => {
  console.log('AudioContext-Status:', ctx.state);
});
AudioContext-Status: suspended

Fehlerbehandlung bei geschlossenem Kontext

const ctx = new AudioContext();
await ctx.close();

try {
  await ctx.suspend();
} catch (err) {
  console.log(err.name);
}
InvalidStateError

// Wichtig · Fallstricke

  • Autoplay-Regeln: Ohne vorherige Nutzerinteraktion starten Browser einen AudioContext oft schon im Zustand "suspended". Ein Aufruf von suspend() ist dann wirkungslos. Zum Starten muss resume() innerhalb eines Nutzerereignisses (z. B. click) aufgerufen werden.
  • Kein Unterschied für die Zeitplanung: Mit start(when) oder über AudioParam-Automation geplante Ereignisse orientieren sich an currentTime. Weil diese Zeit während der Pause stehen bleibt, verschieben sich die Ereignisse mit und gehen nicht verloren.
  • Nur auf AudioContext: OfflineAudioContext.suspend(suspendTime) ist eine andere Methode. Sie braucht einen Zeitparameter und hält das Offline-Rendering an einer bestimmten Stelle an.
  • Wettlaufsituationen: Schnell aufeinanderfolgende Aufrufe von suspend() und resume() werden nacheinander abgearbeitet. Den Wert von state sollte man deshalb erst nach dem await auswerten.
  • suspend() oder close(): suspend() gibt keine Knoten und keinen Speicher frei. Wird ein Kontext nicht mehr gebraucht, ist close() die richtige Wahl.
  • Ältere Safari-Versionen verwenden das Präfix webkitAudioContext.