Signatur
Beschreibung
PictureInPictureEvent ist Teil der Picture-in-Picture-API. Der Browser erzeugt dieses Ereignisobjekt, wenn ein HTMLVideoElement in den Bild-im-Bild-Modus wechselt (enterpictureinpicture) oder ihn wieder verlässt (leavepictureinpicture). Die Schnittstelle erbt alle Eigenschaften und Methoden von Event.
Die einzige zusätzliche Eigenschaft ist pictureInPictureWindow: Sie verweist auf das PictureInPictureWindow-Objekt, das das schwebende Fenster repräsentiert. Darüber lassen sich die aktuelle Fenstergröße (width, height) auslesen und ein resize-Listener registrieren – etwa um die Videoqualität an die Fenstergröße anzupassen oder Nutzungsstatistiken zu erfassen.
Typische Einsatzfälle sind das Umschalten eigener Bedienelemente (z. B. einen „PiP beenden“-Button anzeigen), das Ausblenden des Inline-Players, solange das Video im PiP-Fenster läuft, sowie das Anpassen der Stream-Auflösung. Die Ereignisse lassen sich sowohl per addEventListener() als auch über die Eigenschaften onenterpictureinpicture und onleavepictureinpicture des Video-Elements abonnieren.
Einen eigenen Konstruktor gibt es zwar (new PictureInPictureEvent(type, options)), er ist aber nur für synthetische Ereignisse sinnvoll, da pictureInPictureWindow Pflicht ist und ein PictureInPictureWindow nur vom Browser erzeugt werden kann.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, z. B. "enterpictureinpicture" oder "leavepictureinpicture" (nur beim Konstruktor). |
|
| $options Pflicht | PictureInPictureEventInit | Initialisierungsobjekt. Enthält die Pflicht-Eigenschaft pictureInPictureWindow sowie optional die von EventInit geerbten Felder bubbles, cancelable und composed (jeweils Standard false). |
|
| $options.pictureInPictureWindow Pflicht | PictureInPictureWindow | Das PiP-Fenster, auf das sich das Ereignis bezieht. Später über event.pictureInPictureWindow lesbar (schreibgeschützt). |
Beispiele
PiP starten und auf enterpictureinpicture reagieren
const video = document.querySelector('video');
const button = document.querySelector('#pip-button');
video.addEventListener('enterpictureinpicture', (event) => {
const pipWindow = event.pictureInPictureWindow;
console.log(`PiP aktiv: ${pipWindow.width}×${pipWindow.height}`);
button.textContent = 'PiP beenden';
// Größenänderungen des schwebenden Fensters verfolgen
pipWindow.addEventListener('resize', () => {
console.log(`Neue Größe: ${pipWindow.width}×${pipWindow.height}`);
});
});
button.addEventListener('click', async () => {
try {
if (document.pictureInPictureElement) {
await document.exitPictureInPicture();
} else if (document.pictureInPictureEnabled) {
await video.requestPictureInPicture();
}
} catch (err) {
console.error('Picture-in-Picture fehlgeschlagen:', err);
}
});
leavepictureinpicture über die on-Property behandeln
const video = document.querySelector('video');
const button = document.querySelector('#pip-button');
video.onleavepictureinpicture = (event) => {
console.log(event.type, event instanceof PictureInPictureEvent);
button.textContent = 'Bild-im-Bild';
// Video nach dem Schließen des PiP-Fensters pausieren
video.pause();
};
Listener wieder entfernen
const video = document.querySelector('video');
const onEnter = (event) => {
console.log('PiP-Breite:', event.pictureInPictureWindow.width);
};
video.addEventListener('enterpictureinpicture', onEnter);
// Später, z. B. beim Abbau einer Komponente:
video.removeEventListener('enterpictureinpicture', onEnter);
// oder: video.onenterpictureinpicture = null;
Funktionsprüfung und synthetisches Ereignis
const video = document.querySelector('video');
if ('PictureInPictureEvent' in window) {
video.addEventListener('enterpictureinpicture', async () => {
// Ein vorhandenes PiP-Fenster wiederverwenden (nur für Tests sinnvoll)
const pipWindow = await video.requestPictureInPicture().catch(() => null);
}, { once: true });
// Synthetisches Ereignis benötigt ein echtes PictureInPictureWindow:
video.requestPictureInPicture().then((pipWindow) => {
const testEvent = new PictureInPictureEvent('test-pip', {
pictureInPictureWindow: pipWindow
});
console.log(testEvent.pictureInPictureWindow === pipWindow);
});
} else {
console.log('Picture-in-Picture-API wird nicht unterstützt');
}
// Wichtig · Fallstricke
- Browser-Kompatibilität: Chromium-Browser (Chrome, Edge, Opera) und Safari ab 13.1 unterstützen die API. Firefox bietet zwar eine eigene PiP-Schaltfläche, implementiert die Web-API aber nicht – dort gibt es weder
requestPictureInPicture()noch diese Ereignisse. Deshalb immer perdocument.pictureInPictureEnabledbzw.'PictureInPictureEvent' in windowprüfen. - Das
resize-Ereignis wird amPictureInPictureWindowausgelöst, nicht am Video-Element. Den Listener also überevent.pictureInPictureWindowregistrieren. - Nach
leavepictureinpictureist das Fenster geschlossen;widthundheightdes altenPictureInPictureWindowliefern dann0. requestPictureInPicture()braucht eine Nutzeraktion (z. B. einen Klick), sonst wird das Promise mitNotAllowedErrorabgelehnt. Auch das Attributdisablepictureinpictureoder eine Permissions-Policy können PiP verhindern.- Die Ereignisse steigen standardmäßig im DOM auf (
bubbles: true), lassen sich aber nicht abbrechen. - Nicht zu verwechseln mit der neueren Document Picture-in-Picture API (
documentPictureInPicture), die beliebige HTML-Inhalte in einem PiP-Fenster anzeigt und das EreignisDocumentPictureInPictureEventverwendet.