从n0个初始帧开始每隔N帧采样一次视频

时间:2017-03-30 21:39:56

标签: algorithm video ffmpeg sampling

问题

我想弄清楚如何从x[n]N开始,每隔n_i帧对视频流i < N进行一次采样,以便我最终得到{ {1}}长度为N的新视频。

在公式中,这只是:len(x) / N

这里有一个我想要实现的图表: sampling

贪婪的解决方案只是将帧转储到文件夹,然后从适当索引的帧中创建新视频。 我希望y_i[n] = x[n_i + n * N]有更优雅的解决方案,因为我必须处理数百个视频。

实施

最后,我设法编写了最终实现,我在这里报告是为了完整性 它确实将最小维度缩放为ffmpeg,处理时间不超过256;每隔max_frames帧执行一次采样,将第一个k样本发送到一个文件夹,将k - 1个样本发送到另一个文件夹。它还将输出帧速率设置为输入平均帧速率,否则某些视频将达到120 Hz ...

k

1 个答案:

答案 0 :(得分:3)

逐一解决方案

您可以使用ffmpeg的选择过滤器,它允许您使用顺序帧编号计算表达式,并决定是否跳过它(以及如果不跳过它将输出发送到哪个输出)。

例如,要生成第二个视频,每次分成四个视频,您将执行以下操作:

ffmpeg -i input_video -vf select='not(mod(n-1\,4)), setpts=0.25*PTS' -an output_video

如果您要分割成不同的数字,请更改4;如果您想要不同的数字,则更改1(因此对于4,您将运行它四次,开始时不会减去任何内容,并结束减去三个。

-vf ... -an段是让视频以正确的速度播放,并且长度合适(需要删除任何音轨)。

一次性解决方案

选择过滤器还可以拆分文件并单独保存每个输出。这是一个将文件拆分为k个输出的命令,(如果你想要一个不同的扩展名,可以改变.mp4)。

k=4;ffmpeg -i INPUT_FILE -an -filter_complex "setpts=`bc -l <<< 1/$k`*PTS[m];[m]select=n=$k:e=mod(n\,$k)+1`for ((i=1; i<=$k; i++)); do echo -n "[a$i]"; done`" `for ((i=1; i<=$k; i++)); do echo -n "-map [a$i] out$i.mp4 "; done`

命令中的循环只是写出[a1][a2]...-map [a1] out1.mp4...。除此之外,修改是使用filter_complex,这是处理多个输出时所需要的,并且更改过滤器以将每个帧定向到其自己的输出mod k。