Озадачился вопросом, как отследить падение rtsp потока с видеокамеры и перезапускать FFMPEG после востановления. Главная проблема FFMPEGа в зависании процесса. Сейчас стоит NGINX на Ubuntu, берет поток с RTSP, через модуль NGINX-RTMP выдает RTMP и HLS. В сети натыкался на скрипт который отслеживает наличие в плейлистов HLS и по отсутствию перезапускает соответствующий процесс ffmpeg. Но он не работает. Кто как решал эту проблему? Есть ли способы отслеживать поступление данных в RTMP?
Некоторые модели регистраторов, которые могут работать по RTSP, умеют проверять наличие потока от камеры и перезапускать подключение. Это железное решение проблемы, но конкретику сейчас не посоветую - слишком специфическое решение.
Леонид: дело даже не в железе. Железо стабильно, если камера не показывает регистратор в сеть в влюбом случае выдаст черный экран. Дело в том что рег могут ребутнуть, скинуть питание, тупо за инет не заплатить... и так далее. Нужно чтобы после возобновление потока FFMPEG сам перезапускался.
#!/bin/bash
touch /tmp/ffmpeg.log
ffmpeg -shortest -re -y -err_detect aggressive -i \
rtmp://127.0.0.1/movies/my.stream timeout=10 -codec copy \
-map 0 -bsf:v h264_mp4toannexb,dump_extra -f segment \
-segment_time 60 -progress /tmp/ffmpeg.log /video/my.stream#%09d.ts &
pid=$!
while true
do
# you'll might have to change "invalid"
# for whatever is being put into the progress log
# just look at /tmp/ffmpeg.log to figure out what
# grep should try to find
error=$(grep -n "invalid" /tmp/ffmpeg.log)
# is the length of the error more than 0 / did grep find it???
if (( ${#error} > 0 ))
then
kill -9 $pid
ffmpeg -shortest -re -y -err_detect aggressive -i \
rtmp://127.0.0.1/movies/my.stream timeout=10 -codec copy \
-map 0 -bsf:v h264_mp4toannexb,dump_extra -f segment \
-segment_time 60 -progress /tmp/ffmpeg.log /video/my.stream#%09d.ts &
pid=$!
else
usleep 100
fi
done
exit 0
Moskus: благодарю, а что этот скрипт то делает? Я совсем не силен в скриптах, но похоже что он запускает FFMPEG, берет поток из RTMP и пишет в лог, далее ждет ошибку в логеи рестартит FFMPEG до тех пор пока ошибка не пропадет? Тоесть этот скрипт нужно переделать под себя, источник потока указывать RTSP с камеры? А nginx запускать только на открытие RTMP?
Lexaz: да, вы практически правильно поняли, что он делает - запускает, ждет появления в логе ffmpeg строки, которая указывает на ошибку (она может в вашем случае содержать что-то другое, а не слово invalid - сначала нужно посмотреть), если она появляется - убивает процесс ffmpeg и перезапускает его, если сообщение об ошибке не появилось - повторяет проверку через 100 мкс.
Критичные параметры ffmpeg, которые нужны для функционирования этого скрипта - -err_detect aggressive и -progress /tmp/ffmpeg.log, остальное можете переделывать под себя. nginx и все остальное - по вкусу.
Moskus: стандартный лог 2>>/tmp/ffmpeg.log ошибок не выдает, при отсутствии потока он просто перестает писаться, а -progress /tmp/ffmpeg.log отличается от предыдущего? Попробую.
А что если оставить конфиг nginx как есть, только добавить критичные параметры:
в скрипте убрать запуск ffmpeg, запуск ffmpeg оставить nginxу,
далее при ошибке либо убивать процесс FFMPEG, но мы не узнаем его PID
либо рестартить nginx по названию
каждая копия NGINX запускает и обрабатывает потоки с 1 регистратора
Moskus, Lexaz, еще желательно добавить проверку на живость самого процесса ffmpeg. А то может вы читаете из лога в который должен писать процесс, который сам давно помер.
Проверять можно так:
while true; do
if kill -0 $pid ; then
sleep 10
else
ffmpeg -shortest -re -y -err_detect aggressive -i \
rtmp://127.0.0.1/movies/my.stream timeout=10 -codec copy \
-map 0 -bsf:v h264_mp4toannexb,dump_extra -f segment \
-segment_time 60 -progress /tmp/ffmpeg.log /video/my.stream#%09d.ts &
pid=$!
fi
done