Navigator.mediaDevices.getUserMedia在iOS 12 Safari上不起作用

Sev*_*sth 15 iphone ios webrtc getusermedia ios12

从iOS 12开始,navigator.mediaDevices.getUserMedia()Safari中返回错误。

要重新创建此代码,请打开iPhone Web Inspector,然后在控制台中运行以下代码段:

var constraints = { audio: true, video: { width: 1280, height: 720 } }; 

navigator.mediaDevices.getUserMedia(constraints)
  .then(function() {
    console.log('getUserMedia completed successfully.');
  })
  .catch(function(error) {
    console.log(error.name + ": " + error.message);
  });
Run Code Online (Sandbox Code Playgroud)

您会看到它在桌面浏览器和iOS 11 Safari中成功运行,但在iOS 12 Safari中失败。

NotAllowedError:在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了权限。

知道为什么吗?

注意:这是在询问用户是否可以访问其相机之前发生的,排除了由于用户拒绝许可而导致的可能性。

jib*_*jib 7

目前有两个可能的立即原因NotAllowedError

1. getUserMedia请求https

Safari https在iOS和OSX中似乎都需要摄像头和麦克风访问。

有了https链接,iOS Safari 12可以为我工作;http中的相同链接获取NotAllowedError

Chrome具有相同的要求。这与规范的方向一致,该规范最近已限于getUserMedia安全上下文。尚未更新的浏览器仍显示navigator.mediaDevices在http中,但getUserMedia始终拒绝NotAllowedError

将来,希望浏览器mediaDevices完全删除http中的内容,以符合规范。

2. getUserMedia需要跨域iframe中的功能策略。

这似乎是Safari 12的新增getUserMedia功能。在iframe中,默认情况下,跨域内容的功能政策处于关闭状态。

对我有用:

<iframe
  allow="camera;microphone"
  src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>
Run Code Online (Sandbox Code Playgroud)

这不起作用

<iframe src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>
Run Code Online (Sandbox Code Playgroud)

...并且除失败外NotAllowedError,Safari在Web控制台中警告:

The top-level frame has prevented a document with a different security origin to
call getUserMedia.
Run Code Online (Sandbox Code Playgroud)

这也是该规范的最新更新。

  • 即使使用https和iframe代码段,这在iOS 12 Safari上对我也不起作用。实际上,直接点击该链接甚至不起作用:https://webrtc.github.io/samples/src/content/getusermedia/gum/在两种情况下,错误均为:`NotAllowedError:该请求不允许当前上下文中的用户代理或平台,可能是因为用户拒绝了许可。 (8认同)
  • 尽管我了解这背后的安全隐患,但在本地主机或本地 Intranet IP 地址上进行开发/测试很糟糕。如果有一个开发标志来启用此功能,那就太好了。 (2认同)

bra*_*sch 6

在调用之前设置以下三个属性可以getUserMedia为我解决问题:

    video.setAttribute('autoplay', '');
    video.setAttribute('muted', '');
    video.setAttribute('playsinline', '');
Run Code Online (Sandbox Code Playgroud)

出于某种原因,video.setAttribute()但是例如尝试将值直接直接分配给视频对象video.muted = ''没有用。

同样,似乎也没有必要调用video.play()

只需将设置为为我工作的video.srcObject返回流getUserMedia

这篇中篇文章具有指向有效演示和源代码的链接。