Renaming MP3 Files According to ID3 Tags with C#
I added a new podcast to my roster this week: Americana Roots, which plays roots rock/Americana music. While I *don't* like the kind of country found on your local country station, I *do* like quite a bit of the music in this Americana/Cowpunk/Alt-Country genre. I'm not sure exactly what it is about that modern Nashville sound, but I'd rather sit in silence than listen to either that or pretty much any form of hip-hop that I've ever come across. But, I figure since that's really the *only* stuff I am not willing to listen to, I'm not exactly being overly narrow in my taste. Anyway, I figured that a podcast like this might introduce me to some music I wouldn't hear otherwise, just like my ongoing SXSW playlist experiment.
Sure enough, on the first episode I listened to, there was a song by a group called The Ryan Bales Band that I really liked. Since the band's store was showing a "Coming soon" link, I did a quick search elsewhere for it and found it for sale as a non-DRM'ed MP3 download. So I bought it from a site called Lone Star Tunes and downloaded it. (See, podcasting works as a promotional tool, people.)
Unfortunately, rather than a neat and tidy ZIP file, it came as an EXE that dumped the files into a directory, with such catchy names as: 3679LSM1.mp3 and 3679LSM2.mp3. Since there was also no directory for Artist or Album, I basically just had 11 MP3 files in a directory, without any way to tell what they were directly. Hoping not to have to both rename them *and* put in the meta-data, I took a peek at the ID3 tags: they were correct.
That got me thinking. This isn't the first time I've had a bunch of MP3 files in a directory that I wanted to sort out into an "Artist/Album/Track - Title" kind of structure. Curious how easy it might be to put together a little console application to do this kind of cleanup, I went searching for how to get info from ID3 tags via C#. (That's what happens when you leave a geek at home alone on a Thursday night.)
Within a few minutes, I had an appropriate class from CodeProject that looked like it might fit the bill. I just took the ID3 class (though I might go back and mess with the rest later) and added that project to a new console app solution in Visual Studio.
For the console app itself, I coded up something that loops through all of the files in the specified directory, looking for those ending in ".mp3". On those, it reads the ID3 tags and creates the directory path for artist and album and then tries to move and rename the MP3 into that directory. Any that fail (for whatever reason) are left in the original directory. I made this move them rather than copy them because most of the time, that's exactly what I want. Fortunately, if you'd prefer that it copy instead, it's pretty much changing the word "Move" to "Copy" in the code.
To run it, I just run "ID3RenameMp3.exe f:\music\unsorted" and it takes care of the rest.
The ID3 part pretty much comes down to knowing the field names for what you're after. They're things like "TALB" for album name. There's a list of them in the CodeProject class, in the FrameInfo.cs file if you want something other than the ones I used.
There are some unused variables you'll notice. Those are from some bits I had in place for checking if you're already inside the appropriate album or artist directory.
The Code
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ID3;
namespace ID3RenameMp3
{
class Program
{
static void Main(string[] args)
{
ID3Info FileID3Info;
String Title;
String Album;
String Artist;
String TrackNumber;
String SongFullPath;
String ParentPath;
String ParentName;
FileInfo songInfo;
String NewSongPath;
String FolderPath;
try
{
FolderPath = args[0];
}
catch (Exception e)
{
FolderPath = ".";
}
string[] songs = Directory.GetFiles(FolderPath);
foreach (string song in songs)
{
songInfo = new FileInfo(song);
SongFullPath = songInfo.FullName;
NewSongPath = FolderPath;
bool IsMp3 = song.EndsWith(".mp3");
if (IsMp3)
{
FileID3Info = new ID3Info(SongFullPath, true);
Title = FileID3Info.ID3v2Info.GetTextFrame("TIT2");
Artist = FileID3Info.ID3v2Info.GetTextFrame("TPE1");
Album = FileID3Info.ID3v2Info.GetTextFrame("TALB");
TrackNumber = FileID3Info.ID3v2Info.GetTextFrame("TRCK");
ParentPath = songInfo.Directory.ToString();
ParentName = songInfo.Directory.Name.ToString();
NewSongPath = NewSongPath + "\\" + Artist;
NewSongPath = NewSongPath + "\\" + Album;
try
{
Directory.CreateDirectory(NewSongPath);
File.Move(song, NewSongPath + "\\" + TrackNumber + " - " + Title + ".mp3");
System.Console.WriteLine("File moved and renamed to: " + Title + ".mp3");
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
}
}
}
}
}
Ways to Extend
- Instead of moving the files, if you had it copy them, you could use this to generate sorted directory trees of your MP3's according to nearly any criteria. You could copy them to Genre directories, Year directories, directories grouped by beats per minute, etc. This is really only limited by how good your metadata is.
- Create smartlists without iTunes or iPods. This would actually copy the files, but if you specified an output directory different from where the files were, you could create a specific directory to sync with your MP3 player and fill it with files that match the criteria. This would also be helpful for those who use a CD-RW to listen to music in the car (like my car is now, with a broken aux input). You could have this clean out your "CarCD" directory, grab an appropriate set of files and just re-burn that every day.
- Add recursion. This should also have a specified output directory to avoid infinite loops, but would let you apply your rules to a complete collection of files.
- Try it out on Mono/Linux. While I spend more time on the Linux side of the fence lately, I wanted to make my initial stab at this utility as simple as possible and that meant Windows. However, since the ID3 stuff can be compiled as an assembly and my code is pretty basic stuff, it should work on Linux via Mono as well. I'm probably going to do this as my next step.
Wrapup
Of course, like many projects of this type, with the basic utility working with just a little bit of coding and testing, I'll probably mostly just get down to using it. It already cleaned up the downloaded album and I'm going through the rest of my files for anything else needing to be cleaned up and then I'll just file it away for the next time I need it.

April 13th, 2007 at 7:52 am
Do you see any problems in porting this to Java? Could you point me to a library that will help me get ID3 tag info in Java? This would be a nice project to try out, because I would like to sort my files as you have done.
April 13th, 2007 at 8:44 am
I don't see why you couldn't do the same task in pretty much any language. Technically, these libraries are just reading through and parsing the first X bytes of the MP3 file.
I don't happen to know of any Java libraries, but I didn't know of any C# libraries when I sat down to do this either.