Merekam streaming video dari elemen mana pun

François Beaufort
François Beaufort

Dengan Screen Capture API, Anda dapat mengambil seluruh tab saat ini. Element Capture API memungkinkan Anda mengambil dan merekam elemen HTML tertentu. Fungsi ini mengubah pengambilan seluruh tab menjadi pengambilan subpohon DOM tertentu, yang hanya mengambil turunan langsung dari elemen target. Dengan kata lain, metode ini memangkas dan menghapus konten yang menghalangi dan 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, Anda mungkin terkadang ingin merekam iframe tersebut sebagai video dan mengirimkannya kepada 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 mengirimkan seluruh tab saat ini. Hal ini kemungkinan akan mengirimkan video orang tersebut kembali kepada mereka. Anda dapat memangkasnya menggunakan Region Capture.

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

Screenshot daftar drop-down yang menutupi konten yang dimaksudkan untuk direkam.
Daftar drop-down akan muncul di atas konten yang akan diambil.

Region Capture tidak akan membantu Anda di sana. Sebagian daftar drop-down mungkin terlihat di layar peserta jarak jauh.

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

Fakta bahwa Region Capture mengambil bagian elemen dengan cara ini (dikenal sebagai konten yang menutupi) menimbulkan beberapa masalah:

  • Konten yang menghalangi dapat menghalangi tampilan konten yang ingin dibagikan pengguna.
  • Konten yang menghalangi mungkin bersifat pribadi (misalnya notifikasi chat).
  • Konten yang menghalangi mungkin membingungkan. (Misalnya, tata letak ulang aplikasi dapat menampilkan video peserta jarak jauh sendiri di atas target yang direkam.)

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 memperoleh 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. Demikian pula, konten yang menghalangi yang muncul, menghilang, atau berpindah tidak memerlukan perlakuan khusus.

Tinjau kembali langkah-langkah ini:

Mulailah dengan mengizinkan pengguna mengambil 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);

Kemudian, 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.
}

Menghasilkan RestrictionTarget

Fokus pada Elemen yang disebut captureTarget. Untuk mendapatkan RestrictionTarget darinya, panggil RestrictionTarget.fromElement(captureTarget). Promise yang ditampilkan akan diselesaikan dengan objek RestrictionTarget baru jika berhasil. Jika tidak, permintaan 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, data ini dapat diteruskan ke dokumen lain menggunakan Window.postMessage().

Membatasi

Saat merekam tab, trek video akan mengekspos restrictTo(). Saat mengambil 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) memutasi trek video menjadi rekaman captureTarget, seolah-olah digambar dengan sendirinya, secara independen dari DOM lainnya. Semua turunan captureTarget juga akan diambil; saudara captureTarget akan dihapus dari pengambilan. Hasilnya adalah setiap frame yang dikirim di jalur akan tampak seperti dipangkas ke kontur captureTarget, dan konten yang menutupi 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 di-resolve jika dapat dijamin bahwa semua frame video berikutnya akan dibatasi hingga captureTarget.

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

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

Pertimbangan pengambilan gambar mandiri

Saat aplikasi memanggil getDisplayMedia(), dan pengguna memilih untuk mengambil tab aplikasi itu sendiri, kita menyebutnya "self-capture".

Metode restrictTo() ditampilkan di trek video perekaman tab, dan tidak hanya untuk perekaman diri. Namun, Element Capture hanya diaktifkan untuk pengambilan gambar mandiri untuk saat ini. 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 melakukan selfie menggunakan preferCurrentTab.

Transparansi

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

  • Warna dapat berubah. Elemen target yang 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 dapat dilihat oleh pengguna saat saluran alfa disetel ke maksimumnya, 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 pengambilan yang tidak memenuhi syarat

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

Salah satu pertimbangan penting untuk memastikan elemen memenuhi syarat untuk pembatasan adalah elemen tersebut harus membentuk konteks penumpukan-nya sendiri. Untuk memastikannya, Anda dapat menentukan properti CSS isolasi, dengan menetapkannya ke isolate.

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

Perhatikan bahwa elemen target dapat beralih antara memenuhi syarat dan tidak memenuhi syarat untuk pembatasan pada titik arbitrer, misalnya, jika aplikasi mengubah properti CSS-nya. Aplikasi dapat menggunakan target pengambilan yang wajar dan menghindari perubahan propertinya secara tidak terduga. Jika elemen target menjadi tidak memenuhi syarat, frame baru tidak akan ditampilkan di jalur hingga elemen target kembali memenuhi syarat untuk pembatasan.

Mengaktifkan Perekaman Elemen

Element Capture API tersedia di Chrome di desktop di balik flag 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 ini bagi pengunjung situs mereka untuk mengumpulkan data dari pengguna sebenarnya. Lihat Memulai uji coba origin untuk mengetahui informasi selengkapnya tentang uji coba origin.

Keamanan dan privasi

Untuk memahami kompromi keamanan, lihat bagian Pertimbangan Privasi dan Keamanan dalam spesifikasi Element Capture.

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

Demo

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

Masukan

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

Beri tahu kami tentang desain

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

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

Mengalami masalah dengan penerapan?

Apakah Anda menemukan bug pada penerapan Chrome? Atau apakah implementasinya berbeda dengan spesifikasi?

  • Laporkan bug di https://new.crbug.com. Pastikan untuk menyertakan detail sebanyak mungkin, dan petunjuk sederhana untuk mereproduksinya. Glitch sangat cocok untuk membagikan rekaman ulang yang cepat dan mudah.

Ucapan terima kasih

Foto oleh Paul Skorupskas di Unsplash