Миниатюры видео с использованием ffmpeg
Я ищу хороший короткий простой способ создать серию миниатюр для любого видео файла. Я почти там использую ffmpeg, вот что у меня есть:
ffmpeg -i /tmp/video.avi -r 1 -ss 60 -r 1 foo-%03d.jpeg`
Единственная проблема в том, что это занимает выстрел каждую секунду, и я хотел бы делать это каждую минуту или около того. Я пытался установить -r
значение для 1/60
или же .02
но безрезультатно.
Для справки вот старый скрипт, который я использовал, который работал только для некоторых файлов:
#!/bin/bash
# grab a screenshot every 60 seconds
file=$1
orig_dir=`pwd`
mins=`exiftool "$file" | grep "Duration" | awk -F : '{print $2}' | grep --only-matching '[0-9]*'`
dir="$file-screenshots"
mkdir "$dir"
cd "$dir"
mplayer -vo png -vf screenshot -sstep 60 -frames $mins -ao null "../$file"
cd "$orig_dir"
Это не обязательно должно быть в командной строке, просто это всегда оказывается самым простым.
1 ответ
Смотрите страницу руководства ffmpeg. Ты хочешь -vframes
:
-vframes
число
Установите количество видеокадров для записи.
Также посмотрите этот пример того, как кто-то делает то же самое. Оригинальное сообщение отмечает, что -r
похоже, не работает должным образом с аргументами меньше одного. Вместо этого предлагается использовать этот вид командной строки для захвата одного кадра (где X - некоторое время для поиска вперед в файле):
ffmpeg -ss X -i input.movie.file -an -vframes 1 ouput.png
Затем используйте сценарии оболочки, чтобы зациклить это, и автоматически сгенерируйте X на основе (а) того, сколько кадров вы хотите захватить и (б) как долго будет длиться видео. Поскольку ваш старый пример сценария уже находит (b), (a) является единственным необходимым вводом:
# generate NFRAMES frames in a movie 90 minutes long
mins=$(exiftool "$file" | grep "Duration" | awk -F : '{print $2}' | grep --only-matching '[0-9]*')
dir="$file-screenshots"
mkdir "$dir"
for i in $(seq 1 $NFRAMES);
do
ffmpeg -ss $(echo "$i * $mins" | bc -l) -i "$file" -an -vframes 1 "$dir/$i.png";
done