I would like to find out if the user's device has an attached camera and microphone, and if so, has permissions been granted to get the audio and video stream using Javascript. I want to make this check to be made across Chrome and Firefox at the very least. What's a consistent API for this?
getUserMedia() method prompts the user for permission to use up to one video input device (such as a camera or shared screen) and up to one audio input device (such as a microphone) as the source for a MediaStream .
DetectRTC is a tiny JavaScript library that can be used to detect WebRTC features e.g. system having speakers, microphone or webcam, screen capturing is supported, number of audio/video devices etc.
You can type "DetectRTC.
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)
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.
Using the old API:
navigator.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 } }, function (error) { // code for when there is an error });
Using the newer, promise-based API:
navigator.mediaDevices.getUserMedia({ audio: true, video: true}) .then(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 } }) .catch(function (error) { // code for when there is an error });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With