Start · Sprachen · JavaScript · Referenz · VideoDecoder.flush()

VideoDecoder.flush()

Methode

Verarbeitet alle ausstehenden Decodier-Aufträge und gibt ein <code>Promise</code> zurück, das aufgelöst wird, sobald alle zugehörigen Frames ausgegeben wurden.

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

Signatur

VideoDecoder.prototype.flush()

Beschreibung

flush() zwingt einen VideoDecoder, alle bisher per decode() eingereihten Chunks vollständig zu verarbeiten. Das zurückgegebene Promise wird erst aufgelöst, wenn für alle diese Chunks der output-Callback aufgerufen wurde. Decoder halten intern oft Frames zurück, etwa wegen B-Frames und Umsortierung. Ohne flush() können deshalb die letzten Frames eines Streams „hängen bleiben“.

Typische Einsatzfälle:

  • Ende eines Streams oder einer Datei: Alle restlichen Frames sollen ausgegeben werden.
  • Vor einem Wechsel der Konfiguration: Zum Beispiel ein anderer Codec oder eine andere Auflösung über configure().
  • Beim Springen (Seeking): Den Decoder sauber leeren und danach mit einem neuen Keyframe weitermachen.

Nach einem flush() muss der nächste Chunk, der an decode() geht, ein Keyframe sein (type: "key"). Sonst meldet der Decoder einen Fehler. Die Methode ist ein Kontrollbefehl: Sie wird in die interne Befehlswarteschlange eingereiht und läuft der Reihe nach nach den vorher eingereihten decode()-Aufrufen ab.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined aufgelöst wird, sobald alle ausstehenden Decodier-Aufträge fertig sind und ihre Frames ausgegeben wurden. Es wird mit einem DOMException abgelehnt: mit InvalidStateError, wenn der Decoder nicht im Zustand "configured" ist, und mit AbortError, wenn vorher reset() oder close() aufgerufen wurde.

Beispiele

Letzte Frames am Stream-Ende ausgeben

const frames = [];

const decoder = new VideoDecoder({
  output: (frame) => {
    frames.push(frame.timestamp);
    frame.close(); // Speicher sofort freigeben
  },
  error: (e) => console.error('Decoder-Fehler:', e),
});

decoder.configure({ codec: 'avc1.42E01E', codedWidth: 640, codedHeight: 360 });

// encodedChunks: Array von EncodedVideoChunk-Objekten, z. B. aus einem MP4-Demuxer
for (const chunk of encodedChunks) {
  decoder.decode(chunk);
}

await decoder.flush();
console.log(`Alle ${frames.length} Frames decodiert`);
decoder.close();
Alle 300 Frames decodiert

Sauberes Springen (Seeking) mit Keyframe-Neustart

async function seekTo(decoder, chunks, targetTimestamp) {
  // Offene Aufträge abschließen und danach verwerfen
  await decoder.flush();

  // Letzten Keyframe vor dem Ziel suchen
  let start = 0;
  chunks.forEach((c, i) => {
    if (c.type === 'key' && c.timestamp <= targetTimestamp) start = i;
  });

  // Nach flush() MUSS ein Keyframe folgen
  for (let i = start; i < chunks.length && chunks[i].timestamp <= targetTimestamp; i++) {
    decoder.decode(chunks[i]);
  }
  await decoder.flush();
  console.log('Seek abgeschlossen bei', targetTimestamp);
}
Seek abgeschlossen bei 5000000

Fehlerbehandlung bei flush()

try {
  await decoder.flush();
} catch (err) {
  if (err.name === 'InvalidStateError') {
    console.warn('Decoder ist nicht konfiguriert oder bereits geschlossen');
  } else if (err.name === 'AbortError') {
    console.warn('flush() wurde durch reset() oder close() abgebrochen');
  } else {
    throw err;
  }
}
flush() wurde durch reset() oder close() abgebrochen

// Wichtig · Fallstricke

  • Keyframe-Pflicht: Nach flush() muss der nächste decode()-Chunk vom Typ "key" sein. Sonst wird ein DataError ausgelöst.
  • Nicht bei jedem Chunk aufrufen: flush() leert die Pipeline des Decoders und bremst die Hardware-Decodierung stark aus. Für die Flusskontrolle besser decodeQueueSize und das Event dequeue nutzen.
  • Frames schließen: Ausgegebene VideoFrame-Objekte müssen mit frame.close() freigegeben werden. Sonst kann der Decoder stehen bleiben, weil ihm die Frame-Puffer ausgehen, und das flush()-Promise wird dann womöglich nie aufgelöst.
  • Abbruch: reset() oder close() lehnen alle offenen flush()-Promises mit AbortError ab.
  • Kompatibilität: Die WebCodecs API gibt es nur in sicheren Kontexten (HTTPS), im Fenster und in Dedicated Workern. Vor der Nutzung mit 'VideoDecoder' in window und VideoDecoder.isConfigSupported() prüfen.