Is it possible to check if the user has a camera and microphone and if the permissions have been granted with Javascript?
Live Demo:
If user didn't allow webcam and/or microphone, then media-devices will be having "NULL" value for the "label" attribute. Above page will show this message: "Please invoke getUserMedia once."
PS. You can type "DetectRTC.MediaDevices" in the Chrome Console developers tool.
Note: It works only in Chrome. Firefox isn't supporting similar API yet. (Updated: Firefox supports as well)
Updated at Dec 16, 2015
Note: Following code snippet works both in Chrome and Firefox.
if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { // Firefox 38+ seems having support of enumerateDevicesx navigator.enumerateDevices = function(callback) { navigator.mediaDevices.enumerateDevices().then(callback); };}var MediaDevices = [];var isHTTPs = location.protocol === 'https:';var canEnumerate = false;if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) { canEnumerate = true;} else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) { canEnumerate = true;}var hasMicrophone = false;var hasSpeakers = false;var hasWebcam = false;var isMicrophoneAlreadyCaptured = false;var isWebcamAlreadyCaptured = false;function checkDeviceSupport(callback) { if (!canEnumerate) { return; } if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) { navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack); } if (!navigator.enumerateDevices && navigator.enumerateDevices) { navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator); } if (!navigator.enumerateDevices) { if (callback) { callback(); } return; } MediaDevices = []; navigator.enumerateDevices(function(devices) { devices.forEach(function(_device) { var device = {}; for (var d in _device) { device[d] = _device[d]; } if (device.kind === 'audio') { device.kind = 'audioinput'; } if (device.kind === 'video') { device.kind = 'videoinput'; } var skip; MediaDevices.forEach(function(d) { if (d.id === device.id && d.kind === device.kind) { skip = true; } }); if (skip) { return; } if (!device.deviceId) { device.deviceId = device.id; } if (!device.id) { device.id = device.deviceId; } if (!device.label) { device.label = 'Please invoke getUserMedia once.'; if (!isHTTPs) { device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.'; } } else { if (device.kind === 'videoinput' && !isWebcamAlreadyCaptured) { isWebcamAlreadyCaptured = true; } if (device.kind === 'audioinput' && !isMicrophoneAlreadyCaptured) { isMicrophoneAlreadyCaptured = true; } } if (device.kind === 'audioinput') { hasMicrophone = true; } if (device.kind === 'audiooutput') { hasSpeakers = true; } if (device.kind === 'videoinput') { hasWebcam = true; } // there is no 'videoouput' in the spec. MediaDevices.push(device); }); if (callback) { callback(); } });}// check for microphone/camera support!checkDeviceSupport(function() { document.write('hasWebCam: ', hasWebcam, '<br>'); document.write('hasMicrophone: ', hasMicrophone, '<br>'); document.write('isMicrophoneAlreadyCaptured: ', isMicrophoneAlreadyCaptured, '<br>'); document.write('isWebcamAlreadyCaptured: ', isWebcamAlreadyCaptured, '<br>');});
Yes it is quite possible to detect whether a microphone and a camera is available after granting the permission,
navigator.mediaDevices.getUserMedia({ audio: true, video: true},function (stream) { if(stream.getVideoTracks().length > 0 && stream.getAudioTracks().length > 0){ //code for when none of the devices are available }else{ // code for when both devices are available }});
1)You should be using Media Recorder and understand promise
2)Check if browser support the API enumerateDevices
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { console.log("This browser does not support the API yet");}
let checking=["audioinput","videoinput"];let onlyHas=[];navigator.mediaDevices.enumerateDevices().then((devices)=> { let haveAllDevices=true; devices.forEach((device)=>{ onlyHas.push(device.kind); if(!(device.kind==checking[0] || device.kind==checking[1])){ haveAllDevices=false; } }); //do something about ... }).catch(function(err) { console.log(err.name + ": " + err.message);});
NotAllowedError
, so for now we are only interested in this error.If you read DOMException you can see you can acces DOMException.name
, this is the one that you should be compared, so:
let constraints={audio:true,video:true};navigator.mediaDevices.getUserMedia(constraints) .then((stream)=>{.....}) .catch((err)=> {if(err.name=="NotAllowedError"){console.log("User has denied accessed")} });
PS: About cross browser compatibility MediaRecorder as for today 09/06/2018 it is only supported in chrome and firefox, and the brothers IE and IOS don't https://caniuse.com/#search=MediaRecorder