Signatur
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
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();
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);
}
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;
}
}
// Wichtig · Fallstricke
- Keyframe-Pflicht: Nach
flush()muss der nächstedecode()-Chunk vom Typ"key"sein. Sonst wird einDataErrorausgelöst. - Nicht bei jedem Chunk aufrufen:
flush()leert die Pipeline des Decoders und bremst die Hardware-Decodierung stark aus. Für die Flusskontrolle besserdecodeQueueSizeund das Eventdequeuenutzen. - Frames schließen: Ausgegebene
VideoFrame-Objekte müssen mitframe.close()freigegeben werden. Sonst kann der Decoder stehen bleiben, weil ihm die Frame-Puffer ausgehen, und dasflush()-Promise wird dann womöglich nie aufgelöst. - Abbruch:
reset()oderclose()lehnen alle offenenflush()-Promises mitAbortErrorab. - Kompatibilität: Die WebCodecs API gibt es nur in sicheren Kontexten (HTTPS), im Fenster und in Dedicated Workern. Vor der Nutzung mit
'VideoDecoder' in windowundVideoDecoder.isConfigSupported()prüfen.