如何通过命令行或批处理脚本与ffmpeg转换整个目录/文件夹?


当前回答

前面的答案只会创建一个名为out.mov的输出文件。要为每一部老电影创建一个单独的输出文件,可以试试这个方法。

for i in *.avi;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mov"
done

其他回答

如果你不想转换文件,只是复制编解码器使用下面的代码

for %i in (*.mkv) do ffmpeg -i "%i" -codec copy "%~ni.mp4"

这样可以减少转换时间。

Bash对我来说很糟糕,所以在Linux/Mac下,我更喜欢Ruby脚本:

(找到一个文件夹中的所有文件,然后将其从rmvb/rm格式转换为mp4格式)

# filename: run.rb
Dir['*'].each{ |rm_file|
  next if rm_file.split('.').last == 'rb'
  command = "ffmpeg -i '#{rm_file}' -c:v h264 -c:a aac '#{rm_file.split('.')[0]}.mp4'"
  puts "== command: #{command}"
  `#{command}`
}

你可以用:ruby run.rb运行它

为了逗你笑,这里有鱼壳的解决方案:

for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end

下面的脚本在Windows上的Bash中工作得很好(所以它在Linux和Mac上也应该工作得很好)。它解决了我在其他解决方案中遇到的一些问题:

处理子文件夹中的文件 用目标扩展替换源扩展,而不仅仅是附加它 适用于名称中有多个空格和多个点的文件 (详见这个答案。) 可以运行时,目标文件存在,提示之前覆盖

ffmpeg-batch-convert.sh:

sourceExtension=$1 # e.g. "mp3"
targetExtension=$2 # e.g. "wav"
IFS=$'\n'; set -f
for sourceFile in $(find . -iname "*.$sourceExtension")
do
    targetFile="${sourceFile%.*}.$targetExtension"
    ffmpeg -i "$sourceFile" "$targetFile"
done
unset IFS; set +f

示例调用:

$ sh ffmpeg-batch-convert.sh mp3

作为奖励,如果你想删除源文件,你可以像这样修改脚本:

sourceExtension=$1 # e.g. "mp3"
targetExtension=$2 # e.g. "wav"
deleteSourceFile=$3 # "delete" or omitted
IFS=$'\n'; set -f
for sourceFile in $(find . -iname "*.$sourceExtension")
do
    targetFile="${sourceFile%.*}.$targetExtension"
    ffmpeg -i "$sourceFile" "$targetFile"
    if [ "$deleteSourceFile" == "delete" ]; then
        if [ -f "$targetFile" ]; then
            rm "$sourceFile"
        fi
    fi
done
unset IFS; set +f

示例调用:

$ sh ffmpeg-batch-convert.sh mp3

对于Linux和macOS,这可以在一行中完成,使用参数展开来更改输出文件的扩展名:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done