Как извлечь один кадр видео каждые N секунд на изображение?

71

Как я могу преобразовать видеофайл в последовательность изображений, например, один кадр каждые N секунд. Может ли mplayer или ffmpeg сделать это? Я использовал MPlayer для захвата скриншотов вручную, но я хотел бы автоматизировать это для длинного видео.

Liam
источник
См. Этот связанный вопрос о выборе качества изображений: stackoverflow.com/questions/10225403/…
Pierz

Ответы:

70

С ffmpeg это очень просто, и он может выводить один кадр каждые N секунд без дополнительных сценариев. Для экспорта в виде последовательности изображений просто используйте myimage_%04d.pngили аналогично в качестве вывода. %0xdБит преобразуется в нулях целых xчисел длинного - пример я дал получает выходной сигнал , как

  • myimage_0000.png,
  • myimage_0001.png,
  • myimage_0002.png

    и т.д..

Вы можете использовать множество форматов неподвижных изображений: png, jpeg, tga и т. Д. (См. ffmpeg -formatsПолный список).

Итак, теперь мы знаем, как экспортировать фильм в виде последовательности изображений, но скажем, мы не хотим экспортировать каждый кадр?

Хитрость заключается в том, чтобы просто изменить частоту кадров на выходе так, как нам нужно, используя -r nопцию где nчисло кадров в секунду. Будет 1 кадр в секунду -r 1, один кадр каждые четыре секунды -r 0.25, один кадр каждые десять секунд -r 0.1и так далее.

Таким образом , чтобы поставить все это вместе, это то , как это будет выглядеть , чтобы сохранить один кадр input.movкаждые четыре секунды output_0000.png, и output_0001.pngт.д .:

ffmpeg -i input.mov -r 0.25 output_%04d.png

Обратите внимание , что -r 0.25опция идет после на -i input.movчасти, потому что это контролировать частоту кадров вывода . Если вы поместите его перед входом, он будет обрабатывать входной файл так, как если бы он имел указанную частоту кадров.

Изменение% к XD однако многие цифры вам нужно, например , если команда будет создавать более 10000 кадров изменить %04dк %05d. Это также работает для входных файлов, которые представляют собой последовательность изображений. Узнайте больше здесь .

Пользователи Windows : в командной строке используйте%

пример: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

В CMD и BAT Scripts используют %%

пример: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Так что дважды %%в сценариях и один %в интерактивной командной строке. Ошибка в любой ситуации приведет к ошибке.

STIB
источник
Что я должен вставить, -rесли я хочу экспортировать каждый кадр? Если я знаю FPS видео, думаю, я это введу, но что если я не знаю?
Томаш Зато
4
Не используйте флаг -r вообще. Тогда FFMPEG будет использовать частоту кадров входного файла.
STIB
2
Обратите внимание, что вы действительно захотите использовать jpegsдля этого, если вы не уверены png, что это то, что вы хотите. В моем случае jpegs составляли около 50 КБ каждый, а pngs около 2 МБ.
mlissner
5
Преимущество pngs заключается в сжатии без потерь, поэтому, если вы используете последовательность изображений в качестве промежуточного и не обращаете внимания на дополнительный размер, тогда вы можете использовать png.
STIB
Стоит добавить, что -q:v 1здесь очень полезная опция, как в superuser.com/questions/318845/…
Николай Шмырев
27
mplayer -vo jpeg -sstep 5 file.avi

будет сохранять кадр в формате JPEG каждые 5 секунд.

Однако, он не остановится в конце файла, он продолжит создавать копии последнего кадра. Чтобы избежать этого, найдите продолжительность видео в секундах, используя другой плеер или с помощью mplayer:

mplayer -vo null -ao null -frames 0 -identify file.avi

и найдите строку вроде "ID_LENGTH = 147.00".

Вычтите 2 из длины и используйте это значение для -endposопции. Например, для 147-секундного видео:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi
Liam
источник
это звучит как ошибка mplayer. хороший обходной путь.
Квик-кихот
Не могли бы вы хотя бы упомянуть, в какой операционной системе вы используете эту команду?
Томаш Зато
Это было 5 лет назад, но, вероятно, это была последняя версия Ubuntu Desktop в то время, Ubuntu 10.4.
Лиам
Как выбрать шаги короче 1 с. Он принимает только целые числа.
fcpenha
В настоящее время mpv --vo=image --sstep=5 movie.mkvпрекрасно работает без вышеупомянутой ошибки ( mpv - это форк mplayer) с использованием mpv 0.27.0 на Debian.
Адам Кац
11

