首页 > 解决方案 > 当 Web Audio API 静默时从 MediaRecorder 获取空 blob

问题描述

我正在使用MediaRecorderJS 类将动画画布 (WebGL) 和 Web 音频 API 输出一起录制为视频。如果某些音频正在播放,一切都会按预期工作,但如果没有,那么在停止MediaRecorder实例时我会得到空 blob。

以下是我的部分代码:

const chunks = [];
var recorder = null, captureStream = null;

function dataAvailable(event) {
    chunks.push(event.data);
}

function startCapture() {
    const streamDestination = audio.context.createMediaStreamDestination();
    masterGain.connect(streamDestination);
    captureStream = canvas.captureStream();

    // This line adds audio to the recording if audio is playing
    // but if audio isn't playing at the moment, I get empty chunks
    // at the end of recording
    captureStream.addTrack(streamDestination.stream.getAudioTracks()[0]);

    recorder = new MediaRecorder(captureStream);

    recorder.ondataavailable = dataAvailable;
    recorder.onstop = exportVideo;
    recorder.start();
}

function exportVideo() {
    // Here chunks will be empty if Web Audio API
    // didn't played anything during recording
    new Blob(chunks, {'type': 'video/webm'});
    ...
}

网络音频静音时如何正确录制?

在 Windows 10 上使用 Chrome v92。

标签: javascriptweb-audio-apiweb-mediarecorder

解决方案


我相信这是我一个月前打开的https://crbug.com/1223382,但从那时起就没有太大的吸引力了。

基本上,他们在处理静音轨道时仍然有很多麻烦。

作为一种解决方法,您可以通过将振荡器连接到增益设置为 的 GainNode0并将此 GainNode 连接到目标流来强制您的轨道永不静音。

const streamDestination = audio.context.createMediaStreamDestination();
const osc = audio.context.createOscillator();
const gainNode = audio.context.createGain();
gainNode.gain.value = 0;
osc.connect(gainNode);
gainNode.connect(streamDestination);
// then your current code
masterGain.connect(streamDestination);
captureStream = canvas.captureStream();
...

这个片段的小提琴,修复了我从错误报告中复制的案例

注意事项

  • 这对树来说不是很好,但与 WebGL 动画和实时 MediaRecorder 相比,我想它可以被视为最低成本。
  • 这将产生带有音轨的媒体文件,无声,但不静音。

Ps:您可能还想传递一个(相对较小的)时间片MediaRecorder.start(timeslice)来解决这个其他相关的错误,如果由于某种原因您的画布或音频流之一会被静音(例如,如果您停止在画布上绘图,则可能会发生这种情况)超过 5 秒)。


推荐阅读