首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在MP3中用JavaScript对PCM数据进行编码?

如何在MP3中用JavaScript对PCM数据进行编码?
EN

Stack Overflow用户
提问于 2014-02-13 20:19:11
回答 6查看 10.9K关注 0票数 5

我正在使用Recorder.js来录制麦克风的音频。这个库可以在WAV中对PCM数据进行编码,我可以使用<audio>成功地回放它。但是,产生的WAV数据太大了(对于5分钟的记录来说,大约是38 is )。我尝试使用来自说话对服务器的libmp3lame.js。

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

代码语言:javascript
运行
复制
importScripts("libmp3lame.js");

然后,我将exportWAV()函数更改为将PCM缓冲区编码为MP3,而不是WAV。

代码语言:javascript
运行
复制
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方法抛出了这个错误:

代码语言:javascript
运行
复制
Uncaught RangeError: Invalid array buffer length 

这里,bufferLbufferR中的PCM数据是Float32Array。我不知道Lame.encode_buffer_ieee_float到底需要什么作为输入。

Lame.encode_buffer_ieee_float中抛出错误的违规行是:

代码语言:javascript
运行
复制
var arraybuf = new ArrayBuffer(nread);

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

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

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2014-02-14 00:49:22

我现在没有很多时间,所以我无法实际下载库并进行测试,但我首先要在这行之后添加一个断点:

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 ]) in libmp3lame.js.

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

这至少能让你对发生的事情有一些了解。

我还注意到,encode_buffer_ieee_float方法内部假定为BUFSIZE = 8192。我不完全确定这是否有意义,但我想知道这个方法是否实际上只是作为编码单个Mp3帧的一种方法,而不是任意长度的缓冲区。

无论如何,如果您能够看到nread的价值,这至少会让您在正确的轨道上找到正在发生的事情。但是第二个和第三个参数显然是Float32Arrays,所以我不认为您发送的参数类型是错误的。

票数 2
EN

Stack Overflow用户

发布于 2015-06-10 15:06:36

有一个用纯javascript编写的库,称为lamejs。它比libmp3lame的emscripten编译要快得多。https://github.com/zhuker/lamejs

示例用法:

代码语言:javascript
运行
复制
lib = new lamejs();
mp3encoder = new lib.Mp3Encoder(1, 44100, 128); //mono 44.1khz encode to 128kbps
samples = new Int16Array(44100); //one second of silence
var mp3 = mp3encoder.encodeBuffer(samples); //encode mp3
票数 7
EN

Stack Overflow用户

发布于 2014-08-20 19:13:40

我也有同样的错误

但是,我通过执行以下步骤来解决这个问题:当您想要开始一个新的录音时,为mp3 worker mp3worker.init()执行init。这是由于mp3codec值为null,因为您执行sendMessage(command: 'end');,这个解决方案解决了您的问题;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21764632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档