Receiving RTP stream - AudioStream, AudioGroup

android, audio, audio-streaming, ffmpeg, rtp

Solution

Answering my own question, the problem was with android rtp packet management.

Android said that `... assume packet interval is 50ms or less.` in the AudioGroup source file.

However, RTP packets are sending with interval 60ms.

That means 50ms is not enough and this leads the problem as described below.

Incoming: X X X X X X Y Y Y Y Y Y X X X X X X Y Y Y Y Y Y X X X X X X
Reading : X X X X X Y Y Y Y Y X X X X X Y Y Y Y Y X X X X X Y Y Y Y Y
          ^ ^ ^ ^ ^ - - - - - - - - - - - - - - - - - - - - ^ ^ ^ ^ ^ 
          ^                                                 ^
          |                                                 |
          |---- just these overlapping packets is valid ----|
          |---- and other packets discarding due to --------|
          |---- invalid RTP headers. -----------------------|

X, Y < packets

I have just one packet in every 300ms interval. That results jittery sound.

I'll send a bug report for this, hope it helps someone.

For ones who are really want to listen raw RTP stream, I suggest them to read packets manually and decode it to PCM 16bit (which is the only audio format that android soundcard supports) and write it on AudioTrack.

Problem

I would like to listen an RTP audio stream, however the voice has little gaps in it - not continues. What may be the solution? Am I missing something on Receiver(android) side or Streamer(ffmpeg) side? I'm using ffmpeg to stream RTP audio, ``` ffmpeg -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -vcodec pcm_u8 -f rtp rtp://192.168.0.15:41954 (port changes.) ``` And here is my related android code: ``` AudioStream audioStream; AudioGroup audioGroup; @Override public void onStart() { super.onStart(); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build(); StrictMode.setThreadPolicy(policy); AudioManager audio = (AudioManager)getSystemService(AUDIO_SERVICE); audio.setMode(AudioManager.MODE_IN_COMMUNICATION); audioGroup = new AudioGroup(); audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION); InetAddress inetAddress; try { inetAddress = InetAddress.getByName("192.168.0.15"); audioStream = new AudioStream(inetAddress); audioStream.setCodec(AudioCodec.PCMU); audioStream.setMode(RtpStream.MODE_NORMAL); InetAddress inetAddressRemote = InetAddress.getByName("192.168.0.14"); audioStream.associate(inetAddressRemote, 6000); ((TextView)findViewById(R.id.tv_port)).setText("Port : " + String.valueOf(audioStream.getLocalPort())); audioStream.join(audioGroup); } catch ( UnknownHostException e ) { e.printStackTrace(); } catch ( SocketException e ) { e.printStackTrace(); } } ```

Original source