Nicolas Reibnitz
Nicolas Reibnitz

Reputation: 65

shell script: ffmpeg can't either read arguments or filenames, if spaces in path- or filename

I'm currently working on a bash shell script on OS X to get a custom tailored Pashua GUI/automatization package, using ffmpeg in the back, to transcode videos, label them, zip them, upload them, organize them and so on. Everything is working like a charm so far.

My problem now is that I can't make ffmpeg take files or paths that have spaces in them IF I use variables in variables. But that (I think) is a must in order to get ffmpeg to transcode multiple files at once depending on the formats and checkboxes the user ticks on.

I made a little example snippet so you can see my dilemma.

No spaces in path or filename / works great:

#!/bin/bash

infile='/Users/nicolas/Desktop/MASTER_[DE]_Test_140626.mov'

gen_outfile () {
    outfile="${1/MASTER/TRANSCODE}"
    ffmpeg_cl="-s $2 -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p -c:a aac -b:a 240k -strict -2 $outfile"
}

gen_outfile "$infile" 1920x1080

./ffmpeg_stat -i "$infile" $ffmpeg_cl

The output is as expected and the file is called "TRANSCODE_[DE]_Test_140626.mov"

Filename variable with spaces - directly fed to ffmpeg:

This works as well but isn't really usable for me because I need to have the option of variable numbers of output files and arguments generated dynamically.

#!/bin/bash

infile_full='/Users/nicolas/Google Drive/encode-o-mat/MASTER_[DE] Test  140626.mov'

gen_outfile () {
    outfile="${1/MASTER/TRANSCODE}"
    ffmpeg_cl="-s $2 -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p -c:a aac -b:a 240k -strict -2"
}

gen_outfile "$infile_full" 1920x1080

./ffmpeg_stat -i "$infile_full" $ffmpeg_cl "$outfile"

The output is as expected and the file is called "TRANSCODE_[DE] Test 140626.mov". But this way is just not an option.

This here does not work! Filename is split up and incomplete:

#!/bin/bash

infile_full='/Users/nicolas/Google Drive/encode-o-mat/MASTER_[DE] Test  140626.mov'

gen_outfile () {
    outfile="${1/MASTER/TRANSCODE}"
    ffmpeg_cl="-s $2 -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p -c:a aac -b:a 240k -strict -2 $outfile"
}

gen_outfile "$infile_full" 1920x1080

./ffmpeg_stat -i "$infile_full" $ffmpeg_cl

Ffmpeg gives this error: "Unable to find a suitable output format for '/Users/nicolas/Google'". Of course.

This doesn't work as well! Quoting and such:

./ffmpeg_stat -i "$infile_full" "$ffmpeg_cl"

If I put the $ffmpeg_cl variable in various quotes ffmpeg doesn't understand the arguments anymore! This is one example output:

"Unrecognized option 's 1920x1080 -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p -c:a aac -b:a 240k -strict -2 /Users/nicolas/Google Drive/encode-o-mat/TRANSCODE_[DE] Test 140626.mov'. Error splitting the argument list: Option not found Conversion failed!"

It's really important that the script can handle path- and filenames with spaces because I can't change the environment in which that tool is supposed to run. All ideas and solutions are more than welcome!

Upvotes: 2

Views: 1861

Answers (1)

konsolebox
konsolebox

Reputation: 75458

Use arrays instead:

#!/bin/bash

infile_full='/Users/nicolas/Google Drive/encode-o-mat/MASTER_[DE] Test  140626.mov'

gen_outfile () {
    outfile="${1/MASTER/TRANSCODE}"
    ffmpeg_cl=(-s "$2" -c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p -c:a aac -b:a 240k -strict -2 "$outfile")
}

gen_outfile "$infile_full" 1920x1080

./ffmpeg_stat -i "$infile_full" "${ffmpeg_cl[@]}"

Make sure you quote arguments with variable expansions around "" properly. Also quote any argument containing *, ?, !, [ and ].

Upvotes: 3

Related Questions