是否可以检查用户是否有摄像头和麦克风,以及是否已使用Javascript授予权限?

是否可以检查用户是否有摄像头和麦克风,以及是否已使用Javascript授予权限?,javascript,html,html5-video,webrtc,html5-audio,Javascript,Html,Html5 Video,Webrtc,Html5 Audio,我想知道用户的设备是否有摄像头和麦克风,如果有,是否授予使用Javascript获取音频和视频流的权限。我想至少在Chrome和Firefox之间进行检查。这方面的一致API是什么?实时演示: 如果用户不允许使用网络摄像头和/或麦克风,则媒体设备将具有标签属性的值“NULL”。上面的页面将显示此消息:“请调用getUserMedia一次。” 另外,您可以在Chrome Console开发者工具中键入“DetectRTC.MediaDevices” 注意:它只在Chrome中工作。Firef

我想知道用户的设备是否有摄像头和麦克风,如果有,是否授予使用Javascript获取音频和视频流的权限。我想至少在Chrome和Firefox之间进行检查。这方面的一致API是什么?

实时演示:

如果用户不允许使用网络摄像头和/或麦克风,则媒体设备将具有标签属性的值“NULL”。上面的页面将显示此消息:“请调用getUserMedia一次。”

另外,您可以在Chrome Console开发者工具中键入“DetectRTC.MediaDevices”

注意:它只在Chrome中工作。Firefox还不支持类似的API。(更新:Firefox也支持)

更新日期:2015年12月16日 注意:下面的代码片段在Chrome和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>');
});
if(navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices){
//Firefox38+似乎支持enumerateDevicesx
navigator.enumerateDevices=函数(回调){
navigator.mediaDevices.enumerateDevices().then(回调);
};
}
var MediaDevices=[];
var isHTTPs=location.protocol=='https:';
var canEnumerate=假;
if(MediaStreamTrack的类型!==“未定义”&&&“获取源代码”在MediaStreamTrack中){
canEnumerate=true;
}else if(navigator.mediaDevices&&!!navigator.mediaDevices.enumerateDevices){
canEnumerate=true;
}
var=false;
var hasSpeakers=假;
var hasWebcam=错误;
var isMicrophoneAlreadyCaptured=假;
var isWebcamAlreadyCaptured=false;
函数检查设备支持(回调){
如果(!canEnumerate){
返回;
}
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);
}
如果(!navigator.enumerateDevices){
如果(回调){
回调();
}
返回;
}
MediaDevices=[];
枚举设备(函数(设备){
设备。forEach(函数(\u设备){
变量设备={};
用于(var d in_设备){
设备[d]=_设备[d];
}
如果(device.kind==='audio'){
device.kind='audioinput';
}
如果(device.kind==='video'){
device.kind='videoinput';
}
var跳跃;
MediaDevices.forEach(功能(d){
if(d.id==device.id&&d.kind==device.kind){
跳过=真;
}
});
如果(跳过){
返回;
}
如果(!device.deviceId){
device.deviceId=device.id;
}
如果(!device.id){
device.id=device.deviceId;
}
如果(!device.label){
device.label='请调用getUserMedia一次';
如果(!isHTTPs){
device.label='需要HTTPs才能获取此'+device.kind+'设备的标签';
}
}否则{
if(device.kind==='videoinput'&&!isWebcamAlreadyCaptured){
isWebcamAlreadyCaptured=true;
}
if(device.kind==='audioinput'&&!isMicrophoneAlreadyCaptured){
isMicrophoneAlreadyCaptured=真;
}
}
如果(device.kind==='audioinput'){
hasmicro=true;
}
如果(device.kind==='audiooutput'){
hasSpeakers=正确;
}
如果(device.kind==='videoinput'){
hasWebcam=true;
}
//规范中没有“视频输出”。
媒体设备。推送(设备);
});
如果(回调){
回调();
}
});
}
//检查麦克风/摄像头的支持情况!
checkDeviceSupport(函数(){
document.write('hasWebCam:',hasWebCam,
'); 文档。写入('hasmicroscopy:',hasmicroscopy,
'); document.write('isMicrophoneAlreadyCaptured:',isMicrophoneAlreadyCaptured',
'); document.write('isWebcamAlreadyCaptured:',isWebcamAlreadyCaptured',
); });
您可以使用表示媒体流的MediaStreamTrack,然后可以使用其getSources方法,如下所述:

如果你没有任何媒体来源,那么你的客户就没有网络摄像头。
firefox不支持它。

请尝试我的简单跨浏览器代码

注意!!!使用https协议打开带有我的代码的网页!请转到


网络摄像机
函数错误消息(消息,e){
控制台错误(消息,类型e=='undefined'?'':e);
//警报(信息);
}
如果(location.protocol===“https:”){
navigator.getUserMedia=navigator.getUserMedia | | navigator.webkitGetUserMedia | | navigator.mozGetUserMedia | | navigator.msGetUserMedia;
if(navigator.getUserMedia){
getUserMedia({audio:true,video:true},函数(流){
document.querySelector('video').src=window.URL.createObjectURL(流);
var mediaStreamTrack=stream.getVideoTracks()[0];
if(mediaStreamTrack的类型!=“未定义”){
mediaStreamTrack.oneded=函数(){//用于Chrome。
errorMessage('您的网络摄像头正忙!')
}
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
     }
});
navigator.permissions.query({ name: "camera" }).then(res => {
    if(res.state == "granted"){
        // has permission
    }
});
checkMediaAccess = async() => {
    navigator.mediaDevices.enumerateDevices().then( devices => 
        devices.forEach( device => {
            if(device.kind == 'audioinput' && device.label) console.log('Has Audio Access');
            if(device.kind == 'videoinput' && device.label) console.log('Has Video Access');
        }
    ));
}