Medya cihazlarını kullanmaya başlama

Web için geliştirme yaparken WebRTC standardı, bilgisayara veya akıllı telefona bağlı kameralara ve mikrofonlara erişmek için API'ler sağlar. Bu cihazlara yaygın olarak Medya Cihazları denir ve bu cihazlara, MediaDevices arayüzünü uygulayan navigator.mediaDevices nesnesi aracılığıyla JavaScript ile erişilebilir. Bu nesneden tüm bağlı cihazları numaralandırabilir, cihaz değişikliklerini dinleyebilir (bir cihaz bağlıyken veya bağlantısı kesildiğinde) ve bir Medya Akışı almak için cihazı açabiliriz (aşağıya bakın).

Bu kullanım en yaygın olarak kullanılan getUserMedia() işlevidir. Bu işlev, eşleşen medya cihazları için MediaStream olarak çözümlenme sözü döndürür. Bu işlev, sahip olduğumuz gereksinimleri belirten tek bir MediaStreamConstraints nesnesi alır. Örneğin, varsayılan mikrofon ve kamerayı açmak için aşağıdakileri yaparız.

Sözleri Kullanma

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);
    });

Eş zamansız/beklemede özelliğini kullanma

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);
}

getUserMedia() çağrısı, bir izin isteğini tetikler. Kullanıcı izni kabul ederse söz, bir video ve bir ses parçası içeren bir MediaStream ile çözümlenir. İzin reddedilirse bir PermissionDeniedError atılır. Bağlı eşleşen cihaz yoksa bir NotFoundError verilir.

MediaDevices arayüzü için tam API referansına MDN web belgelerinde ulaşabilirsiniz.

Medya cihazları sorgulanıyor

Daha karmaşık bir uygulamada büyük olasılıkla tüm bağlı kamera ve mikrofonları kontrol etmek ve kullanıcıya uygun geri bildirimi sağlamak isteriz. Bu, enumerateDevices() işlevi çağrılarak yapılabilir. Bu işlem, bilinen her medya cihazını açıklayan MediaDevicesInfo dizisine çözümlenen bir söz döndürür. Bunu kullanarak kullanıcıya tercih ettiği arayüzü seçebileceği bir kullanıcı arayüzü sunabiliriz. Her MediaDevicesInfo, ne tür medya cihazı olduğunu belirten audioinput, audiooutput veya videoinput değerine sahip kind adlı bir özellik içerir.

Sözleri Kullanma

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));

Eş zamansız/beklemede özelliğini kullanma

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);

Cihaz değişikliklerini dinliyor

Çoğu bilgisayar, çalışma zamanında çeşitli cihazların takılmasını destekler. USB, Bluetooth mikrofonlu kulaklık veya harici hoparlör seti aracılığıyla bağlı bir web kamerası olabilir. Bir web uygulamasının bunu doğru şekilde desteklemek için medya cihazlarındaki değişiklikleri dinlemesi gerekir. Bunu, devicechange etkinliği için navigator.mediaDevices öğesine bir işleyici ekleyerek yapabilirsiniz.

// 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);
});

Medya kısıtlamaları

getUserMedia() öğesine parametre olarak geçirdiğimiz MediaStreamConstraints arayüzünü uygulaması gereken kısıtlama nesnesi, belirli bir gereksinimle eşleşen bir medya cihazını açmamıza olanak tanır. Bu şart çok genel bir tanım (ses ve/veya video) ya da çok spesifik (minimum kamera çözünürlüğü veya tam cihaz kimliği) olabilir. getUserMedia() API'yi kullanan uygulamaların öncelikle mevcut cihazları kontrol etmesi ve ardından deviceId kısıtlamasını kullanarak tam cihazla eşleşen bir kısıtlama belirtmesi önerilir. Ayrıca, mümkünse cihazlar kısıtlamalara göre yapılandırılır. Mikrofonlarda yankı giderme özelliğini etkinleştirebilir veya kameradan video için belirli ya da minimum genişlik ve yükseklik ayarlayabiliriz.

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);
}

MediaStreamConstraints arayüzüyle ilgili tüm belgeleri MDN web belgelerinde bulabilirsiniz.

Yerel oynatma

Bir medya cihazı açıldıktan ve MediaStream kullanılabilir olduğunda, akışı yerel olarak oynatmak için bu cihazı bir video veya ses öğesine atayabiliriz.

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);
    }
}

getUserMedia() ile kullanılan tipik bir video öğesi için gereken HTML, genellikle autoplay ve playsinline özelliklerine sahip olur. autoplay özelliği, öğeye atanan yeni akışların otomatik olarak oynatılmasına neden olur. playsinline özelliği, videonun belirli mobil tarayıcılarda tam ekran yerine satır içinde oynatılmasını sağlar. Ayrıca, kullanıcının duraklatmasına izin verilmiyorsa canlı yayınlar için controls="false" kullanılması önerilir.

<html>
<head><title>Local video playback</title></head>
<body>
    <video id="localVideo" autoplay playsinline controls="false"/>
</body>
</html>