Atc*_*old 1 algorithm video ffmpeg sampling
我试图弄清楚如何从帧 , 开始,对x[n]每帧视频流进行采样,以便最终得到长度为 的新视频。Nn_ii < NNlen(x) / N
在公式中这很简单:y_i[n] = x[n_i + n * N]。
贪婪的解决方案只是将帧转储到文件夹中,然后从适当索引的帧中创建新视频。我希望有一些更优雅的解决方案,ffmpeg因为我必须处理数百个视频。
最后,我设法编写了最终的实现,为了完整性,我在这里报告它。
它确实将最小尺寸缩放到256,但处理的尺寸不会超过max_frames;每帧执行采样k,将第一个k - 1样本发送到一个文件夹,将第k一个样本发送到另一个文件夹。它还将输出帧速率设置为输入平均帧速率,否则某些视频将以 120 Hz 播放...
k=5
kk=$(awk "BEGIN{print 1/$k}")
ffmpeg \
-i $src_video_path \
-an \
-loglevel error \
-filter_complex \
"setpts=$kk*PTS, \
scale=w=2*trunc(128*max(1\, iw/ih)):h=2*trunc(128*max(1\, ih/iw))[m]; \
[m]select=n=$k:e=(mod(n\,$k)+1)*lt(n\,$max_frames) \
$(for ((i=1; i<=$k; i++)); do
echo -n "[a$i]"
done)" \
$(for ((i=1; i<$k; i++)); do
echo -n "-r $fps -map [a$i] $dst_video_path/$i.mp4 "
done
echo -n "-r $fps -map [a$k] $val_video_path/$k.mp4"
)
Run Code Online (Sandbox Code Playgroud)
您可以使用 ffmpeg 的选择过滤器,它允许您使用连续帧编号评估表达式,并决定是否跳过它(以及如果不跳过则将其发送到哪个输出)。
例如,要生成每次分成四个的第二个视频,您可以执行以下操作:
ffmpeg -i input_video -vf select='not(mod(n-1\,4)), setpts=0.25*PTS' -an output_video
Run Code Online (Sandbox Code Playgroud)
4如果您要分割成不同的数字,请更改1,如果您想要不同的选择,请更改(因此对于四个,您将运行四次,开始时不减去任何内容,并以减去三结束。
该-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`
Run Code Online (Sandbox Code Playgroud)
命令中的循环只是写出[a1][a2]...和-map
[a1] out1.mp4...。除此之外,修改是使用filter_complex,这是在处理多个输出时需要的,并更改过滤器以将每个帧定向到其自己的输出mod k。