איך מוסיפים את התכונה 'תמונה בתוך תמונה' לפקדים של הסרטון

François Beaufort
François Beaufort

הדרך המודרנית

ה-API של התכונה 'תמונה בתוך תמונה' (PiP) לאינטרנט מאפשר לאתרים ליצור חלון וידאו צף שמוצג תמיד מעל חלונות אחרים. כך המשתמשים יכולים להמשיך לצרוך מדיה בזמן שהם מבצעים אינטראקציה עם אתרים או אפליקציות אחרים במכשיר.

בדוגמה הבאה מוצג איך ליצור לחצן שמשתמשים יכולים ללחוץ עליו כדי להפעיל את התכונה 'תמונה בתוך תמונה' בסרטון.

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

הדרך הקלאסית

לפני שהפכנו את Picture-in-Picture Web API לזמין, לא הייתה דרך ליצור חלון וידאו צף שתמיד מוצג מעל חלונות אחרים. אפשר להפעיל את הסרטון מעל אלמנטים אחרים בדף האינטרנט באמצעות CSS.

בדוגמה שלמטה אפשר לראות איך להציג את הסרטון מעל רכיבים אחרים בפינה השמאלית התחתונה של דף האינטרנט כשמשתמש לוחץ על לחצן.

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

קריאה נוספת

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