Merekam streaming video dari elemen mana pun

Prancis Beaufort
François Beaufort
Elad Alon
Elad Alon

Dengan Screen Capture API, Anda dapat merekam seluruh tab saat ini. Element Capture API memungkinkan Anda mengambil dan merekam elemen HTML tertentu. Fungsi ini mengubah tangkapan seluruh tab, menjadi tangkapan subhierarki DOM tertentu, dan hanya menangkap turunan langsung dari elemen target. Dengan kata lain, fitur ini memangkas dan menghapus konten yang terhalang dan yang terhalang.

Mengapa menggunakan Element Capture?

Mempertimbangkan persyaratan aplikasi konferensi video dapat membantu Anda memahami kegunaan Element Capture. Jika memiliki aplikasi konferensi video yang memungkinkan Anda menyematkan aplikasi pihak ketiga dalam iframe, terkadang Anda ingin merekam iframe tersebut sebagai video dan mengirimkannya ke peserta jarak jauh.

Screenshot panggilan konferensi video di Chrome.
Elad menggunakan aplikasi pihak ketiga dalam panggilan konferensi video bersama François.

Memanggil getDisplayMedia() dan mengizinkan pengguna memilih tab saat ini akan mengirimkan seluruh tab saat ini. Hal ini kemungkinan akan mengirimkan kembali video orang itu kepada mereka. Anda dapat memangkasnya menggunakan Pengambilan Wilayah.

Namun, bagaimana jika presenter berinteraksi dengan aplikasi konferensi video dan beberapa konten, seperti menu drop-down, ternyata menarik di atas konten yang dimaksudkan untuk direkam?

Screenshot menu drop-down yang menutupi konten yang ingin diambil gambarnya.
Menu drop-down akan muncul di atas konten yang ditujukan untuk pengambilan gambar.

Region Capture tidak akan membantu Anda. Bagian dari menu drop-down mungkin akan terlihat di layar peserta jarak jauh.

Screenshot menu drop-down yang diambil.
Daftar drop-down Elad muncul di atas konten yang diterima oleh François.

Fakta bahwa Pengambilan Wilayah menangkap bagian elemen dengan cara ini (dikenal sebagai konten yang menghalangi) menimbulkan beberapa masalah:

  • Konten yang menghalangi pengguna dapat menghalangi penayangan konten yang ingin dibagikan oleh pengguna.
  • Konten yang menghalangi mungkin bersifat pribadi (misalnya notifikasi chat).
  • Konten yang menghalangi dapat membingungkan. (Misalnya, tata letak ulang aplikasi dapat secara singkat menampilkan video peserta jarak jauh daripada target yang ditangkap.)

Element Capture API menyelesaikan semua masalah ini, dengan memungkinkan Anda menargetkan elemen yang ingin dibagikan.

Screenshot elemen target tanpa daftar dropdown yang terlihat.
François tidak melihat menu drop-down dari Elad.

Bagaimana cara menggunakan Element Capture?

captureTarget adalah Elemen di halaman Anda yang berisi konten yang ingin diambil pengguna. Anda ingin aplikasi web konferensi video merekam captureTarget dan membagikannya kepada peserta jarak jauh. Jadi, Anda mendapatkan RestrictionTarget dari captureTarget. Setelah membatasi trek video menggunakan RestrictionTarget ini, frame pada trek video tersebut sekarang hanya terdiri dari piksel yang merupakan bagian dari captureTarget dan turunan DOM langsungnya.

Jika captureTarget mengubah ukuran, bentuk, atau lokasi, trek video akan mengikutinya, tanpa memerlukan input tambahan dari salah satu aplikasi web. Memblokir konten yang muncul, menghilang, atau bergerak, juga tidak memerlukan perlakuan khusus.

Tinjau kembali langkah-langkah ini:

Mulailah dengan mengizinkan pengguna merekam tab saat ini.

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

