Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to check if the user has a camera and microphone and if the permissions have been granted with Javascript?

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?

like image 789
Amal Antony Avatar asked May 05 '15 07:05

Amal Antony


People also ask

What is get user Media?

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 .

What is DetectRTC?

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.

How to Check camera permission in JavaScript?

You can type "DetectRTC.


2 Answers

Live Demo:

  • https://www.webrtc-experiment.com/DetectRTC/

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>'); }); 
like image 105
Muaz Khan Avatar answered Sep 19 '22 14:09

Muaz Khan


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    }); 
like image 39
imal hasaranga perera Avatar answered Sep 21 '22 14:09

imal hasaranga perera