Запись многоадресного потока на хосте Linux с несколькими компьютерами
У меня есть то, что звучит как простейший из возможных вариантов использования, и все же ничто не является удовлетворительным.
У меня есть хост с несколькими домами, и я хотел бы слушать многоадресные передачи на eth1 и помещать всю полезную нагрузку (НЕ включая заголовки пакетов UDP, только полезную нагрузку) в файл. Вот некоторые вещи, которые я уже пробовал,
- Сокат. Похоже, это был бы идеальный инструмент, но я понятия не имею, какой синтаксис использовать, и все примеры, которые я нахожу, предназначены для гораздо более сложных вариантов использования. Я не могу сделать из примеров, которые я вижу, головы или хвосты. Если кто-нибудь знает, как я могу заставить socat сделать это? Не стесняйтесь называть меня идиотом за то, что я не понял этого.
- VLC. Изредка отбрасывает пакеты, что недопустимо. Мне нужно, чтобы он работал долго без потери одного пакета. Я вижу это случайное падение во многих версиях VLC на нескольких платформах, и я просто не доверяю этому.
- Wireshark. Это работает и никогда не сбрасывает пакеты, такие как vlc (даже при одновременном запуске), но на самом деле мне не нужен дамп пакета, только полезная нагрузка. После этого я могу использовать wireshark, чтобы записать всю полезную нагрузку в файл, используя функцию "следить за потоком UDP", но это занимает много времени и мешает мне сохранять полезную нагрузку в реальном времени. Кроме того, это возможно только в графическом интерфейсе Wireshark. Мой рабочий процесс был бы намного проще без некоторого графического интерфейса.
- Netcat. Звучит как правильный инструмент, но не делает дерьмо, когда дело доходит до получения многоадресной рассылки. Не знаю, как отлаживать или просто не работает с многоадресной рассылкой. Кроме того, я использую nemesis для принудительного соединения igmp, и с помощью tcpdump я вижу, что это работает. Пожалуйста, предложите, если я что-то упускаю глупо.
- Кс6. тот же результат, что и у netcat.
1 ответ
socat -u UDP4-RECV:6666,ip-add-membership=224.1.0.1:0.0.0.0 CREATE:test.out
Возможно, не оптимально, но должно работать.
Вы можете использовать ffmpeg
, multicat
, tsudpreceive
а также tsp
:
ffmpeg -i udp://<multicast_ip>:<port_number> -c copy -f mpegts test.ts
Имейте в виду, что ffmpeg удалит NULL PID, но скопирует все остальные PID в test.ts
файл.
Другой вариант заключается в использовании multicat
:
multicat -u -U @<multicast_ip>:<port_number> test.ts
По умолчанию, mutlticat
ожидает поток RTP в качестве входных данных, и поэтому вам нужно определить -u
а также -U
сказать, что источник и назначение не содержат заголовки RTP.
Вы можете установить Opencaster и использовать tsudpreceive
:
tsudpreceive <multicast_ip> <port_number> > test.ts
Вы также можете попробовать сделать это с TSDuck и tsp
:
tsp -rtrue -I ip <multicast_ip>:<port_number> --buffer-size-mb 50 -O file test.ts
rtrue
говорит tsp
использовать обработку в реальном времени-I ip
- определяет, что вход является потоком IP--buffer-size-mb
указывает размер буфера в мегабайтах, по умолчанию 16 МБ, так что это просто необязательный параметр-O file
определяет тип вывода в файл.
Вы можете определить продолжительность записи в FFmpeg
мимоходом -t <seconds>
, Вы можете сделать то же самое для мультивещания, но на этот раз вам нужно определить длительность в единицах 27 МГц, а это означает, что если вы хотите записать 30 секунд, вам нужно пройти: -d 810000000
(27E + 6 * 30 = 81E + 7). Для остальных вариантов вы можете использовать timeout --foreground 30
в качестве префикса к командам, и это будет сокращать записи ровно через 30 секунд.
Скорее всего, вы сможете сделать то же самое, используя gstreamer
, cvlc
и так далее, но я не знаком с их синтаксисом.