Tentukan RestrictionTarget dengan memanggil RestrictionTarget.fromElement() dengan elemen pilihan Anda sebagai input.

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

Lalu, panggil restrictTo() di trek video dengan RestrictionTarget sebagai input. Setelah promise terakhir diselesaikan, semua frame berikutnya akan dibatasi.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

Pembahasan mendalam

Deteksi fitur

Untuk memeriksa apakah RestrictionTarget.fromElement() didukung, gunakan:

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

Memperoleh RestrictionTarget

Fokus pada Elemen bernama captureTarget. Untuk mendapatkan RestrictionTarget darinya, panggil RestrictionTarget.fromElement(captureTarget). Promise yang ditampilkan akan diselesaikan dengan objek RestrictionTarget baru jika berhasil. Jika tidak, penawaran akan ditolak jika Anda telah membuat objek RestrictionTarget dalam jumlah yang tidak wajar.

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

Tidak seperti Elemen, objek RestrictionTarget dapat diserialisasi. Misalnya, nilai tersebut dapat diteruskan ke dokumen lain menggunakan Window.postMessage().

Membatasi

Saat merekam tab, trek video akan menampilkan restrictTo(). Saat merekam tab saat ini, memanggil restrictTo() dengan null atau RestrictionTarget yang berasal dari Elemen dalam tab saat ini adalah valid.

Panggilan ke restrictTo(restrictionTarget) akan mengubah trek video menjadi rekaman captureTarget, seolah-olah trek tersebut digambar sendiri, terlepas dari DOM lainnya. Setiap turunan captureTarget juga akan diambil; turunan captureTarget akan dieliminasi dari pengambilan gambar. Hasilnya, setiap frame yang dikirimkan di jalur akan tampak seolah-olah dipangkas sesuai kontur captureTarget, dan setiap konten yang terhalang dan terhalang akan dihapus.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

Panggilan ke restrictTo(null) akan mengembalikan trek ke status aslinya.

// Stop restricting.
await track.restrictTo(null);

Jika panggilan ke restrictTo() berhasil, Promise yang ditampilkan akan diselesaikan ketika dapat dijamin bahwa semua frame video berikutnya akan dibatasi ke captureTarget.

Jika gagal, Promise akan ditolak. Panggilan yang gagal ke restrictTo() disebabkan oleh salah satu alasan berikut:

  • Jika restrictionTarget dibuat di tab selain tab yang sedang diambil. (Perhatikan bahwa dengan menggunakan tombol "bagikan tab ini", pengguna dapat mengubah tab mana yang diambil pada waktu tertentu.)
  • Jika restrictionTarget berasal dari Elemen yang sudah tidak ada lagi.
  • Apakah jalur memiliki clone. (Lihat masalah 1509418).
  • Jika trek saat ini bukan trek video yang merekam diri sendiri.
  • Jika Elemen tempat restrictionTarget berasal tidak memenuhi syarat untuk pembatasan.

Pertimbangan foto diri

Saat aplikasi memanggil getDisplayMedia(), dan pengguna memilih untuk merekam tab aplikasi itu sendiri, kita menyebutnya "foto diri".

Metode restrictTo() diekspos pada trek video perekaman tab apa pun, dan bukan hanya untuk perekaman diri. Namun, saat ini Element Capture hanya diaktifkan untuk ambil foto diri. Oleh karena itu, sebaiknya periksa apakah pengguna telah memilih tab saat ini, sebelum mencoba membatasi trek. Hal ini dapat dilakukan menggunakan Capture Handle. Anda juga dapat meminta browser untuk mendorong pengguna mengambil gambar diri sendiri menggunakan preferCurrentTab.

Transparansi

