Pengantar
Perekaman Audio/Video telah menjadi "Holy Grail" pengembangan web dalam waktu yang lama. Selama bertahun-tahun, kami harus mengandalkan plugin browser (Flash atau Silverlight) untuk menyelesaikan tugas itu. Ayo!
HTML5 dapat membantu. Ini mungkin tidak terlihat, tetapi kemunculan HTML5 telah membawa lonjakan akses ke perangkat keras perangkat. Geolokasi (GPS), Orientation API (akselerometer), WebGL (GPU), dan Web Audio API (hardware audio) adalah contoh yang sempurna. Fitur-fitur ini luar biasa canggih, mengekspos API JavaScript tingkat tinggi yang ada di atas kemampuan hardware yang mendasarinya pada sistem.
Tutorial ini memperkenalkan API baru, GetUserMedia, yang memungkinkan aplikasi web mengakses kamera dan mikrofon pengguna.
Jalan menuju getUserMedia()
Jika Anda tidak mengetahui sejarahnya, cara kita mencapai getUserMedia()
API adalah kisah yang menarik.
Beberapa varian "Media Capture API" telah berkembang selama beberapa tahun terakhir. Banyak orang menyadari perlunya mengakses perangkat native di web, tetapi hal itu membuat semua orang dan ibu mereka membuat spesifikasi baru. Semuanya menjadi sangat berantakan sehingga W3C akhirnya memutuskan untuk membentuk kelompok kerja. Satu-satunya tujuan mereka? Jelaskan kegilaannya! Grup Kerja Kebijakan Perangkat API (DAP) telah ditugaskan untuk menggabungkan dan menstandarkan banyak proposal.
Aku akan mencoba merangkum apa yang terjadi pada tahun 2011...
Tahap 1: Pengambilan Media HTML
HTML Media Capture merupakan upaya pertama DAP dalam
standarisasi pengambilan media di web. Cara ini bekerja dengan membebani <input type="file">
dan menambahkan nilai baru untuk parameter accept
.
Jika ingin mengizinkan pengguna mengambil snapshot mereka dengan webcam,
Anda dapat melakukannya dengan capture=camera
:
<input type="file" accept="image/*;capture=camera">
Cara merekam video atau audio memiliki cara yang mirip:
<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">
Kelihatan bagus kan? Saya sangat suka bahwa ini menggunakan kembali input file. Secara semantik,
itu masuk akal. Di mana "API" khusus ini gagal adalah kemampuan untuk melakukan efek realtime (misalnya merender data webcam langsung ke <canvas>
dan menerapkan filter WebGL).
Pengambilan Media HTML hanya memungkinkan Anda merekam file media atau mengambil snapshot tepat waktu.
Dukungan:
- Browser Android 3.0 - salah satu implementasi pertama. Tonton video ini untuk melihat cara kerjanya.
- Chrome untuk Android (0.16)
- Firefox Mobile 10.0
- iOS6 Safari dan Chrome (dukungan sebagian)
Putaran 2: elemen perangkat
Banyak yang beranggapan bahwa HTML Media Capture terlalu membatasi, sehingga muncul spesifikasi
baru yang mendukung semua jenis perangkat (masa depan). Tidak mengherankan, desain ini memanggil
elemen baru, elemen <device>
,
yang menjadi pendahulunya getUserMedia()
.
Opera adalah salah satu browser pertama yang membuat penerapan awal
rekaman video berdasarkan elemen <device>
. Segera setelah
(tepatnya pada hari yang sama),
WhatWG memutuskan untuk menghapus tag <device>
demi mendukung versi yang lebih baru dan baru, kali ini JavaScript API yang disebut
navigator.getUserMedia()
. Seminggu kemudian, Opera merilis build baru yang menyertakan
dukungan untuk spesifikasi getUserMedia()
yang diupdate. Kemudian pada tahun yang sama,
Microsoft ikut serta dengan merilis Lab untuk IE9
yang mendukung spesifikasi baru ini.
Berikut tampilan <device>
:
<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
function update(stream) {
document.querySelector('video').src = stream.url;
}
</script>
Dukungan:
Sayangnya, tidak ada browser yang dirilis yang menyertakan <device>
.
Saya rasa, lebih sedikit API yang perlu dikhawatirkan :) <device>
memang memiliki dua hal hebat
untuknya: 1.) API itu semantik, dan 2.) mudah diperluas untuk mendukung
lebih dari sekadar perangkat audio/video.
Ambil napas. Fitur ini bergerak cepat!
Tahap 3: WebRTC
Elemen <device>
pada akhirnya mengikuti jalan Dodo.
Kemampuan untuk menemukan API pengambilan yang sesuai kini dipercepat berkat upaya WebRTC (Web Real Time Communications) yang lebih besar. Spesifikasi tersebut diawasi oleh Grup Kerja WebRTC W3C. Google, Opera, Mozilla, dan beberapa lainnya memiliki implementasi.
getUserMedia()
terkait dengan WebRTC karena merupakan gateway ke dalam kumpulan API tersebut.
Layanan ini menyediakan cara untuk mengakses streaming kamera/mikrofon lokal pengguna.
Dukungan:
getUserMedia()
telah didukung sejak Chrome 21, Opera 18, dan Firefox 17.
Memulai
Dengan navigator.mediaDevices.getUserMedia()
, akhirnya kita dapat memanfaatkan input webcam dan mikrofon tanpa plugin.
Akses kamera sekarang dapat diakses melalui panggilan jauh, bukan hanya sekali. File ini akan langsung dimasukkan ke dalam browser. Sudah bersemangat?
Deteksi fitur
Mendeteksi fitur adalah pemeriksaan sederhana untuk keberadaan navigator.mediaDevices.getUserMedia
:
if (navigator.mediaDevices?.getUserMedia) {
// Good to go!
} else {
alert("navigator.mediaDevices.getUserMedia() is not supported");
}
Mendapatkan akses ke perangkat input
Untuk menggunakan webcam atau mikrofon, kita perlu meminta izin.
Parameter pertama untuk navigator.mediaDevices.getUserMedia()
adalah objek yang menentukan detail dan
persyaratan untuk setiap jenis media yang ingin Anda akses. Misalnya, jika Anda ingin mengakses webcam, parameter pertama harus {video: true}
. Untuk menggunakan mikrofon dan kamera,
teruskan {video: true, audio: true}
:
<video autoplay></video>
<script>
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((localMediaStream) => {
const video = document.querySelector("video");
video.srcObject = localMediaStream;
})
.catch((error) => {
console.log("Rejected!", error);
});
</script>
Oke. Jadi apa yang terjadi? Perekaman media adalah contoh sempurna dari API HTML5 baru yang bekerja sama. Ini berfungsi bersama teman HTML5 kami yang lain, <audio>
dan <video>
.
Perhatikan bahwa kita tidak menetapkan atribut src
atau menyertakan elemen <source>
pada elemen <video>
. Alih-alih memasukkan URL ke file media pada video, kita menyetel
srcObject
ke objek LocalMediaStream
yang mewakili webcam.
Saya juga memberi tahu <video>
ke autoplay
, jika tidak, kode akan dibekukan di
frame pertama. Menambahkan controls
juga berfungsi seperti yang Anda harapkan.
Menetapkan batasan media (resolusi, tinggi, lebar)
Parameter pertama untuk getUserMedia()
juga dapat digunakan untuk menentukan lebih banyak persyaratan (atau batasan) pada streaming media yang ditampilkan. Misalnya, sebagai ganti hanya menunjukkan bahwa Anda menginginkan akses dasar ke video (misalnya {video: true}
), Anda juga dapat mewajibkan streaming tersebut dalam format HD:
const hdConstraints = {
video: { width: { exact: 1280} , height: { exact: 720 } },
};
const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);
const vgaConstraints = {
video: { width: { exact: 640} , height: { exact: 360 } },
};
const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);
Untuk konfigurasi lainnya, lihat constraints API.
Memilih sumber media
Metode enumerateDevices()
dari antarmuka MediaDevices
meminta daftar perangkat input dan output media yang tersedia, seperti mikrofon, kamera, headset, dan sebagainya. Promise yang ditampilkan diselesaikan dengan array objek MediaDeviceInfo
yang mendeskripsikan perangkat.
Dalam contoh ini, mikrofon dan kamera terakhir yang ditemukan dipilih sebagai sumber streaming media:
if (!navigator.mediaDevices?.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
let audioSource = null;
let videoSource = null;
devices.forEach((device) => {
if (device.kind === "audioinput") {
audioSource = device.deviceId;
} else if (device.kind === "videoinput") {
videoSource = device.deviceId;
}
});
sourceSelected(audioSource, videoSource);
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
async function sourceSelected(audioSource, videoSource) {
const constraints = {
audio: { deviceId: audioSource },
video: { deviceId: videoSource },
};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
}
Lihat demo bagus Sam Dutton tentang cara memungkinkan pengguna memilih sumber media.
Keamanan
Browser menampilkan dialog izin saat memanggil navigator.mediaDevices.getUserMedia()
,
yang memberi pengguna opsi untuk memberikan atau menolak akses ke kamera/mikrofon. Misalnya, berikut
adalah dialog izin Chrome:
Menyediakan penggantian
Bagi pengguna yang tidak memiliki dukungan untuk navigator.mediaDevices.getUserMedia()
, salah satu opsinya adalah melakukan penggantian
ke file video yang ada jika API tidak didukung dan/atau panggilan gagal karena beberapa alasan:
if (!navigator.mediaDevices?.getUserMedia) {
video.src = "fallbackvideo.webm";
} else {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
}