Signatur
Beschreibung
Das Interface PictureInPictureWindow steht für das schwebende Fenster, in dem ein <video>-Element im Bild-im-Bild-Modus (Picture-in-Picture) läuft. Man erzeugt es nicht selbst: Der Browser liefert eine Instanz als Erfüllungswert des Promise von HTMLVideoElement.requestPictureInPicture(). Außerdem steht sie in den Events enterpictureinpicture und leavepictureinpicture unter event.pictureInPictureWindow bereit.
Das Objekt hat zwei schreibgeschützte Eigenschaften, width und height. Sie geben die aktuelle Größe des Fensters in CSS-Pixeln an. Ändert der Nutzer die Fenstergröße, löst das Objekt ein resize-Event aus. Das Event lässt sich per addEventListener("resize", …) oder über die Eigenschaft onresize abonnieren.
Typische Anwendung ist adaptives Streaming: Ist das Fenster klein, reicht eine geringere Videoauflösung. Das spart Bandbreite und Rechenleistung. Die Werte eignen sich auch für Statistiken oder dafür, Overlays an die Fenstergröße anzupassen.
Wird der Bild-im-Bild-Modus beendet, gilt das Fenster als geschlossen. width und height liefern dann 0, und es kommen keine resize-Events mehr.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $width | number | Schreibgeschützt. Aktuelle Breite des schwebenden Fensters in CSS-Pixeln. Ist das Fenster geschlossen, ist der Wert 0. |
|
| $height | number | Schreibgeschützt. Aktuelle Höhe des schwebenden Fensters in CSS-Pixeln. Ist das Fenster geschlossen, ist der Wert 0. |
|
| $onresize | ((event: Event) => void) | null | null | Handler-Eigenschaft für das resize-Event. Sie wird aufgerufen, wenn sich die Fenstergröße ändert. |
Beispiele
Instanz über requestPictureInPicture() erhalten
const video = document.querySelector('video');
const button = document.querySelector('#pip-button');
button.addEventListener('click', async () => {
try {
// Muss durch eine Nutzeraktion ausgelöst werden
const pipWindow = await video.requestPictureInPicture();
console.log(`PiP-Fenster: ${pipWindow.width}×${pipWindow.height}`);
} catch (err) {
console.error('Bild-im-Bild nicht möglich:', err.message);
}
});
Videoqualität beim resize-Event anpassen
const video = document.querySelector('video');
const chooseQuality = (width) =>
width < 320 ? '240p' : width < 640 ? '480p' : '720p';
const onPipResize = (event) => {
const { width, height } = event.target;
console.log(`Neue Größe: ${width}×${height} → ${chooseQuality(width)}`);
// hier z. B. player.setQuality(chooseQuality(width)) aufrufen
};
video.addEventListener('enterpictureinpicture', (event) => {
const pipWindow = event.pictureInPictureWindow;
pipWindow.addEventListener('resize', onPipResize);
});
video.addEventListener('leavepictureinpicture', (event) => {
// Listener aufräumen
event.pictureInPictureWindow.removeEventListener('resize', onPipResize);
});
onresize-Property und Feature-Erkennung
const video = document.querySelector('video');
if ('pictureInPictureEnabled' in document && document.pictureInPictureEnabled) {
video.addEventListener('enterpictureinpicture', ({ pictureInPictureWindow: win }) => {
win.onresize = () => {
console.log('Seitenverhältnis:', (win.width / win.height).toFixed(2));
};
});
} else {
console.log('Picture-in-Picture wird nicht unterstützt.');
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Chromium-basierte Browser (Chrome, Edge, Opera) und Safari unterstützen die API. Firefox hat zwar einen eigenen Bild-im-Bild-Knopf, implementiert die Web-API aber nicht. Deshalb vorher immer
document.pictureInPictureEnabledprüfen. requestPictureInPicture()muss durch eine Nutzeraktion ausgelöst werden, etwa einen Klick. Sonst wird das Promise mit einemNotAllowedErrorabgelehnt.- Man kann das Fenster nicht per Skript verschieben oder in der Größe ändern.
widthundheightsind schreibgeschützt. - Nach
leavepictureinpictureliefernwidthundheightden Wert0. Einmal geschlossene Fenster werden nicht wiederverwendet: Jeder neue Aufruf liefert eine neue Instanz. resize-Events können beim Ziehen sehr oft hintereinander feuern. Aufwendige Reaktionen, etwa ein Qualitätswechsel, sollten daher gedrosselt werden (Debounce).- Nicht verwechseln mit der Document Picture-in-Picture API (
documentPictureInPicture.requestWindow()). Diese liefert ein vollständigesWindow-Objekt mit beliebigem HTML-Inhalt.