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 padrões e
inclui dispositivos de saída de áudio. Você pode testar 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
. Recomendamos que os desenvolvedores usem
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
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()
que fornece informações sobre quais restrições podem ser usadas para uma
chamada getUserMedia()
: recursos de áudio e vídeo aceitos pelo 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