Signatur
Beschreibung
Die Eigenschaft type eines EncodedVideoChunk gibt einen String zurück, der den Frame-Typ beschreibt. "key" steht für einen Schlüssel-Chunk (Keyframe bzw. I-Frame), der ohne Bezug auf andere Frames dekodiert werden kann. "delta" steht für einen Delta-Chunk, der nur die Unterschiede zu vorherigen (oder anderen) Frames enthält. Er lässt sich also nur dekodieren, wenn die Frames, auf die er sich bezieht, vorher dekodiert wurden.
Den Wert legst du beim Erzeugen über den Konstruktor new EncodedVideoChunk({ type, timestamp, data, ... }) fest. Bei Chunks aus einem VideoEncoder setzt ihn der Encoder. Danach lässt er sich nicht mehr ändern.
In der Praxis brauchst du type vor allem in diesen Fällen:
- Dekodierung starten: Ein
VideoDecodermuss nachconfigure()oderflush()zuerst einen"key"-Chunk bekommen. - Muxing: Beim Schreiben in Container wie MP4 oder WebM müssen Keyframes als Sync-Samples markiert werden.
- Streaming: Bei Live-Übertragungen und nach Paketverlust kann der Empfänger erst ab dem nächsten Keyframe wieder sauber einsteigen.
Rückgabewert
"key", wenn der Chunk eigenständig dekodierbar ist, sonst "delta".Beispiele
Chunk manuell erzeugen und Typ auslesen
// Beispiel-Daten, z. B. aus einem Demuxer (hier nur ein Platzhalter)
const data = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x65]);
const chunk = new EncodedVideoChunk({
type: 'key',
timestamp: 0, // Mikrosekunden
duration: 33333,
data
});
console.log(chunk.type); // "key"
chunk.type = 'delta'; // wird ignoriert (schreibgeschützt)
console.log(chunk.type);
Keyframes beim Kodieren zählen
let keyCount = 0;
let deltaCount = 0;
const encoder = new VideoEncoder({
output: (chunk, metadata) => {
if (chunk.type === 'key') {
keyCount++;
console.log(`Keyframe bei ${chunk.timestamp} µs, ${chunk.byteLength} Bytes`);
} else {
deltaCount++;
}
},
error: (e) => console.error(e)
});
encoder.configure({ codec: 'vp8', width: 640, height: 480 });
const canvas = new OffscreenCanvas(640, 480);
const ctx = canvas.getContext('2d');
for (let i = 0; i < 60; i++) {
ctx.fillStyle = `hsl(${i * 6}, 80%, 50%)`;
ctx.fillRect(0, 0, 640, 480);
const frame = new VideoFrame(canvas, { timestamp: i * 33333 });
// Jeden 30. Frame als Keyframe erzwingen
encoder.encode(frame, { keyFrame: i % 30 === 0 });
frame.close();
}
await encoder.flush();
console.log({ keyCount, deltaCount });
Decoder erst ab dem ersten Keyframe füttern
const decoder = new VideoDecoder({
output: (frame) => { /* rendern */ frame.close(); },
error: (e) => console.error('Dekodierfehler:', e)
});
decoder.configure({ codec: 'vp8', codedWidth: 640, codedHeight: 480 });
let waitingForKey = true;
// Wird z. B. für jedes Paket aus einem WebSocket-Stream aufgerufen
const onChunkReceived = (chunk) => {
if (waitingForKey) {
if (chunk.type !== 'key') return; // Delta-Chunks verwerfen
waitingForKey = false;
}
decoder.decode(chunk);
};
// Nach Paketverlust: wieder auf Keyframe warten
const onPacketLoss = () => { waitingForKey = true; };
// Wichtig · Fallstricke
- Erster Chunk muss ein Keyframe sein: Gibst du einem
VideoDecodernachconfigure()oderflush()zuerst einen"delta"-Chunk, wirftdecode()einenDataError. - Der Typ muss zu den Daten passen: Der Browser prüft nicht, ob
typezum tatsächlichen Bitstrom passt. Ein falsch als"key"markierter Delta-Frame führt zu Bildfehlern oder Dekodierfehlern. Übernimm den Wert deshalb zuverlässig aus dem Container, etwa aus dem Sync-Sample-Flag bei MP4 oder dem Keyframe-Flag bei WebM. - Keyframes anfordern: Beim
VideoEncodererzwingst du einen Keyframe überencode(frame, { keyFrame: true }). Den ersten Frame kodiert der Encoder immer als Keyframe. - Schreibgeschützt: Eine Zuweisung an
typewird ignoriert (im Strict Mode wirft sie einenTypeError). - Kompatibilität: Die WebCodecs API steht nur in sicheren Kontexten (HTTPS) zur Verfügung, auch in Workern. Frag die Unterstützung vorher mit
'EncodedVideoChunk' in globalThisab. Ältere Safari- und Firefox-Versionen kennen die API nicht.