我现在想实现一个需求:在录制前指定是否开启麦克风,在录制期间也可以开关麦克风。录制开始时,录制屏幕 + 选择的设备。
我的尝试:
方式一:先创建屏幕录制,然后在需要添加麦克风时 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)
}
所以我的问题是,有没有什么简单的办法可以实现我的需求呢?目前这两种方式只有第一种可行,而在设计上感觉又不太合理。我还有一种想法是,将这两种流分开录制,最后再按照时间来进行合并。但是这样的工作量有点大。大家有什么解决思路或想法吗?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.