【问题标题】:Bash script to convert imgs in subfolders to video (using ffmpeg and Ubuntu)将子文件夹中的 imgs 转换为视频的 Bash 脚本(使用 ffmpeg 和 Ubuntu)
【发布时间】:2015-10-31 00:26:43
【问题描述】:

我正在尝试转换

给定文件夹中的所有文件
 allFolders.txt
> head folderNames.txt
0001 
0002 
0003 
0004 
0005 
...

使用 ffmpeg 转至视频

ffmpeg version 2.2.3 Copyright (c) 2000-2014 the FFmpeg developers  built on Apr 20 2015 13:38:52 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
configuration: --prefix=/home/myUsername/usr/local --enable-nonfree --enable-gpl --enable-pic --enable-shared --enable-libx264 --disable-vaapi

根据 stackoverflow 上的一些答案,我编写了以下 bash 脚本:

#!/bin/bash
while read p; do
    cd "$p"
    ffmpeg -f concat -i "allImgNames.txt" -framerate 30 -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4
    cd -
done < folderNames.txt

其中allImgNames.txt 是一个包含所有图像名称的文本文件。

奇怪的是,它适用于一些视频,但对于文件列表的其余部分,它却无法显示allImgNames.txt: No such file or directory,这是不正确的。我检查了所有路径几次。我也可以手动执行上面的ffmpeg ... 命令而不会出现问题。 我不知道我做错了什么。所有文件/文件夹名称都是正常的(没有特殊字符)。也许我对 bash 或 ffmpeg 的了解不够。

【问题讨论】:

  • 文件名或目录名中是否有空格?
  • 您更改了脚本中的目录,因此文件allImgNames.txt 不再位于当前 目录中。除非您将每个目录更改为具有该名称的单独文件?
  • 不。真正奇怪的是,当我在上面给出的示例中在cd "$p" 之后放置echo "$p" 时,当我评论ffmpeg 评论时它表现正常,但是一旦我再次取消评论ffmpeg 甚至它打印的路径错误(缺少前导 0),例如它打印 30 而不是 0030
  • 我有一个文本文件,其中包含每个子目录中的所有图像文件名。这就是为什么我可以在我的 bash 脚本之外正常执行ffmpeg 命令
  • 我的意思是allImgNames.txt 文件,它真的有那个外壳吗?在所有文件夹中?它does 存在于all 文件夹中吗?它总是在相同的目录上失败吗?还是看似随机?你有没有试过做例如脚本中的ls allImgNames.txt 而不是ffmpeg 命令?或者不要更改目录和ffmpeg,只需在循环中执行ls "$p/allImgNames.txt,如果仅在某些目录中丢失文件,这将使其非常明显。

标签: linux bash video ffmpeg


【解决方案1】:

在脚本中添加一些逻辑以确保文件/文件夹在执行某些操作之前存在。这将帮助您调试问题。

如果文件夹路径不是相对的,这样的事情会有所帮助

while read p; do
    [ -d "$p" ] && cd "$p" || echo "Folder $p not found"
    [ -f "allImgNames.txt" ] && ffmpeg -f concat -i "allImgNames.txt" -framerate 30 -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4 || echo "$p/allImgNames.txt not found"
    [ -d "$p" ] && cd -
done < folderNames.txt

【讨论】:

  • 此脚本总是在第二个文件夹“未找到文件夹”中失败。它不会按应有的方式打印“Folder $p not found”。当我编辑您的脚本以使其不使用 cd $pcd - 时,它会处理大量视频(总共 3000 个视频中的 800 个),因此有一些改进,但似乎仍然存在问题。
  • 好的,所以问题出在环境的某个地方。可能是 FFMPG 以某种方式与 OLDPWD 一起玩。因此,不要使用“cd -”,而是尝试使用该方到父文件夹。另外,在 "CD $p" 之前添加一个 echo 语句以打印出变量 $p。
  • 谢谢。同时,我可以使用您的答案解决我的问题。正如我上面所说,我正在删除所有 cd $pcd - 语句,而是从父目录调用文件。然后我添加了一行检查输出视频是否已经存在,然后跳过该文件夹。像这样我可以多次执行相同的脚本,最后转换了所有 3000 个视频。我会在回答中提到这个 hack,但是我仍然认为这个问题没有解决,因为不清楚为什么 ffmpeg 在那个 bash 脚本中使用时会任意失败,尽管所有路径都是正确的。
【解决方案2】:

根据this post 帖子ffmpeg 确实搞砸了批处理脚本中的循环。您必须在 ffmpeg 命令中添加 -nostdin 作为选项,否则 ffmpeg 会吃掉后续文件夹名称的某些部分。
此外,由于libx264 编解码器中的this bug,一些视频转换失败。 要修复它,只需使用此选项将图像转换为具有均匀高度大小的图像:-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

借助 Iyad K 的回答,我可以解决我的问题:

这是一个完整的解决方案:

#!/bin/bash
while read p; do
    # Continue if output file already exists
    {
    if [ -f "$p/output.mp4" ]; 
    then
        echo " --> File already exists. Continue ..."
        continue
    else
        echo " --> Start processing vid ..."
    fi
    }    

    # Convert video using ffmpeg:
    # "-nostdin" prevents bashscript from messing up
    # "-vf ..." makes sure the video doesn't break for images with uneven pixel hight
    ffmpeg -f concat -i "$p/allImgNames.txt" -nostdin -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "$p/output.mp4" 
done < folderNames.txt  

一些备注:
不知何故,ffmpeg 命令似乎弄乱了 bash 脚本,例如某些路径不再正确打印,这可能导致 cd "$p"cd - 失败。
同样奇怪的是,这些文件夹没有按照folderNames.txt 给出的相同顺序进行处理,而是以某种随机顺序处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 2021-12-24
    • 1970-01-01
    • 2020-08-25
    • 2021-10-06
    • 2015-12-25
    • 1970-01-01
    相关资源
    最近更新 更多