Start · Sprachen · JavaScript · Referenz · VideoFrame.rotation

VideoFrame.rotation

Eigenschaft

Schreibgeschützte Ganzzahl, die angibt, um wie viel Grad (0, 90, 180 oder 270, im Uhrzeigersinn) ein <code>VideoFrame</code> bei der Darstellung gedreht werden soll.

seit JavaScript WebCodecs-API; neu (Chromium-Browser ab ca. 2025), Kategorie: webapi

Signatur

VideoFrame.rotation

Beschreibung

Die Eigenschaft rotation des VideoFrame-Interfaces aus der WebCodecs-API liefert die Drehung, die beim Anzeigen des Frames angewendet werden soll. Der Wert ist immer einer von 0, 90, 180 oder 270 und wird in Grad im Uhrzeigersinn angegeben. Zusammen mit VideoFrame.flip beschreibt er die Ausrichtung des Bildes.

Solche Metadaten sind typisch für Smartphone-Aufnahmen: Die Kamera speichert die Pixel im Sensorformat und legt nur einen Drehhinweis ab, statt die Pixel selbst umzurechnen. Mit rotation kann dieser Hinweis durch eine Verarbeitungskette (Demuxer → VideoDecoder → Rendering/Encoding) weitergereicht werden, ohne dass die Pixeldaten neu berechnet werden müssen.

Gesetzt wird der Wert über die Option rotation im Konstruktor new VideoFrame(source, init) oder über rotation in der VideoDecoderConfig. Übergibt man einen Wert, der kein Vielfaches von 90 ist, rundet der Browser ihn auf das nächste Vielfache von 90 und normalisiert ihn in den Bereich 0–270 (z. B. -90 → 270, 450 → 90). Erzeugt man einen Frame aus einem anderen VideoFrame, wird die neue Drehung mit der bestehenden kombiniert.

Wichtig: Die Rohpixel (codedWidth, codedHeight, copyTo()) sind nicht gedreht. Wer die Pixeldaten selbst verarbeitet oder zeichnet, muss rotation und flip selbst berücksichtigen.

Beispiele

Rotation im Konstruktor setzen und auslesen

const canvas = new OffscreenCanvas(640, 480);
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'teal';
ctx.fillRect(0, 0, 640, 480);

const frame = new VideoFrame(canvas, {
  timestamp: 0,
  rotation: 90
});

console.log(frame.rotation);   // 90
console.log(frame.codedWidth, frame.codedHeight); // Rohpixel bleiben ungedreht

// Ungültige Werte werden normalisiert
const frame2 = new VideoFrame(frame, { timestamp: 0, rotation: -90 });
console.log(frame2.rotation);  // (90 + 270) % 360 = 0

frame.close();
frame2.close();
90 640 480 0

Drehhinweis beim Dekodieren übernehmen

// z. B. aus den Container-Metadaten (MP4 'tkhd'-Matrix) ermittelt
const rotationFromContainer = 270;

const decoder = new VideoDecoder({
  output: (frame) => {
    console.log(`Frame ${frame.timestamp}: rotation=${frame.rotation}, flip=${frame.flip}`);
    frame.close();
  },
  error: (e) => console.error(e)
});

decoder.configure({
  codec: 'avc1.42E01E',
  codedWidth: 1920,
  codedHeight: 1080,
  rotation: rotationFromContainer,
  flip: false
});
// Anschließend decoder.decode(chunk) für jeden EncodedVideoChunk aufrufen
Frame 0: rotation=270, flip=false

Frame manuell gedreht auf ein Canvas zeichnen

// Hilfsfunktion: zeichnet einen Frame unter Beachtung von rotation und flip
// (sinnvoll, wenn die Pixel selbst verarbeitet werden sollen)
const drawOriented = (ctx, frame) => {
  const w = frame.displayWidth;
  const h = frame.displayHeight;
  const quarter = frame.rotation === 90 || frame.rotation === 270;

  ctx.canvas.width = quarter ? h : w;
  ctx.canvas.height = quarter ? w : h;

  ctx.save();
  ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
  ctx.rotate((frame.rotation * Math.PI) / 180);
  if (frame.flip) ctx.scale(-1, 1);
  // Rohes Bild ohne automatische Orientierung zeichnen
  createImageBitmap(frame).then((bmp) => {
    ctx.drawImage(bmp, -w / 2, -h / 2, w, h);
    ctx.restore();
    bmp.close();
    frame.close();
  });
};

// Feature-Erkennung vor der Nutzung
if ('rotation' in VideoFrame.prototype) {
  console.log('VideoFrame.rotation wird unterstützt');
}
VideoFrame.rotation wird unterstützt

// Wichtig · Fallstricke

  • Browser-Kompatibilität: rotation und flip sind relativ neue Ergänzungen der WebCodecs-Spezifikation und bisher vor allem in Chromium-Browsern verfügbar. Mit 'rotation' in VideoFrame.prototype prüfen. In älteren Browsern ist die Eigenschaft undefined, und die Option im Konstruktor wird stillschweigend ignoriert.
  • Nur Metadaten: copyTo(), codedWidth/codedHeight und visibleRect beziehen sich auf die ungedrehten Rohpixel. Wer die Daten selbst verarbeitet (WebGL, WebGPU, WASM), muss die Drehung selbst anwenden.
  • Uneinheitliches Rendering: Ob drawImage(), createImageBitmap() oder VideoEncoder die Drehung automatisch anwenden, hängt vom Browser und dessen Version ab. Das Ergebnis immer testen.
  • Normalisierung: Werte, die kein Vielfaches von 90 sind, werden gerundet, negative Werte in den Bereich 0–270 umgerechnet. Bei new VideoFrame(otherFrame, { rotation }) wird die Drehung zur bestehenden addiert und nicht ersetzt.
  • Die Eigenschaft ist schreibgeschützt. Für eine andere Ausrichtung einen neuen Frame erzeugen und nicht mehr benötigte Frames mit close() freigeben, sonst droht ein Speicherleck.