【发布时间】:2021-12-14 10:46:47
【问题描述】:
短版
如何将文件img1000.png、img5000.png、img10000.png、img11000.png 以正确的顺序组合成一部电影?
加长版
我正在使用 ffmpeg 从模拟快照中制作电影。例如,每秒应该有 5 张图像。名字是:
image0200.png
image0300.png
image0400.png
image0500.png
image1000.png
image1500.png
image2000.png
...
image8500.png
image9000.png
image9500.png
image10000.png
image15000.png
即,它们是连续的,但数字中有不规则的间隙。这些数字是根据'%04d' 格式化的,但要高于 9999。我试过了
ffmpeg -y -loglevel debug -nostats \
-r:v 5 -thread_queue_size 1024 -f image2 \
-pattern_type glob -i "*[0-9][0-9][0-9][0-9].png" \
-r:v 30 -preset veryslow -pix_fmt yuv420p -crf 28 \
-an AMDG.mp4
还有许多其他变体,但要么最终只有两帧在电影中可见(即使使用 -debug 时找到了图像),要么只使用高达 image9500.png 的文件(而 glob 确实似乎不允许[0-9]{4,} 使用正则表达式),或者,使用
ffmpeg -y -loglevel debug -nostats \
-r:v 5 \
-thread_queue_size 1024 -f image2 -pattern_type glob \
-i "image[0-9][0-9][0-9][0-9].png" \
-r:v 5 \
-thread_queue_size 1024 -f image2 -pattern_type glob \
-i "image[1-9][0-9][0-9][0-9][0-9].png" \
-r:v 30 -preset veryslow -pix_fmt yuv420p -crf 28 \
-map 0 -map 1 \
-an AMDG.mp4
输出电影中显然有两个流,并且只有一个正在播放。 (我意识到在这个过程中需要-map 0 -map 1 才能使用两个输入流。)
在我发现的一种选项变体中(现在我已经失去了它的本来面目!)所有图像都包括在内,但顺序不是所需的:image1000.png 显示在image10000.png 之前。显然,较新版本的 ffmpeg(我有 ffmpeg version 3.4.8-0ubuntu0.2)能够像 sort -V 一样排序,因此 image10000 排在 image1000 之后,但重新安装 ffmpeg 通常不是一个实际的选择。重命名文件也不实用,并且创建例如以 '%05d' 格式的顺序名称的软链接从 0 开始,步长为 1(以便可以使用 -i '%05d')当然不优雅。
使用-concat 过滤器,如https://unix.stackexchange.com/questions/77016/ffmpeg-pattern-type-glob-not-loading-files-in-correct-order,即,
ffmpeg -y -loglevel debug -nostats -r:v 5 \
-thread_queue_size 1024 -f image2 -f concat \
-safe 0 -i <(find . -maxdepth 1 -regex 'image*.png' \
-exec echo "file $(pwd)/"{} \; | sort -V) \
-r:v 30 -codec:v libx264 -preset veryslow -pix_fmt yuv420p -crf 28 \
-an \
AMDG.mp4
处理时间很长,使整个系统变得迟缓,同时制作了大约 60 kB 的电影,只显示了两个不同的图像。
我的印象是同时存在几个问题...如果您能提供帮助,谢谢!
【问题讨论】:
-
像
ffmpeg -pattern_type glob -i '*.png' -vcodec libx264 out.mp4描述的here 怎么样?如果没有任何效果,请考虑使用 Python 脚本。 -
谢谢,但
-pattern_type glob -i '*.png'将文件按错误的顺序排列(10000、1000、10500、...、6000等),如-loglevel debug所列即使在-i之前使用-r:v 2和-r:v 10在-vcodec之前使用-r:v 10(使其非常慢),在一段不规则的时间内,电影中也只能看到两个不同的图像。我不能使用该链接中的-start_number,因为我的数字不会增加1。脚本的内容是什么,无论是bash、python等? -
使用 Python 脚本我们可以将 PNG 文件名读入一个列表,并按照前缀编号对列表进行排序(在 Python 中排序比较简单)。列表排序后,我们可以一次读取每个PNG文件,并将内容写入FFmpeg子进程的stdin管道。 (只是有点慢)。
-
尤里卡!令人尴尬的是,问题在于,在测试时,我将大多数 PNG 相互覆盖,以便不同的文件具有相同的内容——因此电影不存在一个问题。为了获得正确的顺序(一旦帧再次不同......),确实
ffmpeg -f concat -safe 0 -i List.txt ...有效,其中List.txt可以使用上面的... <(find ...)部分即时制作(请参阅ffmpeg wiki 下的“进程替换” . 使用... | sort -V | tee list.txt),您可以保存列表。无需外部脚本。感谢您的帮助! -
只有 List.txt 中的文件名(前面有“file”),我得到了很多
[concat @ 0x556604e50940] DTS -230584300921369 < 0 out of orderDTS -230584300921369, next:40000 st:0 invalid droppingPTS -230584300921369, next:40000 invalid dropping st:0。如果在每行file ...之后添加一行带有duration XXX的行,这种情况就会消失,其中XXX是任意的并且不会改变结果。请参阅 [this SO post]/stackoverflow.com/questions/46952350/…) 指出要重复最后一帧。