ffmpeg -pattern_type glob -- 未按正确顺序加载文件

ffmpeg -pattern_type glob -- 未按正确顺序加载文件

我陷入了困境......我已经有一段时间有一个脚本,每隔几分钟从网络摄像头下载图片。命名约定就这样new_image((len(files(dir))+1) + '.jpg'),一切都很好......直到今天......

我有一个加载图像的 Python 脚本基于创建日期并渲染它们,我获取 OpenGL 数据并将其转储到电影中,这并不难,一切都好..除了现在我有几千张图像,以这种方式继续下去是相当无效的(即使它是很酷,因为我可以构建自己的 GUI 和覆盖等)..无论如何,我正在使用 ffmpeg 将图像组合成幻灯片,如下所示:

ffmpeg -f image2 -r 25 -pattern_type glob -i '*.jpg' -qscale 3 -s 1920x1080 -c:v wmv1 video.wmv

ffmpeg 工作正常,只是-pattern_type glob按命名顺序获取图像不起作用,因为文件的获取方式与 类似(如果不一样的话)ls,如下所示:

user@host:/storage/photos$ ls
0.jpg     1362.jpg  1724.jpg  2086.jpg  2448.jpg  280.jpg   3171.jpg  3533.jpg  3896.jpg  4257.jpg  4619.jpg  4981.jpg  5342.jpg  5704.jpg  6066.jpg  650.jpg
1000.jpg  1363.jpg  1725.jpg  2087.jpg  2449.jpg  2810.jpg  3172.jpg  3534.jpg  3897.jpg  4258.jpg  461.jpg   4982.jpg  5343.jpg  5705.jpg  6067.jpg  651.jpg

0, 1000, 1, 2000, 2...这是这样的逻辑ls,所以图像序列(游戏中时光倒流)将被全部f-ed..

关于如何使用 ffmpeg 以更排序的方式加载图像有什么想法吗?

答案1

ffmpeg连接相同的文件类型

您可以使用这样的命令以任何您想要的方式连接文件列表:

ffmpeg -f concat -i <( for f in *.wav; do echo "file '$(pwd)/$f'"; done ) \
         output.wav

仅当您连接的文件都是相同的编解码器时,上述方法才有效。例如,它们都必须是 .wav 或 .mpg。

笔记:您需要有 ffmpeg v1.1 或更高版本才能使用 concat demuxer,您可以阅读有关上述示例的更多信息以及如何使用此技术连接不同的编解码器ffmpeg 网站

使用 printf 格式化程序的 ffmpeg

FFmpeg 还可以使用 printf 格式化程序(例如%d.这匹配从 0 开始并按顺序向上的数字。如果数字的结构类似于 000 - 099,您可以使用此格式化程序 ,%03d它表示一系列 3 位数字,用零填充。

所以你可以这样做:

ffmpeg -r 25 -i %d.png -qscale 3 -s 1920x1080 -c:v wmv1 video.wmv

上面的内容对我来说不太有效,ffmpeg我正在抱怨这个选项-c:v。我只是省略了该选项,该版本的命令按预期工作。

ffmpeg -r 25 -i %d.png -qscale 3 -s 1920x1080 video.wmv

答案2

最简单的方法是使用该rename工具将短文件名重命名为带有前导零。然而,有两种标准的重命名工具 - 我所描述的工具是从手册页中的 Perl 程序员参考指南中描述的。这是 Debian 及其派生发行版上的版本。

rename 's/^/000/' [0-9].jpg
rename 's/^/00/' [0-9][0-9].jpg
rename 's/^/0/' [0-9][0-9][0-9].jpg

然后应该使用 glob 正确地整理文件名。

但是,如果您不想重命名文件,则不能使用 glob,因为按字典顺序而不是数字顺序扩展。

所以,不要使用 glob。摆脱-pattern_type glob并使用-i %d.jpg代替-i *.jpg.这使用数字模式,在我的快速测试中可以满足您的要求。

答案3

最好的方法是重命名文件,使它们都具有相同的位数。使用 zsh (4是最大位数):

autoload zmv     # put this in your ~/.zshrc
zmv '(<->).jpg' '${(l:4::0:)1}.jpg'

使用其他 shell(0如果文件名超过 4 位,则继续并根据需要添加 's):

for x in [0-9].jpg; do mv "$x" "000$x"; done
for x in [0-9][0-9].jpg; do mv "$x" "00$x"; done
for x in [0-9][0-9][0-9].jpg; do mv "$x" "0$x"; done

如果您无法重命名文件,另一种选择是在其他目录中创建符号链接。使用 zsh:

zmv -Ls '$PWD/(<->).jpg' '/somewhere/writable/${(l:4::0:)1}.jpg'

对于任何外壳:

for x in [0-9].jpg; do ln -s "$PWD/$x" "/somewhere/writable/000$x"; done
for x in [0-9][0-9].jpg; do ln -s "$PWD/$x" "/somewhere/writable/00$x"; done
for x in [0-9][0-9][0-9].jpg; do ln -s "$PWD/$x" "/somewhere/writable/0$x"; done

另一种方法是为符号链接提供连续的编号。只要您按照所需的顺序创建符号链接,这种方法就可以推广到原始文件顺序不正确的其他情况。从 10000 开始计数器并删除前导1是获得具有前导零的计数器的便捷方法。

i=10000
for x in [0-9].jpg [0-9][0-9].jpg [0-9][0-9][0-9].jpg; do
  ln -s "$PWD/$x" /somewhere/writable/${i#1}.jpg
  i=$((i+1))
done

如果您确实不想进行任何写入,则可以传递连续的-i选项并增加文件名长度。

ffmpeg -pattern_type glob -i '[0-9].jpg' -i '[1-9][0-9].jpg' -i '[1-9][0-9][0-9].jpg' -i '[1-9][0-9][0-9][0-9].jpg' …

相关内容