Синхронизация двух потоков RTSP с помощью ffmpeg

Вопрос или проблема

Перед созданием поста я выполнил несколько поисков в интернете, не найдя решения своей проблемы.

Мне нужно захватить два потока rtsp с 2 ip-камер для последующего анализа с помощью opencv. Я использую Raspberry Pi, и малая вычислительная мощность не позволяет мне проводить анализ двух видеопотоков с разрешением 1080p в реальном времени с помощью opencv. Поэтому я подумал захватить два потока на Raspberry и проанализировать их позже на более мощной машине.

Команды, используемые для захвата:

ffmpeg -stimeout 2000000 -re -rtsp_transport tcp -i rtsp://192.168.1.131/h264 -c copy -f mp4 -y out1.mp4
ffmpeg -stimeout 2000000 -re -rtsp_transport tcp -i rtsp://192.168.1.132/h264 -c copy -f mp4 -y out2.mp4

Проблема в том, что два потока rtsp, захваченных в двух файлах out1.mp4 и out2.mp4, никогда не синхронизируются идеально. Задержка составляет около 1 секунды и является переменной, что представляет для меня проблему. Я считаю, что задержка в коммуникации с камерой может влиять на задержку.

Как я могу решить эту проблему? Заранее спасибо.

Попробуйте удалить

-stimeout 2000000 -re -rtsp_transport tcp

ffmpeg обычно справляется с этим лучше, чем мы!

установка временных меток видео с помощью

-filter_complex "[0:v]setpts="(RTCTIME - RTCSTART) / (TB * 1000000)"[v1];[1:v]setpts="(RTCTIME - RTCSTART) / (TB * 1000000)"[v2]"

Из документации ffmpeg https://ffmpeg.org/ffmpeg-filters.html#Examples-139:
(в некоторых документах говорится, что это устарело, но я использую сборку от 27 ноября и это работает.)

вам понадобится повторно перекодировать видео

-map '[v1]' -map '[v2]' -map a -c:v libx265 -c:a copy

Итак, для вашей последней командной строки это будет выглядеть так:

ffmpeg -i rtsp://192.168.5.131/h264 \
-i rtsp://192.168.5.132/h264 \
-filter_complex \
"[0:v]setpts="(RTCTIME - RTCSTART) / (TB * 1000000)"[v1]; \
[1:v]setpts="(RTCTIME - RTCSTART) / (TB * 1000000)"[v2]" \
-map '[v1]' -map '[v2]' -map a -c:v libx264 -c:a copy -f mpegts -y out.ts

YMMV, но это работает с моими бюджетными китайскими IP-камерами

Ответ или решение

Синхронизация двух RTSP потоков с помощью FFmpeg может быть сложной задачей, особенно если необходимо уменьшить задержку и дискретность каждого из потоков. Чтобы понять, как это сделать, мы используем теоретическое обоснование, практический пример и его использование в реальных условиях.

Теория

RTSP (Real-Time Streaming Protocol) используется для удовлетворения потребностей в потоковом передаче данных в реальном времени, к примеру, с IP-камер. Среди основных характеристик RTSP потоков – это их потенциальная задержка и возможность изменения времени начала записи. По мере использования RTSP, передача данных может столкнуться с задержками, вызванными, например, сетевыми задержками или аппаратными ограничениями. Для видеопотоков это может представлять существенную проблему, поскольку даже минимальная асинхронность может привести к значительным трудностям, особенно в задачах, связанных с видеоналитикой как с использованием OpenCV.

FFmpeg – это мощный и универсальный инструмент для обработки мультимедийных данных, который, среди прочих возможностей, позволяет реализовывать операции записи, транскодинга и синхронизации потоков. Включение правильных опций и фильтров может помочь в достижении синхронизации потоков. Для этого надо учитывать временные метки и специфику кодирования аудио- и видеоданных.

Пример

Предположим, у нас есть две IP-камеры, транслирующие RTSP видео по адресам rtsp://192.168.1.131/h264 и rtsp://192.168.1.132/h264. Мы можем использовать FFmpeg для записи этих потоков в виде отдельных видеофайлов с целью дальнейшего анализа.

Оригинальные команды, которые вы использовали:

ffmpeg -stimeout 2000000 -re -rtsp_transport tcp -i rtsp://192.168.1.131/h264 -c copy -f mp4 -y out1.mp4
ffmpeg -stimeout 2000000 -re -rtsp_transport tcp -i rtsp://192.168.1.132/h264 -c copy -f mp4 -y out2.mp4

Однако такая реализация приводит к несинхронизированным файлам. Причиной может быть использование опций -re (которая ограничивает поток до частоты кадров для реального времени, что не всегда желательно при записи) и -rtsp_transport tcp, которая может вызывать дополнительную задержку из-за особенностей TCP.

Рекомендуется удалить эти опции и вместо этого использовать фильтр для синхронизации временных меток потоков:

ffmpeg -i rtsp://192.168.1.131/h264 -i rtsp://192.168.1.132/h264 \
-filter_complex "[0:v]setpts=RTCTIME-RTCSTART/TB/1000000[v1]; \
[1:v]setpts=RTCTIME-RTCSTART/TB/1000000[v2]" \
-map "[v1]" -map "[v2]" -map a -c:v libx264 -c:a copy -f mpegts -y out.ts

Применение

  1. Удаление Излишней Конфигурации: Удалив -re и -rtsp_transport tcp, вы позволите FFmpeg использовать стандартные параметры, которые часто более эффективны для синхронизации потоков. Это упрощает процесс и может уменьшить задержку.

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

  3. Транскодирование: Включение -c:v libx264 гарантирует сохранение всех важных аспектов движущегося изображения и может быть более эффективным для хранения и анализа, чем просто copy.

  4. Результат: Собрав два потока в один файл с использованием формата mpegts, вы получите более стабильное временное восприятие видео для обработки с OpenCV.

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

Оцените материал
Добавить комментарий

Капча загружается...