Scott Klarr Jr
SKwizard - Linux M4A Converter and file rename tool
As they say, you want something done right, you got to do it yourself! After my failed attempts to find a working tool to take care of 2 simple tasks on a large scale, I decided to write my own little program. Enter, SKwizard!
This shell script has two very useful abilities that are done recursively from any given starting point.
Features
File Renamer - This program will crawl your files/folders and not only replace all underscores with spaces, but will also capitalize the first letter of each word. I plan to add some more renaming options in the future but these two things were mainly what i was after.
M4A to MP3 Converter - This program will convert any M4A music files into MP3 - and retain the song tag information!
Usage
To use the program, all you have to do is run the command skwizard with the desired arguments (see below).

So say if you have your music collection at /storage/music/. You wanted to rename all files/folders and also convert any m4a files. Simply load up the command line and run skwizard -dfcr /storage/music/ - it will do its thing!
You can have it do any or all of the actions listed by themselves or together.
I ran this program against my 180gb music collection and am very happy with the results :)
View source code at: http://www.scottklarr.com/files/skwizard/skwizard
Installation
This script requires that you have LAME and FAAD2 installed in order to use the M4A to MP3 conversion. The file/folder renaming operations will work fine without these dependencies.
su
cd /tmp
wget http://www.scottklarr.com/files/skwizard/skwizard
mv skwizard /bin/
chmod +x /bin/skwizard
exit
Like I said above, I used this on my own music collection and it worked absolutely great (i did a lot of testing and triple checking before actually enabling the destructive commands). I am 99% sure it will work for you, but I have to say that I do not guarantee its performance. Use at your own risk.
This is my first shell script thats beyond just a couple lines, so there are probably better ways to do things, but I'm still new to it, so...
If you have any comments, suggestions, or ideas -- please let me know! This script is completely free to do with as you please. If you make any changes to it though, please send me a copy so i can see the improvements made!
Todo
- See how reacts to permission denied.
- Fix bug of renaming II, III to Ii, Iii.
- Add more file renaming abilities with command line switches.
This topic has the following tags:
Last 5 Linkbacks
- Apr 10, 2008www.oneafrikan.com
- Mar 13, 2008emanuelecipolla.net



