【问题标题】:Bash loop over files in directory outputting non existent filesBash循环遍历目录中的文件输出不存在的文件
【发布时间】:2026-01-18 17:25:01
【问题描述】:

我正在从一系列图像制作 mp4 文件。图像应该运行大约 1 小时,但我无法获得完整的视频,因为 FFMPEG 会查找它不应该有的文件。

[image2 @ 0x55fe14bef700] Could not open file : /mnt/run/image-005437.jpeg

令人困惑的是,我传递给 ffmpeg 应该 的列表不包括该文件。如果我的脚本不喜欢结果,它会将文件发送到目标文件夹中名为失败的子目录

具有该编号的文件的位置

$ pwd
run/failed
]$ ls
failed-005437.jpeg 

我用来启动 ffmpeg 的命令如下

image_folder=$1
singularity exec --bind $work_dir:/mnt $work_dir/longleaf2.sif ffmpeg -f concat -safe 0 -y -i <(for f in /mnt/processed_images/$image_folder/image-%06d.jpeg; do echo "file '$f'";done) -vf "crop=trunc(iw/3)*2:trunc(ih/2)*2" -movflags +faststart /mnt/run/summary_files/${image_folder}.mp4

我检查了已处理的图像,但它不存在,为什么 ffmpeg 会寻找它?

失败运行的pastebin

https://pastebin.com/pF5ZefLf

我检查文件不在for循环引用的文件夹中,因此它永远不会导致错误

$ ls image-005437.*
ls: cannot access image-005437.*: No such file or directory

【问题讨论】:

    标签: bash ffmpeg directory io


    【解决方案1】:

    问题

    当你运行时:

    for f in /mnt/processed_images/$image_folder/image-%06d.jpeg; do echo "file '$f'";done
    

    它会输出:

    file '/mnt/processed_images/foo/image-%06d.jpeg'
    

    那么 ffmpeg 将使用image demuxer 的序列模式类型。这需要一个连续的序列。

    解决方案 1:全局

    使用 glob:

    for f in /mnt/processed_images/$image_folder/*.jpeg; do echo "file '$f'";done
    

    现在它将输出每个文件。在此示例中,image-000003.jpeg 不存在,因此未列出:

    file '/mnt/processed_images/foo/image-000001.jpeg'
    file '/mnt/processed_images/foo/image-000002.jpeg'
    file '/mnt/processed_images/foo/image-000004.jpeg'
    

    解决方案 2:简化并跳过 concat

    更好的是通过在 ffmpeg 本身中使用 image demuxer 的 glob 模式类型来简化您的命令,然后您可以避免使用 concat demuxer:

    image_folder=$1
    singularity exec --bind "$work_dir":/mnt "$work_dir"/longleaf2.sif ffmpeg -pattern_type glob -framerate 25 -i "/mnt/processed_images/$image_folder/*.jpeg" -vf "crop=trunc(iw/3)*2:trunc(ih/2)*2,format=yuv420p" -movflags +faststart /mnt/run/summary_files/${image_folder}.mp4
    
    • 图像解复用器 glob 模式不适用于 Windows 用户。
    • image demuxer 添加了-framerate 输入选项。
    • 添加了format filter 以进行 YUV 4:2:0 色度二次采样以实现兼容性。
    • 变量已被引用。见shellcheck.net
    • FFmpeg 4.1 发布分支是旧的。 Downloadcompile 一个现代版本,然后再做任何其他事情。

    【讨论】:

    • 非常感谢!