Playing mp3 data compressed by lame mp3 with JLayer and Audiotrack in android

2.7k Views Asked by At

I have followed this example to convert raw audio data coming from AudioRecord to mp3, and it happened successfully, if I store this data in a file the mp3 file and play with music player then it is audible.

Now my question is instead of storing mp3 data to a file i need to play it with AudioTrack, the data is coming from the Red5 media server as live stream, but the problem is AudioTrack can only play PCM data, so i can only hear noise from my data.

Now i am using JLayer to my require task.

My code is as follows.

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

and this mp3buffer data is sent to other user by Red5 stream.

data received at other user is in form of stream, so for playing it the code is

    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);

But my code freezes at bitstream.readFrame after 2-3 seconds, also no sound is produced before that.

Any guess what will be the problem? Any suggestion is appreciated.

Note: I don't need to store the mp3 data, so i cant use MediaPlayer, as it requires a file or filedescriptor.

2

There are 2 best solutions below

0
On

You need to loop through the frames like this:

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

And make sure you are not running them on main thread.(This is probably the reason of freezing.)

0
On

just a tip, but try to

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

after yours write code. I'm processing MP3 same as you do, but I'm closing buffers after usage and I have no problem.
Second tip - do it in Thread or any other Background process. As you mentioned these deaf 2 seconds, media player may wait until you process whole stream because you are loading it in same thread.
Try both tips (and you should anyway). In first, problem could be in internal buffers; In second you probably fulfill Media's input buffer and you locked app (same thread, full buffer cannot receive your input and code to play it and release same buffer is not invoked because writing locks it...)
Also, if you don't doing it now, check for 'frameHeader == null' due to file end. Good luck.