Os navegadores modernos permitem selecionar dispositivos de entrada e saída, incluindo câmeras, microfones e alto-falantes.
Exemplo:
- Em um smartphone, selecione a câmera frontal ou traseira.
- Em um laptop, escolha os alto-falantes internos ou um alto-falante conectado por Bluetooth.
- Para um chat por vídeo, escolha o microfone ou a câmera interna ou externa.
Todas essas funcionalidades são expostas pelo objeto MediaDevices, que é retornado
por navigator.mediaDevices
.
O MediaDevices tem dois métodos, ambos implementados no Chrome 47 para computador e
Android: enumerateDevices()
e getUserMedia()
.

enumerateDevices()
Retorna uma promessa que dá acesso a uma matriz de objetos MediaDeviceInfo
para
os dispositivos disponíveis.
O método é semelhante ao
MediaStreamTrack.getSources()
, mas, ao contrário desse
método (que só foi implementado no Chrome), ele é compatível com os padrões e
inclui dispositivos de saída de áudio. Teste isso com as demonstrações abaixo.
Confira um código um pouco simplificado de uma das demonstrações:
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(errorCallback);
...
function gotDevices(deviceInfos) {
...
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label ||
'Microphone ' + (audioInputSelect.length + 1);
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || 'Speaker ' +
(audioOutputSelect.length + 1);
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' +
(videoSelect.length + 1);
videoSelect.appendChild(option);
}
...
}
Depois de extrair os IDs dos dispositivos disponíveis com enumerateDevices()
, use setSinkId()
(definido na API Audio Output Devices) para mudar o destino de saída de áudio de um elemento de vídeo ou áudio:
element.setSinkId(sinkId)
.then(function() {
console.log('Audio output device attached: ' + sinkId);
})
.catch(function(error) {
// ...
});
Esse método define o dispositivo de saída de áudio do elemento. Depois que setSinkId()
for chamado, você poderá conferir o ID do dispositivo de áudio de saída atual do elemento com a propriedade sinkId
.
getUserMedia()
Isso substitui navigator.getUserMedia()
, mas, em vez de usar um callback, retorna
uma promessa que dá acesso a um MediaStream
. Os desenvolvedores são incentivados a usar
MediaDevices.getUserMedia()
, mas não há planos de remover
navigator.getUserMedia()
: ele continua sendo parte da especificação.
Há uma demonstração no site de amostras do WebRTC.
Confira um fragmento de código da demonstração:
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
var videoTracks = stream.getVideoTracks();
console.log('Got stream with constraints:', constraints);
console.log('Using video device: ' + videoTracks[0].label);
stream.onended = function() {
console.log('Stream ended');
};
window.stream = stream; // make variable available to console
video.srcObject = stream;
})
.catch(function(error) {
// ...
}
Agitação de bandeira
O método enumerateDevices()
não tem flag no Chrome, mas para
MediaDevices.getUserMedia()
, ainda é necessário ativar os recursos experimentais da
plataforma da Web em chrome://flags ou usar a flag de linha de comando a seguir:
--enable-blink-features=GetUserMedia
Da mesma forma para setSinkId()
: ative os recursos experimentais da plataforma da Web ou use uma flag:
--enable-blink-features=AudioOutputDevices
Confira mais detalhes sobre a compatibilidade com navegadores abaixo.
O futuro
O manipulador de eventos ondevicechange
proposto faz o que diz: o evento devicechange
é acionado quando o conjunto de
dispositivos disponíveis muda, e em um manipulador, você pode chamar enumerateDevices()
para
receber a nova lista de dispositivos. Isso ainda não foi implementado em nenhum navegador.
O rascunho de captura de tela é uma extensão
da API Media Capture que propõe um método MediaDevices.getDisplayMedia()
que permite que as regiões da tela de um usuário sejam usadas como a origem de um stream
de mídia. Há também uma proposta de extensão MediaDevices
para
getSupportedConstraints()
(link em inglês), que fornece informações sobre quais restrições podem ser usadas para uma
chamada getUserMedia()
: recursos de áudio e vídeo compatíveis com o navegador.
Demonstrações
- getUserMedia()
- enumerateDevices():
- MediaDevices shim
Saiba mais
- Mozilla Developer Network: dispositivos de mídia
- Status da implementação
- Rascunho do editor de captura e transmissão de mídia: MediaDevices
- API Audio Output Devices