Start · Sprachen · JavaScript · Referenz · HTMLVideoElement.requestPictureInPicture()

HTMLVideoElement.requestPictureInPicture()

Methode

Fordert asynchron an, das Video in einem schwebenden Bild-in-Bild-Fenster anzuzeigen, und liefert ein Promise mit dem zugehörigen <code>PictureInPictureWindow</code>.

seit JavaScript Chrome 70, Edge 79, Safari 13.1, Opera 57; Firefox Kategorie: webapi

Signatur

HTMLVideoElement.prototype.requestPictureInPicture()

Beschreibung

Mit requestPictureInPicture() wird ein <video>-Element aus der Seite gelöst und in einem kleinen, immer im Vordergrund liegenden Fenster abgespielt. So können Nutzer ein Video weiterschauen, während sie in anderen Tabs oder Anwendungen arbeiten – typisch für Videoplattformen, Webinare, Videokonferenzen oder Tutorials.

Die Methode gibt ein Promise zurück, das mit einem PictureInPictureWindow-Objekt erfüllt wird. Über dessen Eigenschaften width und height sowie das Ereignis resize lässt sich auf die Größe des Fensters reagieren. Am Element selbst werden die Ereignisse enterpictureinpicture und leavepictureinpicture ausgelöst; das aktuell schwebende Element steht in document.pictureInPictureElement.

Der Aufruf erfordert eine transiente Nutzeraktivierung (z. B. innerhalb eines click-Handlers). Vorher sollte man mit document.pictureInPictureEnabled prüfen, ob die Funktion verfügbar ist, und das Attribut disablePictureInPicture des Videos beachten. Beendet wird der Modus mit document.exitPictureInPicture().

Rückgabewert

Typ
Promise<PictureInPictureWindow>
Beschreibung
Ein Promise, das mit dem PictureInPictureWindow erfüllt wird, sobald das Video im Bild-in-Bild-Modus ist. Es wird mit einer DOMException abgelehnt, wenn die Anfrage nicht erfüllt werden kann.

Beispiele

Bild-in-Bild per Button umschalten

const video = document.querySelector('#player');
const button = document.querySelector('#pip-button');

// Button nur anzeigen, wenn PiP möglich ist
button.hidden = !document.pictureInPictureEnabled || video.disablePictureInPicture;

button.addEventListener('click', async () => {
  try {
    if (document.pictureInPictureElement === video) {
      await document.exitPictureInPicture();
    } else {
      const pipWindow = await video.requestPictureInPicture();
      console.log(`PiP-Fenster: ${pipWindow.width}×${pipWindow.height}`);
    }
  } catch (err) {
    console.error('Bild-in-Bild fehlgeschlagen:', err.name, err.message);
  }
});
PiP-Fenster: 400×225

Auf Ein-/Austritt und Größenänderung reagieren

const video = document.querySelector('video');

video.addEventListener('enterpictureinpicture', (event) => {
  const pipWindow = event.pictureInPictureWindow;
  document.body.classList.add('pip-aktiv');

  const onResize = () => console.log('Neue Größe:', pipWindow.width, pipWindow.height);
  pipWindow.addEventListener('resize', onResize);

  video.addEventListener('leavepictureinpicture', () => {
    pipWindow.removeEventListener('resize', onResize);
    document.body.classList.remove('pip-aktiv');
    console.log('Bild-in-Bild beendet');
  }, { once: true });
});
Neue Größe: 480 270 Bild-in-Bild beendet

Beim Tab-Wechsel automatisch in PiP (nur mit vorheriger Nutzeraktion)

const video = document.querySelector('video');

// Nutzer startet das Video per Klick – dadurch ist PiP im selben Handler erlaubt
document.querySelector('#play').addEventListener('click', async () => {
  await video.play();
  if (document.pictureInPictureEnabled && !document.pictureInPictureElement) {
    await video.requestPictureInPicture().catch((err) => {
      console.warn('PiP nicht möglich:', err.name);
    });
  }
});

// Wichtig · Fallstricke

  • Nutzeraktivierung erforderlich: Ohne vorhergehende Nutzeraktion (Klick, Tastendruck) wird das Promise mit NotAllowedError abgelehnt. Ein await vor dem Aufruf (z. B. auf fetch) kann die Aktivierung verbrauchen bzw. ablaufen lassen.
  • Weitere Fehler: NotSupportedError, wenn die Funktion nicht unterstützt oder per disablePictureInPicture deaktiviert ist; InvalidStateError, wenn das Video noch keine Metadaten hat (readyState === HAVE_NOTHING) oder keine Videospur besitzt; SecurityError, wenn die Permissions Policy picture-in-picture den Zugriff (z. B. im iframe) verbietet.
  • Es kann immer nur ein Element gleichzeitig im PiP-Modus sein; ein neuer Aufruf ersetzt das bisherige Element.
  • Kompatibilität: Unterstützt in Chromium-Browsern und Safari. Firefox implementiert die API nicht, bietet aber eine eigene PiP-Schaltfläche an – daher stets per Feature-Erkennung ('pictureInPictureEnabled' in document) prüfen. Safari kennt zusätzlich das ältere webkitSetPresentationMode('picture-in-picture').
  • Für beliebige HTML-Inhalte (nicht nur Videos) gibt es die neuere Document Picture-in-Picture API (documentPictureInPicture.requestWindow()), bislang nur in Chromium.