Recorder.js计算并抵消延迟记录

时间:2015-02-10 04:27:41

标签: javascript audio web-audio recorder.js

我使用Recorder.js录制来自Google Chrome桌面和移动浏览器的音频。在我的特定用例中,我需要准确记录3秒的音频,在特定时间开始和结束。

现在我知道,在录制音频时,由于硬件延迟,您的声卡无法实时工作,因此总有一个内存缓冲区可以让您在不听到跳跃/断断续续的情况下保持录音。

Recorder.js允许您为此精确配置bufferLen变量,而sampleRate则自动从音频上下文对象中获取。以下是其工作原理的简化版本:

var context = new AudioContext();
var recorder;
navigator.getUserMedia({audio: true}, function(stream) {
    recorder = new Recorder(context.createMediaStreamSource(stream), {
        bufferLen: 4096
    });
});

function recordLoop() {
    recorder.record();
    window.setTimeout(function () {
        recorder.stop();
    }, 3000);
}

我面临的问题是record()没有抵消缓冲延迟,也没有停止()。因此,不是获得三秒钟的声音,而是2.97秒,并且开始被切断。

这意味着我的录音不会在同一个地方开始,而且当我循环播放时,循环的长度会有所不同,具体取决于您的设备延迟!!

我在这里看到两种可能的解决方案:

  • 调整Recorder.js代码以根据您的开始/停止时间自动抵消缓冲区(可能添加新的startSync / stopSync函数)
  • 计算延迟并创建两个偏移计时器,以便在正确的时间点启动和停止Recorder.js。

我正在尝试解决方案2,因为解决方案1需要了解我不具备的缓冲阵列:(我相信延迟的计算是:

var bufferSize = 4096;
var sampleRate = 44100
var latency = (bufferSize / sampleRate) * 2; // 0.18575963718820862 secs

然而,当我在真实测试中运行这些计算时,我得到:

var duration = 2.972154195011338 secs
var latency = 0.18575963718820862 secs
var total = duration + latency // 3.1579138321995464 secs

有些事情是对的,它没有3秒钟,它现在开始迷惑我了!我创建了一个带有日志的Recorder.js演示的工作分支:

http://kmturley.github.io/Recorderjs/

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:2)

我对你对延迟的关注感到有些困惑。是的,最小可能的延迟确实与缓冲区的长度有关,但还有许多其他延迟。在任何情况下,延迟与录制持续时间无关,这在我看来就是你的问题。

如果要在44100处记录正好3秒长的缓冲区,即44100 * 3 = 132,300个样本。缓冲区大小为4096个样本,系统只记录该数字的偶数倍。鉴于您最接近的是记录32或33个完整缓冲区。这给出了131072(2.97秒)或135168(3.065秒)样本。

你有几个选择。

  • 选择均匀分割采样率的缓冲区长度。例如11025.然后你可以准确记录12个缓冲区。
  • 记录稍长于您需要的3.0秒,然后再扔掉额外的2868个样本。