Signatur
Beschreibung
Die schreibgeschützte Eigenschaft visibleRect des VideoFrame-Interfaces gibt ein DOMRectReadOnly zurück. Es beschreibt, welcher Ausschnitt der codierten Pixeldaten tatsächlich angezeigt werden soll. Die Koordinaten (x, y, width, height) beziehen sich auf das codierte Bild, dessen volle Größe über codedWidth/codedHeight bzw. codedRect angegeben wird.
Videocodecs arbeiten oft mit Blockgrößen (z. B. 16×16-Makroblöcke). Deshalb ist das codierte Bild häufig größer als das eigentliche Video, etwa 1920×1088 statt 1920×1080. Die überzähligen Zeilen und Spalten sind Füllpixel. visibleRect gibt an, welcher Bereich davon echter Bildinhalt ist.
Wofür man die Eigenschaft praktisch nutzt:
- Ausschnitt ermitteln vor dem Kopieren der Rohdaten mit
copyTo(). Ohne die Optionrectwird standardmäßig genauvisibleRectkopiert. - Zuschneiden ohne Kopie: Mit
new VideoFrame(frame, { visibleRect })entsteht ein neuer Frame, der auf dieselben Pixeldaten verweist, aber nur einen Teil davon zeigt. - Größen richtig berechnen, etwa für Canvas, Encoder-Konfiguration oder Pufferspeicher über
allocationSize().
Die Anzeigegröße (displayWidth/displayHeight) kann von visibleRect abweichen, zum Beispiel bei nicht-quadratischen Pixeln. visibleRect beschreibt immer den Ausschnitt in Pixeln des codierten Bildes, nicht die skalierte Darstellung.
Rückgabewert
x, y, width und height in Pixeln des codierten Bildes. Nach dem Aufruf von close() ist der Wert null.Beispiele
Sichtbaren Bereich eines Frames 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 });
const { x, y, width, height } = frame.visibleRect;
console.log(`sichtbar: ${width}x${height} ab (${x}, ${y})`);
console.log(`codiert: ${frame.codedWidth}x${frame.codedHeight}`);
frame.close();
console.log(frame.visibleRect); // nach close() nicht mehr verfügbar
Frame ohne Kopie zuschneiden (Crop)
const canvas = new OffscreenCanvas(640, 480);
canvas.getContext('2d').fillRect(0, 0, 640, 480);
const source = new VideoFrame(canvas, { timestamp: 0 });
// Mittleren Ausschnitt verwenden – dieselben Pixeldaten, anderer sichtbarer Bereich
const cropped = new VideoFrame(source, {
visibleRect: { x: 80, y: 60, width: 480, height: 360 }
});
const r = cropped.visibleRect;
console.log(r.x, r.y, r.width, r.height);
console.log(cropped.displayWidth, cropped.displayHeight);
source.close();
cropped.close();
Pixeldaten des sichtbaren Bereichs kopieren
const processFrame = async (frame) => {
const rect = frame.visibleRect;
// Puffergröße genau für den sichtbaren Bereich berechnen
const size = frame.allocationSize({ rect });
const buffer = new Uint8Array(size);
const layout = await frame.copyTo(buffer, { rect });
console.log(`Format ${frame.format}, ${rect.width}x${rect.height}, ${size} Bytes`);
console.log('Zeilenabstand:', layout[0].stride);
frame.close();
return buffer;
};
const canvas = new OffscreenCanvas(320, 240);
canvas.getContext('2d').fillRect(0, 0, 320, 240);
await processFrame(new VideoFrame(canvas, { timestamp: 0 }));
// Wichtig · Fallstricke
nullnachclose(): Wer nach dem Schließen aufvisibleRect.widthzugreift, bekommt einenTypeError. Benötigte Werte also vorher auslesen.- Nicht mit dem codierten Bereich verwechseln:
codedWidth/codedHeightkönnen größer sein, zum Beispiel 1088 statt 1080 Zeilen. Wer beim Kopieren von Rohdaten die codierte Größe verwendet, übernimmt auch die Füllpixel. - Ausrichtung beachten: Bei Formaten mit Farb-Unterabtastung wie
I420oderNV12müssen die Koordinaten eines eigenenvisibleRectzur Unterabtastung passen, also meist gerade Werte sein. Außerdem muss das Rechteck vollständig innerhalb voncodedRectliegen. Andernfalls wird einTypeErrorausgelöst. - Anzeigegröße kann abweichen: Für die Darstellung zählen
displayWidth/displayHeight, nichtvisibleRect. - Browser-Unterstützung: WebCodecs gibt es nur in sicheren Kontexten (HTTPS) und sowohl im Fenster als auch in Workern. Unterstützt wird es von Chromium-Browsern ab Version 94, von Firefox ab 130 und von Safari ab 16.4. Vor der Nutzung mit
'VideoFrame' in globalThisprüfen, ob die API vorhanden ist.