如何在使用 navigator.mediaDevices.getUserMedia 录制音频时修复广泛的回声?

Posted

技术标签:

【中文标题】如何在使用 navigator.mediaDevices.getUserMedia 录制音频时修复广泛的回声?【英文标题】:How to fix an extensive echoing while recording audio using navigator.mediaDevices.getUserMedia? 【发布时间】:2020-04-30 03:07:32 【问题描述】:

所以,我正在开发一个小型电子桌面应用程序,它可以捕获桌面屏幕并记录视频和音频。 当我尝试向流中添加音频时,它开始回显非常糟糕,我不知道为什么。

我正在使用:

Windows 10 专业版 18362.778 Chrome 81.0.4044.113 电子 8.2.3

这是一些代码。

当我只想捕捉和录制视频时,我会创建这些约束:

const constraints = 
        audio: false,
        video: 
            mandatory: 
                chromeMediaSource: 'desktop',
                chromeMediaSourceId: source.id
            
        
    

然后我像这样传递给流:

const stream = await navigator.mediaDevices.getUserMedia(constraints)

它就像一个魅力。但是,当我开始添加音频时,它会给我回声:

const constraints = 
        audio: 
            mandatory: 
                chromeMediaSource: 'desktop',
            
        ,
        video: 
            mandatory: 
                chromeMediaSource: 'desktop',
            
        
    

另外,我不能只将音频设置为 true。然后它给了我这个错误:

Uncaught (in promise) DOMException: Error started screen capture

一个有趣的事实。当我在音频限制上转到Mozilla documentation page 并使用演示按钮时,它也会给我回声。我尝试在 Edge 上进行,结果更好,但仍然有回声。那么它可以是音频编解码器吗?

Here 表示支持 echoCancellation 约束,默认情况下从 Chrome 版本 62 开始。

Here 是我在 Github 上尝试寻找解决方案但失败的分支。

Here 是我的 git repo,如果你想更仔细地看的话。

PS:这是我在这里的第一篇文章。如果我在这里做错了什么并且可以改进帖子,请告诉我。谢谢!

【问题讨论】:

更新。 Chrome 版本是 80.0.3987.163 【参考方案1】:

问题来自于尝试同时启动麦克风音频和计算机屏幕视频的单一流。要解决此问题,您需要先创建音频流,然后单独创建捕获计算机屏幕的视频流,最后将流合并为一个。

// create audio and video constraints
const constraintsVideo = 
    audio: false,
    video: 
        mandatory: 
            chromeMediaSource: 'desktop',
            chromeMediaSourceId: source.id
        
    

const constraintsAudio = audio: true

// create audio and video streams separately
const audiostream = await navigator.mediaDevices.getUserMedia(constraintsAudio)
const videoStream = await navigator.mediaDevices.getUserMedia(constraintsVideo)

// combine the streams 
const combinedStream = new MediaStream([...videoStream.getVideoTracks(), ...audioStream.getAudioTracks()])

合并流后,您可以使用combinedStream,就好像它起源于单个流一样。

【讨论】:

谢谢,亚历克斯。这真的很好。我希望有关于使用 WebRTC 的更好的文档和示例。 很好的答案,亚历克斯,谢谢。您能否详细说明一下为什么会这样以及区别在哪里? 甚至 webrtc.org 网站也提供了一个带有音频的示例:true,video:true (webrtc.org/getting-started/media-devices#using-asyncawait)...我尝试了您的解决方案,但是我一直有回声...我想我可以通过将 来修复它【参考方案2】:

我认为这里的简单解决方法是将静音元素添加到您页面上的播放中。

 // Preview the source in a video element
    videoElement.srcObject = stream
    videoElement.muted = true
    videoElement.play()

这适用于所有浏览器,您仍然可以录制音频。

【讨论】:

我刚刚尝试了该解决方案,应用程序不会使用静音元素录制声音。 嘿,道格。我也会提高你的答案,因为它部分正确。但是,我只能录制系统音频,而不是麦克风。

以上是关于如何在使用 navigator.mediaDevices.getUserMedia 录制音频时修复广泛的回声?的主要内容,如果未能解决你的问题,请参考以下文章

如何在发布管道中使用输出变量

如何在Hive&Impala中使用UDF

如何使用 Firebase 在 Web 上托管 Flutter?它的效果如何?

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何在android中使用WCF服务?

如何使用 Java 在 selenium webdriver 中打开新选项卡,或者如何使用 selenium webdriver 使用动作类在 selenium 中按 ctrl + T [重复]