![Как создать миниатюру из середины видео с помощью FFmpeg](https://rvso.com/image/1330228/%D0%9A%D0%B0%D0%BA%20%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C%20%D0%BC%D0%B8%D0%BD%D0%B8%D0%B0%D1%82%D1%8E%D1%80%D1%83%20%D0%B8%D0%B7%20%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D1%8B%20%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE%20%D1%81%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E%20FFmpeg.png)
Есть ли способ получить миниатюру видео в 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