我正在使用Recorder.js来录制来自麦克风的音频。该库可以将WAV中的PCM数据编码,并且我可以使用<audio>成功播放它。但是,生成的WAV数据太大(5分钟的录制时间约为38MB)。我尝试使用Speech-to-Server提供的libmp3lame.js。

recorderWorker.js中,我正在导入Lame脚本:

importScripts("libmp3lame.js");

然后,我更改了exportWAV()函数,以将PCM缓冲区编码为MP3而不是WAV。
function exportWAV(type){
    var bufferL = mergeBuffers(recBuffersL, recLength);
    var bufferR = mergeBuffers(recBuffersR, recLength);
    //var interleaved = interleave(bufferL, bufferR);

    console.log("Start MP3 encoding");
    var mp3codec = Lame.init();
    Lame.set_mode(mp3codec, Lame.JOINT_STEREO);
    Lame.set_num_channels(mp3codec, 2);
    Lame.set_out_samplerate(mp3codec, sampleRate);
    Lame.set_bitrate(mp3codec, 128);
    Lame.init_params(mp3codec);

    var mp3data = Lame.encode_buffer_ieee_float(mp3codec, bufferL, bufferR);
    audioBlob = new Blob([mp3data.data], { type: "audio/mp3" });
    console.log("Done MP3 encoding");

    this.postMessage(audioBlob);
}

但是,Lame.encode_buffer_ieee_float方法抛出此错误:
Uncaught RangeError: Invalid array buffer length

此处bufferLbufferR中的PCM数据为Float32Array。我无法确定Lame.encode_buffer_ieee_float究竟期望输入什么。

引发错误的Lame.encode_buffer_ieee_float中有问题的行是:
var arraybuf = new ArrayBuffer(nread);

我设置了一个断点,并检查了nread的值。是-1。

因此,我的问题是在这种情况下如何使用Lame MP3 JavaScript库?谢谢你。

最佳答案

我现在没有很多时间,所以我实际上无法下载库并进行测试,但是我将从在这行之后放置一个断点开始:
var nread = Module.ccall('lame_encode_buffer_ieee_float', 'number', [ 'number', 'number', 'number', 'number', 'number', 'number' ], [ handle, inbuf_l, inbuf_r, channel_l.length, outbuf, BUFSIZE ])中的libmp3lame.js

然后为nread设置一个监视表达式。您想查看该值是什么,因为我很确定它是下一行(var arraybuf = new ArrayBuffer(nread);)抛出的值。

这至少可以使您对正在发生的事情有一些了解。

我还注意到encode_buffer_ieee_float方法在内部假设BUFSIZE = 8192。我不确定这是否有意义,但是我想知道这种方法是否实际上仅打算用作编码单个Mp3帧的手段,而不是用作任意长度的缓冲区的手段。

无论如何,如果您可以看到nread的值是什么,那么至少应该可以使您正确地了解正在发生的事情。但是肯定看起来第二个和第三个参数是Float32Arrays,所以我认为您发送的参数类型错误。

09-13 02:41