我现在想实现一个需求:在录制前指定是否开启麦克风,在录制期间也可以开关麦克风。录制开始时,录制屏幕 + 选择的设备。
我的尝试:
方式一:先创建屏幕录制,然后在需要添加麦克风时 addTrack
recorder
recorder.stream.addTrack(${audioTrack})
代码大致如下:
const recorder = new MediaRecorder(
new MediaStream([
...(await getUserScreenStream(this.id)).getVideoTracks()
])
)
// add audio track if needed
if (store.selectedAudioInput) {
recorder.stream.addTrack((await getUserAudioStream(store.selectedAudioInput)).getAudioTracks()[0])
}
这种方式在 addTrack
调用时会自动触发 recorder
的 stop 事件。也就是说如果我还继续想使用这个思路的话不可避免的需要考虑重新开启一个 recorder
然后将原来断的和新的 combine 一下。
方式二:使用 AudioContext 创建一个 MediaStream ,然后使用 MediaStream 去创建 recorder
AudioContext
创建 mediaStreamAudioDestinationNode
mediaStreamAudioDestinationNode.stream
中的音频和屏幕 stream
创建 recorder
MediaStreamAudioSourceNode
对象去 connect mediaStreamAudioDestinationNode
,从而实现 recorder
音频流的更新。但是这种方式有个问题。如果一开始创建时没有开启麦克风,也就是说没有 connect 音频流时 recorder
不会触发 ondataavailable
事件。也就是说没有正确的被录制。
而对于要实现的需求,一开始没有打开麦克风是有可能的。
大致代码如下:
this.audioContext = new AudioContext()
this.mediaStreamAudioDestinationNode = new MediaStreamAudioDestinationNode(this.audioContext)
const recorder = new MediaRecorder(
new MediaStream([
...this.mediaStreamAudioDestinationNode.stream.getAudioTracks(),
...(await getUserScreenStream(this.id)).getVideoTracks()
])
)
// connect stream
if (store.selectedAudioInput) {
const mediaStreamAudioSourceNode = new MediaStreamAudioSourceNode(this.audioContext, {
mediaStream: await getUserAudioStream(devicesStore.selectedAudioInput)
})
mediaStreamAudioSourceNode.connect(this.mediaStreamAudioDestinationNode)
}
所以我的问题是,有没有什么简单的办法可以实现我的需求呢?目前这两种方式只有第一种可行,而在设计上感觉又不太合理。我还有一种想法是,将这两种流分开录制,最后再按照时间来进行合并。但是这样的工作量有点大。大家有什么解决思路或想法吗?
1
chnwillliu 2023-11-24 03:59:48 +08:00 via Android
换个思路,关闭麦克风音轨音量调成 0 ,打开再恢复行么?不一定要真的把 audioTrack 移除。
See GainNode |
2
qianzhu OP @chnwillliu 哇,你好聪明!!非常感谢!我试试看!
|