O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Introdução aos dispositivos de mídia

Ao desenvolver para a web, o padrão WebRTC fornece APIs para acessar câmeras e microfones conectados ao computador ou smartphone. Esses dispositivos são comumente chamados de Dispositivos de mídia e podem ser acessados ​​com JavaScript por meio do objeto navigator.mediaDevices , que implementa a interface MediaDevices . A partir desse objeto, podemos enumerar todos os dispositivos conectados, ouvir as alterações do dispositivo (quando um dispositivo é conectado ou desconectado) e abrir um dispositivo para recuperar um Media Stream (veja abaixo).

A maneira mais comum de usar isso é por meio da função getUserMedia() , que retorna uma promessa que será resolvida para um MediaStream para os dispositivos de mídia correspondentes. Esta função usa um único objeto MediaStreamConstraints que especifica os requisitos que temos. Por exemplo, para simplesmente abrir o microfone e a câmera padrão, faríamos o seguinte.

Usando Promessas

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

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

A chamada para getUserMedia() acionará uma solicitação de permissão. Se o usuário aceitar a permissão, a promessa é resolvida com um MediaStream contendo um vídeo e uma faixa de áudio. Se a permissão for negada, um PermissionDeniedError é lançado. Caso não haja dispositivos correspondentes conectados, um NotFoundError será lançado.

A referência completa da API para a interface MediaDevices está disponível em MDN web docs .

Consultando dispositivos de mídia

Em um aplicativo mais complexo, provavelmente desejaremos verificar todas as câmeras e microfones conectados e fornecer o feedback apropriado ao usuário. Isso pode ser feito chamando a função enumerateDevices() . Isso retornará uma promessa que resolve para uma matriz de MediaDevicesInfo que descreve cada dispositivo de mídia conhecido. Podemos usar isso para apresentar uma IU ao usuário, permitindo que ele escolha a que preferir. Cada MediaDevicesInfo contém uma propriedade chamada kind com o valor audioinput , audiooutput ou videoinput , indicando que tipo de dispositivo de mídia ele é.

Usando Promessas

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

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

Ouvindo mudanças de dispositivos

A maioria dos computadores suporta a conexão de vários dispositivos durante o tempo de execução. Pode ser uma webcam conectada por USB, um fone de ouvido Bluetooth ou um conjunto de alto-falantes externos. Para oferecer suporte adequado a isso, um aplicativo da web deve ouvir as alterações dos dispositivos de mídia. Isso pode ser feito adicionando um ouvinte a navigator.mediaDevices para o evento 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);
});

Restrições de mídia

O objeto constraints, que deve implementar a interface MediaStreamConstraints , que passamos como parâmetro para getUserMedia() nos permite abrir um dispositivo de mídia que atenda a um determinado requisito. Este requisito pode ser definido de forma muito vaga (áudio e / ou vídeo) ou muito específico (resolução mínima da câmera ou uma ID exata do dispositivo). É recomendado que os aplicativos que usam a API getUserMedia() verifiquem primeiro os dispositivos existentes e, a seguir, especifique uma restrição que corresponda ao dispositivo exato usando a restrição deviceId . Os dispositivos também serão, se possível, configurados de acordo com as restrições. Podemos ativar o cancelamento de eco em microfones ou definir uma largura e altura específicas ou mínimas do vídeo da câmera.

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

A documentação completa para a interface MediaStreamConstraints pode ser encontrada nos documentos da web MDN .

Reprodução local

Assim que um dispositivo de mídia for aberto e tivermos um MediaStream disponível, podemos atribuí-lo a um elemento de vídeo ou áudio para reproduzir o fluxo localmente.

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

O HTML necessário para um elemento de vídeo típico usado com getUserMedia() geralmente terá os atributos autoplay e playsinline . O atributo autoplay fará com que novos streams atribuídos ao elemento sejam reproduzidos automaticamente. O atributo playsinline permite que o vídeo seja reproduzido em linha, em vez de apenas em tela inteira, em certos navegadores móveis. Também é recomendado usar controls="false" para transmissões ao vivo, a menos que o usuário deva ser capaz de pausá-las.

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