ffmpeg - 从视频中提取准确的帧数 [英] ffmpeg - extract exact number of frames from video

查看:6193
本文介绍了ffmpeg - 从视频中提取准确的帧数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从视频中创建最多30张图像(并为他们绘制精灵图片)。



我尝试使用'select'与'mod',但是如果总帧数不适合整合到所需数量的图像(30),那么我有时候会得到更多的图像,有时会更少。



例如,如果我的视频是72帧长,我的'mod'将是72/30,这是2.4。



我从一个python脚本运行,所以我''做一些类似如下的过滤器:

  select ='not(mod(n\,+ str mod)+))'

我认为mod必须是一个整数(?),所以我可以舍弃使用2,它给我36张图像或向上,给我24张图像



什么是最好的方式来准确地30? - 显然间隔不一样,但是很好。



也许我可以使用for循环生成最接近所需间隔的帧的列表,然后传递作为选择过滤器?



例如要获得框架,我会做这样的事情:

  nframes = 72#视频中的帧数
outImages = 30#我想要的图像数量
mod = float(nframes)/ outImages#2.4

frames = []

idx = 1

,而i < nframes:
print str(idx)+:+ str(math.floor(i + 0.5))
frames.append(int(math.floor(i + 0.5)))
idx + = 1
i + = mod

然后我可以通过框架列表)到ffmpeg命令中?或者我可以告诉ffmpeg做类似的事情吗?

解决方案

如果你有一个框架列表,你可以运行

  ffmpeg -i in.mp4 -vf select ='eq(n,5)+ eq(n,11)+ eq(n, 15)..'-vsync 0 frames%d.jpg 






如果您可以将频率分解为有理数字(并进行一些数学计算),则可以直接使用选择过滤器执行此操作。



f = 2.4 12/5 相同。所以这意味着你需要从每12个5帧。你可以将它分解为12中的3 + 1中的1。由于在这种情况下,后者将与前一个选择一致,所以我们可以选择一个帧,即第11个每个第12帧。

  ffmpeg -i in.mp4 -vf select ='not(mod(n,3))+不(mod(n + 1,12))'-vsync 0 frames%d.jpg 

想法是将您的频率表示为相互之和, 1 / f = 1 / m + 1 / n + 1 / p 。您可以使用偏移设备 n + c nc 如果其中一个分母是其他分母的倍数。 / p>




这样做的一个主要方法是

  ffmpeg -i in.mp4 -vf select ='not(mod(n,12))+ not(mod(n + 3,12))+ not(mod(n + 5,12)) +不(mod(n + 7,12))+ not(mod(n + 11,12))`-vsync 0 frames%d.jpg 

其中select子句的总数等于每组X帧所需的帧数。






无论如何,您可以通过添加 -vframes 30


来粗略地限制帧总数

I want to create a maximum of 30 images from a video (and tile them for a sprite sheet).

I've tried using the 'select' with 'mod' but if the total number of frames does not fit neatly into the desired number of images (30) then I sometimes end up with more images, sometimes less.

For example if my video is 72 frames long, my 'mod' would be 72 / 30, which is 2.4.

I'm running this from a python script so i'm doing something like the following for the filter:

select='not(mod(n\," + str(mod) + "))'

I think the mod has to be an integer (?) so I could either round down and use 2 which gives me 36 images or round up which gives me 24 images

Whats the best way to get exactly 30? - obviously the interval wouldn't be identical but thats fine.

Maybe I could use a for loop to generate a list of the frames closest to the desired interval and then pass that in as the select filter?

e.g. to get the frames I would do something like this:

nframes = 72 # number of frames in video
outImages = 30 # number of images I want
mod = float(nframes) / outImages # 2.4

frames = []

idx = 1

while i < nframes:
    print str(idx) + ": " + str(math.floor(i+0.5)) 
    frames.append(int(math.floor(i+0.5)))
    idx += 1
    i += mod

Then am I able to pass that (the frames list) into the ffmpeg command? Or can I tell ffmpeg to do something similar?

解决方案

If you have a list of frames, you can just run

ffmpeg -i in.mp4 -vf select='eq(n,5)+eq(n,11)+eq(n,15)..' -vsync 0 frames%d.jpg


There is a way to do this directly with select filter if you can decompose the frequency into a rational number (and do a bit of maths).

Let's take f = 2.4 which is the same as 12/5. So that means you need 5 frames from every 12. You can decompose that as 1 out of 3 + 1 out of 12. Since, in this case, the latter will coincide with the former selection, we can pick one frame earlier i.e. the 11th of every 12th frame.

ffmpeg -i in.mp4 -vf select='not(mod(n,3))+not(mod(n+1,12))' -vsync 0 frames%d.jpg

The idea is to represent your frequency as a sum of reciprocals, 1/f = 1/m + 1/n + 1/p. You can use the offset device n+c or n-c if one of the denominators is a multiple of the others.


A cruder way to do this is

ffmpeg -i in.mp4 -vf select='not(mod(n,12))+not(mod(n+3,12))+not(mod(n+5,12))+not(mod(n+7,12))+not(mod(n+11,12))` -vsync 0 frames%d.jpg

where total number of select clauses is equal to the number of frames needed from each set of X frames.


In any case, you can crudely limit the total number of frames by adding -vframes 30

这篇关于ffmpeg - 从视频中提取准确的帧数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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