Web Audio API 静音时从 MediaRecorder 获取空 blob

Getting empty blob from MediaRecorder when Web Audio API is silent

我正在使用 MediaRecorder JS class 将动画 canvas (WebGL) 和网络音频 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'});
    ...
}

Web Audio静音时如何正确录音?

在 Windows 10.

上使用 Chrome v92

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

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

作为解决方法,您可以通过将振荡器连接到增益设置为 0 的 GainNode 并将此 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();
...

A fiddle with this snippet, fixing my repro case from the bug report.

注意事项:

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

Ps:您可能还想在 MediaRecorder.start(timeslice) 中传递一个(相对较小的)时间片来解决此 other related bug,如果出于某种原因您的 canvas 或音频流将静音(例如,如果您停止在 canvas 上绘图超过 5 秒)。