我想使用 avconv 在指定时间从视频文件中获取单张图片。
我已经阅读了足够的关于 libav 的信息,认为我知道自己在做什么,但实际上并不知道。
我试过了:
avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -frames 1 output_image.jpg
以及使用t来避免'frames'参数:
avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -t 0.01 output_image.jpg
并在几秒内传递而不是使用hh:mm:ss.xxx格式:
avconv -ss 1.786 -r 25 -i input_video.h264 -t 0.01 output_image.jpg
我看到的是当ss设置为0(即'0','00:00:00.000','0.0'等)时,output_image只是视频的第一帧。正如所料。
ss的任何其他值 - 甚至0.0001 - 都会给我视频的最后一帧。
我正在使用来自Raspbian wheezy repo的最新avconv。这种行为对我来说就像是一个错误,但我不知道视频流的其他复杂性是否足以确定。
有谁知道我做错了什么?
奖金问题:我实际上想从同一个视频中获取大量这些图片。将命令串起来之前似乎有效,即:
avconv -ss 1.786 -r 25 -i input_video.h264 -t 0.01 output_image1.jpg
-ss 3.454 -r 25 -i input_video.h264 -t 0.01 output_image2.jpg
-ss 5.823 -r 25 -i input_video.h264 -t 0.01 output_image3.jpg
-ss etc,etc.
但我切换回单张图片来调试此问题。假设第一个问题得到解决,那么构造这个命令的最佳方法还是更好的方法呢?
答案 0 :(得分:3)
编辑:正如Mulvya所说,ffmpeg将始终使用-ss准确搜索。此问题仅适用于avconv。
如果在-ss
选项之前指定-i
选项,则avconv将错误地计算帧位置。
您需要先指定-i
选项,以便avconv知道它需要“搜索”整个流,直到它准确找到正确的时间戳。
此外,您的示例时间1.786
未与您在示例中指定的每秒帧数-r 25
对齐。
1/25=0.04
-ss
0.04
的任何值都应该被avconv -i input_video.h264 -r 25 -ss 1.8 -frames:v 1 output_image.jpg
整除,以便精确指定单个帧。
以下内容应该是您视频的第46帧:
bc
如果您想通过索引获取特定框架,则需要使用avconv -i input_video.h264 -r 25 -ss 0$(echo "scale=2;1000/25" | bc -l) -frames:v 1 output_image.jpg
:
1000
0/25
是视频的第1001帧(因为-l
是第1帧)。
请注意,与@ hamboy75的示例不同,我们将bc
(小写L)传递给scale=2
,以便它执行浮点计算(并且不会舍入到最接近的整数)。 bc
用于生成精确到2dp的数字。
另请注意,.04
具有输出小于1的数字的“特征”,而没有avconv不理解的前导零(即0$()
)。因此,我们还需要在计算frame= 0 fps= 0 q=0.0 size= 0kB time=10000000000.00 bitrate= 0.0kbit
frame= 0 fps= 0 q=0.0 size= 0kB time=10000000000.00 bitrate= 0.0kbit
frame= 0 fps= 0 q=0.0 size= 0kB time=10000000000.00 bitrate= 0.0kbit
frame= 0 fps= 0 q=0.0 size= 0kB time=10000000000.00 bitrate= 0.0kbit
frame= 0 fps= 0 q=0.0 size= 0kB time=10000000000.00 bitrate= 0.0kbit
使用此命令时,您将获得类似于以下内容的输出
avconv -i input_video.h264 -r 25 -ss 0$(echo "scale=2;7500/25" | bc -l) -t 0$(echo "scale=2;250/25" | bc -l) output_image_%04d.jpg
这是因为avconv正在通过该文件来查找您准确请求的特定帧。因此,具有较大索引的帧将需要更长的时间来提取,因为avconv将始终从流的开头“搜索”流。
因此可能更需要提取一系列帧:
avconv -i input_video.h264 -r 25 -ss 300.0 -t 10.0 | bc -l) output_image_%04d.jpg
此示例从视频中的5分钟内提取10秒的帧数。当然你也可以使用:
0.04
但是,请记住,对于任何持续时间不到一秒的时间,该值应该可以被视频的帧速率整除(例如output_image_0001.jpg
为25 fps)。
每个帧的图像将命名为output_image_0002.jpg
,output_image_0003.jpg
,png
等。如果您要在提取的帧上执行图像比较,您可能需要考虑使用{ {1}}超过jpg
以获得更高的保真度。
请注意,如果指定的帧索引大于视频中存在的帧数,avconv将只提取它找到的最后一帧。您可能希望通过查看Duration:
输出的avconv -i input_video.h264
部分来计算视频中的帧数。
答案 1 :(得分:-1)
在我的情况下,我想在前3分钟每60秒拍一张图片......
{0..3}中的;做avconv -ss echo $i*60.0 | bc
-i input_video.h264 -frames:v 1 -y out $ i.jpg;完成
如果你需要一段时间,你可以稍微改变一下:9。