如何使用ffmpeg提取第一帧并将其恢复为图像?

87

有人知道诀窍吗?

如何安装ffmpeg?yum install mpeg 只返回这个:

======================================================================================== Matched: mpeg ========================================================================================
libiec61883.i386 : Streaming library for IEEE1394
libiec61883.x86_64 : Streaming library for IEEE1394
qffmpeg-devel.i386 : Development package for qffmpeg
qffmpeg-devel.x86_64 : Development package for qffmpeg
qffmpeg-libs.i386 : Libraries for qffmpeg
qffmpeg-libs.x86_64 : Libraries for qffmpeg
4个回答

112

我从各种答案中凑出了这个命令行,对我来说非常有效,可以从视频中获取绝对第一帧。 我用它来保存视频的缩略图截图。

ffmpeg -i inputfile.mkv -vf "select=eq(n\,0)" -q:v 3 output_image.jpg

说明:

选择过滤器 -vf "select=eq(n\,0)" 用于选择仅第一帧。

-q:v 允许您在1到31之间设置输出jpeg的质量。 数字越小,质量越高。 2-5效果很好,我使用3。

注意:这将获取与视频大小相同的图像。 要获取缩略图,您可以使用比例过滤器以适合所需的任何宽度,例如:

ffmpeg -i inputfile.mkv -vf "select=eq(n\,0)" -vf scale=320:-2 -q:v 3 output_image.jpg

上述命令将给您一个缩略图jpeg,它将被缩放以匹配宽度为320,并且高度将被计算以匹配纵横比。


对我来说,它没有保持视频的宽高比并输出了一个正方形图像。 - Guig
我发现宽度和高度是相同的,但是纵横比是元数据的一部分,并且以上命令没有正确处理。 - Guig
1
@DhirajGupta,我在使用scale命令时遇到了错误:“无法从模式'output_image2.jpg'中获取帧文件名编号2(请设置updatefirst或在文件名模式中使用%03d等模式)av_interleaved_write_frame():无效参数”。 - Murilo
@Murilo 请检查您在参数周围的引号和顺序 - 根据您看到的错误,似乎ffmpeg正在将output_image2.jpg作为输入文件处理? - Dhiraj Gupta
1
这种方法不是最优的,因为它在转储第一帧后仍会解码整个视频。@jcomeau_ictx的回答是最优的。 - Vishal
显示剩余5条评论

80

这在man手册上有说明:

* 你可以从视频中提取图像或从多个图像创建视频:
提取视频中的图像:
ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
这将从视频中每秒提取一个视频帧,并将它们输出到名为foo-001.jpeg,foo-002.jpeg等文件中。图像将被重新调整大小以适应新的WxH值。
如果您只想提取有限数量的帧,则可以将上述命令与-vframes或-t选项组合使用,或与-ss结合使用以从特定时间点开始提取。

当然,您必须先安装它。我在Debian上,不使用yum。

[对于另一个问题的更新]


i=1
for avi in *.avi; do
 ffmpeg -i $avi -vframes 1 -f image2 /tmp/$i.jpg; i=$((i+1))
done

已测试并可用。

[更新另一个问题...]


for flv in *.flv; do
 ffmpeg -i $flv -vframes 1 -f image2 ${flv%%.flv}.jpg
done

7
如何从一个.flv文件列表中仅提取第一帧? - lex
抱歉,我的.flv文件列表是由类似于a.flv,b.flv...的东西指定的,并且我想将图像保存为与flv文件相同的名称。 - lex
继续深入探讨,是否有可能将视频转换为以1fps的速度从第一帧开始的图像?将fps设置为1会从1秒开始。 - Chris
2
可能是,但你必须将其作为问题提出,而不是作为评论。 - jcomeau_ictx

52

我觉得一个易于理解的解决方案是

ffmpeg -i <input> -vframes 1 <output>.jpeg
请注意,我确实会得到一个错误信息 "[swscaler @ 0x111652000] 使用了不建议使用的像素格式,请确保您已正确设置范围",但根据一些阅读(例如请参阅https://dev59.com/01gQ5IYBdhLWcg3wRBzK#43038480),可以安全地忽略该错误。

1
被接受的答案对我没用,出现了Error initializing filter 'select' with args 'eq(n'错误,但可能是我的格式问题。你的答案很好用! - Evan Wagstaff
1
比这里提出的其他解决方案工作速度快了很多。 - hannojg

7

对我来说有效

ffmpeg -i sample-mp4-file.mp4 -ss 1 -vframes 1 output.jpg

7
这里的“-ss 1”是错误的,因为它会寻找第一秒而不是第一帧。 - Maria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接