使用avconv在设定的时间从h264视频中获取单帧 [英] Using avconv to get a single frame from h264 video at set time

查看:22
本文介绍了使用avconv在设定的时间从h264视频中获取单帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 avconv 在指定时间从视频文件中获取单个图像.

I want to use avconv to get a single image at a specified time out of a video file.

我对 libav 的了解已足够,认为我知道自己在做什么,但还不足以真正了解.

I've read just enough about libav to think I know what I'm doing, but not enough to actually know.

我试过了:

avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -frames 1 output_image.jpg

以及使用 t 来避免 'frames' 参数:

as well as using t to avoid the 'frames' parameter:

avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -t 0.01 output_image.jpg

并以秒为单位传递而不是使用 hh:mm:ss.xxx 格式:

and passing in seconds rather than using the hh:mm:ss.xxx format:

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 只是视频的第一帧.正如预期的那样.

What I see is when ss is set to 0 (that's '0', '00:00:00.000', '0.0', etc.) the output_image is just the first frame of the video. As expected.

ss 的任何其他值 - 甚至 0.0001 - 都会给我视频的最后一帧.

Any other value for ss - even 0.0001 - gives me the last frame of the video.

我正在使用来自 Raspbian wheezy 存储库的最新 avconv.这种行为对我来说就像一个错误,但我不太了解视频流的其他复杂性,无法确定.

I'm using the latest avconv from the Raspbian wheezy repo. This behaviour feels like a bug to me, but I don't know the other intricacies of video streaming well enough to be sure.

有人知道我做错了什么吗?

Does anyone have any idea what I'm doing wrong?



额外问题:我实际上希望从同一个视频中获取大量这些图像.以前似乎可以将命令串在一起,即:

Bonus question: I'd actually like to get a whole bunch of these images out of the same video. Stringing commands together seemed to work before, ie:

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.

但我切换回单个图像来调试这个问题.假设第一个问题得到解决,这是构建此命令的最佳方法还是有更好的方法?

but I switched back to single images to debug this problem. Assuming the first issue gets solved, is that the best way to structure this command or is there a better one?

推荐答案

正如 Mulvya 所指出的,ffmpeg 将始终使用 -ss 准确查找.此问题是 avconv 独有的.

As Mulvya noted, ffmpeg will always seek accurately with -ss. This issue is exclusive to avconv.

如果在 -i 选项之前指定 -ss 选项,则 avconv 将不准确地计算帧位置.

If you specify the -ss option before the -i option then avconv will inaccurately calculate the frame position.

您需要先指定 -i 选项,以便 avconv 知道它需要搜索"流,直到准确找到正确的时间戳.

You need to specify the -i option first so that avconv knows it needs to "seek" through the stream until it accurately finds the correct timestamp.

此外,您的示例时间 1.786 未与您在示例中指定的每秒帧数 -r 25 对齐.

Also, your example time 1.786 is not aligned to the frames per second -r 25 that you specify in your example.

由于 1/25=0.04 任何 -ss 的值都应该被 0.04 整除,以便精确地指定单个帧.

Since 1/25=0.04 any value for -ss should be divisible by 0.04 in order to specify an individual frame precisely.

以下内容应获得视频的第 46 帧:

The following should get the 46th frame of your video:

avconv -i input_video.h264 -r 25 -ss 1.8 -frames:v 1 output_image.jpg

如果你想通过它的索引获得一个特定的帧,那么你需要使用 bc:

If you want to get a specific frame by it's index then you will need to employ 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 帧).

Where 1000 is the 1001st frame of the video (since 0/25 is the 1st frame).

请注意,与@hamboy75 的示例不同,我们将 -l(小写 L)传递给 bc 以便它执行浮点计算(并且不会四舍五入到最接近的整数).scale=2 用于生成精确到 2dp 的数字.

Note that unlike @hamboy75's example we pass -l (lower case L) to bc so that it performs a floating point calculation (and doesn't round to the nearest integer). scale=2 is used to produce a number accurate to 2dp.

另请注意,bc 具有输出小于 1 的数字而没有前导零(即 .04)的特性",这是 avconv 无法理解的.因此我们还需要在计算0$()

Also note that bc has the "feature" of outputting numbers less than 1 without the leading zero (i.e. .04) which avconv does not understand. Therefore we also need to insert a leading zero prefixed to the calculation 0$()

使用此命令时,您将获得如下所示的输出

When using this command you will get output that looks like the following

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 将始终从流的开头寻找"流.

This is because avconv is seeking through the file to find the specific frame you requested accurately. So frames with a larger index will take longer to extract because avconv will always "seek" through the stream from the stream's beginning.

因此可能更需要提取一系列帧:

It may therefore be more desirable to extract a range of frames:

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 秒的帧.当然你也可以直接使用:

This example extracts 10 seconds worth of frames from 5 minutes within the video. Of course you could also just use:

avconv -i input_video.h264 -r 25 -ss 300.0 -t 10.0 |bc -l) output_image_%04d.jpg

但是,请记住,对于小于一秒的任何持续时间,该值应该可以被视频的帧速率整除(即 0.04 表示 25 fps).

However, remember that for any duration less than a second the value should be divisible by the frame rate for the video (i.e. 0.04 for 25 fps).

每一帧的图像将被命名为output_image_0001.jpgoutput_image_0002.jpgoutput_image_0003.jpg等.如果你正在寻找要对提取的帧执行图像比较,您可能需要考虑使用 png 而不是 jpg 以获得更高的保真度.

The images for each frame will be named output_image_0001.jpg, output_image_0002.jpg, output_image_0003.jpg, etc. If you are looking to perform image comparison on the extracted frames you may want to consider using png over jpg for greater fidelity.

请注意,如果您指定的帧索引大于视频中存在的帧数,avconv 将简单地提取它找到的最后一帧.您可能希望通过查看 avconv -i input_video.h264 输出的 Duration: 部分来计算视频中的帧数.

Note that if you specify a frame index larger than the number of frames present in the video, avconv will simply extract the last frame it finds. You may want to calculate the number of frames in a video by looking at the Duration: part of the output of avconv -i input_video.h264.

这篇关于使用avconv在设定的时间从h264视频中获取单帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