2

我已经按照这个示例将来自 AudioRecord 的原始音频数据转换为 mp3,并且它成功地发生了,如果我将此数据存储在 mp3 文件的文件中并使用音乐播放器播放,那么它是可以听到的。

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

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

我的代码如下。

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

并且这个 mp3buffer 数据通过 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,因为它需要一个文件或文件描述符。

4

2 回答 2

0

您需要像这样遍历帧:

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

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

于 2018-09-04T20:21:54.457 回答
0

只是一个提示,但尝试

output.close();
bitstream.closeFrame();

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

于 2018-02-05T17:46:48.620 回答