2009-06-30 154 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

感谢,这正是我一直在寻找! – 2009-07-29 23:08:39

+0

@Derek Gathright请给我一些基本的细节,以开始使用ffmpeg。请看看我的[问题](http://stackoverflow.com/questions/10071408/how-to-get-frames-of-video-file-in-android)。 – 2012-04-25 04:56:46

4

FFmpeg可以帮助您获得帧率和视频的长度,因此您可以将一个乘以另一个并除以2以获得中间帧的编号。

即,对于以15帧/秒运行的30秒视频:30 * 15 = 450/2 = 225,这意味着您需要抓住第225帧。

0

这个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 
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 

这消除了任何需要使用awktrgrepsed

或者,你可以使用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