Verwendung der Document Picture-in-Picture API
Dieser Leitfaden bietet einen Überblick über die typische Verwendung der Document Picture-in-Picture API.
Hinweis: Sie können das vorgestellte Demo in Aktion unter Document Picture-in-Picture API Example sehen (siehe auch den vollständigen Quellcode).
Beispiel-HTML
Das folgende HTML richtet einen einfachen Videoplayer ein.
<div id="container">
<p class="in-pip-message">
Video player is currently in the separate Picture-in-Picture window.
</p>
<div id="player">
<video
src="assets/bigbuckbunny.mp4"
id="video"
controls
width="320"></video>
<div id="credits">
<a href="https://peach.blender.org/download/" target="_blank">
Video by Blender </a
>;
<a href="https://peach.blender.org/about/" target="_blank">
licensed CC-BY 3.0
</a>
</div>
<div id="control-bar">
<p class="no-picture-in-picture">
Document Picture-in-Picture API not available
</p>
<p></p>
</div>
</div>
</div>
Funktionsüberprüfung
Um zu prüfen, ob die Document Picture-in-Picture API unterstützt wird, können Sie testen, ob documentPictureInPicture auf window verfügbar ist:
if ("documentPictureInPicture" in window) {
document.querySelector(".no-picture-in-picture").remove();
const togglePipButton = document.createElement("button");
togglePipButton.textContent = "Toggle Picture-in-Picture";
togglePipButton.addEventListener("click", togglePictureInPicture);
document.getElementById("control-bar").appendChild(togglePipButton);
}
Wenn es verfügbar ist, entfernen wir die Nachricht "Document Picture-in-Picture API not available" und fügen stattdessen ein <button> Element hinzu, um den Videoplayer in einem Document Picture-in-Picture Fenster zu öffnen.
Öffnen eines Picture-in-Picture Fensters
Das folgende JavaScript ruft window.documentPictureInPicture.requestWindow() auf, um ein leeres Picture-in-Picture Fenster zu öffnen. Das zurückgegebene Promise wird mit einem Picture-in-Picture Window Objekt erfüllt. Der Videoplayer wird in dieses Fenster verschoben, indem Element.append() verwendet wird, und wir zeigen die Meldung an, dass es verschoben wurde.
Die width und height Optionen von requestWindow() setzen das Picture-in-Picture Fenster auf die gewünschte Größe. Browser können die Optionswerte beschränken, wenn sie zu groß oder zu klein sind, um eine benutzerfreundliche Fenstergröße zu erhalten.
async function togglePictureInPicture() {
// Early return if there's already a Picture-in-Picture window open
if (window.documentPictureInPicture.window) {
return;
}
// Open a Picture-in-Picture window.
const pipWindow = await window.documentPictureInPicture.requestWindow({
width: videoPlayer.clientWidth,
height: videoPlayer.clientHeight,
});
// …
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(videoPlayer);
// Display a message to say it has been moved
inPipMessage.style.display = "block";
}
Kopieren von Stylesheets in das Picture-in-Picture Fenster
Um alle CSS-Stylesheets aus dem ursprünglichen Fenster zu kopieren, durchlaufen Sie alle Stylesheets, die explizit in das Dokument eingebunden oder eingebettet sind (über Document.styleSheets), und fügen Sie sie dem Picture-in-Picture Fenster hinzu. Beachten Sie, dass dies eine einmalige Kopie ist.
// …
// 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);
}
});
// …
Stile gezielt anwenden, wenn im Picture-in-Picture Modus
Der picture-in-picture Wert der display-mode Media-Feature ermöglicht es Entwicklern, ein Dokument basierend darauf, ob es im Picture-in-Picture Modus angezeigt wird, mit CSS zu stylen. Die grundlegende Verwendung sieht folgendermaßen aus:
@media (display-mode: picture-in-picture) {
body {
background: red;
}
}
Dieser Codeausschnitt wird den Hintergrund des Dokument <body> rot färben, nur wenn es im Picture-in-Picture Modus angezeigt wird.
In unserem Demo kombinieren wir den display-mode: picture-in-picture Wert mit dem prefers-color-scheme Media-Feature, um helle und dunkle Farbschemata zu erstellen, die basierend auf den Farbschema-Einstellungen des Benutzers nur dann angewendet werden, wenn die App im Picture-in-Picture Modus gezeigt wird.
@media (display-mode: picture-in-picture) and (prefers-color-scheme: light) {
body {
background: antiquewhite;
}
}
@media (display-mode: picture-in-picture) and (prefers-color-scheme: dark) {
body {
background: #333333;
}
a {
color: antiquewhite;
}
}
Behandlung, wenn das Picture-in-Picture-Fenster geschlossen wird
Der Code zum Umschalten des Picture-in-Picture Fensters, wenn der Button ein zweites Mal gedrückt wird, sieht so aus:
inPipMessage.style.display = "none";
playerContainer.append(videoPlayer);
window.documentPictureInPicture.window.close();
Hier kehren wir die DOM-Änderungen um — die Meldung wird ausgeblendet und der Videoplayer wird zurück in den Player-Container im Hauptanwendungsfenster verschoben. Wir schließen das Picture-in-Picture Fenster auch programmgesteuert mit der Window.close() Methode.
Sie müssen jedoch auch den Fall berücksichtigen, dass der Benutzer das Picture-in-Picture Fenster schließt, indem er das vom Browser bereitgestellte Schließsteuerungselement auf dem Fenster selbst drückt. Sie können damit umgehen, indem Sie erkennen, wann das Fenster über das pagehide Ereignis geschlossen wird:
pipWindow.addEventListener("pagehide", (event) => {
inPipMessage.style.display = "none";
playerContainer.append(videoPlayer);
});
Hinweis:
Das vom Browser bereitgestellte Schließsteuerungselement kann ausgeblendet werden, indem Sie den Hinweis disallowReturnToOpener auf true im Optionsobjekt setzen, wenn DocumentPictureInPicture.requestWindow() aufgerufen wird, um das Picture-in-Picture Fenster zu öffnen.
Ereignis hören, wenn die Website das Picture-in-Picture betritt
Hören Sie auf das enter Ereignis der DocumentPictureInPicture Instanz, um zu wissen, wann ein Picture-in-Picture Fenster geöffnet wird.
In unserem Demo verwenden wir das enter Ereignis, um dem Picture-in-Picture Fenster einen Stummschalterknopf hinzuzufügen:
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
console.log("Video player has entered the pip window");
const pipMuteButton = pipWindow.document.createElement("button");
pipMuteButton.textContent = "Mute";
pipMuteButton.addEventListener("click", () => {
const pipVideo = pipWindow.document.querySelector("#video");
if (!pipVideo.muted) {
pipVideo.muted = true;
pipMuteButton.textContent = "Unmute";
} else {
pipVideo.muted = false;
pipMuteButton.textContent = "Mute";
}
});
pipWindow.document.body.append(pipMuteButton);
});
Hinweis:
Das DocumentPictureInPictureEvent Ereignisobjekt enthält eine window Eigenschaft, um auf das Picture-in-Picture Fenster zuzugreifen.
Elemente und Ereignisse behandeln
Sie können auf unterschiedliche Weise auf Elemente im Picture-in-Picture Fenster zugreifen:
- Die
WindowInstanz, die von derDocumentPictureInPicture.requestWindow()Methode zurückgegeben wird, wie oben zu sehen. - Über die
windowEigenschaft desDocumentPictureInPictureEventEreignisobjekts (beimenterEreignis), wie oben zu sehen. - Über die
DocumentPictureInPicture.windowEigenschaft:
const pipWindow = window.documentPictureInPicture.window;
if (pipWindow) {
// Mute video playing in the Picture-in-Picture window.
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
}
Sobald Sie eine Referenz zur Picture-in-Picture window Instanz haben, können Sie das DOM manipulieren (zum Beispiel Schaltflächen erstellen) und auf Benutzereingabeereignisse (wie click) reagieren, wie Sie es normalerweise im regulären Browserfensterkontext tun würden.