如何在使用 navigator.mediaDevices.getUserMedia 录制音频时修复大量回声?

Sim*_*nko 3 javascript audio html5-audio electron

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

我在用:

  • Windows 10 专业版 18362.778
  • 铬 81.0.4044.113
  • 电子 8.2.3

这是一些代码。

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

const constraints = {
        audio: false,
        video: {
            mandatory: {
                chromeMediaSource: 'desktop',
                chromeMediaSourceId: source.id
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后我传递给这样的流:

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

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

const constraints = {
        audio: {
            mandatory: {
                chromeMediaSource: 'desktop',
            }
        },
        video: {
            mandatory: {
                chromeMediaSource: 'desktop',
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

未捕获(承诺)DOMException:启动屏幕捕获时出错

一个有趣的事实。当我转到有关音频约束的Mozilla 文档页面并使用演示按钮时,它也会给我回声。我尝试在 Edge 上做,结果更好,但仍然有回声。那么它可以是音频编解码器吗?

这里表示支持 echoCancellation 约束,并且默认情况下从 Chrome 62 版开始。

是 Github 上的分支,我试图在那里找到解决方案,但失败了。

如果您想更仔细地查看它,是我的 git repo。

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

Ale*_*rov 10

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

// 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()])
Run Code Online (Sandbox Code Playgroud)

合并流后,您可以将combinedStream其用作单个流。


Dou*_*ars 7

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

 // Preview the source in a video element
    videoElement.srcObject = stream
    videoElement.muted = true
    videoElement.play()
Run Code Online (Sandbox Code Playgroud)

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