Start · Sprachen · JavaScript · Referenz · VideoDecoder: dequeue

VideoDecoder: dequeue

Ereignis

Wird ausgelöst, sobald sich <code>VideoDecoder.decodeQueueSize</code> verringert, also ein Chunk die Warteschlange des Decoders verlassen hat.

seit JavaScript WebCodecs: Chrome/Edge 106+, Safari 17+, Firefox 1 Kategorie: webapi

Signatur

videoDecoder.addEventListener("dequeue", handler)

Beschreibung

Das Ereignis dequeue eines VideoDecoder wird ausgelöst, wenn die Zahl der wartenden Decodier-Anfragen (decodeQueueSize) sinkt. Das passiert, sobald der Decoder einen per decode() übergebenen EncodedVideoChunk aus seiner internen Warteschlange übernimmt.

Hauptsächlich braucht man es für Gegendruck (backpressure). Statt decodeQueueSize ständig per Timer abzufragen, speist die Anwendung erst dann neue Chunks ein, wenn der Decoder wieder Kapazität hat. Das hält den Speicherverbrauch niedrig und verhindert, dass beim Streamen oder Demuxen großer Dateien Tausende Chunks auf einmal in der Warteschlange landen.

Einen Handler registrieren Sie entweder mit addEventListener("dequeue", handler) oder über die Eigenschaft ondequeue. Das Ereignis ist ein einfaches Event ohne zusätzliche Daten und lässt sich nicht abbrechen. Den aktuellen Füllstand lesen Sie direkt aus decoder.decodeQueueSize.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, immer "dequeue".
$handler Pflicht (event: Event) => void Die Rückruffunktion. Sie erhält ein normales Event, dessen target der auslösende VideoDecoder ist.
$options boolean | AddEventListenerOptions false Optionale Angaben für addEventListener, etwa { once: true } oder { signal }.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Den neuen Füllstand lesen Sie im Handler über decoder.decodeQueueSize.

Beispiele

Warteschlange mit addEventListener beobachten

const decoder = new VideoDecoder({
  output: (frame) => {
    // Frame verarbeiten und danach unbedingt freigeben
    frame.close();
  },
  error: (e) => console.error('Decoder-Fehler:', e)
});

decoder.configure({ codec: 'vp8', codedWidth: 640, codedHeight: 480 });

decoder.addEventListener('dequeue', () => {
  console.log('Wartende Chunks:', decoder.decodeQueueSize);
});
Wartende Chunks: 2 Wartende Chunks: 1 Wartende Chunks: 0

Gegendruck: Chunks erst nachliefern, wenn Platz frei ist

const MAX_QUEUE = 10;

// chunks: Array von EncodedVideoChunk, z. B. aus einem Demuxer
const feedDecoder = (decoder, chunks) => {
  let index = 0;

  const pump = () => {
    while (index < chunks.length && decoder.decodeQueueSize < MAX_QUEUE) {
      decoder.decode(chunks[index++]);
    }
    if (index >= chunks.length) {
      decoder.removeEventListener('dequeue', pump);
      decoder.flush().then(() => console.log('Alle Chunks decodiert'));
    }
  };

  decoder.addEventListener('dequeue', pump);
  pump(); // erste Füllung anstoßen
};
Alle Chunks decodiert

Alternative über die Eigenschaft ondequeue

const decoder = new VideoDecoder({
  output: (frame) => frame.close(),
  error: console.error
});

decoder.ondequeue = () => {
  if (decoder.decodeQueueSize === 0) {
    console.log('Decoder-Warteschlange ist leer');
  }
};

// Später wieder abmelden:
// decoder.ondequeue = null;
Decoder-Warteschlange ist leer

Auf freien Platz als Promise warten

const waitForDequeue = (decoder) =>
  new Promise((resolve) =>
    decoder.addEventListener('dequeue', resolve, { once: true })
  );

const decodeAll = async (decoder, chunks) => {
  for (const chunk of chunks) {
    while (decoder.decodeQueueSize >= 5) {
      await waitForDequeue(decoder);
    }
    decoder.decode(chunk);
  }
  await decoder.flush();
};

// Wichtig · Fallstricke

  • Ereignisse werden zusammengefasst: Der Browser kann mehrere Verringerungen zu einem einzigen dequeue-Ereignis bündeln. Rechnen Sie also nicht mit einem Ereignis pro Chunk, sondern lesen Sie immer decodeQueueSize aus.
  • Das Ereignis sagt nur aus, dass der Decoder einen Chunk übernommen hat. Ein fertiges Frame ist damit noch nicht erzeugt, denn fertige Frames kommen über den output-Callback.
  • Geben Sie jedes VideoFrame mit frame.close() frei. Sonst kann der Decoder mangels Speicher hängen bleiben, und dequeue wird nicht mehr ausgelöst.
  • Nach reset() oder close() leert sich die Warteschlange ohne regulären Decodiervorgang. Entfernen Sie deshalb Listener sauber, etwa mit removeEventListener oder AbortSignal.
  • Kompatibilität: WebCodecs gibt es nur in sicheren Kontexten (HTTPS), im Fenster und in Dedicated Workern. Den VideoDecoder selbst gibt es in Chrome schon ab Version 94, das dequeue-Ereignis erst ab Chrome 106. Prüfen Sie vorher mit 'VideoDecoder' in self und 'ondequeue' in VideoDecoder.prototype, ob beides verfügbar ist.