Start · Sprachen · JavaScript · Referenz · EncodedVideoChunk.type

EncodedVideoChunk.type

Eigenschaft

Schreibgeschützte Eigenschaft, die mit <code>"key"</code> oder <code>"delta"</code> angibt, ob ein kodierter Video-Chunk ein eigenständig dekodierbarer Schlüssel-Frame ist.

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

Signatur

EncodedVideoChunk.type

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 VideoDecoder muss nach configure() oder flush() 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

Typ
"key" | "delta"
Beschreibung
"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);
key key

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 });
Keyframe bei 0 µs, ... Bytes Keyframe bei 999990 µs, ... Bytes { keyCount: 2, deltaCount: 58 }

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 VideoDecoder nach configure() oder flush() zuerst einen "delta"-Chunk, wirft decode() einen DataError.
  • Der Typ muss zu den Daten passen: Der Browser prüft nicht, ob type zum 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 VideoEncoder erzwingst du einen Keyframe über encode(frame, { keyFrame: true }). Den ersten Frame kodiert der Encoder immer als Keyframe.
  • Schreibgeschützt: Eine Zuweisung an type wird ignoriert (im Strict Mode wirft sie einen TypeError).
  • 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 globalThis ab. Ältere Safari- und Firefox-Versionen kennen die API nicht.