Как можно конвертировать поток байт RTP в формат wav?

Как мне правильно обрабатывать RTP поток в файл и затем конвертировать его в формат .wav с помощью Python и ffmpeg, чтобы избежать появления шумов? Я считываю RTP поток из сокета, преобразую его в .wav формат, и в итоге в файле появляются сильные шумы. Хотя голос остается чистым, из-за шумов его практически не слышно. Однако, когда я слушаю тот же RTP поток, захваченный Wireshark, шумов не обнаруживается. Мне представляется, что причиной шумов может быть то, что в файл попадает не только payload, но и заголовки RTP. Не могли бы вы предложить способ как это исправить?
  • 2 декабря 2023 г. 12:09
Ответы на вопрос 2
При обработке RTP потока вы должны отделить заголовок RTP от полезного содержимого (payload). Заголовок RTP обычно размещается в 12 первых байтах датаграммы RTP. Если вы сохраняете весь поток целиком, включая заголовки, то у вас, конечно, возникнут проблемы с шумом.

Вот примерный порядок действий:

1. Слушайте RTP поток из сокета и принимайте RTP пакеты. Формат RTP пакета будет следующий: первые 12 байт - RTP заголовок, остальное - полезное содержимое (payload).

2. Отбросьте первые 12 байт каждого пакета (заголовок RTP), сохраните остальные байты в отдельный файл. Исключение могут составлять расширенные заголовки RTP, если они присутствуют. Для этого необходимо проверить маркеры в основном RTP заголовке.

3. В результате у вас будет файл, состоящий только из полезного содержания RTP пакетов. В зависимости от используемого аудио-кодека, этот файл можно будет конвертировать в wav-формат с помощью ffmpeg.

Подробное описание RTP заголовка можно найти в RFC3550.

Пример кода на Python для включения в ваш сценарий:

```python
import socket

# создаем сокет и слушаем на нем RTP поток
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('localhost', 12345))

with open('payload.bin', 'wb') as f:
    while True:
        data, addr = sock.recvfrom(2048)
        # отбрасываем RTP заголовок (12 первых байт)
        payload = data[12:]
        # записываем полезное содержание в файл
        f.write(payload)
```

После того как вы сохраните payload RTP в файл, вы можете использовать ffmpeg для конвертации в wav-формат. Команда ffmpeg будет зависеть от используемого кодека в RTP потоке. Например, для кодека PCMU:

```sh
ffmpeg -f mulaw -ar 8000 -i payload.bin output.wav
```

Это основы, и вам может понадобиться адаптировать их для вашего конкретного случая.
Тебе придется немного обработать RTP, поскольку там содержатся служебные данные: ссылка на источник здесь https://datatracker.ietf.org/doc/html/rfc3550. Если ты используешь Python, я нашел полезный ресурс здесь https://github.com/bbc/rd-apmm-python-lib-rtp. 
Похожие вопросы