Start · Sprachen · JavaScript · Referenz · VideoDecoder.decode()

VideoDecoder.decode()

Methode

Stellt ein kodiertes Videostück (<code>EncodedVideoChunk</code>) zur asynchronen Dekodierung in die Warteschlange des <code>VideoDecoder</code>.

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

Signatur

VideoDecoder.prototype.decode(chunk)

Beschreibung

decode() übergibt ein EncodedVideoChunk an den Decoder. Die Methode arbeitet asynchron: Sie kehrt sofort zurück, und der Chunk landet in der internen Warteschlange. Die fertigen Bilder bekommt man als VideoFrame-Objekte über den output-Callback, den man dem Konstruktor übergibt. Fehler beim Dekodieren kommen über den error-Callback an.

Vor dem ersten Aufruf muss der Decoder mit configure() eingerichtet sein, sein state muss also "configured" sein. Der erste Chunk nach configure() oder flush() muss ein Schlüsselbild sein (type: "key"). Andernfalls wirft die Methode einen DataError.

Die Eigenschaft decodeQueueSize zeigt an, wie viele Anfragen noch warten. Sinkt sie, wird das Ereignis dequeue ausgelöst. Damit kann man Gegendruck umsetzen (Backpressure), also nicht mehr Chunks einspeisen, als der Decoder schafft. Mit flush() wartet man darauf, dass alle ausstehenden Chunks verarbeitet sind, zum Beispiel am Ende eines Streams.

Typische Einsatzfälle: eigene Videoplayer, Echtzeit-Streaming über WebTransport oder WebRTC-Datenkanäle, Videobearbeitung im Browser und die Analyse einzelner Bilder aus MP4- oder WebM-Containern, die man vorher selbst zerlegt (demuxt).

Parameter

Name Typ Default Beschreibung
$chunk Pflicht EncodedVideoChunk Das kodierte Videostück mit type ("key" oder "delta"), timestamp (Mikrosekunden), optional duration und den Nutzdaten data.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Dekodierte Bilder kommen asynchron im output-Callback als VideoFrame an.

Beispiele

Decoder einrichten und Schlüsselbild dekodieren

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const decoder = new VideoDecoder({
  output: (frame) => {
    ctx.drawImage(frame, 0, 0);
    frame.close(); // Speicher sofort freigeben!
  },
  error: (e) => console.error('Dekodierfehler:', e.message)
});

decoder.configure({
  codec: 'avc1.42E01E', // H.264 Baseline
  codedWidth: 640,
  codedHeight: 480
});

// keyFrameData: ArrayBuffer aus einem Demuxer (z. B. mp4box.js)
const chunk = new EncodedVideoChunk({
  type: 'key',
  timestamp: 0,
  data: keyFrameData
});

decoder.decode(chunk);
console.log(decoder.decodeQueueSize);
1

Stream mit Backpressure dekodieren und am Ende flushen

const MAX_QUEUE = 10;

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

const decodeAll = async (decoder, chunks) => {
  for (const chunk of chunks) {
    // Nicht mehr einspeisen, als der Decoder verarbeiten kann
    while (decoder.decodeQueueSize >= MAX_QUEUE) {
      await waitForDequeue(decoder);
    }
    decoder.decode(chunk);
  }
  await decoder.flush(); // alle ausstehenden Frames ausgeben
  console.log('Alle Chunks dekodiert');
};
Alle Chunks dekodiert

Unterstützung prüfen und Fehler abfangen

const config = { codec: 'vp09.00.10.08', codedWidth: 1280, codedHeight: 720 };

const { supported } = await VideoDecoder.isConfigSupported(config);
if (!supported) throw new Error('Codec nicht unterstützt');

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

try {
  // Delta-Frame als erster Chunk ist unzulässig
  decoder.decode(new EncodedVideoChunk({ type: 'delta', timestamp: 0, data: new Uint8Array(8) }));
} catch (e) {
  console.log(e.name);
}
DataError

// Wichtig · Fallstricke

  • Ausnahmen: InvalidStateError, wenn state nicht "configured" ist (etwa vor configure() oder nach close()). DataError, wenn nach configure()/flush() zuerst kein Schlüsselbild kommt.
  • Speicher: Jedes ausgegebene VideoFrame muss mit frame.close() freigegeben werden. Sonst füllt sich der Speicher der GPU bzw. des Hardware-Decoders, und der Decoder kann blockieren.
  • Ein fehlerhafter Chunk wirft meist keine Ausnahme. Stattdessen wird der error-Callback aufgerufen und der Decoder geht in den Zustand "closed". Danach muss man eine neue Instanz erzeugen.
  • Die Reihenfolge der Ausgabe folgt der Anzeigereihenfolge (Presentation Order) und kann bei B-Frames von der Eingabereihenfolge abweichen.
  • Für H.264/HEVC im AVC-Format braucht man beim Konfigurieren den description-Eintrag (avcC). Sonst erwartet der Decoder Annex-B-Daten.
  • Kompatibilität: Nur in sicheren Kontexten (HTTPS) verfügbar, auch in Workern. Chromium ab 94, Safari ab 16.4, Firefox ab 130. Vor der Nutzung mit 'VideoDecoder' in window und VideoDecoder.isConfigSupported() prüfen.