Pengantar
Perekaman Audio/Video telah menjadi the "Cawan Suci" dalam pengembangan web untuk waktu yang lama. Selama bertahun-tahun kita harus mengandalkan plugin browser (Flash atau Silverlight) untuk menyelesaikan pekerjaan. Ayo!
HTML5 dapat diselamatkan. Mungkin tidak jelas, tetapi kemunculan HTML5 telah membawa lonjakan akses ke perangkat keras. Geolokasi (GPS), Orientation API (akselerometer), WebGL (GPU), dan Web Audio API (hardware audio) merupakan contoh yang bagus. Fitur-fitur ini sangat ampuh, dan mengekspos JavaScript API tingkat tinggi yang di atas kemampuan perangkat keras yang mendasari sistem.
Tutorial ini memperkenalkan API baru, GetUserMedia, yang memungkinkan aplikasi web untuk mengakses kamera dan mikrofon pengguna.
Jalan menuju getUserMedia()
Jika Anda tidak mengetahui sejarahnya, cara kita sampai di getUserMedia()
API merupakan kisah yang menarik.
Beberapa varian "Media Capture API" telah berkembang selama beberapa tahun terakhir. Banyak orang menyadari kebutuhan untuk dapat mengakses perangkat asli di web, tetapi yang membuat semua orang dan ibu mereka menyusun spesifikasi baru. Banyak hal yang didapatkan sangat berantakan sehingga W3C akhirnya memutuskan untuk membentuk kelompok kerja. Satu-satunya tujuan mereka? Masuk akal! Grup Kerja Kebijakan API Perangkat (DAP) ditugaskan untuk mengonsolidasikan + menstandarkan banyak proposal.
Saya akan mencoba merangkum apa yang terjadi di tahun 2011...
Tahap 1: Pengambilan Media HTML
HTML Media Capture adalah upaya pertama DAP
standarisasi pengambilan media di web. Fungsi ini berfungsi dengan membebani <input type="file">
dan menambahkan nilai baru untuk parameter accept
.
Jika Anda ingin membiarkan pengguna
mengambil foto diri mereka dengan {i>webcam<i},
yang mungkin dilakukan dengan capture=camera
:
<input type="file" accept="image/*;capture=camera">
Perekaman video atau audio mirip:
<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">
Bagus, kan? Saya sangat menyukainya karena menggunakan input file. Secara semantik,
sudah dapat diterapkan. Di mana "API" khusus ini gagal adalah kemampuan untuk
melakukan efek realtime
(misalnya, merender data webcam langsung ke <canvas>
dan menerapkan filter WebGL).
HTML Media Capture hanya memungkinkan Anda untuk merekam file media atau mengambil cuplikan dengan 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 orang berpikir bahwa HTML Media Capture terlalu membatasi, jadi spesifikasi baru
yang mendukung semua jenis perangkat (di masa mendatang). Tidak mengherankan, desain yang disebut
untuk elemen baru, elemen <device>
,
yang menjadi pendahulu getUserMedia()
.
Opera adalah salah satu browser pertama yang membuat implementasi awal
perekaman video berdasarkan elemen <device>
. Segera setelah
(tepatnya hari yang sama),
WhatWG memutuskan untuk menghapus tag <device>
dan menggantinya dengan yang lain, kali ini JavaScript API yang disebut
navigator.getUserMedia()
. Seminggu kemudian, Opera mengeluarkan
bangunan baru yang mencakup
dukungan untuk spesifikasi getUserMedia()
yang diperbarui. Pada akhir tahun itu,
Microsoft ikut serta dengan merilis Lab untuk IE9
yang mendukung spesifikasi baru ini.
Tampilan <device>
akan terlihat seperti berikut:
<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, ada satu API yang tidak perlu dikhawatirkan :) <device>
memiliki dua hal hebat
untuk itu: 1.) bersifat semantik, dan 2.) mudah diperluas untuk mendukung
lebih dari sekadar perangkat audio/video.
Ambil napas. Fitur ini bergerak cepat!
Putaran 3: WebRTC
Elemen <device>
akhirnya menggantikan Dodo.
Kecepatan untuk menemukan API perekaman yang sesuai dipercepat berkat upaya WebRTC (Web Real Time Communications) yang lebih besar. Spesifikasi tersebut diawasi oleh W3C WebRTC Working Group. Google, Opera, Mozilla, dan beberapa aplikasi lainnya memiliki implementasi.
getUserMedia()
terkait dengan WebRTC karena merupakan gateway ke kumpulan API tersebut.
Layanan 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.
Kini akses kamera tinggal panggilan, bukan penginstalan jauh. Data tersebut disimpan langsung ke dalam browser. Anda sudah bersemangat?
Deteksi fitur
Pendeteksian fitur adalah pemeriksaan sederhana untuk mengetahui 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 diakses. Misalnya, jika Anda ingin mengakses webcam, parameter pertama harus {video: true}
. Untuk menggunakan mikrofon dan kamera,
melalui {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? Pengambilan media adalah contoh sempurna dari API HTML5 baru
dan bekerja sama. Ini berfungsi bersama dengan teman HTML5 kita yang lain, <audio>
dan <video>
.
Perhatikan bahwa kita tidak menetapkan atribut src
atau menyertakan elemen <source>
pada elemen <video>
. Alih-alih memasok URL ke video media, kita mengatur
srcObject
ke objek LocalMediaStream
yang mewakili webcam.
Saya juga memberi tahu <video>
kepada autoplay
, jika tidak, kode akan dibekukan di
{i>frame<i} pertama. Menambahkan controls
juga berfungsi seperti yang diharapkan.
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, alih-alih hanya menunjukkan bahwa Anda menginginkan akses dasar ke video (misalnya, {video: true}
), Anda juga dapat mewajibkan streaming
menjadi 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 API batasan.
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 di-resolve 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 hebat Sam Dutton tentang cara agar pengguna dapat memilih sumber media.
Keamanan
Browser akan menampilkan dialog izin saat memanggil navigator.mediaDevices.getUserMedia()
,
yang memberi pengguna opsi untuk memberikan atau menolak
akses ke kamera/mikrofon mereka. Misalnya, di sini
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 sudah 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;
}