Document Picture-in-Picture API memungkinkan pengguna membuka jendela yang selalu berada di atas dan dapat diisi dengan konten HTML arbitrer. Ini memperluas Picture-in-Picture API untuk <video>
yang hanya memungkinkan elemen <video>
HTML dimasukkan ke jendela Picture-in-Picture.
Jendela Picture-in-Picture di Document Picture-in-Picture API mirip dengan jendela asal sama kosong yang dibuka melalui window.open()
, dengan beberapa perbedaan:
- Jendela Picture-in-Picture mengambang di atas jendela lain.
- Jendela Picture-in-Picture tidak pernah aktif lebih lama dibandingkan jendela yang terbuka.
- Jendela Picture-in-Picture tidak dapat dibuka.
- Posisi jendela Picture-in-Picture tidak dapat disetel oleh situs.
Status saat ini
Langkah | Status |
---|---|
1. Buat pesan penjelasan | Selesai |
2. Membuat draf awal spesifikasi | Dalam proses |
3. Mengumpulkan masukan & mengulangi desain | Dalam proses |
4. Uji coba origin | Selesai |
5. Luncurkan | Selesai (Desktop) |
Kasus penggunaan
Pemutar video kustom
Situs dapat memberikan pengalaman video Picture-in-Picture dengan Picture-in-Picture API untuk <video>
, tetapi sangat terbatas. Jendela Picture-in-Picture yang ada menerima sedikit input, dan memiliki kemampuan terbatas untuk menata gayanya. Dengan Document in Picture-in-Picture, situs dapat menyediakan kontrol dan input kustom (misalnya, teks, playlist, scrubber waktu, menyukai dan tidak menyukai video) untuk meningkatkan pengalaman video Picture-in-Picture pengguna.
Konferensi video
Umumnya pengguna meninggalkan tab browser selama sesi konferensi video karena berbagai alasan (misalnya, mempresentasikan tab lain ke panggilan atau multitasking) sambil tetap ingin melihat panggilan, jadi ini adalah kasus penggunaan utama untuk Picture-in-Picture. Sekali lagi, pengalaman saat ini yang dapat diberikan oleh situs konferensi video melalui Picture-in-Picture API untuk <video>
dibatasi dalam gaya dan input. Dengan Dokumen dalam mode Picture-in-Picture, situs dapat dengan mudah menggabungkan beberapa streaming video ke dalam satu jendela PiP tanpa harus mengandalkan tips kanvas dan memberikan kontrol kustom seperti mengirim pesan, membisukan audio pengguna lain, atau mengangkat tangan.
Produktivitas
Riset menunjukkan bahwa pengguna memerlukan lebih banyak cara untuk menjadi produktif di web. Document in Picture-in-Picture memberi aplikasi web fleksibilitas untuk melakukan lebih banyak hal. Baik itu pengeditan teks, pencatatan, daftar tugas, pesan dan obrolan, atau alat desain dan pengembangan, aplikasi web sekarang dapat menjaga konten mereka selalu dapat diakses.
Antarmuka
Properti
documentPictureInPicture.window
- Menampilkan jendela Picture-in-Picture saat ini, jika ada. Jika tidak, tampilkan
null
.
Metode
documentPictureInPicture.requestWindow(options)
Menampilkan promise yang di-resolve saat jendela Picture-in-Picture dibuka. Promise akan ditolak jika dipanggil tanpa gestur pengguna. Kamus
options
berisi anggota opsional berikut:width
- Menyetel lebar awal jendela Picture-in-Picture.
height
- Menyetel tinggi awal jendela Picture-in-Picture.
disallowReturnToOpener
- Menyembunyikan tombol "kembali ke tab" di jendela Picture-in-Picture jika true (benar). Nilainya salah secara default.
Peristiwa
documentPictureInPicture.onenter
- Diaktifkan pada
documentPictureInPicture
saat jendela Picture-in-Picture dibuka.
Contoh
HTML berikut menyiapkan pemutar video khusus 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);
});
Menyetel ukuran jendela Picture-in-Picture
Untuk menyetel ukuran jendela Picture-in-Picture, setel opsi width
dan height
dari documentPictureInPicture.requestWindow()
ke ukuran jendela Picture-in-Picture yang diinginkan. Chrome dapat membatasi nilai opsi jika nilai terlalu besar atau terlalu kecil untuk menyesuaikan 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" pada jendela Picture-in-Picture
Untuk menyembunyikan tombol di jendela Picture-in-Picture yang memungkinkan pengguna kembali ke tab pembuka, setel 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,
});
});
Menyalin lembar gaya ke jendela Picture-in-Picture
Untuk menyalin semua lembar gaya CSS dari jendela asal, ulangi 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 Picture-in-Picture ditutup
Proses peristiwa "pagehide"
jendela untuk mengetahui kapan jendela Picture-in-Picture ditutup (baik karena situs memulainya atau pengguna menutupnya secara manual). Pengendali peristiwa adalah tempat yang baik untuk mengeluarkan elemen kembali dari jendela Picture-in-Picture seperti yang ditampilkan di bawah ini.
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 Picture-in-Picture
Proses 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 Picture-in-Picture
Akses elemen di jendela Picture-in-Picture dari objek yang ditampilkan oleh documentPictureInPicture.requestWindow()
, atau dengan documentPictureInPicture.window
seperti yang ditunjukkan di bawah.
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 Picture-in-Picture
Buat tombol dan kontrol serta respons peristiwa input pengguna seperti "click"
seperti yang biasa Anda lakukan 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 Picture-in-Picture
Gunakan metode Jendela resizeBy()
dan resizeTo()
untuk mengubah ukuran jendela Picture-in-Picture. Kedua metode tersebut 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);
Memfokuskan jendela pembuka
Gunakan metode Jendela focus()
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 picture-in-picture CSS
Gunakan mode tampilan picture-in-picture
CSS untuk menulis aturan CSS tertentu yang hanya diterapkan saat (bagian dari) 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
Anda dapat bermain-main dengan Demo pemutar VideoJS Document Picture-in-Picture API. Pastikan untuk memeriksa kode sumber.
Pomodoro
Tomodoro, sebuah aplikasi web pomodoro, juga memanfaatkan Document Picture-in-Picture API jika tersedia (lihat permintaan pull GitHub).
Masukan
Harap laporkan masalah di GitHub dengan saran dan pertanyaan.
Link penting
- Penjelasan untuk umum
- Spesifikasi WICG
- Bug pelacakan Chromium
- Entri ChromeStatus.com
- Komponen Blink:
Blink>Media>PictureInPicture
- Tinjauan TAG
- Niat untuk Bereksperimen
- Rencana Pengiriman
Ucapan terima kasih
Banner besar oleh Jakob Owens.