使用 ffmpeg concat 和 filter_complex 进行循环

使用 ffmpeg concat 和 filter_complex 进行循环

由于我已经“翻转”了我的课堂,所以我正在尝试制定 ffmpeg 命令,该命令将一组 m4a 音频文件与一组匹配的静态 PNG 连接起来以创建预先录制的讲话。

合并单个 PNG(幻灯片)和单个音频文件(旁白)没有任何问题,例如:

ffmpeg -r 30 \
  -loop 1 -i 2.3-Python_the_Basics_1_1280x720.png \
  -i 2.3-1.m4a \
    -c:v libx264 -tune stillimage -shortest -pix_fmt yuv420p \
    -b:a 64k \
    out1.mp4

ffmpeg -r 30 \
  -loop 1 -i 2.3-Python_the_Basics_2_1280x720.png \
  -i 2.3-2.m4a \
    -c:v libx264 -tune stillimage -shortest -pix_fmt yuv420p \
    -b:a 64k \
    out2.mp4

ffmpeg -r 30 \
  -loop 1 -i 2.3-Python_the_Basics_3_1280x720.png \
  -i 2.3-3.m4a \
    -c:v libx264 -tune stillimage -shortest -pix_fmt yuv420p \
    -b:a 64k \
    out3.mp4

然后我可以使用该list.txt方法(包含file 'out1.mp4'等等)将其连接起来:

ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

但是,这种方法似乎会在视频开头插入一个黑框,这让我很烦。如果我使用修剪来解决这个问题,我的生活可能会更轻松:

ffmpeg -ss 00:00:00.750 -i output.mp4 -t 10:00:00 -c:v copy -c:a copy cleaned.mp4

然而,在我看来应该我也可以结合全部将上面的音频和 PNG 文件通过一个命令合并到单个输出中,这就是我绕圈子的地方。

我是猜测这里的一个挑战是,该-loop 1方法不适用于多个 PNG 输入,因为在处理复杂的过滤器时,我应该为每个输入指定一个时间。但我不想对持续时间进行硬编码,因为自动化角度就是能够重新录制我演讲的一部分(因此更改单个幻灯片的音轨),然后重新渲染整个视频。这意味着音轨的长度可能会改变,所以我不想手动更新 PNG 循环时间。

我发现这个concat过滤器相当难理解,但以下是种类我希望能起作用的事情(但显然没有):

ffmpeg -r 30 \
  -loop 1 -i 2.3-Python_the_Basics_1_1280x720.png \
  -loop 1 -i 2.3-Python_the_Basics_2_1280x720.png \
  -loop 1 -i 2.3-Python_the_Basics_3_1280x720.png \
  -i 2.3-1.m4a \
  -i 2.3-2.m4a \
  -i 2.3-3.m4a \
  -filter_complex "[0:v][3:a] [1:v][4:a] [2:v][5:a] concat=n=3:v=1:a=1 [vvv][aaa]" \
  -map "[vvv]" -map "[aaa]" \
  -c:v libx264 -tune stillimage -pix_fmt yuv420p \
  -c:a aac -b:a 64k \
  out6.mp4

有没有办法不用该list.txt方法就能实现我想要的效果? 某种shortest针对每个段的选项[0:v][3:a][1:v][4:a]

使用ffprobe捕捉剪辑长度到脚本参数中是可行的,但似乎……不够优雅。即捕捉每个音轨的长度,然后将其作为PNG 文件参数ffmpeg中“脚本”的一部分写出:-t

ffprobe -sexagesimal -show_entries format=duration 2.3-1.m4a

非常感谢!

相关内容