Как создать миниатюру из середины видео с помощью FFmpeg

Как создать миниатюру из середины видео с помощью FFmpeg

Есть ли способ получить миниатюру видео в FFmpeg?

Я бы хотел захватить средний кадр как видео и использовать его как миниатюру. Длительность видео неизвестна.

Также было бы полезно указать размеры миниатюры.

решение1

Однострочная команда:

ffmpeg -i input.mp4 -vcodec mjpeg -vframes 1 -an -f rawvideo -ss `ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'` output.jpg

Подкоманда получает общую длительность входного видео

ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,

И передайте это awkдля вычисления продолжительности/2 следующим образом:

echo '00:01:30.000' | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'

Итак, это указывает на несколько секунд для опции -ss, и все готово.

Если вы хотите указать размер, добавьте опцию -s, например WxH, где W и H — целые числа (например: -s 800x600 или -s svga), или прочитайте страницу руководства ffmpeg, чтобы узнать о других доступных опциях или форматах.

решение2

Вот метод, использующий:

  • ffprobeчтобы получить длительность
  • bcдля расчета половины продолжительности
  • ffmpegчтобы сделать миниатюру изображения

Пример:

input=input.mp4; ffmpeg -ss "$(bc -l <<< "$(ffprobe -loglevel error -of csv=p=0 -show_entries format=duration "$input")*0.5")" -i "$input" -frames:v 1 half.png

решение3

Прежде всего, всегда используйте последнюю версию FFmpeg.

Если у вас есть доступ к PHP, на ваш вопрос есть исчерпывающий ответ на Stack Overflow:Использовать FFMpeg для получения среднего кадра видео?

$output = shell_exec("/usr/local/bin/ffmpeg -i {$path}");
preg_match('/Duration: ([0-9]{2}):([0-9]{2}):([^ ,])+/', $output, $matches);
$time = str_replace("Duration: ", "", $matches[0]);
$time_breakdown = explode(":", $time);
$total_seconds = round(($time_breakdown[0]*60*60) + ($time_breakdown[1]*60) + $time_breakdown[2]);
shell_exec("/usr/local/bin/ffmpeg -y  -i {$path} -f mjpeg -vframes 1 -ss " . ($total_seconds / 2) . " -s {$w}x{$h} {$output_filename}"; 

Он просто извлечет длительность из выходных данных FFmpeg и использует ее для определения тайм-кода среднего кадра.

Вы можете легко адаптировать это к другим оболочкам и просто вставить в следующую команду, где средний кадр будет примерно на 534секундах:

ffmpeg -y  -i input.mp4 -f mjpeg -vframes 1 -ss 534 thumbnail.jpg

Вы всегда можете изменить размер с помощью -s 480x320или аналогичного параметра, в зависимости от того, насколько большой он вам нужен, вставив его где-нибудь после -i input.mp4параметра.


Вышеуказанное решение немного неточно. Оно немедленно даст вам результат, но вы не сможете указать, какой именно кадр вам нужен. Если вы уже знаете, какой именно кадр хотите извлечь, используйте фильтр select, например, с номером кадра 12345:

ffmpeg -i input.mp4 -filter:v select="eq(n\,12345)" -vframes 1 thumbnail.jpg

Обратите внимание, что выполнение этой команды может занять некоторое время, поскольку ей необходимо перейти к указанному кадру, прежде чем она сможет извлечь его.

решение4

Простое решение:

 ffmpeg -i l1.mp4 -ss 00:00:14.435 -vframes 1 out.png

Связанный контент