使用 ffmpeg 和文件列表将图像序列转换为视频
Convert image sequence to video using ffmpeg and list of files
我有一台相机每 2-3 秒拍摄一次延时照片,并且我会保留几天的滚动记录。因为文件很多,所以我按天和小时将它们保存在子目录中:
images/
2015-05-02/
00/
2015-05-02-0000-02
2015-05-02-0000-05
2015-05-02-0000-07
01/
(etc.)
2015-05-03/
我正在编写一个脚本,每天自动将日出的延时摄影上传到 YouTube。我可以提前从网上获取日出时间,然后在日出后返回并使用 find
:
获取该时间段拍摄的文件列表
touch -d "$SUNRISE_START" sunrise-start.txt
touch -d "$SUNRISE_END" sunrise-end.txt
find images/"$TODAY" -type f -anewer sunrise-start.txt ! -anewer sunrise-end.txt
现在我想使用 ffmpeg
将这些文件转换为视频。理想情况下,我希望在不复制所有文件的情况下执行此操作(因为我们正在谈论每小时约 3.5 GB 的图像),并且我不希望将它们重命名为 image000n.jpg
之类的名称,因为其他用户可能想要访问图像。复制图像是我的后备。
但是我无法将 find
的结果发送到 ffmpeg
。我知道 ffmpeg 可以在内部扩展通配符,但我不确定这是否适用于文件不在一个目录中的情况。我还看到一些人使用 find
的 --exec
选项和 ffmpeg
来进行批量转换,但我不确定这是否适用于图像序列输入(相反比如说,将 1000 张图像转换为 1000 个单帧视频)。
关于如何将两者联系起来的任何想法——或者,如果失败了,有更好的方法将跨多个子目录的日期范围内的文件作为图像序列获取到 ffmpeg
中吗?
将 concat
多路分解器与文件列表一起使用。列表格式为:
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
ffmpeg 的基本用法:
`ffmpeg -f concat -i mylist.txt ... <output>`
Concatenate [FFmpeg 维基]
ffmpeg 可能使用与 shell 相同的文件名通配工具,因此所有有效的文件名通配模式都应该有效。具体在您的情况下,images/201?-??-??/??/201?-??-??-????-??
的模式将扩展到所有有问题的文件,例如
ls -l images/201?-??-??/??/201?-??-??-????-??
ffmpeg ... 'images/201?-??-??/??/201?-??-??-????-??' ...
注意 ffmpeg
调用中模式周围的引号:您想将模式逐字传递给 ffmpeg
以将模式扩展为文件名,而不是让 shell 执行扩展。
为此使用 pattern_type glob
ffmpeg -f image2 -r 25 -pattern_type glob -i '*.jpg' -an -c:v libx264 -r 25 timelapse.mp4
我有一台相机每 2-3 秒拍摄一次延时照片,并且我会保留几天的滚动记录。因为文件很多,所以我按天和小时将它们保存在子目录中:
images/
2015-05-02/
00/
2015-05-02-0000-02
2015-05-02-0000-05
2015-05-02-0000-07
01/
(etc.)
2015-05-03/
我正在编写一个脚本,每天自动将日出的延时摄影上传到 YouTube。我可以提前从网上获取日出时间,然后在日出后返回并使用 find
:
touch -d "$SUNRISE_START" sunrise-start.txt
touch -d "$SUNRISE_END" sunrise-end.txt
find images/"$TODAY" -type f -anewer sunrise-start.txt ! -anewer sunrise-end.txt
现在我想使用 ffmpeg
将这些文件转换为视频。理想情况下,我希望在不复制所有文件的情况下执行此操作(因为我们正在谈论每小时约 3.5 GB 的图像),并且我不希望将它们重命名为 image000n.jpg
之类的名称,因为其他用户可能想要访问图像。复制图像是我的后备。
但是我无法将 find
的结果发送到 ffmpeg
。我知道 ffmpeg 可以在内部扩展通配符,但我不确定这是否适用于文件不在一个目录中的情况。我还看到一些人使用 find
的 --exec
选项和 ffmpeg
来进行批量转换,但我不确定这是否适用于图像序列输入(相反比如说,将 1000 张图像转换为 1000 个单帧视频)。
关于如何将两者联系起来的任何想法——或者,如果失败了,有更好的方法将跨多个子目录的日期范围内的文件作为图像序列获取到 ffmpeg
中吗?
将 concat
多路分解器与文件列表一起使用。列表格式为:
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
ffmpeg 的基本用法:
`ffmpeg -f concat -i mylist.txt ... <output>`
Concatenate [FFmpeg 维基]
ffmpeg 可能使用与 shell 相同的文件名通配工具,因此所有有效的文件名通配模式都应该有效。具体在您的情况下,images/201?-??-??/??/201?-??-??-????-??
的模式将扩展到所有有问题的文件,例如
ls -l images/201?-??-??/??/201?-??-??-????-??
ffmpeg ... 'images/201?-??-??/??/201?-??-??-????-??' ...
注意 ffmpeg
调用中模式周围的引号:您想将模式逐字传递给 ffmpeg
以将模式扩展为文件名,而不是让 shell 执行扩展。
为此使用 pattern_type glob
ffmpeg -f image2 -r 25 -pattern_type glob -i '*.jpg' -an -c:v libx264 -r 25 timelapse.mp4