Mit der Document Picture-in-Picture API lässt sich ein Fenster öffnen, das immer im Vordergrund angezeigt wird und mit beliebigem HTML-Inhalt gefüllt werden kann. Sie erweitert die vorhandene Picture-in-Picture API für <video>, mit der nur ein HTML <video> Element in ein Bild-im-Bild-Fenster (PiP) eingefügt werden kann.
Das Bild-im-Bild-Fenster in der Document Picture-in-Picture API ähnelt
einem leeren Fenster mit derselben Quelle, das mit window.open() geöffnet wird. Es gibt jedoch einige Unterschiede:
- Das Bild-im-Bild-Fenster wird über anderen Fenstern angezeigt.
- Das Bild-im-Bild-Fenster ist nie länger geöffnet als das Fenster, in dem es geöffnet wurde.
- Das Bild-im-Bild-Fenster kann nicht navigiert werden.
- Die Position des Bild-im-Bild-Fensters kann nicht von der Website festgelegt werden.
Status
| Schritt | Status |
|---|---|
| 1. Erläuterung erstellen | Abgeschlossen |
| 2. Ersten Entwurf der Spezifikation erstellen | In Bearbeitung |
| 3. Feedback einholen und Design optimieren | In Bearbeitung |
| 4. Ursprungstest | Abgeschlossen |
| 5. Starten | Abgeschlossen (Desktop) |
Anwendungsfälle
Sie können diese API auf verschiedene Weise verwenden, z. B. für benutzerdefinierte Videoplayer, Videokonferenzen und Produktivitäts-Apps.
Benutzerdefinierter Videoplayer
Eine Website kann mit der vorhandenen Picture-in-Picture API für <video> eine Bild-im-Bild-Videowiedergabe anbieten. Die Möglichkeiten sind jedoch sehr begrenzt. Das vorhandene PiP-Fenster akzeptiert nur wenige Eingaben und bietet nur begrenzte Möglichkeiten für die Gestaltung. Mit einem vollständigen Dokument im Bild-im-Bild-Modus kann die Website benutzerdefinierte Steuerelemente und Eingaben (z. B. Untertitel, Wiedergabelisten, Zeitachse, Videos mit „Gefällt mir“ markieren und „Gefällt mir nicht“ markieren) anbieten, um die PiP-Videowiedergabe für Nutzer zu verbessern.
Videokonferenzsysteme
Nutzer verlassen den Browsertab während einer Videokonferenz häufig vorübergehend, z. B. wenn sie von einem anderen Tab aus präsentieren, Notizen machen oder andere Multitasking-Aktivitäten ausführen. In den meisten Fällen möchten sie jedoch weiterhin den Anruf sehen. Dies ist also ein idealer Anwendungsfall für die Bild-im-Bild-Funktion. Auch hier sind die Möglichkeiten, die eine Website für Videokonferenzen mit der Picture-in-Picture API für <video> bieten kann, in Bezug auf Stil und Eingabe begrenzt. Mit einem vollständigen Dokument im Bild-im-Bild-Modus kann die Website mehrere Videostreams ganz einfach in einem einzigen PiP-Fenster kombinieren, ohne auf Canvas-Hacks zurückgreifen zu müssen. Außerdem können benutzerdefinierte Steuerelemente bereitgestellt werden, z. B. zum Senden einer Nachricht, zum Stummschalten eines anderen Nutzers oder zum Melden.
Produktivität
Untersuchungen haben ergeben, dass Nutzer mehr Möglichkeiten benötigen, um im Web produktiv zu sein. Mit der Funktion „Dokument im Bild-im-Bild-Modus“ können Web-Apps mehr erledigen. Ob Textbearbeitung, Notizen, Aufgabenlisten, Messaging und Chat oder Design- und Entwicklungstools – Web-Apps können ihre Inhalte jetzt immer zugänglich machen.
Schnittstelle
Attribute
documentPictureInPicture.window- Gibt das aktuelle Bild-im-Bild-Fenster zurück, falls vorhanden. Andernfalls wird
nullzurückgegeben.
Methoden
documentPictureInPicture.requestWindow(options)Gibt ein Promise zurück, das aufgelöst wird, wenn ein Bild-im-Bild-Fenster geöffnet wird. Das Promise wird abgelehnt, wenn es ohne Nutzeraktion aufgerufen wird. Das
optionsWörterbuch enthält die folgenden optionalen Elemente:width- Legt die anfängliche Breite des Bild-im-Bild-Fensters fest.
height- Legt die anfängliche Höhe des Bild-im-Bild-Fensters fest.
disallowReturnToOpener- Blendet die Schaltfläche „Zurück zum Tab“ im Bild-im-Bild-Fenster aus, wenn „true“. Der Standardwert ist „false“.
preferInitialWindowPlacement- Öffnet das Bild-im-Bild-Fenster in der Standardposition und -größe, wenn „true“. Der Standardwert ist „false“.
Ereignisse
documentPictureInPicture.onenter- Wird für
documentPictureInPictureausgelöst, wenn ein Bild-im-Bild-Fenster geöffnet wird.
Beispiele
Mit dem folgenden HTML-Code wird ein benutzerdefinierter Videoplayer und ein Schaltflächenelement eingerichtet, um den Videoplayer in einem Bild-im-Bild-Fenster zu öffnen.
<div id="playerContainer">
<div id="player">
<video id="video"></video>
</div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>
Bild-im-Bild-Fenster öffnen
Das folgende JavaScript ruft documentPictureInPicture.requestWindow() auf, wenn der Nutzer auf die Schaltfläche klickt, um ein leeres Bild-im-Bild-Fenster zu öffnen. Das zurückgegebene Promise wird mit einem JavaScript-Objekt für das Bild-im-Bild-Fenster aufgelöst. Der Videoplayer wird mit append() in dieses Fenster verschoben.
pipButton.addEventListener('click', async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
Größe des Bild-im-Bild-Fensters festlegen
Wenn Sie die Größe des Bild-im-Bild-Fensters festlegen möchten, legen Sie die width und height Optionen von documentPictureInPicture.requestWindow() auf die ideale Größe für das PiP-Fenster fest. Chrome kann die Optionswerte reduzieren, wenn sie zu groß oder zu klein sind, um eine nutzerfreundliche Fenstergröße zu erreichen.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window whose size is
// the same as the player's.
const pipWindow = await documentPictureInPicture.requestWindow({
width: player.clientWidth,
height: player.clientHeight,
});
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
Schaltfläche „Zurück zum Tab“ im PiP-Fenster ausblenden
Wenn Sie die Schaltfläche im Bild-im-Bild-Fenster ausblenden möchten, mit der der Nutzer zum Tab des Öffners zurückkehren kann, legen Sie die disallowReturnToOpener Option von documentPictureInPicture.requestWindow() auf true fest.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window which hides the "back to tab" button.
const pipWindow = await documentPictureInPicture.requestWindow({
disallowReturnToOpener: true,
});
});
PiP in Standardposition und -größe öffnen
Wenn Sie die Position oder Größe des vorherigen Bild-im-Bild-Fensters nicht wiederverwenden möchten, legen Sie die preferInitialWindowPlacement Option von documentPictureInPicture.requestWindow() auf true fest.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window in its default position / size.
const pipWindow = await documentPictureInPicture.requestWindow({
preferInitialWindowPlacement: true,
});
});
Stilvorlagen in PiP kopieren
Wenn Sie alle CSS-Stilvorlagen aus dem ursprünglichen Fenster kopieren möchten, durchlaufen Sie styleSheets, die explizit mit dem Dokument verknüpft oder darin eingebettet sind, und hängen Sie sie an das Bild-im-Bild-Fenster an. Beachten Sie, dass dies eine einmalige Kopie ist.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Copy style sheets over from the initial document
// so that the player looks the same.
[...document.styleSheets].forEach((styleSheet) => {
try {
const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
const style = document.createElement('style');
style.textContent = cssRules;
pipWindow.document.head.appendChild(style);
} catch (e) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = styleSheet.type;
link.media = styleSheet.media;
link.href = styleSheet.href;
pipWindow.document.head.appendChild(link);
}
});
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
Umgang mit dem Schließen des PiP-Fensters
Achten Sie auf das Ereignis "pagehide" des Fensters, um zu erfahren, wann das Bild-im-Bild-Fenster geschlossen wird (entweder weil es von der Website initiiert wurde oder weil der Nutzer es manuell geschlossen hat). Der Ereignishandler ist ein guter Ort, um die Elemente wieder aus dem Bild-im-Bild-Fenster zu entfernen, wie hier gezeigt.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
// Move the player back when the Picture-in-Picture window closes.
pipWindow.addEventListener("pagehide", (event) => {
const playerContainer = document.querySelector("#playerContainer");
const pipPlayer = event.target.querySelector("#player");
playerContainer.append(pipPlayer);
});
});
Schließen Sie das Bild-im-Bild-Fenster programmatisch mit der close() Methode.
// Close the Picture-in-Picture window programmatically.
// The "pagehide" event will fire normally.
pipWindow.close();
Erfassen, wenn die Website in den PiP-Modus wechselt
Achten Sie auf das "enter" Ereignis für documentPictureInPicture, um zu erfahren, wann ein
Bild-im-Bild-Fenster geöffnet wird. Das Ereignis enthält ein window-Objekt, mit dem auf das Bild-im-Bild-Fenster zugegriffen werden kann.
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
Auf Elemente im PiP-Fenster zugreifen
Greifen Sie über das von documentPictureInPicture.requestWindow() zurückgegebene Objekt oder mit documentPictureInPicture.window auf Elemente im Bild-im-Bild-Fenster zu.
const pipWindow = documentPictureInPicture.window;
if (pipWindow) {
// Mute video playing in the Picture-in-Picture window.
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
}
Ereignisse aus dem PiP-Fenster verarbeiten
Erstellen Sie Schaltflächen und Steuerelemente und reagieren Sie wie immer in JavaScript auf Nutzereingabeereignisse (z. B.
"click").
// Add a "mute" button to the Picture-in-Picture window.
const pipMuteButton = pipWindow.document.createElement("button");
pipMuteButton.textContent = "Mute";
pipMuteButton.addEventListener("click", () => {
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
});
pipWindow.document.body.append(pipMuteButton);
Größe des PiP-Fensters anpassen
Verwenden Sie die resizeBy()
und resizeTo()
Window-Methoden, um die Größe des Bild-im-Bild-Fensters anzupassen. Für beide Methoden ist eine Nutzeraktion erforderlich.
const resizeButton = pipWindow.document.createElement('button');
resizeButton.textContent = 'Resize';
resizeButton.addEventListener('click', () => {
// Expand the Picture-in-Picture window's width by 20px and height by 30px.
pipWindow.resizeBy(20, 30);
});
pipWindow.document.body.append(resizeButton);
Fokus auf das Fenster des Öffners legen
Verwenden Sie die focus()
Window-Methode, um den Fokus vom Bild-im-Bild-Fenster auf das Fenster des Öffners zu legen.
Für diese Methode ist eine Nutzeraktion erforderlich.
const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
window.focus();
});
pipWindow.document.body.append(returnToTabButton);
CSS-Anzeigemodus für PiP
Verwenden Sie den CSS picture-in-picture Anzeigemodus, um bestimmte CSS-Regeln zu schreiben, die nur angewendet werden, wenn (ein Teil der) Web-App im Bild-im-Bild-Modus angezeigt wird.
@media all and (display-mode: picture-in-picture) {
body {
margin: 0;
}
h1 {
font-size: 0.8em;
}
}
Funktionserkennung
Verwenden Sie Folgendes, um zu prüfen, ob die Document Picture-in-Picture API unterstützt wird:
if ('documentPictureInPicture' in window) {
// The Document Picture-in-Picture API is supported.
}
Demos
- VideoJS-Player: Spielen Sie mit der Demo des VideoJS-Players für die Document Picture-in-Picture API .
- Tomodoro, eine Pomodoro-Web-App, nutzt die Document Picture-in-Picture API, wenn sie verfügbar ist. Weitere Informationen finden Sie in der GitHub-Pull-Anfrage.
Feedback geben
Melden Sie Probleme auf GitHub und geben Sie Vorschläge und Fragen an.