0

I have composed the following bash script to automatically concatenate mp3 files using ffmpeg:

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"

However, I often have to deal with files that have spaces in their filenames, but when dragged to the terminal, all spaces get escaped, generating the following command call:

./mergemp3.sh outfilename /path/to/my\ file\ with\ spaces.mp3 /path/to/another\ file\ with\ spaces.mp3 

which seems correct to me. However, ffmpeg fails with

/path/to/my: No such file or directory

So obviously, ffmpeg does not understand the space in the filename, although it is properly escaped by a backslash. I guess there's just a nifty detail going on regarding that filename list. Any ideas?

1

For clarity and safety when building command lines, arrays are your friend:

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"
0

Try this, which should work with any shell, not just bash (based on a trick I've first seen in an answer by @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"

This is only about the shell part; I'm not sure that complex filter stuff is really needed.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.