За последние 24 часа нас посетили 34370 программистов и 1695 роботов. Сейчас ищут 727 программистов ...

Как заставить ffmpeg обрабатывать только новые файлы?

Тема в разделе "Настройка веб-сервера", создана пользователем ushkom, 21 июн 2020.

Метки:
  1. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Доброго времени суток. Получилось собрать небольшой баш скрипт для поиска всех файлов .mp4 в каталоге и нанести на видео логотип с помощью ffmpeg.

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

    Сам скрипт:
    Код (Text):
    1. #!/bin/sh
    2. cd /videofiles/;
    3. for i in *.mp4;
    4. do ffmpeg -i "$i" -i /images/logo-video.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10" -n convert/"${i%.*}.mp4";
    5. done
    Всем спасибо
     
  2. vapa

    vapa Гость

    С нами с:
    21 июн 2020
    Сообщения:
    2
    Симпатии:
    0
    Приветствую!
    Не должно быть повторных нанесений при сохранении в подпапку.
    Маска *.mp4; их не находит как правило.
     
  3. vapa

    vapa Гость

    С нами с:
    21 июн 2020
    Сообщения:
    2
    Симпатии:
    0
    Может забыта команда
    Код (Text):
    1. rm "$i";
    в конце цикла?
     
  4. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Дело в том что я хотел бы чтоб скрипт потом копировал видео с подпапки в основную, а с подпапки удалял. Сейчас повторно не наносит, но в двух экземплярах держать видео не буду, а чтение видео идет с основной папки.
     
  5. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    Связка touch + find -newer filename
    Код (Text):
    1. #!/bin/bash
    2.  
    3. filename="lol"
    4. date=`date -R`
    5.  
    6. cd /videofiles/;
    7.  
    8. find . -name "*.mp4" -newer "$filename" -maxdepth 1 -print0  | while read -r -d '' i;
    9. do ffmpeg -i "$i" -i /images/logo-video.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10" -n convert/"${i%.*}.mp4";
    10. done
    11.  
    12. touch -d "$date" "$filename"
    Скопировать дату модификации с какого-нибудь файла можно так:
    Код (Text):
    1. touch -r file.mp4  filename
     
  6. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Большое спасибо за помощь.

    Не совсем понял эту строчку filename="lol", что она делает?
    Как я вижу это, задача создавать или обновлять каждый раз при проходе файл допустим .timeMarker и обрабатывать файлы младше .timeMarker
     
  7. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Большое спасибо, все работает. Единственное попросило поставить -maxdepth 1 перед -name:
    find: предупреждение: вы указали ключ -maxdepth после аргумента без ключа -name, а ключи не являются позиционными (-maxdepth влияет на тесты указанные как перед ним, так и после него). Указывайте ключи перед другими аргументами.


    Я сделал так: find . -maxdepth 1 -name "*.mp4" -newer "$filename" -print0 | while read -r -d '' i;

    А подскажите пожалуйста, как можно после нанесение логотипа копировать с заменой файл с подкаталога convert в основной, а с convert удалить?
     
  8. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    filename=".timeMarker" присваивает значение переменной. Потом "$filename" используется для find и touch.

    А как часто там добавляются новые файлы?
    Возможно ли добавление нового файла, когда find уже прочитал список файлов в каталоге, а ffmpeg ещё не закончил работу.

    Код (Text):
    1. #!/bin/bash
    2.  
    3. filename=".timeMarker"
    4. date=`date -R`
    5.  
    6. cd /videofiles/;
    7.  
    8. find . -maxdepth 1 -name "*.mp4" -newer "$filename" -print0 | while read -r -d '' i;
    9. do
    10.   ffmpeg -i "$i" -i /images/logo-video.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10" -n convert/"${i%.*}.mp4";
    11. done
    12.  
    13. touch -d "$date" "$filename"
    14.  
    15. for i in convert/*.mp4;
    16. do
    17.   [ -e "$i" ] || continue
    18.   touch -d "$date" "$i"
    19.   mv "$i" ./
    20. done
     
    #8 Emilien, 22 июн 2020
    Последнее редактирование: 22 июн 2020
    ushkom нравится это.
  9. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    И есть еще проблема, обрабатывает скрипт только один файл, не пойму чего.
    --- Добавлено ---
    Файлы добавляются каждый день, буду скрипт ставить на ночь по крону, хотя файлы идут по названию 1, 2, 3 Может лучше запоминать имя файла и искать те которые больше?
     
  10. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    Скрипт обрабатывает только файлы моложе .timeMarker и нужно сравнить время изменения этого и остальных файлов.
    Менять время на .timeMarker нужно крайне осторожно т.к. высок риск повторно нанести логотип и перезаписать исходник.
     
    ushkom нравится это.
  11. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Дело в том что если есть два файла младше даты .timeMarker, обрабатывается только один, я предполагаю что после первого обработанного меняется маркер и второй необработанный становится уже старше маркера. Как заставить менять дату маркера после обработки всех файлов?
    Спасибо Вам за помощь
     
  12. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    find ... | while read ...; do ffmpeg ... done
    Для нормальной работы этой конструкции нужно чтобы ffmpeg не трогал stdin.
    Решается добавлением -nostdin к опциям ffmpeg.

    Может и лучше. Думаю что-то такое можно реализовать.
     
  13. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Большое спасибо Вам за помощь. Я тоже думаю что проще будет не с временной меткой играться а с названием файла. Если будет у Вас время, смогли бы помочь, очень сильно помогли бы, сам я в этом не селен.
     
  14. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    С -nostdin все работает на ура
     
  15. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    Если там имена файлов 1.mp4, 2.mp4, 3.mp4 идут без пропусков.
    Сначала записываем стартовый номер в файл .startID
    Код (Text):
    1. echo 100500 > .startID
    Потом скрипт читает этот номер и последовательно проверяет существование файлов 100500.mp4, 100501.mp4, 100502.mp4 ...
    В конце скрипт сохраняет в файл .startID номер на котором остановился.
    Код (Text):
    1. #!/bin/sh
    2.  
    3. filename=".startID"
    4.  
    5. cd /videofiles/;
    6.  
    7. id=$(< "$filename")
    8. i="${id}.mp4"
    9.  
    10. while [ -f $i ]
    11. do
    12.   ffmpeg -i "$i" -i /images/logo-video.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10" -n convert/"${i%.*}.mp4"
    13.   ((id++))
    14.   i="${id}.mp4"
    15. done
    16.  
    17. echo "$id" > "$filename"
     
  16. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Спасибо.
    А если я удалю какой то из файлов в промежутке, какие последствия будут?
    --- Добавлено ---
    Выдает ошибку
    [: слишком много аргументов
    в строке
    while [ -f $i ]
     
  17. Emilien

    Emilien Активный пользователь

    С нами с:
    30 июн 2016
    Сообщения:
    246
    Симпатии:
    156
    А что там в строке i="${id}.mp4" как там на самом деле выглядят имена файлов?
    Ошибка слишком много аргументов значит, что в переменной $i имя файла с пробелами и нужны кавычки.
    while [ -f "$i" ]

    Там цикл обработки просто останавливается на первом же файле, который не сможет найти.
    Продолжить можно вручную поправив номер в файле .startID.
    Так что этот скрипт не подойдёт если там в нумерации есть пропуски.
     
    ushkom нравится это.
  18. ushkom

    ushkom Активный пользователь

    С нами с:
    5 сен 2016
    Сообщения:
    68
    Симпатии:
    1
    Файлы выглядят так https://prnt.sc/t4yhnr
    Значит буду использовать скрипт с временной меткой, он хорошо работает. Большое Вам спасибо. У Вас есть киви кошелек, на пиво бы сбросил пару рублей.