Mulai menggunakan perangkat media

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>