Frame video yang diperoleh aplikasi melalui getDisplayMedia() tidak menyertakan saluran alfa. Jika aplikasi menetapkan target pengambilan yang transparan sebagian, penghapusan saluran alfa memiliki beberapa kemungkinan konsekuensi:

  • Warna mungkin berubah. Elemen target transparan sebagian yang digambar di atas latar belakang terang dapat terlihat lebih gelap saat saluran alfa dihapus, dan yang digambar di atas latar belakang gelap mungkin terlihat lebih terang.
  • Warna yang tidak terlihat atau tidak terlihat oleh pengguna saat saluran alfa disetel ke maksimum, akan muncul setelah saluran alfa dihapus. Misalnya, hal ini dapat menyebabkan area hitam yang tidak terduga dalam frame yang diambil, jika bagian transparan memiliki kode RGBA rgba(0, 0, 0, 0).
Screenshot hasil target pengambilan transparan non-persegi panjang.
Streaming video target pengambilan gambar transparan non-persegi panjang (kanan) adalah persegi panjang berlatar belakang hitam yang berisi lingkaran biru buram.

Target tangkapan tidak memenuhi syarat

Anda dapat mulai membatasi trek ke target tangkapan yang valid. Namun, frame tidak akan dihasilkan dalam kondisi tertentu, misalnya, jika elemen atau ancestor adalah display:none. Alasan umumnya adalah pembatasan berlaku hanya untuk elemen yang terdiri dari satu, kohesif, dua dimensi, area persegi panjang, yang pikselnya secara logis dapat ditentukan terpisah dari elemen induk atau seinduk.

Salah satu pertimbangan penting untuk memastikan bahwa elemen memenuhi syarat untuk pembatasan, adalah bahwa elemen harus membentuk konteks tumpukan sendiri. Untuk memastikan hal ini, Anda dapat menentukan properti CSS isolasi dengan menyetelnya ke isolate.

<div id="captureTarget" style="isolation: isolate;"></iframe>

Perlu diperhatikan bahwa elemen target dapat beralih antara memenuhi syarat dan tidak memenuhi syarat untuk pembatasan kapan saja, misalnya, jika aplikasi mengubah properti CSS-nya. Aplikasi dapat menggunakan target pengambilan yang wajar dan menghindari perubahan properti secara tidak terduga. Jika elemen target menjadi tidak memenuhi syarat, frame baru tidak akan dimunculkan di jalur hingga elemen target kembali memenuhi syarat untuk pembatasan.

Mengaktifkan Element Capture

Element Capture API tersedia di Chrome pada desktop di balik tanda Element Capture dan dapat diaktifkan di chrome://flags/#element-capture.

Fitur ini juga memasuki uji coba origin dari Chrome 121 di desktop, yang memungkinkan developer mengaktifkan fitur bagi pengunjung situs mereka untuk mengumpulkan data dari pengguna sungguhan. Lihat Mulai menggunakan uji coba origin untuk mengetahui informasi selengkapnya tentang uji coba origin.

Keamanan dan privasi

Untuk memahami konsekuensi keamanan, lihat bagian Pertimbangan Privasi dan Keamanan di spesifikasi Element Capture.

Browser Chrome menggambar batas biru di sekitar tepi tab yang ditangkap.

Demo

Anda dapat bermain menggunakan Element Capture dengan menjalankan demo di Glitch. Pastikan untuk memeriksa kode sumbernya.

Masukan

Tim Chrome dan komunitas standar web ingin mengetahui pengalaman Anda saat menggunakan Element Capture.

Beri tahu kami tentang desainnya

Apakah ada sesuatu pada Pengambilan Wilayah yang tidak berfungsi seperti yang Anda harapkan? Atau apakah ada metode atau properti yang hilang yang Anda butuhkan untuk menerapkan ide Anda? Punya pertanyaan atau komentar tentang model keamanan?

  • Laporkan masalah spesifikasi di repo GitHub, atau tambahkan pendapat Anda ke masalah yang sudah ada.

Mengalami masalah dengan penerapan?

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 sederhana untuk mereproduksi bug. Glitch berfungsi dengan baik untuk berbagi repro dengan cepat dan mudah.

Ucapan terima kasih

Foto oleh Paul Skorupskas di Unsplash