Document Picture-in-Picture API memungkinkan Anda membuka jendela selalu di atas yang dapat diisi dengan konten HTML arbitrer. API ini memperluas Picture-in-Picture API yang ada untuk <video> yang hanya memungkinkan elemen <video> HTML dimasukkan ke dalam jendela Picture-in-Picture (PiP).
Jendela Picture-in-Picture di Document Picture-in-Picture API serupa dengan jendela kosong yang sama asalnya yang dibuka menggunakan window.open(), dengan beberapa perbedaan:
- Jendela Picture-in-Picture mengambang di atas jendela lain.
- Jendela Picture-in-Picture tidak pernah lebih lama dari jendela pembuka.
- Jendela Picture-in-Picture tidak dapat dinavigasi.
- Posisi jendela Picture-in-Picture tidak dapat ditetapkan oleh situs.
Status
| Langkah | Status |
|---|---|
| 1. Membuat penjelasan | Selesai |
| 2. Membuat draf awal spesifikasi | In progress |
| 3. Kumpulkan masukan & lakukan iterasi pada desain | In progress |
| 4. Uji coba origin | Selesai |
| 5. Luncurkan | Selesai (Desktop) |
Kasus penggunaan
Anda dapat menggunakan API ini dengan berbagai cara, termasuk pemutar video kustom, konferensi video, dan aplikasi produktivitas.
Pemutar video kustom
Situs dapat memberikan pengalaman video Picture-in-Picture dengan Picture-in-Picture API untuk <video> yang ada, tetapi sangat terbatas. Jendela PiP yang ada menerima beberapa input, dan memiliki kemampuan terbatas untuk menata gaya. Dengan Dokumen lengkap dalam Picture-in-Picture, situs dapat menyediakan kontrol dan input kustom (misalnya, teks, playlist, penggeser waktu, menyukai dan tidak menyukai video) untuk meningkatkan pengalaman video PiP pengguna.
Konferensi video
Pengguna sering kali keluar sementara dari tab browser selama sesi konferensi video, seperti saat melakukan presentasi dari tab lain ke panggilan, membuat catatan, atau melakukan aktivitas multi-tasking lainnya. Namun, dalam sebagian besar kasus, pengguna tetap ingin melihat panggilan, sehingga ini adalah kasus penggunaan yang ideal untuk Picture-in-Picture. Sekali lagi, pengalaman saat ini yang dapat diberikan oleh situs konferensi video dengan Picture-in-Picture API untuk <video> terbatas dalam gaya dan input. Dengan Dokumen lengkap dalam Picture-in-Picture, situs dapat dengan mudah menggabungkan beberapa streaming video ke dalam satu jendela PiP, tanpa mengandalkan peretasan kanvas, dan menyediakan kontrol kustom, seperti mengirim pesan, membisukan pengguna lain, atau mengangkat tangan.
Produktivitas
Penelitian menunjukkan bahwa pengguna memerlukan lebih banyak cara untuk menjadi produktif di web. Dokumen dalam Picture-in-Picture memberi aplikasi web fleksibilitas untuk menyelesaikan lebih banyak hal. Baik itu pengeditan teks, pencatatan, daftar tugas, pesan dan chat, atau alat desain dan pengembangan, aplikasi web kini dapat membuat kontennya selalu dapat diakses.
Antarmuka
Properti
documentPictureInPicture.window- Menampilkan jendela Picture-in-Picture saat ini jika ada. Jika tidak, akan menampilkan
null.
Metode
documentPictureInPicture.requestWindow(options)Menampilkan promise yang di-resolve saat jendela Picture-in-Picture dibuka. Promise ditolak jika dipanggil tanpa gestur pengguna. Kamus
optionsberisi anggota opsional berikut:width- Menetapkan lebar awal jendela Picture-in-Picture.
height- Menetapkan tinggi awal jendela Picture-in-Picture.
disallowReturnToOpener- Menyembunyikan tombol "kembali ke tab" di jendela Picture-in-Picture jika benar. Nilainya adalah false secara default.
preferInitialWindowPlacement- Membuka jendela Picture-in-Picture dalam posisi dan ukuran defaultnya jika benar (true). Secara default, nilainya adalah false.
Acara
documentPictureInPicture.onenter- Diaktifkan pada
documentPictureInPicturesaat jendela Picture-in-Picture dibuka.
Contoh
HTML berikut menyiapkan pemutar video kustom dan elemen tombol untuk membuka pemutar video di jendela Picture-in-Picture.
<div id="playerContainer">
<div id="player">
<video id="video"></video>
</div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>
Membuka jendela Picture-in-Picture
JavaScript berikut memanggil documentPictureInPicture.requestWindow() saat pengguna mengklik tombol untuk membuka jendela Picture-in-Picture kosong. Promise yang ditampilkan diselesaikan dengan objek JavaScript jendela Picture-in-Picture. Pemutar video dipindahkan ke jendela tersebut menggunakan append().
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);
});
Menetapkan ukuran jendela Picture-in-Picture
Untuk menyetel ukuran jendela Picture-in-Picture, tetapkan opsi width dan height dari documentPictureInPicture.requestWindow() ke ukuran jendela PiP yang ideal. Chrome dapat mengurangi nilai opsi jika terlalu besar atau terlalu kecil agar sesuai dengan ukuran jendela yang mudah digunakan.
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);
});
Menyembunyikan tombol "kembali ke tab" di jendela PiP
Untuk menyembunyikan tombol di jendela Picture-in-Picture yang memungkinkan pengguna kembali ke tab pembuka, tetapkan opsi disallowReturnToOpener dari documentPictureInPicture.requestWindow() ke true.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window which hides the "back to tab" button.
const pipWindow = await documentPictureInPicture.requestWindow({
disallowReturnToOpener: true,
});
});
Membuka PiP ke posisi dan ukuran default
Agar tidak menggunakan kembali posisi atau ukuran jendela Picture-in-Picture sebelumnya, setel opsi preferInitialWindowPlacement dari documentPictureInPicture.requestWindow() ke true.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window in its default position / size.
const pipWindow = await documentPictureInPicture.requestWindow({
preferInitialWindowPlacement: true,
});
});
Menyalin lembar gaya ke PiP
Untuk menyalin semua lembar gaya CSS dari jendela asal, lakukan loop melalui styleSheets yang ditautkan secara eksplisit ke atau disematkan dalam dokumen dan tambahkan ke jendela Picture-in-Picture. Perhatikan bahwa ini adalah salinan satu kali.
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);
});
Menangani saat jendela PiP ditutup
Dengarkan peristiwa "pagehide" jendela untuk mengetahui kapan jendela Picture-in-Picture ditutup (baik karena situs memulainya atau pengguna menutupnya secara manual). Handler peristiwa adalah tempat yang tepat untuk mengeluarkan kembali elemen dari jendela Picture-in-Picture seperti yang ditunjukkan di sini.
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);
});
});
Tutup jendela Picture-in-Picture secara terprogram menggunakan metode close().
// Close the Picture-in-Picture window programmatically.
// The "pagehide" event will fire normally.
pipWindow.close();
Mendengarkan saat situs memasuki PiP
Dengarkan peristiwa "enter" di documentPictureInPicture untuk mengetahui kapan jendela Picture-in-Picture dibuka. Peristiwa ini berisi objek window untuk mengakses jendela Picture-in-Picture.
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
Mengakses elemen di jendela PiP
Akses elemen di jendela Picture-in-Picture dari objek yang ditampilkan oleh documentPictureInPicture.requestWindow(), atau dengan documentPictureInPicture.window.
const pipWindow = documentPictureInPicture.window;
if (pipWindow) {
// Mute video playing in the Picture-in-Picture window.
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
}
Menangani peristiwa dari jendela PiP
Buat tombol dan kontrol serta merespons peristiwa input pengguna (seperti
"click"), seperti biasa di JavaScript.
// 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);
Mengubah ukuran jendela PiP
Gunakan metode resizeBy()
dan resizeTo()
Window untuk mengubah ukuran jendela Picture-in-Picture. Kedua metode memerlukan gestur pengguna.
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);
Fokuskan jendela pembuka
Gunakan metode focus()
Window untuk memfokuskan jendela pembuka dari jendela Picture-in-Picture.
Metode ini memerlukan gestur pengguna.
const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
window.focus();
});
pipWindow.document.body.append(returnToTabButton);
Mode tampilan PiP CSS
Gunakan mode tampilan CSS picture-in-picture untuk menulis aturan CSS tertentu yang hanya diterapkan saat (sebagian) aplikasi web ditampilkan dalam mode Picture-in-Picture.
@media all and (display-mode: picture-in-picture) {
body {
margin: 0;
}
h1 {
font-size: 0.8em;
}
}
Deteksi fitur
Untuk memeriksa apakah Document Picture-in-Picture API didukung, gunakan:
if ('documentPictureInPicture' in window) {
// The Document Picture-in-Picture API is supported.
}
Demo
- Pemutar VideoJS: Putar dengan Document Picture-in-Picture API demo pemutar VideoJS.
- Tomodoro, aplikasi web pomodoro, memanfaatkan Document Picture-in-Picture API jika tersedia. Lihat permintaan pull GitHub mereka.
Beri masukan
Laporkan masalah di GitHub dengan saran dan pertanyaan.