С помощью ffmpegвы можете сделать следующее:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

Эта команда генерирует миниатюру JPG размером 320 × 240 на 4-й секунде видео. Поместите это в скрипт, который меняет время и имя файла, и все готово.

Дополнительная информация: создание миниатюрного изображения каждые X секунд видео

Nifle
источник
Кажется, это делает то, что я хочу, но с одной проблемой. Он будет обрабатывать файл с самого начала на каждой итерации, становясь экспоненциально медленным.
Лиам
@Liam - Поможет ли вам, если вы оставите время смещения в одиночку (установите его на 1) и воспользуетесь -ss positionфлагом, чтобы искать дальше в файле? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle
1
@liam: поставьте -ssперед, -iчтобы поиск происходил до декодирования входного видео. это должно ускорить это. источник
шарлатан-кихот
2
Есть лучший, гораздо более быстрый способ сделать это с помощью ffmpeg. Смотрите мой ответ ниже.
STIB
Решение Стиба является лучшим ИМО.
Гриффин
8

Если вам нужен своего рода контактный лист и вы работаете с Unix-подобной ОС, вы можете использовать этот сложный сценарий, называемый в виде Video Contact Sheet * NIX , short vcs .

В фоновом режиме он также использует ffmpeg(по умолчанию) или mplayer, следовательно, может обрабатывать множество видеоформатов. Он автоматизирует процесс захвата неподвижных изображений из фильма и объединения их в изображение с некоторым верхним и нижним колонтитулом. Вы можете выбрать, например, сколько снимков вы хотите, или, альтернативно, разницу во времени между ними.

В течение 10 минут вызов выглядит так:

vcs -i 10m input.avi

Проверьте полный список параметров командной строки для некоторых других настроек.

Вот пример контактного листа, взятого с домашней страницы :

введите описание изображения здесь

МРУ
источник
7

С VLC 1.1.0 и выше, вы можете использовать видео фильтр сцены:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

Вышеуказанное сохраняет 1 из каждых 24 кадров (--scene-ratio = 24), начиная с 00:00:10 и заканчивая в 00:00:11.

Только что проверил и подтвердил, что это работает с VLC 2.0.3 на новой установке Windows 8 (у меня нет дополнительных видео плагинов или программного обеспечения).

Полная документация: http://wiki.videolan.org/How_to_create_thumbnails

Майкл
источник
2

VirtualDub может сделать это для вас

File-> Export->Image sequence

введите описание изображения здесь

Shevek
источник
Сохранит ли это каждый кадр как изображение?
Лиам
да, каждый кадр
Шевек
Мне нужно пропустить большинство кадров, выводя все кадры будет занимать слишком много места для хранения. Мне нужен только один кадр каждые несколько секунд.
Лиам
1

Вы также можете попробовать это

из командной строки VLC ...

vlc "C: \ YOUR \ file \ path \ file.avi" -V image --image-out-prefix = capname --image-out-ratio = 60

file.avi - это видео, которое вы хотите захватить, capname - это префикс сохраненных изображений, вы можете поиграть с соотношением (60 означает, что 1 из 60 изображений захвачено). Вы можете добавить больше команд, например --image-out-format jpeg сохранит ваши заглавные буквы как jpegs вместо pngs, --snapshot-path позволяет вам выбрать, где сохранять заглавные буквы.

Источник выше

Nifle
источник
Я получил это сообщение: Параметры командной строки не могут быть загружены, проверьте, что они действительны.
Лиам
В Ubuntu я получил это сообщение: неизвестный параметр или пропущен обязательный аргумент `--image-out-prefix = capname '
Liam
1

Вы можете пропустить кадры в VirtualDub. Просто используйте опцию «Decimate By», расположенную в меню «Видео -> Частота кадров». Например, если вы установите «Decimate By 100», затем используйте File -> Export -> последовательность изображений, он будет сохранять только каждый сотый кадр.

Alex
источник