【问题标题】:Execute "ffmpeg" command in a loop [duplicate]在循环中执行“ffmpeg”命令[重复]
【发布时间】:2014-03-05 05:44:17
【问题描述】:

我的文件夹中有三个 .wav 文件,我想使用 ffmpeg 将它们转换为 .mp3

我写了这个 bash 脚本,但是当我执行它时,只有第一个被转换为 mp3。

我应该怎么做才能让脚本继续遍历我的文件?

这是脚本:

#!/bin/bash
find . -name '*.wav' | while read f; do
    ffmpeg -i "$f" -ab 320k -ac 2 "${f%.*}.mp3"
done

【问题讨论】:

    标签: bash ffmpeg


    【解决方案1】:

    使用-nostdin 标志禁用交互模式,

    ffmpeg -nostdin -i "$f" -ab 320k -ac 2 "${f%.*}.mp3"
    

    或者让ffmpeg从控制终端而不是标准输入读取它的输入。

    ffmpeg -i "$f" -ab 320k -ac 2 "${f%.*}.mp3" </dev/tty
    

    查看ffmpeg documentation 中的-stdin/-nostdin 标志

    【讨论】:

      【解决方案2】:

      如果您确实需要find(用于查找子目录或执行更高级的过滤),请尝试以下操作:

      find ./ -name "*.wav" -exec sh -c 'ffmpeg -i "$1" -ab 320k -ac 2 "$(basename "$1" wav).mp3"' _ {} \;
      

      find 的输出传送到while 循环有两个缺点:

      1. 在匹配的文件名包含换行符的情况下(可能很少见)失败。
      2. ffmpeg,出于某种我不知道的原因,将从标准输入读取,这会干扰read 命令。这很容易解决,只需从/dev/null 重定向标准输入,即find ... | while read f; do ffmpeg ... &lt; /dev/null; done

      无论如何,不​​要将命令存储在变量名中并使用eval 评估它们。这是危险的,也是一个坏习惯。如果您确实需要分解出实际的命令行,请使用 shell 函数。

      【讨论】:

        【解决方案3】:

        没有理由,只需使用 通配符通配符

        #!/bin/bash
        for name in *.wav; do
          ffmpeg -i "$name" -ab 320k -ac 2 "${name%.*}.mp3" 
        done 
        

        【讨论】:

        • 不会处理子目录。
        • 投反对票。这是解释bash 功能的解决方法,而不是解决ffmpeg 实际问题的解决方案。请参阅 Shammell Lee 的回答。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-15
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多