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 merekam dan merekam elemen HTML tertentu. Metode ini mengubah pengambilan seluruh tab menjadi pengambilan subtree DOM tertentu, yang hanya mengambil turunan langsung dari target-element. Dengan kata lain, fitur ini memangkas dan menghapus konten yang menghalangi dan terhalang.

Mengapa menggunakan Pengambilan Elemen?

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

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

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

Screenshot daftar drop-down yang menutupi konten yang akan direkam.
Menu drop-down muncul di atas konten yang akan direkam.

Pengambilan Wilayah tidak akan membantu Anda dalam hal ini. Sebagian daftar drop-down mungkin akan 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 Perekaman Wilayah merekam bagian elemen dengan cara ini (dikenal sebagai menutupi konten) menimbulkan beberapa masalah:

  • Menutupi konten dapat menghalangi tampilan konten yang ingin dibagikan pengguna.
  • Konten yang menutupi konten lain mungkin bersifat pribadi (misalnya, notifikasi chat).
  • Konten yang menghalangi mungkin membingungkan. (Misalnya, tata ulang aplikasi dapat secara singkat menampilkan video peserta jarak jauh 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 Perekaman Elemen?

captureTarget adalah Elemen di halaman Anda yang berisi konten yang ingin direkam 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 turunannya DOM langsung.

Jika captureTarget berubah ukuran, bentuk, atau lokasi, trek video akan mengikuti, tanpa memerlukan input tambahan dari aplikasi web mana pun. Konten yang muncul, menghilang, atau berpindah-pindah, juga tidak memerlukan penanganan 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() 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 janji 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.
}

Mendapatkan 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 mencetak sejumlah objek RestrictionTarget yang tidak wajar.

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

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

Membatasi

Saat merekam tab, trek video akan 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) mengubah trek video menjadi rekaman captureTarget, seolah-olah direkam dengan sendirinya, terlepas dari DOM lainnya. Semua turunan captureTarget juga direkam; saudara kandung captureTarget tidak disertakan dalam rekaman. Hasilnya adalah semua frame yang dikirimkan di jalur akan muncul seolah-olah dipangkas ke 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 jalur ke status aslinya.

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

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

Jika tidak berhasil, Promise akan ditolak. Panggilan yang tidak berhasil ke restrictTo() akan disebabkan oleh 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 yang direkam kapan saja.)
  • Jika restrictionTarget berasal dari Elemen yang tidak ada lagi.
  • Jika jalur memiliki clone. (Lihat masalah 1509418.)
  • Jika trek saat ini bukan trek video perekaman diri.
  • Jika Elemen yang darinya restrictionTarget berasal tidak memenuhi syarat untuk pembatasan.

Pertimbangan pengambilan gambar sendiri

Saat aplikasi memanggil getDisplayMedia(), dan pengguna memilih untuk merekam tab aplikasi itu sendiri, kami menyebutnya "perekaman mandiri".

Metode restrictTo() diekspos di semua trek video pengambilan tab, dan tidak hanya untuk pengambilan sendiri. Namun, Pengambilan Elemen saat ini hanya diaktifkan untuk pengambilan sendiri. 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 pengambilan gambar sendiri menggunakan preferCurrentTab.

Transparansi

Frame video yang didapatkan aplikasi melalui getDisplayMedia() tidak menyertakan saluran alfa. Jika aplikasi menyetel target pengambilan yang transparan sebagian, penghapusan saluran alfa dapat menimbulkan beberapa 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 yang digambar di atas latar belakang gelap mungkin tampak lebih terang.
  • Warna yang tidak terlihat atau tidak dapat dirasakan 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 direkam, jika bagian transparan memiliki kode RGBA rgba(0, 0, 0, 0).
Screenshot hasil target pengambilan transparan non-persegi panjang.
Aliran 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 selalu dapat mulai membatasi jalur ke target pengambilan yang valid. 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 area persegi panjang dua dimensi yang kohesif dan tunggal, yang pikselnya dapat ditentukan secara logis secara terpisah dari elemen induk atau elemen saudara.

Salah satu pertimbangan penting untuk memastikan elemen memenuhi syarat untuk pembatasan adalah bahwa elemen tersebut harus membentuk konteks penumpukan sendiri. Untuk memastikannya, Anda dapat menentukan properti CSS isolation, 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 mana pun, misalnya, jika aplikasi mengubah properti CSS-nya. Aplikasi harus menggunakan target pengambilan yang wajar dan menghindari perubahan propertinya secara tidak terduga. Jika elemen target menjadi tidak memenuhi syarat, frame baru tidak akan dipancarkan di jalur hingga elemen target kembali memenuhi syarat untuk pembatasan.

Dukungan browser

Pengambilan Elemen tersedia mulai Chrome 132 di desktop saja.

Keamanan dan privasi

Untuk memahami pertimbangan keamanan, lihat bagian Pertimbangan Privasi dan Keamanan dalam spesifikasi Pengambilan Elemen.

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

Demo

Anda dapat bereksperimen dengan Pengambilan Elemen dengan menjalankan demo.

Masukan

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

Beri tahu kami tentang desainnya

Apakah ada sesuatu tentang Perekaman Elemen yang tidak berfungsi seperti yang Anda harapkan? Atau, apakah ada metode atau properti yang hilang yang Anda butuhkan untuk menerapkan ide Anda? Ada pertanyaan atau komentar tentang model keamanan?

  • Laporkan masalah spesifikasi di repositori 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 mereproduksi.

Ucapan terima kasih

Foto oleh Paul Skorupskas di Unsplash