在Android中用JLayer和Audiotrack播放由lame mp3压缩的mp3数据

时间:2014-01-21 09:43:43

标签: android audio lame audiotrack jlayer

我已按照此example将来自AudioRecord的原始音频数据转换为mp3,并且它成功发生,如果我将此数据存储在mp3文件的文件中并与音乐播放器一起播放,则可以听到它。< / p>

现在我的问题是不是将mp3数据存储到我需要用AudioTrack播放的文件中,而是将数据作为直播来自Red5媒体服务器,但问题是AudioTrack只能播放PCM数据,所以我可以只听到我数据中的噪音。

现在我正在使用JLayer来完成我的需求任务。

我的代码如下。

int readresult = recorder.read(audioData, 0, recorderBufSize);
int encResult = SimpleLame.encode(audioData,audioData, readresult, mp3buffer);

这个mp3缓冲区数据由Red5流发送给其他用户。

其他用户收到的数据是流的形式,因此播放时代码为

    Bitstream bitstream = new Bitstream(data.read());
    Decoder decoder = new Decoder();
    Header frameHeader = bitstream.readFrame();
    SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
    short[] pcm = output.getBuffer();
    player.write(pcm, 0, pcm.length);

但是我的代码在2-3秒后冻结在bitstream.readFrame上,之前也没有声音产生。

有什么猜测会出现什么问题?任何建议都表示赞赏。

注意:我不需要存储mp3数据,因此我无法使用MediaPlayer,因为它需要文件或文件描述符。

2 个答案:

答案 0 :(得分:0)

只是提示,但尝试

output.close();
bitstream.closeFrame();
在你编写代码之后

。我正在处理与你相同的MP3,但我在使用后关闭缓冲区,我没有问题 第二个提示 - 在Thread或任何其他后台进程中执行此操作。正如你提到这些聋人2秒,媒体播放器可能会等到你处理整个流,因为你在同一个线程中加载它 尝试这两个提示(无论如何你应该)。首先,问题可能在于内部缓冲;在第二个你可能完成媒体的输入缓冲区和你锁定的应用程序(相同的线程,完整的缓冲区无法接收您的输入和代码来播放它并释放相同的缓冲区不会被调用因为写入锁定它...)
此外,如果您现在不这样做,请检查由于文件结束而导致的'frameHeader == null'。 祝你好运。

答案 1 :(得分:0)

您需要像这样遍历这些帧:

While (frameHeader = bitstream.readFrame()){
    SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
    short[] pcm = output.getBuffer();
    player.write(pcm, 0, pcm.length);
    bitstream.close();
}

并确保您不在主线程上运行它们。(这可能是冻结的原因。)