Подтвердить что ты не робот

Получение потока RTP - AudioStream, AudioGroup

Я хотел бы прослушать аудиопоток RTP, однако голос имеет небольшие пробелы в нем - не продолжается. Каким может быть решение? Я что-то пропустил на стороне Receiver (android) или Streamer (ffmpeg)?

Я использую ffmpeg для потокового аудио RTP,

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

И вот мой связанный код Android:

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();
    }
}
4b9b3361

Ответ 1

Отвечая на мой собственный вопрос, проблема заключалась в управлении пакетами android rtp.

Android сказал, что ... assume packet interval is 50ms or less. в исходном файле AudioGroup.

Однако пакеты RTP отправляются с интервалом 60 мс.

Это означает, что 50 мс недостаточно, и это приводит к проблеме, как описано ниже.

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

У меня всего один пакет за каждые 300 мс. Это приводит к дрожанию звука.

Я отправлю отчет об ошибке, надеюсь, что это кому-то поможет.

Для тех, кто действительно хочет прослушивать исходный поток RTP, я предлагаю им вручную читать пакеты и декодировать их на PCM 16bit (это единственный аудиоформат, поддерживаемый звуковой картой Android) и записать его на AudioTrack.

Ответ 2

Извините, если следующее нечеткое:

Командная строка ffmpeg, по-видимому, генерирует тестовый звук и излучает его как поток данных pcm через RTP.

RTP сам по себе не гарантирует надежную доставку потоковых данных, он просто предоставляет достаточно информации, чтобы сообщить получателю, если он получил все данные, и точно, какие данные отсутствуют, если некоторые были потеряны в пути. Плюс это обычно используется над UDP.

Следовательно, с RTP акцент делается на пользователе RTP для отправки данных, которые закодированы таким образом (то есть с кодированием с исправлением ошибок, избыточности в данных и т.д.), чтобы получатель мог восстановить достаточно исходных данных до удовлетворить потребности приложения. Таким образом, с аудиопотоком вам понадобится какой-то формат кодирования, который подходит.

Я не нашел ссылку на то, что означает pcm_u8, но это очень наводит на мысль, что это простой поток импульсно-кодовой модулированной информации с 8-битными данными. Это не похоже на то, что в него встроена кодировка с исправлением ошибок или избыточность данных. Потеря байт означает потерю образца, и нет ничего, что можно было бы сделать на принимающей стороне для заполнения.

Итак, я думаю, что происходит то, что что-то в вашей сети отбрасывает UDP-пакеты, что RTP сообщает AudioStream, какие данные отсутствуют, а результат - зазоры, потому что в потоке данных pcm_u8 нет исправления ошибок или избыточности данных, чтобы потерянные данные должны быть восстановлены с помощью AudioStream.

Я видел такие вещи, как VMWare, намеренно упускаю UDP-пакеты в виртуальной сети как способ обеспечения хорошей производительности, оправданием является то, что UDP не гарантируется доставка в любом случае, поэтому "это не имеет значения". Это сильно потрясло коллегу, который использовал RTP и ожидал гарантированной доставки, но не получил его. У него был замкнутый сегмент сети с разъемом на каждом конце провода, один из которых размещал одну виртуальную машину.

Таким образом, это может быть случай изменения кодека, который вы используете. Я не могу рекомендовать его. Для начала стоит рассмотреть, что использует широковещательный цифровой медиапоток. DVB-T использует транспортный поток MPEG (который имеет кодирование с исправлением ошибок и т.д.), Как AFAIK, обертка вокруг MPEG-2.