Автоматизация создания 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

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

  • Philipp Chernousov

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

    • Roman NMSK

      можно сделать и несколько копий ) для ютуба тот скрипт уже давно не работает. сейчас я у себя настроил вот это - работает как часы! https://github.com/tokland/youtube-upload

      • Philipp Chernousov

        Спасибо огромное, я две ночи мучался с установкой ffmpeg вместо какой то заразы на убунту, и еще ночь потратил на php 7 версии, 5ой, и всех возможных версий curl чтобы запустить этот скрипт.
        Сейчас попробую ваш совет

      • Philipp Chernousov

        Поделитесь своим решением как добавить это задание в крон? Скрипт по расписанию выполняется весь, но часть с загрузкой на ютуб пропускается.... Уже и разделил на части файл, из консоли все работает с крона нет

        • Roman NMSK

          обновленный файл jpg2avi.sh у меня выглядит вот так (добавил комменты):

          #!/bin/sh

          export DATE=`date +%Y%m%d`
          export DATE2=`date +%Y-%m-%d`
          export dateNowName=`date +%d-%m-%Y`

          ### картинки в видео + наложение вотермарка
          /usr/bin/ffmpeg -i /home/roman/timelapse/$DATE2/img%05d.jpg -vf "movie=/home/roman/timelapse/logo.png [watermark]; [in][watermark] overlay=10:main_h-overlay_h-10 [out]" -acodec libx264 -b:v 2048k -f avi /home/roman/timelapse/$DATE2/TimeLapse-$DATE2.avi

          ### выбор случайной музыки
          FILES="/home/roman/timelapse/music/*"
          r_file="$(/usr/bin/shuf -n1 -e $FILES)"

          ### добавляем музыку
          /usr/bin/ffmpeg -y -i /home/roman/timelapse/$DATE2/TimeLapse-$DATE2.avi -i $r_file -shortest -c:v copy -c:a copy /home/roman/timelapse/$DATE2/TimeLapse-$DATE2.mp4

          ### получившееся видео копируем в отдельную папку, а текущую удаляем
          cp /home/roman/timelapse/$DATE2/TimeLapse-$DATE2.mp4 /home/roman/timelapse/all_video/
          rm -rf /home/roman/timelapse/$DATE2

          ### заливка на youtube
          ### https://github.com/tokland/youtube-upload
          ### https://gist.github.com/dgp/1b24bf2961521bd75d6c

          /usr/local/bin/youtube-upload
          --title="Timelapse $dateNowName - Lorem Ipsum"
          --description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut faucibus nunc. Pellentesque sit amet tristique tellus. Morbi luctus malesuada ex non sodales. Mauris faucibus, justo eu pulvinar tristique, est mauris bibendum ipsum, eu convallis lacus turpis in lacus. Nunc dictum venenatis massa."
          --category=Music
          --tags="tag1, tag2, tag3"
          --default-language="en"
          --default-audio-language="en"
          --client-secrets=/usr/local/share/youtube_upload/client_secrets.json
          --credentials-file=/home/roman/.youtube-upload-credentials.json
          --playlist "Lorem Ipsum"
          /home/roman/timelapse/all_video/TimeLapse-$DATE2.mp4

  • Philipp Chernousov

    Кстати ртсп ссылку пришлось взять в кавычки, иначе не подключалось

    осталась вот такая ошибка у меня 🙁

    Unrecognized option 'start_number'

    Failed to set value '00000' for option 'start_number'