3

I have a problem with ffmpeg and spaces in folders/filenames. My code looks like this:

cd /volume1/PUBLIC/Musik/AutoConvert
find . -type d -exec mkdir -p -- /volume1/PUBLIC/Musik/Converted/{} \;
find -type f |sed 's|./||' |while read NEWNAME; do
ffmpeg -i ""/volume1/PUBLIC/Musik/AutoConvert/"$NEWNAME""" -codec:a libmp3lame -qscale:a 2 "/volume1/PUBLIC/Musik/Converted/"${NEWNAME%.[Ff][Ll][Aa][Cc]}".mp3"
echo done with file: "$NEWNAME"
done

But that fails with ffmpeg if there is a space anywhere. My Folder Structure looks like that:

user@NAS:/volume1/PUBLIC/Musik/AutoConvert$ find -type f |sed 's|./||'
A B/C.mp3
A B/C D.mp3
A/C D.mp3
A/C.mp3

The /Converted/A/C.mp3 does work, but thats the only one. All the others with Spaces in Folder oder Filename fail.

[NULL @ 0x20bb3e0] Unable to find a suitable output format for '/volume1/PUBLIC/Musik/Converted/A/C'
/volume1/PUBLIC/Musik/Converted/A/C: Invalid argument
done with file: A/C D.mp3

[NULL @ 0x11bf280] Unable to find a suitable output format for '/volume1/PUBLIC/Musik/Converted/A'
/volume1/PUBLIC/Musik/Converted/A: Invalid argument
done with file: A B/C D.mp3

[NULL @ 0x11f93e0] Unable to find a suitable output format for '/volume1/PUBLIC/Musik/Converted/A'
/volume1/PUBLIC/Musik/Converted/A: Invalid argument
done with file: A B/C.mp3

If i don't use the double " on ffmpeg -input i get the error:

/volume1/PUBLIC/Musik/AutoConvert/A: Is a directory
done with file: A B/C.mp3

/volume1/PUBLIC/Musik/AutoConvert/A: Is a directory
done with file: A B/C D.mp3

/volume1/PUBLIC/Musik/AutoConvert/A/C: No such file or directory
done with file: A/C D.mp3

It looks like i'm on the right track... just way too far from my goal.

Can anyone offer some help?

Ha.Maier
  • 31
  • 3
  • 1
    why not just `"/volume1/PUBLIC/Musik/AutoConvert/$NEWNAME" .... "/volume1/PUBLIC/Musik/Converted/${NEWNAME%.[Ff][Ll][Aa][Cc]}.mp3"`? Variables values with spaces **should** be surrounded by dbl-quotes.. Good luck. – shellter Oct 27 '17 at 01:32
  • 1
    Why strip the `./` prefixes instead of just telling `find` not to put them there in the first place? For instance: `find . -type f -printf '%P\0' | while IFS= read -r -d ''` won't have any `./` prefix (not that it hurts anything). – Charles Duffy Oct 27 '17 at 02:03
  • 2
    And `""` does *absolutely nothing*: It starts a quoting context and immediately ends it, thus having zero effect whatsoever on how the surrounding code is parsed. – Charles Duffy Oct 27 '17 at 02:04

1 Answers1

1

Maybe this code can help you

#!/bin/bash
cd /volume1/PUBLIC/Musik/AutoConvert 2>/dev/null || { echo "The folder is unavailable."; exit 1; }
find . -type d -exec mkdir -p -- /volume1/PUBLIC/Musik/Converted/{} \;
while IFS= read -r -d $'\0' NEWNAME; do
    ffmpeg -i "/volume1/PUBLIC/Musik/AutoConvert/$NEWNAME" -codec:a libmp3lame -qscale:a 2 "/volume1/PUBLIC/Musik/Converted/${NEWNAME%.*}.mp3"
    echo "done with file: $NEWNAME"
done < <(find . -iname '*.flac' -printf '%P\0')
Darby_Crash
  • 446
  • 3
  • 6
  • Probably should have a `-iname '*.flac'` on the `find` so we don't try to treat non-FLAC files as input (and thus have the parameter expansion stripping the extension fail). – Charles Duffy Oct 27 '17 at 02:05
  • I'd also suggest (as http://shellcheck.net/ does) a `|| exit` on the `cd`, so we don't continue to run (in the wrong directory) if `/volume1/PUBLIC/Musik/AutoConvert` is unavailable. – Charles Duffy Oct 27 '17 at 02:06
  • 1
    AIUI `ffmpeg` can read from stdin, so it might steal part of the filename list. I'd recommend sending the file list over FD 3 rather than stdin by adding `<&3` to the `read` command, and using `3<` instead of just `<` after `done`. – Gordon Davisson Oct 27 '17 at 05:35
  • seems like synology modified their bash4.3 somehow... sh: -c: line 6: syntax error near unexpected token `<' sh: -c: line 6: `done < <(find . -iname '*.flac' -printf '%P\0')' – Ha.Maier Oct 28 '17 at 12:51
  • 1
    @Ha.Maier You must use bash and not sh. – Darby_Crash Oct 28 '17 at 16:38