select - ffmpeg - 从视频中提取确切的帧数

标签 select video ffmpeg frames

我想从视频中创建最多 30 张图像(并将它们平铺为 Sprite 表)。

我尝试过将“select”与“mod”一起使用,但如果总帧数不能完全符合所需的图像数量(30),那么我有时会得到更多图像,有时会更少。

例如,如果我的视频长 72 帧,我的“mod”将为 72/30,即 2.4。

我正在从 python 脚本运行它,所以我正在为过滤器执行以下操作:

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

我认为 mod 必须是一个整数(?)所以我可以向下取整并使用 2 给我 36 个图像或向上取整给我 24 个图像

精确到 30 的最佳方法是什么? - 显然间隔不会相同,但没关系。

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

例如为了得到框架,我会做这样的事情:
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

那么我可以将它(帧列表)传递给 ffmpeg 命令吗?或者我可以告诉 ffmpeg 做类似的事情吗?

最佳答案

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

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

如果您可以将频率分解为有理数(并进行一些数学运算),则有一种方法可以直接使用 select filter 执行此操作。

让我们取 f = 2.412/5 相同.所以这意味着你需要每 12 帧中的 5 帧。你可以将其分解为 3 帧中的 1 帧 + 12 帧中的 1 帧。由于在这种情况下,后者将与前一个选择相吻合,我们可以选择更早的一帧,即第 11 帧每 12 帧。
ffmpeg -i in.mp4 -vf select='not(mod(n,3))+not(mod(n+1,12))' -vsync 0 frames%d.jpg

这个想法是将您的频率表示为倒数的总和,1/f = 1/m + 1/n + 1/p .您可以使用偏移设备n+cn-c如果其中一个分母是其他分母的倍数。

一个更粗略的方法是
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

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

在任何情况下,您都可以通过添加 -vframes 30 来粗略地限制总帧数。

关于select - ffmpeg - 从视频中提取确切的帧数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43079422/

相关文章:

mysql - 在 IF 语句中带有子查询的 MySQL SELECT 语句的语法

mysql - 使用 INSERT INTO 选择更新

r - 如何从整体中提取数据框的一部分?

javascript - Handlebars 多选助手

audio - 使用Gstreamer在录制音频+视频的同时显示无音频视频

ffmpeg - 如何选择自定义需要的编译参数?

python - OpenCV:从 VideoCapture 读取帧将视频推进到奇怪的错误位置

javascript - 一个小时无法播放一组视频

php - 如何将 '00:04:13.67' 格式的时间转换为秒?

c - ffmpeg 与 CodeBlocks 的链接错误