使用avconv在设定的时间从h264视频中获取单帧

时间:2014-08-14 12:56:20

标签: video ffmpeg raspberry-pi raspbian avconv

我想使用 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.

但我切换回单张图片来调试此问题。假设第一个问题得到解决,那么构造这个命令的最佳方法还是更好的方法呢?

2 个答案:

答案 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.jpgoutput_image_0003.jpgpng等。如果您要在提取的帧上执行图像比较,您可能需要考虑使用{ {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。