Merekam streaming video dari elemen mana pun

François Beaufort
François Beaufort

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 subpohon DOM tertentu, yang hanya menangkap turunan langsung dari elemen target. Dengan kata lain, fungsi ini memangkas dan menghapus konten yang terhalang dan terhalang.

Mengapa menggunakan Pengambilan Elemen?

Mempertimbangkan persyaratan aplikasi konferensi video dapat membantu Anda memahami kegunaan Pengambilan Elemen. Jika memiliki aplikasi konferensi video yang memungkinkan Anda menyematkan aplikasi pihak ketiga dalam iframe, terkadang Anda dapat 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 dengan François.

Memanggil getDisplayMedia() dan mengizinkan pengguna memilih tab saat ini akan mentransmisikan seluruh tab saat ini. Hal itu kemungkinan besar mengirimkan kembali video milik orang lain kepada mereka. Anda dapat memangkasnya menggunakan Region Capture.

Namun, bagaimana jika presenter terlibat dengan aplikasi konferensi video dan beberapa konten, seperti daftar {i>drop-down<i}, kebetulan menggambar di atas konten yang dimaksudkan untuk direkam?

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

Pengambilan Wilayah tidak akan membantu Anda dalam hal tersebut. Bagian dari daftar {i>drop-down<i} mungkin terlihat di layar peserta jarak jauh.

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

Fakta bahwa Pengambilan Wilayah mengambil bagian elemen dengan cara ini (dikenal sebagai konten yang menutupi konten) akan menimbulkan beberapa masalah:

  • Menghalangi konten dapat menghalangi melihat konten yang ingin dibagikan oleh pengguna.
  • Konten yang dihalangi mungkin bersifat pribadi (misalnya notifikasi chat).
  • Menghalangi konten mungkin membingungkan. (Misalnya, tata letak ulang aplikasi dapat secara singkat memindahkan video milik peserta jarak jauh melebihi target yang diambil.)

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

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

Bagaimana cara menggunakan Pengambilan Elemen?

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 kini hanya terdiri dari piksel yang merupakan bagian dari captureTarget dan turunan DOM langsungnya.

Jika captureTarget mengubah ukuran, bentuk, atau lokasi, trek video akan mengikuti, tanpa memerlukan input tambahan dari salah satu aplikasi web. Membatasi konten yang muncul, menghilang, atau berpindah-pindah, juga tidak memerlukan perlakuan khusus.

Tinjau kembali langkah-langkah berikut:

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() menggunakan 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 selesai, 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 di-resolve dengan objek RestrictionTarget baru jika berhasil. Jika tidak, item ini akan ditolak jika Anda telah mencetak 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. Instance dapat diteruskan ke dokumen lain menggunakan Window.postMessage().

Membatasi

Saat merekam tab, trek video menampilkan restrictTo(). Saat merekam tab saat ini, Anda dapat memanggil restrictTo() dengan null atau RestrictionTarget apa pun yang berasal dari Elemen dalam tab saat ini.

Panggilan ke restrictTo(restrictionTarget) akan mengubah trek video menjadi rekaman captureTarget, seolah-olah trek tersebut digambar dengan sendirinya, terlepas dari DOM lainnya. Setiap turunan dari captureTarget juga akan ditangkap; saudara dari captureTarget dieliminasi dari penangkapan. Hasilnya adalah setiap frame yang ditayangkan pada jalur tampak seolah-olah dipangkas sesuai kontur captureTarget, dan semua konten yang menghalangi 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 keadaan semula.

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

Jika panggilan ke restrictTo() berhasil, Promise yang ditampilkan akan di-resolve ketika ada jaminan bahwa semua frame video berikutnya akan dibatasi ke captureTarget.

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

  • Jika restrictionTarget dicetak di tab selain yang sedang direkam. (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.
  • Jika trek memiliki clone. (Lihat masalah 1509418.)
  • Jika trek saat ini bukan trek video rekaman otomatis.
  • Jika Elemen tempat restrictionTarget berasal tidak memenuhi syarat untuk pembatasan.

Pertimbangan pengambilan gambar diri

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

Metode restrictTo() ditampilkan pada trek video perekaman tab, dan tidak hanya untuk perekaman otomatis. Namun, untuk saat ini, Pengambilan Elemen hanya diaktifkan untuk pengambilan otomatis. Oleh karena itu, sebaiknya periksa apakah pengguna memilih tab saat ini, sebelum mencoba membatasi jalur. Hal ini dapat dilakukan menggunakan Capture Handle. Anda juga dapat meminta browser untuk mendorong pengguna mengambil foto diri menggunakan preferCurrentTab.

Transparansi

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

  • Warna dapat berubah. Elemen target transparan sebagian yang digambar di atas latar belakang terang mungkin tampak lebih gelap saat saluran alfa dihapus, dan elemen yang digambar di atas latar belakang gelap mungkin tampak lebih terang.
  • Warna yang tidak terlihat atau tidak terlihat oleh pengguna ketika 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 transparan non-persegi panjang (kanan) adalah persegi panjang latar belakang hitam yang berisi lingkaran biru buram.

Target penangkapan yang tidak memenuhi syarat

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

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

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

Perhatikan 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 mengubah propertinya 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 Pengambilan Elemen

Element Capture API tersedia di Chrome pada desktop di balik tanda Pengambilan Elemen 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 tersebut bagi pengunjung situs mereka untuk mengumpulkan data dari pengguna sungguhan. Lihat Memulai uji coba origin untuk mengetahui informasi selengkapnya tentang uji coba origin.

Keamanan dan privasi

Untuk memahami konsekuensi keamanan, lihat bagian Pertimbangan Privasi dan Keamanan pada spesifikasi Pengambilan Elemen.

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

Demo

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

Masukan

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

Beri tahu kami tentang desainnya

Apakah ada sesuatu tentang Region Capture yang tidak berfungsi seperti yang Anda harapkan? Atau apakah ada metode atau properti yang hilang yang diperlukan untuk menerapkan ide Anda? Ada pertanyaan atau komentar tentang model keamanan?

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

Ada 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 sederhana untuk mereproduksi bug. Glitch sangat cocok untuk membagikan repro dengan cepat dan mudah.

Ucapan terima kasih

Foto oleh Paul Skorupskas di Unsplash