...making Linux just a little more fun!
Mulyadi Santosa [mulyadi.santosa at gmail.com]
First, why? Easy, because mp3 is a patented format and ogg is an open source format. So, to guarantee your peace of mind (like what Cattano said to Frank Lucas in "American Gangster" ), use ogg.
To do it, first I assume you have mpg123 (http://www.mpg123.de/) installed and the binary is located in searchable path (check your $PATH).
Your mp3 files probably contain spaces, so use this script:
#!/bin/bash for b in *; do ( cd $b; for a in *; do mv -v "$a" $(echo $a | sed s/\ /\_/g); done ) ; done
The script assumes your working directory has subdirectories that holds the mp3 files (think of it as albums). Outer loop lists the directories and inner loop "cd" into them and rename the files inside so they don't contain spaces anymore.
Finally, the real piece of work:
#!/bin/bash for b in *; do ( cd $b; for a in *; do test=$(echo $a | cut -f1 -d\.).wav ; mpg123 -v -w $test "$a"; oggenc $test ; rm -fv $test ; rm -fv "$a" ; done ); done
In short, the script loops over your collections. It uses mpg123 to convert your mp3s into wavs. Then, oggenc converts it as ogg. The wav is then deleted since we don't need it anymore. Why create wav 1st, you might ask? Well, i tried to pipe mpg123 directly to oggenc but somehow it didn't work (at least in my case), so that's my workaround.
regards,
Mulyadi.
Ben Okopnik [ben at linuxgazette.net]
On Sat, Jan 26, 2008 at 09:54:43PM +0700, Mulyadi Santosa wrote:
> First, why? Easy, because mp3 is a patented format and ogg is an open > source format. So, to guarantee your peace of mind (like what Cattano > said to Frank Lucas in "American Gangster" ), use ogg. > > To do it, first I assume you have mpg123 (http://www.mpg123.de/) > installed and the binary is located in searchable path (check your > $PATH). > > Your mp3 files probably contain spaces, so use this script: > #!/bin/bash > > for b in *; do ( cd $b; for a in *; do mv -v "$a" $(echo $a | sed s/\ > /\_/g); done ) ; done >
If you want to loop over filenames that contain spaces without splitting on those spaces, the easiest way is to tell Bash not to use spaces as a delimiter. This is done via the $IFS (Internal Field Separator) variable, which initially consists of a space, a tab, and a newline:
ben@Tyr:~$ printf "$IFS"|od -ta 0000000 sp ht nl 0000003
If you set the IFS, remember to restore it if your script is going to continue after the loop:
# Save the IFS old=$IFS # Set the IFS to a hard-coded newline IFS=' ' for n in *mp3 do # Doesn't matter much for 'echo', but it's a good idea to enclose # the filename in double-quotes; otherwise, other programs may get # confused about those spaces. echo "$n" done # Restore the IFS IFS=$old
Of course, if you're exiting the script at this point, then restoring the IFS isn't necessary; the current definition will go away when the current child process (the script) exits, and the definition from the parent process will come into effect.
> The script assumes your working directory has subdirectories that > holds the mp3 files (think of it as albums). Outer loop lists the > directories and inner loop "cd" into them and rename the files inside > so they don't contain spaces anymore. > > Finally, the real piece of work: > #!/bin/bash > > for b in *; > do ( cd $b; > for a in *; > do test=$(echo $a | cut -f1 -d\.).wav ; > mpg123 -v -w $test "$a"; > oggenc $test ; > rm -fv $test ; rm -fv "$a" ; > done ); > done
Since you're using Bash, you could just use the parameter substitution mechanism to modify the filenames instead of using 'cut'.
mpg123 -v -w "${a%mp3}wav" "$a";
This will remove 'mp3' from the end of the content in "$a", and replace it with 'wav'. However, you should indeed be able to pipe the output of the MP3 decoder into the input of the OGG encoder, since the latter is significantly slower than the former.
> In short, the script loops over your collections. It uses mpg123 to > convert your mp3s into wavs. Then, oggenc converts it as ogg. The wav > is then deleted since we don't need it anymore. Why create wav 1st, > you might ask? Well, i tried to pipe mpg123 directly to oggenc but > somehow it didn't work (at least in my case), so that's my workaround.
The syntax can be a little tricky.
... for a in *mp3 do mpg123 -w - "$a" | oggenc - -o "${a%mp3}wav" && \ done ...
I'd also want to test the newly-created OGGs before discarding the MP3s.
for n in *ogg do # Play 10 seconds of the OGG ogg123 -K 10 "$a" printf "Delete \"${a%ogg}mp3\" [Yn]?" read answer if echo $ans|grep -iq '^y' then echo "Deleting ${a%ogg}mp3" rm "${a%ogg}mp3" fi done
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Ben Okopnik [ben at linuxgazette.net]
On Sat, Jan 26, 2008 at 12:07:41PM -0500, Benjamin Okopnik wrote:
> > ``` > for n in *ogg > do > # Play 10 seconds of the OGG > ogg123 -K 10 "$a" > printf "Delete \"${a%ogg}mp3\" [Yn]?" > read answer
^^^^^^Whoops - that would be 'read ans', of course. Or you could change the next line to '$answer'.
> if echo $ans|grep -iq '^y' > then > echo "Deleting ${a%ogg}mp3" > rm "${a%ogg}mp3" > fi > done > '''
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Mulyadi Santosa [mulyadi.santosa at gmail.com]
Hi....
On Jan 27, 2008 12:10 AM, Ben Okopnik <ben@linuxgazette.net> wrote:
> On Sat, Jan 26, 2008 at 12:07:41PM -0500, Benjamin Okopnik wrote: > > > > ``` > > for n in *ogg > > do > > # Play 10 seconds of the OGG > > ogg123 -K 10 "$a" > > printf "Delete \"${a%ogg}mp3\" [Yn]?" > > read answer > ^^^^^^ > > Whoops - that would be 'read ans', of course. Or you could change the > next line to '$answer'.
I perfectly agree with you...sorry about my stupid bash knowledge Willing to share seems is not enough this time :D
regards,
Mulyadi.
Ben Okopnik [ben at linuxgazette.net]
On Mon, Jan 28, 2008 at 08:19:34AM +0700, Mulyadi Santosa wrote:
> Hi.... > > On Jan 27, 2008 12:10 AM, Ben Okopnik <ben@linuxgazette.net> wrote: > > On Sat, Jan 26, 2008 at 12:07:41PM -0500, Benjamin Okopnik wrote: > > > > > > ``` > > > for n in *ogg > > > do > > > # Play 10 seconds of the OGG > > > ogg123 -K 10 "$a" > > > printf "Delete \"${a%ogg}mp3\" [Yn]?" > > > read answer > > ^^^^^^ > > > > Whoops - that would be 'read ans', of course. Or you could change the > > next line to '$answer'. > > I perfectly agree with you...sorry about my stupid bash knowledge > Willing to share seems is not enough this time :D
Mulyadi, if you hadn't shared this tip, you wouldn't have had this opportunity to improve your Bash knowledge. By doing so, you've also given other people a) ideas about how to play with shell scripting and b) a chance to learn a few tricks. This is precisely why tips need to go to TAG rather than being directly submitted like articles: The Answer Gang is where tips get sharpened, polished, and vetted for errors.
You have nothing to be sorry about, and no reason to feel stupid; everything worked exactly as it was supposed to. "Stupid" would be beating up on yourself when you've done everything right and achieved a good result.
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *