Signatur
Beschreibung
Das dequeue-Ereignis eines VideoEncoder signalisiert, dass die interne Warteschlange ausstehender Kodieraufträge kleiner geworden ist. Der Wert von encodeQueueSize ist also gesunken. Den Handler registrierst du entweder mit addEventListener("dequeue", handler) oder über die Eigenschaft ondequeue.
Wichtig ist das Ereignis vor allem für die Gegendrucksteuerung (Backpressure): Statt encodeQueueSize ständig in einer Schleife oder mit setTimeout abzufragen, wartet die Anwendung auf dequeue und reicht erst dann neue VideoFrame-Objekte per encode() nach. So wächst die Warteschlange nicht grenzenlos, der Speicherverbrauch bleibt niedrig und die Latenz bei Echtzeit-Anwendungen wie WebRTC-ähnlichem Streaming oder Bildschirmaufnahmen bleibt klein.
Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften und wird nicht weitergereicht (bubbling). Der Browser kann mehrere Verringerungen zu einem einzigen Ereignis zusammenfassen. Lies deshalb im Handler immer den aktuellen Wert von encodeQueueSize aus, anstatt pro Ereignis genau einen freien Platz anzunehmen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "dequeue". |
|
| $handler Pflicht | (event: Event) => void | Callback, der bei jeder Verringerung der Warteschlange aufgerufen wird. Er bekommt ein einfaches Event-Objekt, dessen target der VideoEncoder ist. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal (zum Entfernen über einen AbortController). |
Rückgabewert
addEventListener hat keinen Rückgabewert. Der Handler selbst bekommt ein Event-Objekt.Beispiele
Warteschlange mit addEventListener beobachten
const encoder = new VideoEncoder({
output: (chunk) => console.log('Chunk:', chunk.type, chunk.byteLength),
error: (e) => console.error('Encoder-Fehler:', e)
});
encoder.configure({ codec: 'vp8', width: 640, height: 480, bitrate: 1_000_000, framerate: 30 });
encoder.addEventListener('dequeue', () => {
console.log('Warteschlange jetzt:', encoder.encodeQueueSize);
});
// Testframe 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();
Backpressure: nur kodieren, wenn Platz in der Warteschlange ist
const MAX_QUEUE = 2;
const waitForSpace = (encoder) =>
new Promise((resolve) => {
if (encoder.encodeQueueSize < MAX_QUEUE) return resolve();
const onDequeue = () => {
if (encoder.encodeQueueSize < MAX_QUEUE) {
encoder.removeEventListener('dequeue', onDequeue);
resolve();
}
};
encoder.addEventListener('dequeue', onDequeue);
});
const encodeStream = async (readable, encoder) => {
const reader = readable.getReader();
let count = 0;
while (true) {
const { value: frame, done } = await reader.read();
if (done) break;
await waitForSpace(encoder);
encoder.encode(frame, { keyFrame: count++ % 60 === 0 });
frame.close();
}
await encoder.flush();
};
// Nutzung, z. B. mit einer Kamera-Spur:
// const track = (await navigator.mediaDevices.getUserMedia({ video: true })).getVideoTracks()[0];
// const { readable } = new MediaStreamTrackProcessor({ track });
// await encodeStream(readable, encoder);
ondequeue-Eigenschaft setzen und wieder entfernen
const encoder = new VideoEncoder({
output: () => {},
error: console.error
});
encoder.ondequeue = () => {
console.log('dequeue, Größe:', encoder.encodeQueueSize);
};
// Später Handler abmelden
encoder.ondequeue = null;
// Wichtig · Fallstricke
- Ereignisse werden zusammengefasst: Nach einem
dequeuekönnen mehrere Plätze frei geworden sein. Werte deshalb immerencodeQueueSizeaus und zähle nicht die Ereignisse. dequeuebedeutet nicht, dass ein kodierter Chunk fertig ist. Fertige Daten kommen ausschließlich über denoutput-Callback.- Rufe
frame.close()nachencode()auf. Sonst bleiben die GPU- und Speicherressourcen des Frames belegt, egal wie gut die Warteschlange gesteuert wird. - Nach
reset()oderclose()sinkt die Warteschlange auf 0. Wartende Promises wie im Backpressure-Beispiel sollten diesen Fall berücksichtigen, damit sie nicht ewig hängen bleiben. - Kompatibilität: WebCodecs gibt es nur in sicheren Kontexten (HTTPS). Das
dequeue-Ereignis kam später dazu als die übrige API. Auf älteren Browsern bleibt nur das Abfragen vonencodeQueueSize. Prüfe die Unterstützung mit'ondequeue' in VideoEncoder.prototype.