Автоматизация создания timelapse с камеры видеонаблюдения с помощью ffmpeg

Итак - имеется у нас городская камера видеонаблюдения + сервера под *nix. Захотелось автоматизировать сборку таймлапсов и заливку их на ютуб.

  1. Создаем баш-файлик на сервере cam2jpg.sh - в нем мы будем с помощью ffmpeg конектится к rtsp-потоку камеры и сохранять скриншоты к себе на винт (каждые 10 секунд) + добавлена проверка, что бы при перезапуске трансляции нумерация файлов продолжалась, а не перезаписывались текущие:
    #!/bin/sh
    
    export DATE2=`date +%Y-%m-%d`
    mkdir -p /usr/home/admin/timelapse/$DATE2
    ST_NUM="$(ls -t1 /usr/home/admin/timelapse/$DATE2/*.jpg |  head -n 1 | rev | cut -d '/' -f1 | rev | sed 's/[^0-9]*//g')"
    
    if [ ! "$ST_NUM" ];then
       ST_NUM="00000"
    fi
    
    /usr/local/bin/ffmpeg -rtsp_transport tcp -i rtsp://login:pass@server_ip/h264/ch2/main/av_stream -f image2 -vf fps=fps=1/10 -q:v 1 -vcodec mjpeg -start_number $ST_NUM /usr/home/admin/timelapse/$DATE2/img%05d.jpg
    

    пути к файлам возможно меняем на свои. далее идем в crontab и делаем там 2 записи - первая будет запускать скрипт сбора скринов, а вторая выключать. ночью вид не интересный, т.ч. я ограничился сбором кадров с 5 утра до 21 вечера

    00 05 * * * /usr/home/admin/timelapse/cam2jpg.sh > /dev/null 2>&1
    00 21 * * * killall ffmpeg

    т.к. у меня нет других запущенных поцесов с ffmpeg, то я убиваю все текущие

  2. переходим к второму файлку jpg2avi.sh - в нем мы будем собирать все наши картинки в таймлапс-видео-файл.
    полученный ролик идет без звука, т.ч. добавляем туда фоновую музыку. для этого создаем рядом папку music и закидываем mp3-файлы (продолжительность желательна от 5 до 8 минут). имена файлов должны быть без пробелов. скрипт будет случайным образом выбирать мелодию. после объеденяем музыку и видео и сохраняем файл в mp4-формат.
    получившийся таймлапс заливаем на юту с помощью php-скрипта из этой статьи

    #!/bin/sh
    
    export DATE2=`date +%Y-%m-%d`
    
    /usr/local/bin/ffmpeg -i /usr/home/admin/timelapse/$DATE2/img%05d.jpg -acodec libx264 -b:v 2048k -f avi /usr/home/admin/timelapse/$DATE2/TimeLapse-$DATE2.avi
    
    FILES="/usr/home/admin/timelapse/music/*"
    r_file="$(/usr/local/bin/gshuf -n1 -e  $FILES)"
    
    /usr/local/bin/ffmpeg -y -i /usr/home/admin/timelapse/$DATE2/TimeLapse-$DATE2.avi -i "$r_file" -c:v copy -c:a copy /usr/home/admin/timelapse/$DATE2/TimeLapse-$DATE2.mp4
    
    /usr/local/bin/php /usr/home/admin/timelapse/ytu.php > /usr/home/admin/timelapse/yt_log.txt

    в crontab добавляем следующую строчку:

    01 21 * * * /usr/home/admin/timelapse/jpg2avi.sh > /usr/home/admin/timelapse/video_log.txt

Ко всему этому можно еще в крон добавить скрипт мониторинга запущеного процесса ffmpeg и если он не обнаруживается - запускать.

#!/bin/sh

if [ $(pgrep ffmpeg)>'0' ]
then
  echo "Запущен"
else
  echo "Не запущен"
  /usr/home/admin/timelapse/cam2jpg.sh
fi

Итого статистика: за сутки в папке собирается 5760 картинок в среднем занимающих под 600мб + создается 2 ролика avi и mp4 занимающие в среднем по 60мб. Результат получившегося на полном автомате таймлапсса ниже:

  • kirush

    Спасибо за статью!
    В крон добавить скрипт мониторинга запущенного процесса ffmpeg и если он не обнаруживается — запускать."
    При перезапуске ffmpeg через скрипт самопроверки, все снимки начинают перезаписываться ;(

    • Roman NMSK

      обновил статью - в начале добавил новый код по сбору кадров с камеры. там теперь добавлена проверка на последнее имя файла 🙂

      • kirush

        Наверно не так как то я объяснил. При проверке кроном на наличие ffmpeg перезапускаем cam2jpg.sh.
        Рассмотрим на примере:
        Запускается в 10:00, к 12:00 в папке уже имеются файлы 00001 до 01000.jpg
        Тут что то случилось и скрипт принял решение перезапустить cam2jpg.sh, начинается перезапись файлов... В 12:01 происходит рестарт ffmpeg и файлы начинают сохранятся с 00001.jpg.

        • Roman NMSK

          ну, все правильно ) я же код и обновил первый. там теперь проверка перед запуском - в папке ищется номер последнего кадра и если он найден - ффмпег начинает делать скриншоты дальше. за это отвечает параметр в командной строке: -start_number $ST_NUM

          • kirush

            Прошу прощения, видимо чертов кеш ;(