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?
我想知道用户的设备是否有连接的摄像头和麦克风,如果是,则授予权限以使用Javascript获取音频和视频流。我想至少在Chrome和Firefox上进行此项检查。什么是一致的API?
5 个解决方案
#1
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."
如果用户不允许网络摄像头和/或麦克风,则媒体设备将具有“标签”属性的“空”值。上面的页面将显示以下消息:“请调用getUserMedia一次。”
PS. You can type "DetectRTC.MediaDevices" in the Chrome Console developers tool.
PS。您可以在Chrome控制台开发人员工具中输入“DetectRTC.MediaDevices”。
Note: It works only in Chrome. Firefox isn't supporting similar API yet. (Updated: Firefox supports as well)
注意:它仅适用于Chrome。 Firefox尚未支持类似的API。 (更新:Firefox也支持)
Updated at Dec 16, 2015
Note: Following code snippet works both in Chrome and Firefox.
注意:以下代码段适用于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>');
});
#2
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
}
});
#3
You can use the MediaStreamTrack which represent a media stream, then you can use its getSources method as explained here: html5rocks
您可以使用代表媒体流的MediaStreamTrack,然后您可以使用其getSources方法,如下所述:html5rocks
If you don't get any media sources then your client hasn't a webcam. It's not supported by firefox.
如果您没有获得任何媒体资源,那么您的客户端就没有网络摄像头。它不受firefox的支持。
#4
Please try my simple cross browser code.
请尝试我的简单跨浏览器代码。
Attention!!! Use https protocol for open web page with my code! Please go to demo
注意!!!使用https协议打开我的代码打开网页!请去演示
<!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!
IE11浏览器不兼容!
Safari 5无法兼容的浏览器!
Android
- Chrome 52
- Firefox 48
- Opera 37
#5
1)You should be using Media Recorder and understand promise
1)您应该使用Media Recorder并理解承诺
2)Check if browser support the API enumerateDevices
2)检查浏览器是否支持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:
如果您读取DOMException,您可以看到您可以访问DOMException.name,这是您应该比较的那个,所以:
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
PS:关于跨浏览器兼容性MediaRecorder和今天09/06/2018它只支持chrome和firefox,兄弟IE和IOS不支持https://caniuse.com/#search=MediaRecorder
#1
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."
如果用户不允许网络摄像头和/或麦克风,则媒体设备将具有“标签”属性的“空”值。上面的页面将显示以下消息:“请调用getUserMedia一次。”
PS. You can type "DetectRTC.MediaDevices" in the Chrome Console developers tool.
PS。您可以在Chrome控制台开发人员工具中输入“DetectRTC.MediaDevices”。
Note: It works only in Chrome. Firefox isn't supporting similar API yet. (Updated: Firefox supports as well)
注意:它仅适用于Chrome。 Firefox尚未支持类似的API。 (更新:Firefox也支持)
Updated at Dec 16, 2015
Note: Following code snippet works both in Chrome and Firefox.
注意:以下代码段适用于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>');
});
#2
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
}
});
#3
You can use the MediaStreamTrack which represent a media stream, then you can use its getSources method as explained here: html5rocks
您可以使用代表媒体流的MediaStreamTrack,然后您可以使用其getSources方法,如下所述:html5rocks
If you don't get any media sources then your client hasn't a webcam. It's not supported by firefox.
如果您没有获得任何媒体资源,那么您的客户端就没有网络摄像头。它不受firefox的支持。
#4
Please try my simple cross browser code.
请尝试我的简单跨浏览器代码。
Attention!!! Use https protocol for open web page with my code! Please go to demo
注意!!!使用https协议打开我的代码打开网页!请去演示
<!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!
IE11浏览器不兼容!
Safari 5无法兼容的浏览器!
Android
- Chrome 52
- Firefox 48
- Opera 37
#5
1)You should be using Media Recorder and understand promise
1)您应该使用Media Recorder并理解承诺
2)Check if browser support the API enumerateDevices
2)检查浏览器是否支持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:
如果您读取DOMException,您可以看到您可以访问DOMException.name,这是您应该比较的那个,所以:
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
PS:关于跨浏览器兼容性MediaRecorder和今天09/06/2018它只支持chrome和firefox,兄弟IE和IOS不支持https://caniuse.com/#search=MediaRecorder