Записать имена файлов отдельных изображений в выходной видеоролик FFmpeg
Я использую FFmpeg для чтения серии отдельных изображений и вывода их в виде видео.
Результатом является интервальная съемка скриншотов сайта с интервалом в 1 минуту.
Теперь я хотел бы записать исходное время захвата каждого изображения в результирующее видео с помощью команды drawtext. Время захвата доступно в имени файла каждого изображения. Но мне не удалось найти какую-либо опцию для drawtext для доступа к именам файлов входных изображений.
Альтернативой было бы получить доступ к дате создания каждого изображения из DrawText (я также не могу найти способ сделать это). Но я бы определенно предпочел получить доступ к имени файла, так как это дало бы мне больше возможностей для форматирования текста.
Есть ли способ сделать это?
Было бы здорово, если бы любое предложенное решение работало и на Windows.
3 ответа
Вы не сможете сделать это в одну строку, так как ffmpeg
Фильтр Drawtext не настолько продвинут.
Вам нужно будет предварительно обработать изображения заранее с помощью некоторых сценариев.
Что-то вроде простого скрипта bash:
for i in *.png; do
time = $(echo $i | cut -d . -f 1)
ffmpeg -i $i -vf "drawtext=text=$time" mod-$time.png
done
Затем вы можете использовать файлы mod*.png для создания вашего видео.
Похоже, со времени предыдущего ответа ffmpeg приобрел возможность делать это самостоятельно, используя метаданные декодера image2:
ffmpeg \
-f image2 \
-pattern_type glob \
-export_path_metadata 1 \
-i '*' \
-vf "drawtext=text='%{metadata\:lavf.image2dec.source_basename\:NA}'" \
-y ../output.mkv
Имена файлов не требуют расширения, ffmpeg все равно определит формат изображения. Таким образом, файлы можно переименовывать по мере необходимости. Поскольку входные данные имеют вид «*», выходные данные отправляются в родительский каталог, чтобы избежать путаницы.
Ответ Znuff великолепен (принят и одобрен) и проложил путь к моему собственному решению. Поскольку это специфично для Unix, и мне пришлось работать над Win, вот мое решение для Windows 7 и выше:
Я использовал два пакетных файла (Master.cmd и Slave.cmd), чтобы просмотреть все изображения и записать в них имена файлов.
Master.cmd:
forfiles /p "MyImagesSubPath" /m "2014-02-15*.png" /c "cmd /c ..\Slave.cmd @file @fname
Slave.cmd:
ffmpeg -i "%~1" -vf "crop=1072:1192:24:101, drawtext=text=%~2: fontcolor=white: fontsize=60: box=1: boxcolor=black@0.6: x=50:y=50: fontfile=c\\:\\\\Windows\\\\Fonts\\\\myfont.ttf" "mod_%~1"
Объяснение:
Необходимо использовать две партии по нескольким причинам:
1. Параметр /c forfiles принимает только командную строку ограниченной длины (253 символа)
2. Вложение команды FFmpeg в параметр forfiles /c потребует безумного уровня выделения символов.
Фильтр имени файла "2014-....png" в Master.cmd используется для предотвращения повторной обработки цикла собственным выводом (с именем "mod_....png") в бесконечном цикле. Вы должны адаптировать эту строку фильтра в соответствии с исходными изображениями.
Подчиненный пакет выполняется из подкаталога "MyImagesSubPath", расположенного под каталогом пакетов (именно здесь вы должны разместить исходные изображения). Slave.cmd получает имя файла с расширением (.png) и без него в качестве двух параметров.
Параметр имени файла без расширения используется в качестве текста для записи в изображение. Полученные изображения сохраняются с префиксом "mod_" в том же пути, что и исходные изображения. Имена файлов могут содержать пробелы.