Saat mengembangkan untuk web, standar WebRTC menyediakan API untuk mengakses
kamera dan mikrofon yang
terhubung ke komputer atau {i>smartphone<i}. Perangkat ini
biasanya disebut sebagai Perangkat Media dan dapat diakses dengan JavaScript
melalui objek navigator.mediaDevices
, yang mengimplementasikan MediaDevices
dalam antarmuka berbasis web
yang sederhana. Dari objek ini kita dapat menghitung
semua perangkat yang terhubung, memproses
perubahan perangkat (saat perangkat terhubung atau terputus), dan membuka
untuk mengambil Aliran Media (lihat di bawah ini).
Cara paling umum penggunaannya adalah melalui fungsi getUserMedia()
, yang
menampilkan promise yang akan di-resolve ke MediaStream
untuk media yang cocok
perangkat. Fungsi ini mengambil satu objek MediaStreamConstraints
yang
menentukan persyaratan yang dimiliki. Misalnya, untuk hanya membuka
mikrofon dan kamera default, kita akan melakukan hal berikut.
Menggunakan Promise
const constraints = {
'video': true,
'audio': true
}
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
console.log('Got MediaStream:', stream);
})
.catch(error => {
console.error('Error accessing media devices.', error);
});
Menggunakan async/await
const openMediaDevices = async (constraints) => {
return await navigator.mediaDevices.getUserMedia(constraints);
}
try {
const stream = openMediaDevices({'video':true,'audio':true});
console.log('Got MediaStream:', stream);
} catch(error) {
console.error('Error accessing media devices.', error);
}
Panggilan ke getUserMedia()
akan memicu permintaan izin. Jika pengguna
menerima izin, promise akan diselesaikan dengan MediaStream
yang berisi
satu video dan satu trek audio. Jika izin ditolak,
PermissionDeniedError
ditampilkan. Jika tidak ada perangkat yang cocok
terhubung, NotFoundError
akan ditampilkan.
Referensi API lengkap untuk antarmuka MediaDevices
tersedia di MDN web
dokumen.
Membuat kueri perangkat media
Dalam aplikasi yang lebih kompleks, kemungkinan besar kita ingin memeriksa semua
kamera dan mikrofon yang terhubung dan
memberikan umpan balik yang sesuai kepada
. Ini dapat dilakukan dengan memanggil fungsi enumerateDevices()
. Hal ini akan
menampilkan promise yang di-resolve ke array MediaDevicesInfo
yang menjelaskan
setiap perangkat media yang dikenal. Kita bisa menggunakan ini untuk
mempresentasikan UI kepada pengguna
mereka memilih salah satu yang mereka sukai. Setiap MediaDevicesInfo
berisi properti bernama
kind
dengan nilai audioinput
, audiooutput
atau videoinput
, yang menunjukkan
jenis perangkat media apa itu.
Menggunakan Promise
function getConnectedDevices(type, callback) {
navigator.mediaDevices.enumerateDevices()
.then(devices => {
const filtered = devices.filter(device => device.kind === type);
callback(filtered);
});
}
getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));
Menggunakan async/await
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
const videoCameras = getConnectedDevices('videoinput');
console.log('Cameras found:', videoCameras);
Memproses perubahan perangkat
Sebagian besar komputer mendukung mencolokkan berbagai perangkat selama {i>runtime<i}. Bisa jadi
webcam yang terhubung dengan USB, headset Bluetooth, atau satu set speaker eksternal. Di beberapa
Untuk mendukung fungsionalitas ini, aplikasi web harus
memproses perubahan yang terjadi
perangkat media. Ini dapat dilakukan dengan menambahkan pemroses ke
navigator.mediaDevices
untuk peristiwa devicechange
.
// Updates the select element with the provided set of cameras
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
}).forEach(cameraOption => listElement.add(cameraOption));
}
// Fetch an array of devices of a certain type
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
// Get the initial set of cameras connected
const videoCameras = getConnectedDevices('videoinput');
updateCameraList(videoCameras);
// Listen for changes to media devices and update the list accordingly
navigator.mediaDevices.addEventListener('devicechange', event => {
const newCameraList = getConnectedDevices('video');
updateCameraList(newCameraList);
});
Batasan media
Objek batasan, yang harus mengimplementasikan MediaStreamConstraints
, yang diteruskan sebagai parameter ke getUserMedia()
memungkinkan kita untuk membuka
yang sesuai dengan persyaratan tertentu. Persyaratan ini bisa sangat
didefinisikan secara longgar (audio dan/atau video), atau sangat spesifik (kamera minimum
resolusi atau ID perangkat yang tepat). Disarankan agar aplikasi yang menggunakan
getUserMedia()
API terlebih dahulu memeriksa perangkat yang ada, lalu menentukan
yang cocok dengan perangkat yang tepat menggunakan batasan deviceId
.
Jika memungkinkan, perangkat juga akan dikonfigurasi sesuai dengan batasan. Rab
dapat mengaktifkan peredam gema di mikrofon atau menyetel lebar minimum atau spesifik
dan tinggi video dari kamera.
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
// Open camera with at least minWidth and minHeight capabilities
async function openCamera(cameraId, minWidth, minHeight) {
const constraints = {
'audio': {'echoCancellation': true},
'video': {
'deviceId': cameraId,
'width': {'min': minWidth},
'height': {'min': minHeight}
}
}
return await navigator.mediaDevices.getUserMedia(constraints);
}
const cameras = getConnectedDevices('videoinput');
if (cameras && cameras.length > 0) {
// Open first available video camera with a resolution of 1280x720 pixels
const stream = openCamera(cameras[0].deviceId, 1280, 720);
}
Dokumentasi lengkap untuk antarmuka MediaStreamConstraints
dapat ditemukan
di web MDN
dokumen.
Pemutaran lokal
Setelah perangkat media dibuka dan ada MediaStream
, kita
menetapkannya ke elemen video atau audio untuk memutar streaming secara lokal.
async function playVideoFromCamera() {
try {
const constraints = {'video': true, 'audio': true};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
const videoElement = document.querySelector('video#localVideo');
videoElement.srcObject = stream;
} catch(error) {
console.error('Error opening video camera.', error);
}
}
HTML yang diperlukan untuk elemen video biasa yang digunakan dengan getUserMedia()
akan
biasanya memiliki atribut autoplay
dan playsinline
. autoplay
akan menyebabkan streaming baru yang ditetapkan ke elemen diputar secara otomatis.
Atribut playsinline
memungkinkan video diputar inline, bukan hanya secara penuh
pada browser seluler tertentu. Juga disarankan untuk menggunakan
controls="false"
untuk live stream, kecuali jika pengguna dapat menjeda
mereka.
<html>
<head><title>Local video playback</title></head>
<body>
<video id="localVideo" autoplay playsinline controls="false"/>
</body>
</html>