Вопрос или проблема
Перед созданием поста я выполнил несколько поисков в интернете, не найдя решения своей проблемы.
Мне нужно захватить два потока 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
Применение
-
Удаление Излишней Конфигурации: Удалив
-re
и-rtsp_transport tcp
, вы позволите FFmpeg использовать стандартные параметры, которые часто более эффективны для синхронизации потоков. Это упрощает процесс и может уменьшить задержку. -
Использование фильтрации видеопотоков: Опция
setpts
пересчитывает метки времени каждого отдельного фрейма, чтобы синхронизировать их по значению времени. В вашем случае это будет использовать системное реальное время (RTCTIME) и время начала транзакции (RTCSTART) для уравнивания потока по временной оси. -
Транскодирование: Включение
-c:v libx264
гарантирует сохранение всех важных аспектов движущегося изображения и может быть более эффективным для хранения и анализа, чем простоcopy
. -
Результат: Собрав два потока в один файл с использованием формата
mpegts
, вы получите более стабильное временное восприятие видео для обработки с OpenCV.
Подводя итог, применение вышеуказанных инструментов FFmpeg обеспечивает базис синхронизации потоков, что улучшает качество и точность последующего анализа изображений. Понимание теоретических основ, реализация на примере и верное применение на практике улучшат общее качество потокового видеоматериала и его аналитическую ценность.