使用getUserMedia的Firefox v41问题在Chrome或Firefox v36中看不到

时间:2015-10-07 00:52:45

标签: firefox getusermedia

我使用(https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)中的以下代码:

navigator.mediaDevices = navigator.mediaDevices || ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
   getUserMedia: function(c) {
     return new Promise(function(y, n) {
       (navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
     });
   }
} : null);

设置麦克风以供使用。这在Chrome(v45)和Firefox(v36)中效果很好,但在Firefox(v41)中,我在控制台中收到以下错误:

Error: setting a property that has only a getter
RecorderSvc.initAudio@http://fakewebsite.com/js/services/recorder.js:61:1

我可以通过以下方式解决问题:

if (navigator.mozGetUserMedia || navigator.webkitGetUserMedia) {
    navigator.mediaDevices.getUserMedia = function(c) {
        return new Promise(function(y, n) {
            (navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
        });
    }
}

但这在Chrome或Firefox(v36)中无效。

  • 在Chrome中,只定义了navigator.webkitGetUserMedia。
  • 在Firefox(v36)中,只定义了navigator.mozGetUserMedia。
  • 在Firefox(v41)中,都是navigator.mozGetUserMedia AND navigator.mediaDevices已定义。

我无法在不破坏其中一个浏览器的情况下弄清楚如何解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您复制的代码(我偶然编写的代码)在尝试将navigator.mediaDevices.getUserMedia填充到本机尚未安装的浏览器中时做了很糟糕的工作。它已从您找到它的地方删除。感谢您发现它已经坏了。

Polyfilling是一项棘手的业务,因此我强烈建议使用官方WebRTC polyfill adapter.js,而不是尝试手动填充它。您可以使用最新版本的adapter.js,或直接链接到最新版本的适配器,如下所示:

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

请参阅https://jsfiddle.net/srn9db4h/以获取适用于您提及的浏览器的示例。

我不会尝试更正您提到的代码,因为填充navigator.mediaDevices正确地变得非常复杂。

这也不够,因为getUserMedia的位置并不是the specification中唯一发生变化的地方。 constraints 参数has changed as well的格式,这就是为什么navigator.mediaDevices.getUsermedia仍然落后于Chrome 45中的实验标记。

adapter.js会在浏览器赶上之前完成所有这些工作。

答案 1 :(得分:1)

如果您在Try Catch块中包含您的语句,它将起作用。

if (navigator.mediaDevices || (navigator.mozGetUserMedia || navigator.webkitGetUserMedia)) {
  try {
    navigator.mediaDevices = {
      getUserMedia: function(c) {
        return new Promise(function(y, n) {
          (navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
        });
      }
    };
  }
  catch(err) {
    navigator.mediaDevices.getUserMedia = function(c) {
      return new Promise(function(y, n) {
        (navigator.mozGetUserMedia || navigator.webkitGetUserMedia).call(navigator, c, y, n);
      });
    }
  }
} else {
  navigator.mediaDevices = null;
}