我想使用 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.
但是我切换回单个图像来调试此问题。假设第一个问题已解决,是构造此命令的最佳方法还是有更好的方法?
最佳答案
如果在-ss
选项之前指定-i
选项,则avconv将不准确地计算帧位置。
您需要首先指定-i
选项,以便avconv知道它需要“搜索”流,直到它准确找到正确的时间戳为止。
同样,您的示例时间1.786
与您在示例中指定的每秒帧-r 25
不对齐。
由于1/25=0.04
,因此-ss
可以将0.04
的任何值均分,以便精确地指定单个帧。
以下内容将获得视频的第46帧:avconv -i input_video.h264 -r 25 -ss 1.8 -frames:v 1 output_image.jpg
如果要通过索引获取特定帧,则需要使用bc
:avconv -i input_video.h264 -r 25 -ss 0$(echo "scale=2;1000/25" | bc -l) -frames:v 1 output_image.jpg
其中1000
是视频的第1001帧(因为0/25
是视频的第1帧)。
请注意,与@ hamboy75的示例不同,我们将-l
(小写L)传递给bc
,以便它执行浮点计算(并且不舍入到最接近的整数)。 scale=2
用于产生精确到2dp的数字。
另请注意,bc
具有输出小于1的数字而没有avconv无法理解的前导零(即.04
)的“功能”。因此,我们还需要在计算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正在搜索文件以准确找到您请求的特定帧。因此,具有较大索引的帧将需要更长的时间提取,因为avconv始终会从流的开头一直“搜索”流。
因此,可能更需要提取一系列帧:
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
本示例从视频中的5分钟中提取了值(value)10秒的帧。当然,您也可以使用:
avconv -i input_video.h264 -r 25 -ss 300.0 -t 10.0 | bc -l) output_image_%04d.jpg
但是,请记住,在少于一秒的持续时间内,该值应可被视频的帧频整除(即
0.04
为25 fps)。每个帧的图像将被命名为
output_image_0001.jpg
,output_image_0002.jpg
,output_image_0003.jpg
等。如果要对提取的帧执行图像比较,则可能需要考虑使用png
而不是jpg
以获得更高的保真度。请注意,如果您指定的帧索引大于视频中存在的帧数,avconv只会提取它找到的最后一帧。您可能需要通过查看
Duration:
输出的avconv -i input_video.h264
部分来计算视频中的帧数。关于video - 在设定的时间使用avconv从h264视频中获取单个帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25308594/