一旦被拒绝,我们如何使用getUserMedia()请求摄像头/麦克风访问?
我正在使用getUserMedia访问用户的摄像头并将数据传输到画布。这一切都很好。
在测试中,我打了一次否认。此时在Chrome和Firefox中,任何带有getUserMedia()的后续请求都默认为拒绝状态。
我们显然不希望通过在拒绝后的每个页面加载上请求相机/麦克风的权限来惹恼我们的用户。对地理位置api来说已经足够烦人了。
但是,必须有一种方法再次请求它。仅仅因为用户点击拒绝一次并不意味着他们想要一直拒绝网络摄像头访问。
我一直在阅读有关规范和谷歌搜索一段时间,但我没有找到任何明确的问题。
编辑:进一步研究,似乎在Chrome中点击Deny会将当前网站添加到阻止列表中。这可以通过chrome:// settings / content手动访问。滚动到媒体。管理例外,删除被阻止的网站。
链接到chrome:// settings / content不起作用(在我们想要添加有用链接以允许人们重新启用权限的情况下)。
用于处理getUserMedia周围权限的整个UX很糟糕。 =(
使用HTTPS。当用户授予一次权限时,会记住该内容,并且Chrome不会再次请求该页面的权限,您可以立即访问该媒体。这并没有为您提供再次强制用户权限栏的方法,但至少确保您在用户授予权限一次后不必继续请求它。
如果您的应用程序是从SSL(https://)运行,则此权限将是持久的。也就是说,用户不必每次都授予/拒绝访问权限。
见:http://www.html5rocks.com/en/tutorials/getusermedia/intro/
jeffreyveon的回答将有助于减少用户选择拒绝的机会,因为她只需要选择一次。
如果她点击拒绝,您可以提供一条消息,说明您需要权限的原因以及如何更新她的选择。例如:
navigator.getUserMedia (
// constraints
{
video: true,
audio: true
},
// successCallback
function(localMediaStream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function(e) {
// Do something with the video here.
};
},
// errorCallback
function(err) {
if(err === PERMISSION_DENIED) {
// Explain why you need permission and how to update the permission setting
}
}
);
Chrome在Permissions API
中实现了navigator.permissions
,这同样适用于camera
和microphone
权限。
截至目前,在调用getUserMedia()
之前,您可以使用此API查询相机和麦克风的权限状态:
navigator.permissions.query({name: 'microphone'})
.then((permissionObj) => {
console.log(permissionObj.state);
})
.catch((error) => {
console.log('Got error :', error);
})
navigator.permissions.query({name: 'camera'})
.then((permissionObj) => {
console.log(permissionObj.state);
})
.catch((error) => {
console.log('Got error :', error);
})
成功后,permissionObj.state
将返回denied
,granted
或prompt
。
有用的SF问题/答案here
对于跨浏览器解决方案,一种简单的方法可以是监视调用getUserMedia()
Promise的时间与拒绝或解析它之间的时间差,如下所示:
// In the Promise handlers, if Date.now() - now < 500 then we can assume this is a persisted user setting
var now = Date.now();
navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then(function(stream) {
console.log('Got stream, time diff :', Date.now() - now);
})
.catch(function(err) {
console.log('GUM failed with error, time diff: ', Date.now() - now);
});
这个Medium article提供了更多细节。
希望这可以帮助!
请注意以下几点。
1. Localhost: In Localhost Chrome Browser asking permission only one time and Firefox every pageload.
2. HTTPS: Both Browsers Chrome and Firefox asking permission only one time.
更新后的答案是,当请求通过HTTP时,Chrome(目前正在73上测试)不再持续提示摄像头访问。
然而,Firefox确实如此。