2019 年访问 navigator.mediaDevices.getUserMedia() 的方式

2019s way of accessing navigator.mediaDevices.getUserMedia()

我目前正在开发一个 angular7-app,通过 CLI 以标准方式创建它并开始编码。 现在我想录制一些音频,这在现代浏览器中并不困难。我正在使用 getUserMedia() 的内置浏览器功能。 现在问题来了:zone.js 捕获了对 then() 回调的所有调用,并且不允许在其中执行自定义代码。

但是:有 zone.js 提供的补丁,因此调用此特殊回调:https://github.com/angular/zone.js/blob/master/dist/zone-patch-user-media.js

不幸的是,这指的是 getUserMedia() (https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia) 的贬值实现。 所以这个脚本不起作用。我尝试更改它但没有任何效果。调用补丁是因为显示 console.log() 并且在调试器中,我可以通过该函数。我假设,这可能是执行回调的一个小改动。在调试器中,回调再次被 zone.js 中的函数捕获,正如我所假设的那样,补丁工作时不应调用该函数。我的实现和这里一样(https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia):

navigator.mediaDevices.getUserMedia(constraints).then(
function(stream) {
    /* use the stream */ 
}).catch(
function(err) { 
    /* handle the error */ 
});

那么,当前使回调起作用的方法是什么?还是我把概念弄错了?或者我应该使用 npm 中的一些库来录制音频吗?

据我所知,如果与 navigator 方法一起使用,zone.js 应该不会引起问题,因为它们众所周知并且已正确修补。顺便说一下,如果你对自己说的有把握的话,还是可以用zone.runOutsideAngular出一个区的:

constructor(private zone: NgZone) { }

yourMethod() {
  this.zone.runOutsideAngular(() => {
    navigator.mediaDevices.getUserMedia(constraints)
      .then(stream => console.log(stream))
      .catch(err => console.error(err));
  });

}

如果你想re-enter一个区域,你可以调用:

this.zone.run(() => {
  // again inside a zone
});

但请注意,只有在您想要继续异步流时才需要它。同步代码将在区域内继续执行:

yourMethod() {
  // this is inside a zone

  this.zone.runOutsideAngular(() => {
    navigator.mediaDevices.getUserMedia(constraints)
      .then(stream => {

        // this is outside a zone

        this.zone.run(() => {

           // and again inside a zone

        });
      })
      .catch(err => console.error(err));
  });

 // this is still inside a zone

}