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

前端 未结 6 1594
情书的邮戳
情书的邮戳 2020-12-13 03:09

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 Javascr

相关标签:
6条回答
  • 2020-12-13 03:27

    Please try my simple cross browser code.

    Attention!!! Use https protocol for open web page with my code! Please go to demo

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <h1>Web camera</h1>
        <video autoplay></video>
    
        <script>
            function errorMessage(message, e) {
                console.error(message, typeof e == 'undefined' ? '' : e);
                //alert(message);
            }
    
            if (location.protocol === 'https:') {
                navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
                if (navigator.getUserMedia) {
                    navigator.getUserMedia({ audio: true, video: true }, function (stream) {
                        document.querySelector('video').src = window.URL.createObjectURL(stream);
                        var mediaStreamTrack = stream.getVideoTracks()[0];
                        if (typeof mediaStreamTrack != "undefined") {
                            mediaStreamTrack.onended = function () {//for Chrome.
                                errorMessage('Your webcam is busy!')
                            }
                        } else errorMessage('Permission denied!');
                    }, function (e) {
                        var message;
                        switch (e.name) {
                            case 'NotFoundError':
                            case 'DevicesNotFoundError':
                                message = 'Please setup your webcam first.';
                                break;
                            case 'SourceUnavailableError':
                                message = 'Your webcam is busy';
                                break;
                            case 'PermissionDeniedError':
                            case 'SecurityError':
                                message = 'Permission denied!';
                                break;
                            default: errorMessage('Reeeejected!', e);
                                return;
                        }
                        errorMessage(message);
                    });
                } else errorMessage('Uncompatible browser!');
            } else errorMessage('Use https protocol for open this page.')
      </script>
    </body>
    </html>

    I have tested it into follow browsers:

    Windows 10

    • Chrome 52
    • Edge 25
    • Firefox 47
    • IE11 Uncompatible browser!
    • Opera 39
    • Safari 5 Uncompatible browser!

    Android

    • Chrome 52
    • Firefox 48
    • Opera 37
    0 讨论(0)
  • 2020-12-13 03:36

    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>');
    });
    
    0 讨论(0)
  • 2020-12-13 03:38

    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");
    }
    3) Check if user has conected audio and camera, the only values are "videoinput", "audioinput" or "audiooutput" DeviceInfo.kind

    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);
    });
    4)Permissions are reused,it means that if user already has denied permission then when you call getUserMedia the bowser won't prompt anything and will reject the promise promise throwing an error of type DOMException, otherwise it will resolve the promise. When the promise rejects it can be many reasons read, one of then is when user has denied access, when this happens it will throw an DOMException of type 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

    0 讨论(0)
  • 2020-12-13 03:38

    Now you can use navigator.permissions also to check permissions already exist

    navigator.permissions.query({ name: "camera" }).then(res => {
        if(res.state == "granted"){
            // has permission
        }
    });
    

    for more info - https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query

    Note: It works perfectly on chrome but firefox not supporting it right now

    0 讨论(0)
  • 2020-12-13 03:40

    You can use the MediaStreamTrack which represent a media stream, then you can use its getSources method as explained here: html5rocks

    If you don't get any media sources then your client hasn't a webcam. It's not supported by firefox.

    0 讨论(0)
  • 2020-12-13 03:50

    Yes it is quite possible to detect whether a microphone and a camera is available after granting the permission,

    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
         }
    });
    
    0 讨论(0)
提交回复
热议问题