从 getUserMedia 对音轨应用约束

Bra*_*rad 4 javascript google-chrome webrtc getusermedia mediastream

是否可以对正在运行的实时音轨应用约束?它似乎对我不起作用,至少在 Chrome v80 上。

假设我有一个流:

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

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

for (const track of stream.getAudioTracks()) {
  track.applyConstraints({
    autoGainControl: false,
    echoCancellation: false,
    noiseSuppression: false
  });
}
Run Code Online (Sandbox Code Playgroud)

这没有效果。如果我调用track.getConstraints(),我会看到我的新约束,但在我重新加载页面并从头开始应用它们之前,我会听到它们没有任何影响。此外,当我打电话track.getSettings(),我看到我的新的制约还没有得到应用。

我也试过track.enabled = false在应用约束之前打电话,track.enabled = true之后没有运气。

关于如何在不拨打新电话的情况下使其工作的任何建议getUserMedia()

Kai*_*ido 7

SO 用户jib,在 Firefox 和 adapter.js 项目上工作,在 2017 年写了一篇关于这个确切功能的博客文章

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

async function apply(c) {
  await track.applyConstraints(Object.assign(track.getSettings(), c));
  update();
}
Run Code Online (Sandbox Code Playgroud)

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

他们这样做是因为所有在传递MediaTrackConstraints字典时被省略的属性 在应用时都会重置为其默认值。

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


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

铬合金

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

这是跟踪即将实施的问题

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

这是带有这种解决方法的 jib 的一个分支。请注意,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();
}
Run Code Online (Sandbox Code Playgroud)

火狐

无缝运行。

苹果浏览器

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

我们为 Chrome 制作的分叉小提琴至少不会崩溃,但它似乎也没有产生任何声音变化......

  • 一如既往地感谢@Kaiido。你似乎总是能够找到我一直尝试使用的所有新东西的 Chrome 错误。:-) (3认同)