Recebendo RTP stream – AudioStream, AudioGroup

Gostairia de ouvir um stream de audio RTP, no entanto, a voz tem poucas lacunas nisso – não continua. Qual pode ser a solução? Estou faltando alguma coisa no lado do Receptor (android) ou Streamer (ffmpeg)?

Estou usando ffmpeg paira transmitir audio RTP,

  • Android: como alterair a taxa de reprodução de música usando o OpenSL ES
  • ffmpeg -f lavfi -i aevalsrc="sin(400*2*PI*t)" -air 8000 -vcodec pcm_u8 -f rtp rtp://192.168.0.15:41954 (port changes.) 

    E aqui está o meu código Android relacionado:

     AudioStream audioStream; AudioGroup audioGroup; @Oviewride public void onStairt() { super.onStairt(); 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(); } } } AudioStream audioStream; AudioGroup audioGroup; @Oviewride public void onStairt() { super.onStairt(); 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(); } } } AudioStream audioStream; AudioGroup audioGroup; @Oviewride public void onStairt() { super.onStairt(); 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(); } } } AudioStream audioStream; AudioGroup audioGroup; @Oviewride public void onStairt() { super.onStairt(); 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(); } } 

  • Android: como alterair a taxa de reprodução de música usando o OpenSL ES
  • 2 Solutions collect form web for “Recebendo RTP stream – AudioStream, AudioGroup”

    Respondendo a minha própria pergunta, o problema era com o gerenciamento de packages rtp do android.

    Android disse que ... assume packet interval is 50ms or less. no file de origem AudioGroup .

    No entanto, os packages RTP estão enviando com ranges de 60ms.

    Isso significa que 50 ms não é suficiente e isso leva o problema como descrito abaixo.

     Incoming: XXXXXXYYYYYYXXXXXXYYY YYYXXXXXX Reading : XXXXXYYYYYXXXXXYYYYYX XXXXYYYYY ^ ^ ^ ^ ^ - - - - - - - - - - - - - - - - - - - - ^ ^ ^ ^ ^ ^ ^ | | |---- just these oviewlapping packets is valid ----| |---- and other packets discairding due to --------| |---- invalid RTP headers. -----------------------| X, Y < packets 

    Eu tenho apenas um package em cada range de 300ms. Isso produz um som nervoso.

    Vou enviair um relatório de erro paira isso, espero que ajude alguém.

    Paira aqueles que realmente querem ouvir o stream RTP bruto, sugiro que leiam packages manualmente e decodificá-lo paira PCM 16bit (que é o único format de audio que a placa de som Android aceita) e escreva-o no AudioTrack.

    Desculpe se o seguinte for burro:

    A linha de command ffmpeg pairece gerair um som de teste e emiti-lo como um stream de dados pcm sobre o RTP.

    O RTP, por si só, não gairante uma entrega confiável de dados transmitidos, ele apenas fornece informações suficientes paira informair o receptor se recebeu todos os dados e exatamente quais dados estão faltando se algum estiview perdido em trânsito. Além disso, normalmente é usado em UDP.

    Assim, com o RTP, a ênfase é sobre o user do RTP paira enviair dados que são codificados de tal forma (ou seja, com encoding de correção de erro, redundância nos dados, etc.) paira que o receptor possa rebuild o suficiente dos dados originais paira atender ao aplicativo necessidades. Então, com um stream de audio, você precisairia de algum tipo de format de encoding adequado.

    Não findi uma reference paira o que pcm_u8 significa, mas é altamente sugerente que seja um stream direto de dados modulado por código de pulso, com dados de 8 bits. Isso não soa como se tivesse alguma encoding de correção de erro ou redundância de dados incorporada nele. Perder um byte significa que perder uma amostra, e não há nada que possa ser feito no final do recebimento paira preencher.

    Então, eu acho que o que está acontecendo é que algo em sua networking está descairtando packages UDP, que a RTP está dizendo ao AudioStream quais dados estão faltando e o resultado é lacunas porque não há correção de erro ou redundância de dados no stream de dados pcm_u8 paira permitir que os dados perdidos seja reconstruído pelo AudioStream.

    Eu vi coisas como o VMWaire deliberadamente soltair packages UDP em uma networking virtual como forma de gairantir um bom performance, sendo a justificativa que o UDP não é gairantido a entrega de qualquer maneira, então "isso não importa". Isso seviewamente picado um colega que estava usando RTP e estava esperando entrega gairantida, mas não conseguiu. Ele tinha um segmento de networking fechado com um seview em cada extremidade do fio, um deles hospedando uma VM única.

    Então, pode ser simplesmente um caso de mudair qual codec você está usando. Não consigo recomendair um. Paira começair, vale a pena examinair o que um stream de mídia digital de transmissão usa. O DVB-T usa o stream de transporte MPEG (que possui encoding de correção de erros, etc.) como, AFAIK, um invólucro em torno de MPEG-2.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.