Start · Sprachen · JavaScript · Referenz · VideoEncoder.close()

VideoEncoder.close()

Methode

Bricht alle ausstehenden Kodierungsaufträge sofort ab, gibt die Systemressourcen des Encoders frei und versetzt ihn endgültig in den Zustand <code>"closed"</code>.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Safari 16.4+, Fir Kategorie: webapi

Signatur

VideoEncoder.prototype.close()

Beschreibung

Die Methode close() beendet einen VideoEncoder endgültig. Alle Aufträge in der Warteschlange werden verworfen, eventuell noch laufende flush()-Promises werden mit einer AbortError-DOMException abgewiesen, und der zugrunde liegende Hardware- oder Software-Codec wird freigegeben. Danach steht encoder.state auf "closed".

Gerade bei Hardware-Encodern ist das wichtig: Die Zahl gleichzeitig nutzbarer Codec-Instanzen ist oft begrenzt. Wer Encoder nicht schließt, belegt GPU- bzw. Codec-Ressourcen, bis der Garbage Collector aufräumt – und wann das passiert, lässt sich nicht vorhersagen. Rufe close() deshalb auf, sobald die Aufnahme oder der Export beendet ist oder die Komponente entfernt wird.

Anders als reset() lässt sich ein geschlossener Encoder nicht wiederverwenden: Jeder weitere Aufruf von configure(), encode(), flush() oder reset() wirft eine InvalidStateError. Sollen alle bereits übergebenen Frames noch als EncodedVideoChunk ankommen, musst du vor close() erst await encoder.flush() aufrufen.

Beispiele

Aufnahme sauber beenden: erst flushen, dann schließen

const chunks = [];

const encoder = new VideoEncoder({
  output: (chunk) => chunks.push(chunk),
  error: (e) => console.error('Encoder-Fehler:', e)
});

encoder.configure({
  codec: 'vp8',
  width: 640,
  height: 480,
  bitrate: 1_000_000,
  framerate: 30
});

// Einen Test-Frame aus einem Canvas erzeugen
const canvas = new OffscreenCanvas(640, 480);
canvas.getContext('2d').fillRect(0, 0, 640, 480);
const frame = new VideoFrame(canvas, { timestamp: 0 });
encoder.encode(frame, { keyFrame: true });
frame.close();

// Alle ausstehenden Frames fertig kodieren lassen
await encoder.flush();
encoder.close();

console.log(encoder.state, chunks.length);
closed 1

Laufende Kodierung abbrechen – flush() wird abgewiesen

const encoder = new VideoEncoder({
  output: () => {},
  error: (e) => console.warn('error-Callback:', e.name)
});
encoder.configure({ codec: 'vp8', width: 320, height: 240 });

const canvas = new OffscreenCanvas(320, 240);
const frame = new VideoFrame(canvas, { timestamp: 0 });
encoder.encode(frame);
frame.close();

const pending = encoder.flush();
encoder.close(); // bricht sofort ab

try {
  await pending;
} catch (e) {
  console.log('flush abgebrochen:', e.name);
}
flush abgebrochen: AbortError

Aufräumen mit Zustandsprüfung (z. B. beim Entfernen einer Komponente)

const disposeEncoder = (encoder) => {
  // Doppeltes Schließen vermeiden
  if (encoder.state !== 'closed') {
    encoder.close();
  }
};

const encoder = new VideoEncoder({ output: () => {}, error: console.error });
disposeEncoder(encoder);
disposeEncoder(encoder); // harmlos dank Prüfung

try {
  encoder.configure({ codec: 'vp8', width: 320, height: 240 });
} catch (e) {
  console.log(e.name);
}
InvalidStateError

// Wichtig · Fallstricke

  • Datenverlust: close() wartet nicht auf ausstehende Frames. Rufe vorher await encoder.flush() auf, wenn alle Chunks ankommen sollen.
  • Endgültig: Ein geschlossener Encoder lässt sich nicht wieder öffnen. Nach close() werfen configure(), encode(), flush() und reset() eine InvalidStateError. Soll derselbe Encoder mit neuer Konfiguration weiterlaufen, nimm reset().
  • Doppelter Aufruf: Laut Spezifikation wirft auch ein zweiter Aufruf von close() eine InvalidStateError. Prüfe deshalb vorher encoder.state.
  • Ressourcen: Schließe auch deine VideoFrame-Objekte selbst mit frame.close() – VideoEncoder.close() gibt nur die Ressourcen des Encoders frei, nicht die übergebenen Frames.
  • Kompatibilität: Die WebCodecs API gibt es nur in sicheren Kontexten (HTTPS), sowohl im Fenster als auch in Dedicated Workern. Unterstützt wird sie in Chromium ab Version 94, in Safari ab 16.4 und in Firefox ab 130. Prüfe die Unterstützung mit 'VideoEncoder' in globalThis.