Использовать FFMpeg для получения среднего кадра видео?
Вопрос
Мне интересно, как использовать FFMpeg для захвата среднего кадра видео.Я уже написал C# для захвата кадра в определенное время (т.е. извлечения одного кадра в секунду 3).Но мне еще предстоит выяснить, как найти середину видео с помощью команд FFMpeg.
Решение
Это можно было бы упростить, но вот какой-то старый PHP-код, который у меня валялся, должен помочь.(Добавьте местоположение в ffmpeg, если его нет на вашем пути)
$output = shell_exec("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("ffmpeg -y -i {$path} -f mjpeg -vframes 1 -ss " . ($total_seconds / 2) . " -s {$w}x{$h} {$output_filename}");
Другие советы
FFmpeg помогает вам получить частоту кадров и длину видео, поэтому вы можете умножить одно на другое и разделить на 2, чтобы получить номер среднего кадра.
т.е. для 30-секундного видео со скоростью 15 кадров в секунду:30*15=450/2=225, значит нужно захватить 225-й кадр.
С помощью простых сценариев оболочки вы можете использовать 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
Это устраняет необходимость в PHP, echo
, awk
, tr
, grep
, sed
, и т. д.
Эта команда bash работает как шарм (проверено):
avconv -i 'in.mpg' -vcodec mjpeg -vframes 1 -an -f rawvideo -s 420x300 -ss avconv -i in.mpg 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F ':' '{print ($3+$2*60+$1*3600)/2}' out.jpg