Cara menambahkan Picture-in-Picture ke kontrol video

François Beaufort
François Beaufort

Cara modern

Picture-in-Picture (PiP) Web API memungkinkan situs membuat jendela video mengambang selalu di atas jendela lain, sehingga pengguna dapat terus menggunakan media saat mereka berinteraksi dengan situs konten atau aplikasi lain di perangkat mereka.

Contoh di bawah menunjukkan cara membuat tombol yang dapat digunakan pengguna untuk mengaktifkan/menonaktifkan Picture-in-Picture di video.

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;
}

Cara klasik

Sebelum tersedianya Picture-in-Picture Web API, tidak ada cara untuk membuat jendela video mengambang yang selalu berada di atas jendela lain. Namun, memutar video di atas elemen lain di halaman web dapat dilakukan dengan CSS.

Contoh di bawah menunjukkan cara menampilkan video di atas elemen lain di pojok kanan bawah halaman web Anda saat pengguna mengklik tombol.

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;
}

Bacaan lebih lanjut

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");
});