如何每隔N秒将一帧视频提取到图像?


Answers:


70

使用ffmpeg非常简单,它可以每N秒输出一帧而无需额外的脚本。要导出为图像序列,只需使用myimage_%04d.png或类似于输出。该%0xd位转换为零填充整数x位 - 我给出的示例输出为myimage_0000.png myimage_0001.png等。您可以使用大量静态图像格式,png,jpeg,tga等等(请参阅ffmpeg -formats完整列表)。

好吧,为了导出为图像序列,我们可以使用图像格式作为带有顺序文件名的输出,但我们不想导出每一帧。因此,只需使用-r n选项将输出的帧速率更改为我们想要的任何n值,其中是每秒帧数。每秒1帧-r 1,每四秒钟-r 0.25一帧,每十秒钟一帧-r 0.1,依此类推。

所以要把它们放在一起,这就是每四秒钟将一帧input.mov保存到output_0000.png,output_0001.png等:

ffmpeg -i input.mov -r 0.25 output_%04d.png

将%xd更改为您需要的多个数字,例如,如果命令创建的帧数超过10,000,则更%04d改为%05d。这也适用于作为图像序列的输入文件。在这里阅读更多。

Windows用户:在命令行上使用 %

例: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

在CMD和BAT Scripts中使用 %%

例: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

不要%在脚本中只使用一个,也不要%%在命令行中使用。这两种情况都会产生错误。


-r如果我想导出每一帧,我应该投入什么?如果我知道视频的FPS,我想我输入了,但如果我不这样做呢?
TomášZato2015年

4
根本不要使用-r标志。然后FFMPEG将使用输入文件的帧速率。
2015年

2
请注意,除非你确定是你想要的,否则你真的想要用jpegspng。在我的情况下,jpeg每个大约50kb,pngs约为2MB。
mlissner 2015年

4
pngs的优点是无损压缩,所以如果你使用图像序列作为中间体并且不介意额外的大小那么你可以使用png。
2016年

值得一提的是,这-q:v 1是一个非常有用的选项,如superuser.com/questions/318845 / ...
Nikolay Shmyrev

27
mplayer -vo jpeg -sstep 5 file.avi

将每隔5秒将帧保存为jpeg文件。

但是,它不会在文件末尾停止,它将继续生成最后一帧的副本。要避免这种情况,请使用其他播放器或mplayer查找视频的持续时间(以秒为单位):

mplayer -vo null -ao null -frames 0 -identify file.avi

并寻找像“ID_LENGTH = 147.00”这样的行。

从长度中减去2,并将该值用于该-endpos选项。例如,对于147秒的视频:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi

这听起来像一个mplayer bug。很好的解决方法。
quack quixote 2010年

您能否至少提一下您使用此命令的操作系统?
托马什Zato

它是在5年前,但它可能是当时最新的Ubuntu桌面,Ubuntu 10.4。
利亚姆2015年

如何选择短于1秒的步骤。它只接受整数。
fcpenha 2016年

现在,在Debian上使用mpv 0.27.0,mpv --vo=image --sstep=5 movie.mkv没有上述错误(mpv是mplayer的一个分支),效果很好。
Adam Katz

11

有了ffmpeg,您可以执行以下操作:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

此命令在视频的第4秒生成320×240大小的JPG缩略图。把它放在一个更改时间和文件名的脚本中,你就完成了。

更多信息:每隔X秒创建一个缩略图图像


这似乎做我想要的,但有一个问题。它将在每次迭代时从头开始处理文件,速度会呈指数级增长。
利亚姆2010年

@Liam - 如果你单独留下偏移时间(将其设置为1)并使用该-ss position标志进一步搜索文件,它会有帮助吗?-ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle 2010年

1
@liam:将-ss之前的值放在-i输入视频被解码之前进行搜索。这应该加快它。 source
quack quixote 2010年

2
有一个更好的,多少更快的方式与ffmpeg的做到这一点。请参阅下面的答案。
2014年

stib的解决方案是最好的IMO。
格里芬2014年

8

如果您正在使用某种联系表,并且如果您正在使用类Unix操作系统,则可以使用这个精心设计的脚本,称为视频联系表* NIX,简称vcs

在后台它也使用ffmpeg(默认情况下)mplayer,因此可以处理很多视频格式。它可以自动捕获电影中静止图像的过程,并将这些图像组合成带有页眉和页脚的图像。您可以选择例如您想要的捕获数量,或者它们之间的时间差异。

对于10分钟的间隔,调用是这样的:

vcs -i 10m input.avi

检查命令行选项完整列表以进行其他一些调整。

以下是从主页获取的示例联系表:

在此输入图像描述


7

使用VLC 1.1.0及更高版本,您可以使用场景视频过滤器:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

以上节省了每24帧中的1帧(--scene-ratio = 24),从00:00:10开始到00:00:11结束。

刚刚测试并确认这适用于新的Windows 8安装上的VLC 2.0.3(我没有额外的视频插件或软件)。

完整文档:http//wiki.videolan.org/How_to_create_thumbnails



1

你也可以试试这个

来自VLC命令行......

vlc“C:\ YOUR \ file \ path \ file.avi”-V image --image-out-prefix = capname --image-out-ratio = 60

file.avi是您要捕获的视频,capname是已保存图像的前缀,您可能想要使用该比率(60表示捕获60个图像中的1个)您可以添加更多命令,例如--image-out-format jpeg会将你的大写字母保存为jpegs而不是pngs, - 快照路径可让你选择保存大写字母的位置。

以上来源


我收到此消息:无法加载命令行选项,检查它们是否有效。
利亚姆2010年

在Ubuntu上,我收到了这条消息:未知选项或缺少强制性参数`--image-out-prefix = capname'
Liam 2010年

1

您可以在VirtualDub中跳过帧。只需使用位于视频 - >帧速率菜单中的“Decimate By”选项。例如,如果您设置“Decimate By 100”然后使用File - > Export - > Image sequence,它将仅保存每100帧。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.