- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 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 存储库的最新 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.
但我切换回单图来调试这个问题。假设第一个问题得到解决,那么这是构建此命令的最佳方式还是有更好的方式?
最佳答案
Edit: As Mulvya noted, ffmpeg will always seek accurately with -ss. This issue is exclusive to avconv.
如果您在 -i
选项之前指定 -ss
选项,则 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
是第一帧)。
请注意,与@hamboy75 的示例不同,我们将 -l
(小写 L)传递给 bc
,以便它执行浮点计算(并且不会四舍五入到最近的整数)。 scale=2
用于生成精确到 2dp 的数字。
另请注意,bc
具有输出小于 1 且不带前导零的数字的“功能”(即 .04
),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 正在寻找文件以准确找到您请求的特定帧。因此,具有较大索引的帧将需要更长的时间来提取,因为 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 分钟中提取 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 将只提取它找到的最后一帧。您可能希望通过查看 avconv -i input_video.h264
输出的 Duration:
部分来计算视频中的帧数。
关于video - 使用avconv在设定时间从h264视频中获取单帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25308594/
为了从未压缩的 v210(像素格式为 kCVPixelFormatType_422YpCbCr10)中提取 RAW 图像缓冲区,我尝试关注这个很棒的帖子: Reading samples via AV
我是一名优秀的程序员,十分优秀!