我正在使用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
此处
bufferL
和bufferR
中的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
,所以我认为您发送的参数类型错误。