我编写了以下 bash 脚本来使用 ffmpeg 自动连接 mp3 文件:
i=0
for f in "${@:2}"
do
filter+="[$i:a:0]"
i=`expr $i + 1`
files+="-i $f "
done
filter+="concat=n=$i:v=0:a=1[outa]"
ffmpeg $files -filter_complex $filter -map '[outa]' "$1.mp3"
但是,我经常需要处理文件名中包含空格的文件,但当拖动到终端时,所有空格都会被转义,生成以下命令调用:
./mergemp3.sh outfilename /path/to/my\ file\ with\ spaces.mp3 /path/to/another\ file\ with\ spaces.mp3
这对我来说似乎是正确的。但是,ffmpeg 失败了
/path/to/my: No such file or directory
显然,ffmpeg 不理解文件名中的空格,尽管它已通过反斜杠正确转义。我猜想有一个关于该文件名列表的漂亮细节。有任何想法吗?
答案1
为了在构建命令行时清晰和安全,数组是你的朋友:
files=()
i=0
for f in "${@:2}"
do
filter+="[$((i++)):a:0]"
files+=(-i "$f")
done
filter+="concat=n=$i:v=0:a=1[outa]"
ffmpeg "${files[@]}" -filter_complex "$filter" -map '[outa]' "$1.mp3"
答案2
试试这个,它应该适用于任何 shell,而不仅仅是bash
(基于我第一次在回答通过@Kusalananda):
output=$1; shift
i=0
for f in "$@"; do
shift
set -- "$@" -i "$f"
filter="$filter[$i:a:0]"
i=$((i+1))
done
filter="${filter}concat=n=$i:v=0:a=1[outa]"
ffmpeg "$@" -filter_complex $filter -map '[outa]' "$output.mp3"
这只是关于外壳部分;我不确定是否真的需要复杂的过滤器。