Start · Sprachen · JavaScript · Referenz · PictureInPictureWindow

PictureInPictureWindow

Schnittstelle

Stellt das schwebende Bild-im-Bild-Videofenster dar. Über dieses Objekt lassen sich <code>width</code> und <code>height</code> auslesen und das <code>resize</code>-Event abonnieren.

seit JavaScript Chrome/Edge 70+, Safari 13.1+ (Firefox: nicht unte Kategorie: webapi

Signatur

interface PictureInPictureWindow extends EventTarget

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);
  }
});
PiP-Fenster: 400×225

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);
});
Neue Größe: 560×315 → 480p

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.');
}
Seitenverhältnis: 1.78

// 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.pictureInPictureEnabled prüfen.
  • requestPictureInPicture() muss durch eine Nutzeraktion ausgelöst werden, etwa einen Klick. Sonst wird das Promise mit einem NotAllowedError abgelehnt.
  • Man kann das Fenster nicht per Skript verschieben oder in der Größe ändern. width und height sind schreibgeschützt.
  • Nach leavepictureinpicture liefern width und height den Wert 0. 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ändiges Window-Objekt mit beliebigem HTML-Inhalt.