Как извлечь 1 снимок экрана для видео с помощью ffmpeg в заданное время?

109

Существует множество руководств и прочего, показывающего, как извлечь несколько скриншотов из видео с помощью ffmpeg. Вы устанавливаете -r и даже можете начать с определенной суммы.

Но мне нужен только 1 снимок экрана, скажем, 01:23:45 дюйма или 1 снимок экрана с размером 86%.

Все это возможно с помощью ffmpegthumbnailer, но это еще одна зависимость, от которой я не хочу зависеть. Я хочу сделать это с помощью ffmpeg.

Питер Бенгтссон
источник

Ответы:

208

Воспользуйтесь -ssопцией:

ffmpeg -ss 01:23:45 -i input -vframes 1 -q:v 2 output.jpg
  • Для вывода JPEG используйте -q:vдля контроля качества вывода. Полный диапазон - это линейная шкала от 1 до 31, где меньшее значение приводит к более высокому качеству. 2-5 - хороший диапазон, чтобы попробовать.

  • Выбрать фильтр обеспечивает альтернативный метод для более сложных потребностей , таких как выбор только для определенных типов кадров, или 1 на 100, и т.д.

  • Размещение -ssперед входом будет быстрее. См. FFmpeg Wiki: Seeking и этот отрывок из ffmpegдокументации инструмента cli :

-ss положение (ввод / вывод)

При использовании в качестве параметра ввода (ранее -i) ищет в этом файле ввода позицию. Обратите внимание, что в большинстве форматов невозможно точно найти, поэтому ffmpegбудет искать ближайшую точку поиска перед позицией. Когда транскодирование и -accurate_seekвключено (по умолчанию), этот дополнительный сегмент между точкой поиска и положением будет декодирован и отброшен. При копировании потока или когда -noaccurate_seek он используется, он будет сохранен.

При использовании в качестве параметра вывода (перед именем файла вывода) декодирует, но отбрасывает ввод, пока отметки времени не достигнут позиции.

позиция может быть либо в секундах, либо в hh:mm:ss[.xxx]форме.

llogan
источник
2
Это НАМНОГО быстрее. Огромное спасибо. Помещение -ss в первую очередь имеет огромное значение.
Питер Бенгтссон
есть ли способ получить n-й кадр по истечении указанного времени?
Дориен
@GuntherPiez Я нигде не упоминаю о возможных артефактах.
Стефан Райх
2
Обратите внимание, что vframesэто устарело (по крайней мере) в версии 4.2.2. Согласно руководству «[ vframes] - устаревший псевдоним для ' -frames:v', который следует использовать вместо него».
Synexis,
Работает отлично и быстро.
Smeterlink
37

FFMpeg может сделать это, перейдя к заданной метке времени и извлекая ровно один кадр в качестве изображения, см., Например:

ffmpeg -i input_file.mp4 -ss 01:23:45 -vframes 1 output.jpg

Поясним варианты:

-i input file           the path to the input file
-ss 01:23:45            seek the position to the specified timestamp
-vframes 1              only handle one video frame
output.jpg              output filename, should have a well-known extension

-ssПараметр принимает значение в форме HH:MM:SS[.xxx]или в виде числа в секундах. Если вам нужен процент, вам нужно заранее рассчитать продолжительность видео.

SirDarius
источник
Кажется, работает как положено. В настоящее время я проверяю, соответствует ли это скорости использования ffmpegthumbnailer.
Питер Бенгтссон
Да, этот подход очень медленный. См. Peterbe.com/plog/fastest-way-to-take-screencaps-out-of-videos
Питер Бенгтссон,
7
попробуйте использовать параметр -ss перед -i, поскольку он пропускает часть конвейера декодирования. Это может ускорить процесс.
SirDarius
1
Есть ли способ вывести в поток как PNG вместо файла?
Nicke Manarin
1
@NickeManarin Да .. ffmpeg -ss 01:23:45 -i video.mp4 -c:v png -frames:v 1 image.jpg. Обратите внимание, что я также поместил параметр -ss«искать» перед входным файлом в командной строке, как рекомендуют другие.
Glenn