7

This is driving me crazy.

I have a bunch of mp3 that I want to transcode using ffmpeg.

I'm trying to use this one-liner (the script is bigger, this is the problematic section):

find . -type f \( -iname \*.mp3 \) | parallel ffmpeg -i "{}" -acodec libmp3lame -ab 128k "$output_folder_with_spaces/{.}-128k.mp3" \;

(The iname section is there because in the future more extensions will maybe be used)

But even using the quotes in {}, I always get No such file or directory, cause the mp3 is named 01 - My song. And I don't know if "$output_folder_with_spaces" is going to work either.

I've googled a lot, but can't find this example: using {} from find that {} has spaces. I've only found when using a variable or hardcoded paths in quotes.

Anyone knows how I can solve this space problem, in this scenario?

4
  • 1
    Shouldn't you be -exec-ing ffmpeg on the results of the find command, rather than piping them to it? May 15, 2015 at 2:51
  • @don_crissti the filename itself without extension. May 15, 2015 at 3:28
  • @steeldriver There was a parallel in there as well. The problem is not with the piping tough, I have a similar setup but for converting videos and it works. But if you have a -exec solution that solves the space issue, no problem. May 15, 2015 at 3:30
  • Please always include the exact error message when asking a question.
    – Mikel
    May 15, 2015 at 15:38

2 Answers 2

6

You are using the wrong replacement string with parallel; you'll also need -q to pass quoted arguments and I'm not sure what the trailing \; does...
Example:

dirname_with_spaces="/home/don/my dir with spaces/"

(note the trailing / in the path assigned to dirname_with_spaces) and some mp3 file names with spaces under a test directory, right under cwd:

./test/Commercial DEMO - 09.mp3
./test/Commercial DEMO - 11.mp3
./test/Handel Royal Fireworks - 07.mp3
./test/Jazz Rag Ensemble - 10.mp3
./test/Mouret - Rondeau.mp3

using

find . -type f -iname \*.mp3 | parallel -q ffmpeg -i {} -acodec \
libmp3lame -ab 128k "$dirname_with_spaces"{/.}-128k.mp3

produces the following files:

/home/don/my dir with spaces/Commercial DEMO - 11-128k.mp3
/home/don/my dir with spaces/Commercial DEMO - 09-128k.mp3
/home/don/my dir with spaces/Handel Royal Fireworks - 07-128k.mp3
/home/don/my dir with spaces/Jazz Rag Ensemble - 10-128k.mp3
/home/don/my dir with spaces/Mouret - Rondeau-128k.mp3

Note the command line quoting (parallel -q) and the usage of:

{}
    Input line.

which means the path from find output e.g. ./test/Mouret - Rondeau.mp3
and

{/.}
    Basename of input line without extension. 

which expands to Mouret - Rondeau and then "$dirname_with_spaces"{/.} expands to /home/don/my dir with spaces/Mouret - Rondeau

The latter is quite different from the {.} used in your command

{.}
    Input line without extension.

which would expand to ./test/Mouret - Rondeau and then "$dirname_with_spaces"{.} would expand to /home/don/my dir with spaces/./test/Mouret - Rondeau. Obviously, this will error out as there is no /./test/ under /home/don/my dir with spaces.

0
2

You've misunderstood find's syntax. The {} syntax is used in conjunction with -exec. Also, those parentheses you have aren't needed; you only need them if you want to override the default order of operations (e.g., not evaluate from left-to-right). Overall, with exec, it'd look something like this (split to avoid horizontal scroll):

find . -type f -iname \*.mp3 -exec \
    ffmpeg -i "{}" -acodec libmp3lame -ab 128k \
    "$output_folder_with_spaces/{}-128k.mp3" \;

Note that'll give you files named like foo.mp3-128.mp3 … I hope that's what you wanted; I have no idea what {.} was supposed to mean—it's not valid syntax, at least with GNU find.

I'd suggest using lame directly though, instead of through FFmpeg (and if -ab uses ABR mode instead of VBR mode, I'd suggest against that without good reason). Actually, I'd suggest against re-encoding MP3s in general; better quality at the same bit rate would be obtained by encoding from a lossless source.

9
  • I'm reencoding to use in a low end device. Thanks for your warning though. May 15, 2015 at 3:37
  • @SomebodystillusesyouMS-DOS Ok. "Hardware limitations" count as a good reason. You may also need to find ffmpeg's equivalent of LAME's -B.
    – derobert
    May 15, 2015 at 3:38
  • Your exec works. But I still can't understand why the pipe solution fails only with spaces, I have the same script but for converting videos (without spaces) and it works. Do you have an explanation? Or was I wrong from the beginning and working was just a matter of luck? May 15, 2015 at 3:42
  • @SomebodystillusesyouMS-DOS I'll add in a guess for what might work... I don't have GNU Parallel installed to test with (and it conflicts with moreutils).
    – derobert
    May 15, 2015 at 3:43
  • @SomebodystillusesyouMS-DOS added.
    – derobert
    May 15, 2015 at 3:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .