从 getUserMedia 将约束应用于音轨

Applying constraints to an audio track from getUserMedia

是否可以对 运行 现场音轨应用约束?它似乎对我不起作用,至少在 Chrome v80.

假设我有一个流:

const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    autoGainControl: true
    channelCount: 2
    echoCancellation: true
    noiseSuppression: true
  },
  video: false
});

现在,稍后我想更改其中一些参数:

for (const track of stream.getAudioTracks()) {
  track.applyConstraints({
    autoGainControl: false,
    echoCancellation: false,
    noiseSuppression: false
  });
}

这没有效果。如果我调用 track.getConstraints(),我会看到我的新约束,但在我重新加载页面并从头开始应用它们之前,我可以听到它们没有任何效果。此外,当我调用 track.getSettings() 时,我发现我的新约束 尚未 被应用。

我也试过在应用约束之前调用 track.enabled = false,之后调用 track.enabled = true,但没有成功。

关于如何在不重新调用 getUserMedia() 的情况下使其工作的任何建议?

SO 用户 jib, which works on Firefox and adapter.js projects wrote a blog post 在 2017 年了解了这个确切的功能。

这是他们如何将约束应用于轨道:

async function apply(c) {
  await track.applyConstraints(Object.assign(track.getSettings(), c));
  update();
}

c 是一个具有要添加的特定约束的对象。

他们这样做是因为在传递 MediaTrackConstraints dictionary will get reset to their defaults when applied.

现在,您的解决方案应该也适用于您设置的属性。


所以使用这个 fiddle 我确实尝试了我的 macOS 机器上的几个 UA:

Chrome

如您所报告,设置未应用。

这里是the issue跟踪即将实施的。

从这个问题的评论中,您还可以找到一种解决方法,这意味着从与您获得的 deviceId 相同的媒体流请求新的 MediaStream,并应用所需的约束。

Here is a fork of jib's fiddle with such a workaround. 注意 deviceId 来自 track.getSettings()

async function apply(c) {
  track.stop(); // required
  const new_constraints = Object.assign(track.getSettings(), c, );
  const new_stream = await gUM({ audio: new_constraints });

  updateSpectrum( audio.srcObject = new_stream );
  track = new_stream.getAudioTracks()[0];
  update();
}

火狐

无缝工作。

野生动物园

严重崩溃。在我的机器上,运行原来的fiddle,只要调整频谱就会完全崩溃整个gUM浏览器。 - 当前流已停止 - 任何获取新流的尝试都会失败 - 直到重新启动整个应用程序。

我们为 Chrome 制作的分叉 fiddle 至少没有崩溃,但它似乎也没有产生任何可听见的变化...