Nowoczesny sposób
Interfejs Picture-in-Picture (PiP) Web API umożliwia witrynom tworzenie pływającego okna wideo, które zawsze znajduje się na wierzchu innych okien. Dzięki temu użytkownicy mogą nadal korzystać z multimediów podczas interakcji z innymi witrynami lub aplikacjami na urządzeniu.
Poniższy przykład pokazuje, jak utworzyć przycisk, za pomocą którego użytkownicy mogą włączać i wyłączać obraz w obrazie w filmie.
togglePipButton.addEventListener("click", async (event) => {
togglePipButton.disabled = true;
try {
if (video !== document.pictureInPictureElement) {
await video.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
} finally {
togglePipButton.disabled = false;
}
});
video.addEventListener("enterpictureinpicture", (event) => {
togglePipButton.classList.add("on");
});
video.addEventListener("leavepictureinpicture", (event) => {
togglePipButton.classList.remove("on");
});
/* Feature detection */
if ("pictureInPictureEnabled" in document) {
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
video.addEventListener("loadedmetadata", setPipButton);
video.addEventListener("emptied", setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
togglePipButton.hidden = true;
}
function setPipButton() {
togglePipButton.disabled =
video.readyState === 0 ||
!document.pictureInPictureEnabled ||
video.disablePictureInPicture;
}
Klasyczny sposób
Zanim pojawił się interfejs Picture-in-Picture Web API, nie było możliwości utworzenia pływającego okna wideo, które zawsze znajdowałoby się na wierzchu innych okien. Odtwarzanie filmu na wierzchu innych elementów na stronie internetowej jest jednak możliwe za pomocą CSS.
Poniższy przykład pokazuje, jak wyświetlić film na wierzchu innych elementów w prawym dolnym rogu strony internetowej, gdy użytkownik kliknie przycisk.
toggleFakePipButton.addEventListener("click", (event) => {
video.classList.toggle("fake-pip");
});
/* Place the video in the bottom right corner on top of everything else via CSS. */
video.fake-pip {
position: fixed;
z-index: 1000;
bottom: 10px;
right: 10px;
}
Więcej informacji
- Specyfikacja W3C dotycząca obrazu w obrazie
- Oglądanie filmów w trybie obraz w obrazie
- MDN Picture-in-Picture API
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📺</text></svg>"
/>
<title>How to add Picture-in-Picture to video controls</title>
</head>
<body>
<h1>How to add Picture-in-Picture to video controls</h1>
<button id="togglePipButton">Picture-in-Picture</button>
<button id="toggleFakePipButton">Fake Picture-in-Picture</button>
<video autoplay muted playsinline loop src="https://storage.googleapis.com/media-session/caminandes/short.mp4"></video>
</body>
</html>CSS
:root {
color-scheme: dark light;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 1rem;
font-family: system-ui, sans-serif;
}
button:before {
content: "Enter ";
}
button.on:before {
content: "Leave ";
}
video {
display: block;
margin-top: 10px;
max-width: 100%;
}
video.fake-pip {
position: fixed;
z-index: 1000;
bottom: 10px;
right: 10px;
}
JS
const video = document.querySelector('video');
const togglePipButton = document.querySelector('#togglePipButton');
const toggleFakePipButton = document.querySelector('#toggleFakePipButton');
togglePipButton.addEventListener("click", async (event) => {
togglePipButton.disabled = true;
try {
if (video !== document.pictureInPictureElement) {
await video.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
} finally {
togglePipButton.disabled = false;
}
});
video.addEventListener("enterpictureinpicture", (event) => {
togglePipButton.classList.add("on");
});
video.addEventListener("leavepictureinpicture", (event) => {
togglePipButton.classList.remove("on");
});
/* Feature detection */
if ("pictureInPictureEnabled" in document) {
// Hide fake PiP button if Picture-in-Picture is supported.
toggleFakePipButton.hidden = true;
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
video.addEventListener("loadedmetadata", setPipButton);
video.addEventListener("emptied", setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
togglePipButton.hidden = true;
}
function setPipButton() {
togglePipButton.disabled =
video.readyState === 0 ||
!document.pictureInPictureEnabled ||
video.disablePictureInPicture;
}
/* Fake Picture-in-Picture */
toggleFakePipButton.addEventListener("click", (event) => {
toggleFakePipButton.classList.toggle("on");
video.classList.toggle("fake-pip");
});