Start · Sprachen · JavaScript · Referenz · VideoFrame.format

VideoFrame.format

Eigenschaft

Gibt das Pixelformat eines <code>VideoFrame</code> als Zeichenkette zurück (z. B. <code>"I420"</code>, <code>"NV12"</code>, <code>"RGBA"</code>). Ist das Format nicht bekannt oder das Frame geschlossen, ist der Wert <code>null</code>.

seit JavaScript WebCodecs API: Chrome/Edge 94+, Firefox 130+, Safa Kategorie: webapi

Signatur

get VideoFrame.prototype.format

Beschreibung

Die schreibgeschützte Eigenschaft format der Schnittstelle VideoFrame aus der WebCodecs API gibt an, wie die Pixeldaten des Frames im Speicher angeordnet sind. Der Wert ist ein VideoPixelFormat-String, z. B. "I420" (planares YUV 4:2:0), "NV12" (YUV 4:2:0 mit verschachtelter UV-Ebene), "I444", "RGBA", "RGBX", "BGRA" oder "BGRX". Neuere Browser kennen außerdem Varianten mit höherer Bittiefe wie "I420P10" oder "I420AP10".

Das Format braucht man vor allem, wenn man mit VideoFrame.prototype.copyTo() auf die Rohdaten zugreift. Es legt fest, wie viele Ebenen (Planes) es gibt, wie sie angeordnet sind und wie man die Bytes deuten muss. Ein "I420"-Frame hat zum Beispiel drei Ebenen (Y, U, V), während "RGBA" nur eine Ebene mit 4 Bytes pro Pixel hat. Wer eigene Filter, Encoder-Pipelines oder WebGL/WebGPU-Uploads schreibt, muss je nach Format unterschiedlich verarbeiten.

Der Wert ist null, wenn der Browser das Format nicht offenlegt. Das kommt z. B. bei manchen GPU-gestützten Frames aus Hardware-Decodern vor. Auch nach dem Aufruf von close() ist der Wert null. In beiden Fällen kann man das Frame oft trotzdem mit drawImage() auf ein Canvas zeichnen, aber nicht zuverlässig byteweise auslesen.

Rückgabewert

Typ
string | null
Beschreibung
Ein VideoPixelFormat-String wie "I420", "I420A", "I422", "I444", "NV12", "RGBA", "RGBX", "BGRA" oder "BGRX" (sowie Varianten mit höherer Bittiefe). null, wenn das Format nicht bekannt ist oder das Frame geschlossen wurde.

Beispiele

Format eines selbst erzeugten RGBA-Frames prüfen

const width = 4;
const height = 2;
// 4 Bytes pro Pixel (R, G, B, A) – alles rot
const data = new Uint8Array(width * height * 4);
for (let i = 0; i < data.length; i += 4) {
  data[i] = 255;     // R
  data[i + 3] = 255; // A
}

const frame = new VideoFrame(data, {
  format: 'RGBA',
  codedWidth: width,
  codedHeight: height,
  timestamp: 0
});

console.log(frame.format);
frame.close();
console.log(frame.format);
RGBA null

Decoder-Ausgabe je nach Format verarbeiten

const handleFrame = async (frame) => {
  switch (frame.format) {
    case 'I420':
    case 'NV12': {
      // YUV-Daten: mehrere Ebenen
      const buffer = new Uint8Array(frame.allocationSize());
      const layout = await frame.copyTo(buffer);
      console.log(`${frame.format}: ${layout.length} Ebenen`, layout);
      break;
    }
    case 'RGBA':
    case 'BGRA': {
      const buffer = new Uint8Array(frame.allocationSize());
      await frame.copyTo(buffer);
      console.log(`${frame.format}: ${buffer.length} Bytes`);
      break;
    }
    case null:
      // z. B. GPU-Frame: nur zeichnen, nicht byteweise lesen
      console.log('Format unbekannt – Ausgabe über Canvas');
      break;
    default:
      console.log('Nicht unterstütztes Format:', frame.format);
  }
  frame.close();
};

const decoder = new VideoDecoder({
  output: handleFrame,
  error: (e) => console.error('Decoder-Fehler:', e)
});
I420: 3 Ebenen [{offset: 0, stride: 640}, {offset: 307200, stride: 320}, {offset: 384000, stride: 320}]

Frame aus einem Canvas erzeugen und Format ausgeben

const canvas = new OffscreenCanvas(320, 240);
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'steelblue';
ctx.fillRect(0, 0, 320, 240);

const frame = new VideoFrame(canvas, { timestamp: 0 });
// Je nach Browser/Plattform z. B. "RGBA", "BGRA" oder "RGBX"
console.log('Pixelformat:', frame.format);
console.log('Größe:', frame.codedWidth, 'x', frame.codedHeight);
frame.close();
Pixelformat: BGRA Größe: 320 x 240

// Wichtig · Fallstricke

  • Auf null prüfen: Hardware-dekodierte oder GPU-gestützte Frames können null liefern. Schreibe Code, der Rohdaten ausliest, immer mit einem Ausweichweg, z. B. Zeichnen auf ein Canvas.
  • Das Format hängt von der Plattform ab: Aus demselben Canvas oder Video kann je nach Browser, Betriebssystem und GPU "RGBA", "BGRA" oder "RGBX" entstehen. Verlasse dich nicht auf einen festen Wert.
  • Nach close() ist format immer null. Lies den Wert also vorher aus.
  • Umwandeln statt selbst rechnen: Neuere Chromium-Versionen können beim Kopieren das Format wechseln, z. B. mit copyTo(buffer, { format: 'RGBA' }). Das wird nicht überall unterstützt, deshalb vorher testen.
  • Kompatibilität: Die WebCodecs API gibt es nur in sicheren Kontexten (HTTPS) und in Window- und Worker-Kontexten. Die Unterstützung in Safari ist teilweise eingeschränkt. Formate mit hoher Bittiefe (…P10, …P12) sind noch nicht überall verfügbar.
  • Die Eigenschaft ist schreibgeschützt. Das Format legt man beim Erzeugen über die Option format im Konstruktor new VideoFrame(data, init) fest.