【问题标题】:Decrease bitrate on WAV file created with recorderjs降低使用 recorderjs 创建的 WAV 文件的比特率
【发布时间】:2013-04-24 04:21:37
【问题描述】:

我正在尝试在用户上传简短录音(例如,1 到 12 秒长)的应用引擎网站上使用 recorderjs。我注意到我上传的 WAV 文件比我预期的要大得多。例如,我刚刚创建了一个持续大约 9 秒的记录,上传的 blob 为 1736769 字节,即 > 1.5 兆字节。

问题:

如何修改 recorderjs 代码(或我自己的代码 - 也许我使用不正确的 recorderjs)以使我的音频 blob 具有较低的比特率?我希望 10 秒的录音安全地低于 1 MB。

我的猜测是我需要修改 here 中的 encodeWAV 函数,或者可能是 exportWAV,但我不确定如何。在 exportWAV 中删除交错缓冲区的所有其他元素是否有意义?有没有更智能的方法来做到这一点?导出的 WAV 的比特率如何取决于我的计算机属性(例如我的声卡的采样率)?

如果有帮助,我可以在我自己的代码中添加一些细节。

编辑:如果您想查看实时示例,请安装 google chrome beta 并尝试this page。在我的电脑上,5-10 秒长的录音超过 1 MB。

非常感谢,

阿德里安

【问题讨论】:

标签: html audio wav audio-recording recorder.js


【解决方案1】:

在我的例子中,Chrome 以 96kHz 录制音频,Firefox 以 44.1kHz 录制音频,这会产生巨大的 WAV 文件。我在 recorderWorker.js 中实现了下采样功能,您可以在其中选择所需的采样率,例如 16000。

function downsampleBuffer(buffer, rate) {
    if (rate == sampleRate) {
        return buffer;
    }
    if (rate > sampleRate) {
        throw "downsampling rate show be smaller than original sample rate";
    }
    var sampleRateRatio = sampleRate / rate;
    var newLength = Math.round(buffer.length / sampleRateRatio);
    var result = new Float32Array(newLength);
    var offsetResult = 0;
    var offsetBuffer = 0;
    while (offsetResult < result.length) {
        var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
        var accum = 0, count = 0;
        for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
            accum += buffer[i];
            count++;
        }
        result[offsetResult] = accum / count;
        offsetResult++;
        offsetBuffer = nextOffsetBuffer;
    }
    return result;
}

我在导出 wav 文件时调用它:

function exportWAV(rate, type) {
    var bufferL = mergeBuffers(recBuffersL, recLength);
    var bufferR = mergeBuffers(recBuffersR, recLength);
    var interleaved = interleave(bufferL, bufferR);
    var downsampledBuffer = downsampleBuffer(interleaved, rate);
    var dataview = encodeWAV(rate, downsampledBuffer, false);
    var audioBlob = new Blob([ dataview ], {
        type : type
    });

    this.postMessage(audioBlob);
}

【讨论】:

  • 这取决于您的最终采样率。您可以尝试另一种策略,不计算平均比特率,每步只考虑一个样本:result[offsetResult] = buffer[offsetBuffer];
  • Asterisk 需要 8khz
  • 只需致电exportWAV(8000, 'audio/wav')
  • 它们是recorderWorker.js 中的属性。小心,有一个新版本的 Recorder.js,现在频道的数量是可配置的recBuffers = [],如果你使用这个版本的库,你必须适应我的解决方案。
  • 像你这样的人让世界变得更美好。
【解决方案2】:

你可以尝试几件事。首先,我认为您正在讨论“删除交错缓冲区的所有其他元素”(将声音转换为单声道)。

为此,您可以选择保留左声道或右声道。您可以将“交错”功能更改为:

function interleave(inputL, inputR){
  return inputL; // or inputR
}

如果您想保留两个通道,但“平移”它们都居中(到单个单声道),您可以执行以下操作:

function interleave(inputL, inputR){
  var result = new Float32Array(inputL.length);
  for (var i = 0; i < inputL.length; ++i)
    result[i] = 0.5 * (inputL[i] + inputR[i]);
  return result;
}

话虽如此,可能还有很多其他位置,您必须将编码音频从表示为立体声更改为单声道。但是,我的猜测是(而且我没有使用 recorder.js,所以我不知道它的内部工作原理),recorderWorker 中的第 113/114 行可能会更改为 1。

我的猜测是,您只需更改此处提到的两个位置(interleave 函数,以及设置通道计数的位置 [第 114 行])就可以逃脱,因为: interleave 和 encodeWAV 仅通过 exportWAV 函数调用,所以不要触及原始工作人员如何录制音频(并且它一直在录制立体声)希望不会破坏它。在这种情况下,我们只会对存储的音频进行更改。

【讨论】:

  • 谢谢,这成功了。我使用了你的第二个 interleave(L,R) 函数,它平均了两个输入,我将第 114 行的通道数设置为 1。这将文件大小减少了一半。
  • 啊,刚刚意识到您还必须修改块对齐(通道数 * 每个样本的字节数),以防其他人正在阅读
  • @Adrian 我是,您可能想在此处发布您的解决方案,以便我们 +1 :)
  • 是否可以将 recorder.js 设置为 11.025 khz 而不是默认的 44.100 khz。当我更改此设置时,生成的文件以通常速度的 1/4 播放 - 就像慢速播放器一样。我只想要更小质量更低的声音。
【解决方案3】:

我正在使用相同的记录器代码,我需要降低比特率。我的解决方案生成一个 11025Hz 的单声道文件。它不是很优雅,所以如果有人对我进行更正,我会很高兴。

首先,我将 init 函数中的采样率更改为 11025,而不是音频上下文的比特率(这是不优雅的部分,因为上下文可能不是 44100Hz)。

我用这个替换interleave函数内容

var length = inputL.length / 4;
var result = new Float32Array(length);

var index = 0,
  inputIndex = 0;

while (index < length) {
    result[index++] = 0.25 * (inputL[inputIndex++] + inputL[inputIndex++] +
                              inputL[inputIndex++] + inputL[inputIndex++]);
}

return result;

这仅占用左通道,并将结果中的每 4 个缓冲区样本转换为 1 个,因此占用的内存更少。如果比特率改变相同的比率(除以 4,例如 11025),文件听起来一样,但会小得多。

我还将encodeWAV 中的频道数更改为一个

/* channel count */
 view.setUint16(22, 1, true);

与最初制作的文件相比,录制文件的大小将是 1/8。

【讨论】:

  • 刚刚试了一下,效果很好。但是我录制的声音变得更高了;有趣的效果。
  • 这会减少文件长度。我录制了 15 秒的音频,结果是 3 秒的音频:/
猜你喜欢
  • 2017-10-21
  • 1970-01-01
  • 2021-04-09
  • 2017-03-28
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多