Pengantar
Perekaman Audio/Video telah lama menjadi "Holy Grail" dalam pengembangan web. Selama bertahun-tahun, kita harus mengandalkan plugin browser (Flash atau Silverlight) untuk menyelesaikan pekerjaan. Ayo!
HTML5 dapat membantu. Mungkin tidak terlihat, tetapi kemunculan HTML5 telah membawa lonjakan akses ke hardware perangkat. Geolokasi (GPS), Orientation API (akselerometer), WebGL (GPU), dan Web Audio API (hardware audio) adalah contoh yang sempurna. Fitur ini sangat canggih, mengekspos JavaScript API tingkat tinggi yang berada di atas kemampuan hardware yang mendasari 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 kami sampai pada API getUserMedia() adalah kisah yang menarik.
Beberapa varian "Media Capture API" telah berkembang selama beberapa tahun terakhir. Banyak orang menyadari perlunya kemampuan untuk mengakses perangkat native di web, tetapi hal itu membuat semua orang dan ibu mereka menyusun spesifikasi baru. Keadaan menjadi sangat kacau sehingga W3C akhirnya memutuskan untuk membentuk kelompok kerja. Tujuan satu-satunya? Pahami kekacauan ini. Device APIs Policy (DAP) Working Group telah ditugaskan untuk menggabungkan + menstandarkan berbagai proposal.
Kami akan mencoba merangkum apa yang terjadi pada tahun 2011…
Babak 1: HTML Media Capture
HTML Media Capture adalah upaya pertama DAP untuk
menstandarkan pengambilan media di web. Cara kerjanya adalah dengan membebani <input type="file"> secara berlebihan
dan menambahkan nilai baru untuk parameter accept.
Jika Anda ingin mengizinkan pengguna mengambil snapshot diri mereka sendiri dengan webcam,
hal itu dapat dilakukan dengan capture=camera:
<input type="file" accept="image/*;capture=camera">
Merekam video atau audio juga serupa:
<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">
Bagus, kan? Saya sangat menyukai penggunaan kembali input file. Secara semantik,
hal ini sangat masuk akal. Kekurangan "API" khusus ini adalah kemampuannya untuk melakukan efek real-time
(misalnya, merender data webcam live ke <canvas> dan menerapkan filter WebGL).
HTML Media Capture hanya memungkinkan Anda merekam file media atau mengambil snapshot pada waktu tertentu.
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 parsial)
Babak 2: Elemen perangkat
Banyak yang menganggap HTML Media Capture terlalu terbatas, sehingga muncul spesifikasi baru yang mendukung semua jenis perangkat (di masa mendatang). Tidak mengherankan, desain tersebut memerlukan
elemen baru, yaitu elemen <device>,
yang menjadi pendahulu getUserMedia().
Opera adalah salah satu browser pertama yang membuat implementasi awal
perekaman video berdasarkan elemen <device>. Tidak lama setelah itu
(pada hari yang sama, tepatnya),
WhatWG memutuskan untuk menghapus tag <device> dan menggantinya dengan teknologi baru yang sedang naik daun, kali ini API JavaScript yang disebut
navigator.getUserMedia(). Seminggu kemudian, Opera merilis build baru yang menyertakan
dukungan untuk spesifikasi getUserMedia() yang diperbarui. Di tahun yang sama,
Microsoft ikut bergabung dengan merilis Lab untuk IE9
yang mendukung spesifikasi baru.
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>.
Satu API yang tidak perlu dikhawatirkan lagi :) <device> memiliki dua hal hebat: 1.) semantik, dan 2.) mudah diperluas untuk mendukung
lebih dari sekadar perangkat audio/video.
Tarik napas. Hal ini berkembang pesat.
Babak 3: WebRTC
Elemen <device> akhirnya tidak digunakan lagi.
Upaya untuk menemukan API perekaman yang sesuai dipercepat berkat upaya WebRTC (Web Real Time Communications) yang lebih besar. Spesifikasi tersebut diawasi oleh Kelompok Kerja WebRTC W3C. Google, Opera, Mozilla, dan beberapa lainnya memiliki implementasi.
getUserMedia() terkait dengan WebRTC karena merupakan gateway ke kumpulan API tersebut.
API ini menyediakan sarana untuk mengakses streaming kamera/mikrofon lokal pengguna.
Dukungan:
getUserMedia() telah didukung sejak Chrome 21, Opera 18, dan Firefox 17.
Memulai
Dengan navigator.mediaDevices.getUserMedia(), kita akhirnya dapat memanfaatkan input webcam dan mikrofon tanpa plugin.
Akses kamera kini dapat dilakukan melalui panggilan, bukan penginstalan. Fitur ini disertakan langsung di browser. Penasaran?
Deteksi fitur
Deteksi 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, kami 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 berupa {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 di sini? Perekaman media adalah contoh sempurna dari API HTML5 baru
yang bekerja sama. Elemen ini berfungsi bersama dengan elemen HTML5 lainnya, <audio> dan <video>.
Perhatikan bahwa kita tidak menetapkan atribut src atau menyertakan elemen <source>
pada elemen <video>. Alih-alih memberikan URL ke file media ke video, kita menetapkan
srcObject ke objek LocalMediaStream yang mewakili webcam.
Saya juga memberi tahu <video> untuk autoplay, jika tidak, video akan berhenti 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, selain menunjukkan bahwa Anda menginginkan akses dasar ke video (misalnya, {video: true}), Anda juga dapat mewajibkan streaming
dalam kualitas 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 menarik dari Sam Dutton tentang cara mengizinkan 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 mereka. Misalnya, berikut
adalah dialog izin Chrome:
Menyediakan penggantian
Untuk pengguna yang tidak memiliki dukungan untuk navigator.mediaDevices.getUserMedia(), salah satu opsinya adalah beralih
ke file video yang ada jika API tidak didukung dan/atau panggilan gagal karena alasan tertentu:
if (!navigator.mediaDevices?.getUserMedia) {
video.src = "fallbackvideo.webm";
} else {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
}