Screen Capture API memungkinkan pengguna memilih tab, jendela, atau layar untuk direkam sebagai aliran media. Aliran ini kemudian dapat direkam atau dibagikan kepada orang lain melalui jaringan. Dokumentasi ini memperkenalkan Conditional Focus, mekanisme bagi aplikasi web untuk mengontrol apakah tab atau jendela yang direkam akan difokuskan saat perekaman dimulai, atau apakah halaman perekaman akan tetap difokuskan.
Dukungan browser
Conditional Focus tersedia mulai Chrome 109.
Latar belakang
Saat aplikasi web mulai merekam tab atau jendela, browser akan menghadapi keputusan—apakah permukaan yang direkam harus ditampilkan di latar depan, atau apakah halaman perekaman harus tetap difokuskan? Jawabannya bergantung pada alasan memanggil getDisplayMedia(), dan pada permukaan yang dipilih pengguna.
Pertimbangkan aplikasi web konferensi video hipotetis. Dengan membaca track.getSettings().displaySurface dan berpotensi memeriksa Capture Handle, aplikasi web konferensi video dapat memahami apa yang dipilih pengguna untuk dibagikan. Lalu:
- Jika tab atau jendela yang direkam dapat dikontrol dari jarak jauh, pertahankan fokus pada konferensi video.
- Jika tidak, fokuskan tab atau jendela yang direkam.
Dalam contoh di atas, aplikasi web konferensi video akan mempertahankan fokus jika membagikan presentasi slide, sehingga pengguna dapat membolak-balik slide dari jarak jauh; tetapi jika pengguna memilih untuk membagikan editor teks, aplikasi web konferensi video akan segera mengalihkan fokus ke tab atau jendela yang direkam.
Menggunakan Conditional Focus API
Buat instance CaptureController dan teruskan ke getDisplayMedia(). Dengan memanggil setFocusBehavior() segera setelah promise yang ditampilkan getDiplayMedia() diselesaikan, Anda dapat mengontrol apakah tab atau jendela yang direkam akan difokuskan atau tidak. Hal ini hanya dapat dilakukan jika pengguna membagikan tab atau jendela.
const controller = new CaptureController();
// Prompt the user to share a tab, a window or a screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
// Focus the captured tab.
controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
// Do not move focus to the captured window.
// Keep the capturing page focused.
controller.setFocusBehavior("focus-capturing-application");
}
Saat memutuskan apakah akan difokuskan, Anda dapat mempertimbangkan Capture Handle.
// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
controller.setFocusBehavior("focus-captured-surface");
}
Anda bahkan dapat memutuskan apakah akan difokuskan sebelum memanggil getDisplayMedia().
// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
Anda dapat memanggil setFocusBehavior() sebanyak yang Anda inginkan sebelum promise diselesaikan, atau paling banyak sekali segera setelah promise diselesaikan. Pemanggilan terakhir akan mengganti semua pemanggilan sebelumnya.
Lebih tepatnya:
- Promise yang ditampilkan
getDisplayMedia()diselesaikan pada microtask. MemanggilsetFocusBehavior()setelah microtask tersebut selesai akan menampilkan error. - Memanggil
setFocusBehavior()lebih dari satu detik setelah perekaman dimulai adalah no-op.
Artinya, kedua cuplikan berikut akan gagal:
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const start = new Date();
while (new Date() - start <= 1000) {
// Idle for ≈1s.
}
// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");
Memanggil setFocusBehavior() juga akan menampilkan error dalam kasus berikut:
- track video dari aliran yang ditampilkan oleh
getDisplayMedia()tidak "live". - setelah promise yang ditampilkan
getDisplayMedia()diselesaikan, jika pengguna membagikan layar (bukan tab atau jendela).
Contoh
Anda dapat mencoba Conditional Focus dengan menjalankan demo.
Deteksi fitur
Untuk memeriksa apakah CaptureController.setFocusBehavior() didukung, gunakan:
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
Masukan
Tim Chrome dan komunitas standar web ingin mengetahui pengalaman Anda dengan Conditional Focus.
Beri tahu kami tentang desainnya
Apakah ada sesuatu tentang Conditional Focus yang tidak berfungsi seperti yang Anda harapkan? Atau apakah ada metode atau properti yang tidak ada yang Anda butuhkan untuk menerapkan ide Anda? Ada pertanyaan atau komentar tentang model keamanan?
- Laporkan masalah spesifikasi di repo GitHub, atau tambahkan pendapat Anda ke masalah yang ada.
Mengalami masalah dengan implementasinya?
Apakah Anda menemukan bug pada implementasi Chrome? Atau apakah implementasinya berbeda dengan spesifikasi?
- Laporkan bug di https://new.crbug.com. Pastikan untuk menyertakan detail sebanyak mungkin, dan petunjuk untuk mereproduksi.
Tunjukkan dukungan
Apakah Anda berencana menggunakan Conditional Focus? Dukungan publik Anda membantu tim Chrome memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung fitur tersebut.
Kirim tweet ke @ChromiumDev dan beri tahu kami di mana dan bagaimana Anda menggunakannya.
Link bermanfaat
Ucapan terima kasih
Terima kasih kepada Rachel Andrew karena telah meninjau dokumen ini.