Munra Mar 08, 2008
Hi:
Thanks for you script, but when i try to convert a directory that have a name with space like this '/path/to/music/directory\ with\ space/'
i have this:
/path/to/music/directory is not a valid starting point!
So i use quotes in the path like this => /path/to/"music directory with space" but give me the same message=>
/path/to/music/directory is not a valid starting point!
So i change the name of the directory to => /path/to/music/directory
and works.
But it is rare because in the "directory" i have another directory with space and works, so my solution was cd into /path/to/"music directory with space" and run skwizard -cr.
i can't do works recursively and the tag of genre disappear in the process.
I don't know is this things are for the program or are for me that don't understand how to use the script.
I hope you give a answer.
Scott Klarr Mar 08, 2008
Munra, thanks for letting me know. I'm having trouble figuring out how to make the for loop not split every space into a separate result. You'd think it would be straight forward but I'm not having any luck figuring it out.
An easy work around to this is to simply CD into '/path/to/music directory with space' yourself, and then run the script without a path (if you run it without a path specified, it will use the current path you are in)
So you would go:
$ cd "/path/to/"music directory with space"
$ skwizard -[dfcr]
Munra Mar 09, 2008
Hi:
Thanks for you answer.
And the thing with the tag of genre?
Because i have this in the terminal:
LC AAC 163.007 secs, 2 ch, 44100 Hz
title: Tell it like it is
artist: Arron Neville
album: SuperHits 1967
genre: Los Años Maravillosos
track: 11
But when i import the file (the mp3) into Rhythmbox i don't have the genre, the Rhythmbox show (unknow) in genre. ( when i import the m4a Rhythmbox show me the genre, in this case "Los Años Maravillosos"). So, how i can do that the Rhythmbox show me the genre in the mp3 files.
Thanks for you script and your time.
Munra Mar 09, 2008
Hi: again me.
Well i fund this, first i make a little change in you script (i don't know nothing about scripting i just see your script and make changes and wait to see what happend)
this was the change
=> your script:
faad -o - "$1" | lame --tt "$title" --ta "$artist" --tn "$track/$totaltracks" --tl "$album" $tg - "$newMp3Name"
=> the change
faad -o - "$1" | lame --tt "$title" --ta "$artist" --tn "$track/$totaltracks" --tl "$album" --tg "$genre" - "$newMp3Name"
So i delete $tg and put --tg "$genre", and works i have the genre of the mp3 file in Rhythmbox. But not with the first song, with another song that have the tag genre "Thecno" this is the info in terminal :
Motorway.m4a file info:
LC AAC 357.725 secs, 2 ch, 44100 Hz
title: Motorway
artist: Carl Cox
unknown: Various Artists
album: Carl Cox - F.A.C.T (Disk 2)
genre: Techno
track: 14
date: 1995
So when i try to convert the first song with the tag genre "Los Años Maravillosos", this is the info in terminal:
Tell it like it is.m4a file info:
LC AAC 163.007 secs, 2 ch, 44100 Hz
title: Tell it like it is
artist: Arron Neville
album: SuperHits 1967
genre: Los Años Maravillosos
track: 11
i have this message:
Unknown genre: 'Los Años Maravillosos'. Specify genre name or number.
I try with other directory and the same happend. This is the info of the other directory:
Somebody Save Me.m4a file info:
LC AAC 196.319 secs, 2 ch, 44100 Hz
title: Somebody Save Me
artist: Cinderella
unknown: Cinderella
writer: Tom Keifer
album: Night Songs
genre: Poser Rock
track: 7
date: 1986
in this is the message:
Unknown genre: 'Poser Rock'. Specify genre name or number.
Thanks again and I hope you give a answer.
I see that when i use you script without any change i still have the message with other mp3 file that have different genre, this is message
Unknown genre: '"Folk"'. Specify genre name or number.
So, with the genre '"Folk"' dont't work, but this time the message is little different have double quotes, this is:
Unknown genre: '"Folk"'. Specify genre name or number
But in Rhythmbox the genre in m4a is just Folk.
Thanks again and I hope you give a answer.
I going to see if i find why have problems with this genres, or mp3 files, probably are the file not the genre. Bye
P.D. I hope you understand me, because i have bad English and the addon "gtranslate" that i use for the words that i don't remember don't work in Firefox Beta 3.
Scott Klarr Mar 10, 2008
Unfortunately (for some odd reason), the LAME encoder will only accept the name of a genre if its included in a somewhat limited list they provide. Run "lame --genre-list" to see a list that genres are limited to.
Munra Mar 11, 2008
Thanks. Sorry i should read the man lame.
Thanks again.
richard d Apr 13, 2008
I found an annoying fact about this script: it will capitalize names after special characters. So Antonín Dvo%u0159ák becomes AntoníN Dvo%u0159áK, Frédéric Chopin becomes FréDéRic Chopin, etc. This should get removed from the code.
Otherwise, wonderful little thing, I wanted to get rid of underscores and .m4a files and this did the trick.
GX May 11, 2008
Hi
Thanks for the script. For some reason it would always show help no matter what so I had to put comments on the if for the help and then it worked.
Bill Jul 01, 2008
When I tried it, all the extensions got changed to M4a. The grep command that looked for m4a wasn't matching. I added "-i" to make it ignore case and it is grinding through my files as I type. Thanks for the script!
bsack Jul 29, 2008
re: renaming as .M4a - i had the same problem initially, so went into the script and changed the two instances of
"grep '.m4a'"
to
"grep '.[Mm]4a'"
not the most elegant solution, but it got the script working. thanks!
Tmo Aug 13, 2008
HELP!! I keep getting this error --- Unable to find correct AAC sound track in the MP4 file.
Christian Sep 23, 2008
Hi,
I am getting also the error:
"Unable to find correct AAC sound track in the MP4 file."
This appears in case the CD is ripped with Sound Juicer. CDs ripped with iPod work ok.
Help very welcome
machrisod Sep 30, 2008
what about quality? is this script going .m4a -> .wav (or similar) -> .mp3? if so we're loosing quality. even if it's not doing that (somehow going straight m4a -> mp3), what is the sample rate that the final .mp3 file is at? ie 192kpbs? 320kbps?
machrisod Sep 30, 2008
i partially solved my own problem. i changed
faad -o - "$1" | lame --tt "$title" --ta "$artist" --tn "$track/$totaltracks" --tl "$album" $tg - "$newMp3Name"
to
faad -o - "$1" | lame -b 256 --tt "$title" --ta "$artist" --tn "$track/$totaltracks" --tl "$album" $tg - "$newMp3Name"
so at lease we can control the quality of the resultant mp3 file. i'm still not sure though what is actually getting "converted". going form RAW -> m4a -> RAW -> mp3 will cause inherent quality loss no matter what the sample rate. my hope is that there's some magic that goes straight m4a -> mp3 with no loss just from the fact that there are multiple compression steps. thoughts?
scott Sep 30, 2008
machrisod: lame's default bitrate is 128. The conversion is done directly from m4a to mp3 so theres no indirect loss of bitrate from the conversion itself (or at least there shouldn't be)
Ray Oct 19, 2008
Scott
Thanks for the work - I especially like the directory search function.
Kade Oct 20, 2008
Okaay! i'm really dumb at linux and i wish i never had it, no offense to you Linux lovers. is there any possible way to "sudo" or what ever to get your program to run, i got Faad2 and Lame ( i think) and now i just need to install Skwizard. every time i put the code
su cd /tmp wget http://www.scottklarr.com/files/skwizard/skwizard mv skwizard /bin/ chmod x /bin/skwizard exit
it doesn't know what "su" is...
Scott Klarr Oct 20, 2008
Kade: What linux distribution are you using?
Jean Aug 28, 2009
Thanks.
Remstah Nov 09, 2009
Excellent ! This script converted those #%&(#@%@) m4a files in a flash, thanx a lot !
Frederick Henderson Dec 20, 2009
Hi Scott Klarr!
I ran into the problem that your script does not recognize the extension if the letters are capital you can fix this in the script by changing the grep statement of line 108 to: grep '.[Mm]4[Aa]'
This will allow it to find all possible variations of the .m4a extension.
I am not sure how to solve the renaming part of the script except to add a command to the script that changes the .m4a with capital letters to lower case.
The problem with passing the directory names with spaces into the variable can be solved by replacing the positional variable $1 with either of the special variables $* and $@ that denote all the positional parameters from the command line. You would have to use the shift command to get rid of the parameters before the path and make sure it is the last argument passed on the command line. I think that you might need to add a -? in front of the path to make it easier to script. This might mean that the command would look like this:
skwizard -fcr -d /storage/music/
In this way having the -d switch after all others would tell the script that the directory path is coming and then you could use either $* or $@ to grab every thing left from the command line variables.
Frederick
Stefan Dec 25, 2009
Thanks a lot for skwizard! Great work, keep it up ;)
diZzy Feb 03, 2010
Awesome work my friend. Fit the bill for my needs. I made one change though, seems in my collection (because of various fiddling and scripting run on it) I have files like:
02 Vertigo.M4A #3.mp3
so, this file USED to be an m4a but is already an mp3 -- so to counter act this little prob, I added a '$' to the grep search string to find only a matching pattern at the END of the string.
change:
if [[ `echo "$i" | grep '.[Mm]4[Aa]'` ]]; then
TO
if [[ `echo "$i" | grep '.[Mm]4[Aa]$'` ]]; then
of course, I added the [Mm] and [Aa] as per above posts before my change...