2009-06-30 2 views
8

Мне интересно, как использовать FFMpeg для захвата среднего кадра видео. Я уже написал C#, чтобы захватить фрейм в определенное время (т. Е. Вытащить один кадр во второй 3). Но мне еще предстоит выяснить, как найти середину видео с помощью команд FFMpeg.Используйте FFMpeg для получения среднего кадра видео?

ответ

8

Это может быть упрощено, но вот какой-то старый 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}"); 
+0

Спасибо, что это именно то, что я искал! –

+0

@Derek Gathright Пожалуйста, дайте мне основные сведения, чтобы начать работу с ffmpeg. Пожалуйста, посмотрите мой [вопрос] (http://stackoverflow.com/questions/10071408/how-to-get-frames-of-video-file-in-android). –

4

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

т. Е. Для видео в течение 30 секунд со скоростью 15 кадров в секунду: 30 * 15 = 450/2 = 225, что означает, что вам нужно захватить 225-й кадр.

0

команда работает Это Баш как шарм (проверено):

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 
2

Пример

Предполагая, что вы используете Linux вам можно использовать ffprobe, чтобы получить длительность, bc вычислить половину точки, то ffmpeg сделать кадр:

eval "$(ffprobe -v error -of flat=s=_ -show_entries format=duration input.mp4)" 
ffmpeg -ss "$(echo "$format_duration/2" | bc)" -i input.mp4 -q:v 2 -frames:v 1 half.jpg 

Это исключает необходимость использования awk, tr, grep, sed и т.д.

В качестве альтернативы можно использовать select filter и устранить bc, но выбрать фильтр может быть медленным.

Примечание о продолжительности

Продолжительность от ffprobe может быть неправильным, если файл поврежден или усеченной неправильно. Продолжительность может быть подтверждена полностью декодирование входа с ffmpeg затем отмечая time= во втором к последней строке в консоли выводе:

ffmpeg -i input -f null - 
… 
frame= 2600 fps=569 q=-0.0 Lsize=N/A time=00:01:48.50 bitrate=N/A 
video:244kB audio:20344kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown 
+0

В Windows/Cygwin мне пришлось сделать уродливую обработку текста kludge вывода eval/ffprobe, чтобы устранить новую строку Windows с конца $ format_duration: 'eval '$ (ffprobe -v error -of flat = s = _ -show_entries формат = длительность tmp.mp4) "' 'эхо $ format_duration> tmp.txt' ' эхо/2 >> tmp.txt' 'dos2unix tmp.txt' format_duration =' 'тр -d '\ n'

+0

В последней части моего комментария есть набор обратных шагов, окружающих назначение переменной после format_duration (который здесь устраняется путем разбора разметки). –