如何使用 ffmpeg 垂直滚动图像并同时检测图像结束(EOI)?

How to scroll an image vertically using ffmpeg and detect the end-of-image (EOI) at same time?

我需要垂直滚动图像,从图像的顶部到图像的底部,然后在图像的最后一位滚出屏幕顶部后立即停止创建输出视频.

这是我找到的解决方案;

ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -i "input.png" -filter_complex "[1:v]scale=1920:-2[fg]; [0:v][fg]overlay=y=-'t*h*0.02'[v]" -map "[v]" -t 00:03:00 output.mp4

请注意,滚动率为 0.02。将它设置得更低,例如 0.01 滚动得更慢,或设置得更高——例如 0.03,滚动得更快。

请注意,我向命令传递了最多 3 分钟的时间。遗憾的是,这一次需要大于任何图像滚动输出在您的特定设置中所能接受的大小。

作为参考,一张 1920x7043 像素的图像需要 49.88 秒。您可以使用编程方式获取图像的高度;

file input.png | sed 's|.*1920 x \([0-9]\+\).*||'
output: 7043

如果有人有更好的 "detecting the end of the image scroll - i.e. the last line/bottom of the image scrolling off the top of the screen" 方法并且能够基于此扩展 time/duration - 那将非常方便。

目前这是我拥有的最佳解决方案;扫描上面最后一个 ffmpeg 命令的输出,寻找类似的东西;

[blackdetect @ 0x559298835480] black_start:49.88

例如使用这个命令;

ffmpeg -i output.mp4 -vf blackdetect=d=0.1:pix_th=.1 -f rawvideo -y /dev/null 2>&1 | grep -o "black_start:[\.0-9]\+ "
output: black_start:49.88

并相应地裁剪;

ffmpeg -i output.mp4 -t 49.88 -c copy finaloutput.mp4
vlc finaloutput.mp4  # Assuming you have vlc installed

要在一个命令中执行此操作,请使用

ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -t 0.08 -i "input.png" -filter_complex "[1:v]scale=1920:-2,setpts=if(eq(N,0),0,1+1/0.02/TB),fps=25[fg]; [0:v][fg]overlay=y=-'t*h*0.02':eof_action=endall[v]" -map "[v]" output.mp4

请注意,在某些 shell 中(例如 Bash)逗号需要转义:

ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -t 0.08 -i "input.png" -filter_complex "[1:v]scale=1920:-2,setpts=if(eq(N\,0)\,0\,1+1/0.02/TB),fps=25[fg]; [0:v][fg]overlay=y=-'t*h*0.02':eof_action=endall[v]" -map "[v]" output.mp4

为图像添加 -t 以便我们有一个包含 2 帧的流。 (25 fps x 0.08 = 2)。 setpts 将第二帧的时间戳设置为滚动速率的倒数,表示高度的一部分。 fps 过滤器使用克隆帧填充时间戳间隙。

当图像输入完成时,叠加层被告知停止。