我正在使用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()不能抵消缓冲区延迟,stop()都不能抵消。因此,它没有发出三秒钟的声音,而是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/

    任何帮助将不胜感激。谢谢!

    最佳答案

    您的延迟让我有些困惑。是的,的确,最小可能的延迟将与缓冲区的长度有关,但是还涉及许多其他延迟。无论如何,延迟与录制持续时间无关,在我看来,这就是您的问题所在。

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

    您在这里有几个选择。

  • 选择一个缓冲区长度,该缓冲区长度平均分配采样率。例如11025.然后,您可以准确记录12个缓冲区。
  • 记录比您需要的3.0秒稍长的时间,然后丢弃多余的2868个样本。
  • 关于javascript - Recorder.js计算并抵消延迟记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28424111/

    10-16 23:11