954,525 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Bash: Multi-threaded mp3 encoder (find, xargs, lame, basename)

Hello,

I'm kinda weird I know but I'm trying to encode my mp3 to a lower quality (for my mobile phone) with one line of shell (with bash). I'm wasting some more time as I would do by hand but I'm very interested. Here is my not-working line :

find -iname "*.mp3" | xargs -n1 -I{} -P5 -0 -p --delimiter='\n' lame -q1 --vbr-new -V6 -b 32 -B 128 {} /mnt/sda1/tmp-zik/\`basename {}\`


So the main problem in my command line is the way I would like to usebasename but it isn't working as my expectation. The reason I use it is that I have as input (of xargs) the relative path of the files (let's say I'm in /mnt/mp3) and there are artist and album folders in it (example: /mnt/mp3/artist/album/file blabla 01 title.mp3). So xargs receive as input: ./artist/album/file blabla 01 title.mp3 in this case.

So the first parameter of lame (the input file) is correct but not the second one (the output file). So here I am: my basename is removed at runtime and won't have any effect. Moreover I have prepared a folder for the output files but without any folder tree: so all the files would be in one folder: /mnt/sda1/tmp-zik.

Can you share your experience or your idea to bypass this little problem ? I will greatly appreciate your help ! Thank you in advance.

Jamesbch
Newbie Poster
20 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

I think you've misinterpreted the situation. The {} is specific to the find utility, and has no special meaning for xargs (in fact I wonder how they are parsed at all in this context). The latter forms the command by appending the input string (as a last argument) to the given set of arguments. To summarize, a filename is mentioned in the lame command line just once.
I don't think there's a one-line solution which involves xargs; you may consider the find's -exec option. If I were you, I'd make a small wrapper script to invoke lame properly.

nezachem
Posting Shark
903 posts since Dec 2009
Reputation Points: 719
Solved Threads: 194
 

For reasons I can't fathom basename doesn't appear to work with xargs, even though the {} is correct. The command below works for me, but I haven't dealt with the case where the filename has spaces in it.

<strong>bash syntax</strong>

find . -iname "*.mp3" -printf "%p /mnt/sda1/tmp-zik/%f\n" | xargs -n2 -P5 -0 -p lame -q1 -b 32 -B 128
shibblez
Junior Poster in Training
72 posts since Oct 2010
Reputation Points: 15
Solved Threads: 6
 

That is **awesome** ! Thank you for your reply, this printf option is so useful !

find mp3/ -iname "*.mp3" -printf "%p\n/mnt/sda1/tmp-zik/%f\n" | xargs -L1 -n2 -P5 -0 --delimiter='\n' lame -S -q1 --vbr-new -V6 -b 32 -B128


This is working on my 4 CPU as hell. This is the best way to encode a massive group of files. Thank you.

Jamesbch
Newbie Poster
20 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

If you have GNU Parallel installed:

find mp3/ -iname "*.mp3" -printf "%p\n/mnt/sda1/tmp-zik/%f\n" | parallel -n2 -j+0 lame -S -q1 --vbr-new -V6 -b 32 -B128

Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

ole.tange
Newbie Poster
1 post since Oct 2010
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: