Signatur
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();
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 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');
}
// Wichtig · Fallstricke
- Browser-Kompatibilität:
rotationundflipsind relativ neue Ergänzungen der WebCodecs-Spezifikation und bisher vor allem in Chromium-Browsern verfügbar. Mit'rotation' in VideoFrame.prototypeprüfen. In älteren Browsern ist die Eigenschaftundefined, und die Option im Konstruktor wird stillschweigend ignoriert. - Nur Metadaten:
copyTo(),codedWidth/codedHeightundvisibleRectbeziehen sich auf die ungedrehten Rohpixel. Wer die Daten selbst verarbeitet (WebGL, WebGPU, WASM), muss die Drehung selbst anwenden. - Uneinheitliches Rendering: Ob
drawImage(),createImageBitmap()oderVideoEncoderdie 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.