My motivation for creating this application was relatively simple and straight-forward. As being slightly OCD, having my ID3 tags properly set for my music was something I felt was an utmost necessity. I used to spend hours looking up each and every song in my music library to make sure the artist, song title, album artwork and other ID3 tags were correct. Merely looking at the music libraries of other people would sometimes make me cringe at how awful and incorrect the tags were. The worst of all libraries was my girlfriend Kati's. One day I was trying to fix her music when the idea came to me of "Hey. I have to do a project for seminar anyways, so why not make an application that will do this for me and everyone else?" Thus, the ID3 Hunter was born.
Of all of the projects I have done in my college career, I have never put as much research in to any of them as I have this one. It was something entirely new to me and I had to really work from the ground up with zero code samples of how to do this. There are many other applications out there that do a similar function as my application, but of the ones I tested, none of them were to my satisfaction. Worst of all was I downloaded some that were in the top 5 applications for automatically detecting ID3 tag data across quite a few different website rankings, so they have a really popular user base. In my experience with them, one of them I could not even figure out how to use it was so clunky with buttons and labels and everything under the sun. Another one just flat out didn't work at all for any song I tried and had no way to manually enter any of the metadata. Finally, the last one I really delved in to and toyed with worked, but nearly every tag it automatically picked up was wrong. So none of these were even close to my standards of what an application should be like. So while they didn't give me any real inspiration for how to make my application, they definitely gave me plenty of inspiration for how not to make my application.
After researching some other applications to give me a basis for what the users expect from an application like this, I started to research how to make it work. This was the real headache of the project and it took me quite some time to really figure this chunk out, but we'll get to that in the Challenges section below. I researched four different technologies to help me do the auto-detection. They were: the last.fm web API, TagLib# (TagLib-Sharp), the Gracenote web API and last.fm# (last.fm-Sharp). Last.fm# was an unofficial wrapper for the last.fm web API for use with C# written by email@example.com. Ultimately, this library did not make the final cut. We'll get in to the details of these four technologies below.
- Visual Studio 2013 Ultimate
- .NET Framework 4.5
- Last.fm Web API
- Last.fm Fingerprint Client
- ParkSquare Gracenote API
- Adobe Photoshop CS6
Visual Studio was used as my IDE for this project. It ties in with the .NET 4.5 framework and C#. I used this because I really enjoy writing code in C# using Visual Studio. It's very fun and simple, and while it may be simple, it's still very powerful. You can do so many things so easily using .NET. It makes writing an application with a GUI so incredibly easy, I'm not sure anyone would opt for some other technology unless they are unfamiliar with Visual Studio. Cross-platform issues can arise, but can be handled using Mono or some other technology. Given my familiarity with the .NET framework, it was an obvious choice for what I wanted to write my application in. I do recall coming across some libraries written for Python and some other languages that rivaled TagLib# but I had never written Python and TagLib# did exactly what I needed it to anyway.
TagLib# was my lifeline to the actual modification of a song's metadata. It was used to manipulate the tags (populate or clear) and then save the file. It provided a very easy way to access the metadata so it wound up being a truly invaluable component of my application. While it is difficult to find the latest version of TagLib# in dll form (v 2.1.0 at the time of this writing [April 2014]), I was able to obtain a copy using the NuGet package manager within Visual Studio. The command is "Install-Package taglib" For further details on how to do this, see http://www.nuget.org/packages/taglib/
The last.fm web API and the fingerprint client was used solely for the auto-detection of the tags. The fingerprint client was used to obtain an acoustic fingerprint of the file in question and send that to last.fm to return the track ID. The track ID was then used to query the last.fm web API to get the metadata of the song. I used the track.getFingerprintMetadata() and track.getInfo() methods primarily. Without the last.fm web API and fingerprint client, I never would have been able to fulfill this requirement given my time constraint. I used last.fm primarily, but Gracenote as a backup.
GitHub was also very handy of course. Revision control is very important to use in my opinion for any application: big or small, solo or team. It housed my code and allowed me to keep track of bugs and what I had implemented in each change very easily. This way, I could work on my application at UVa or at home without missing a beat. I used it over other revision control websites because I already had an account there and was familiar with how to use it.
Adobe Photoshop CS6 wasn't a huge component of this application, but vital nonetheless. Without it, I would have had to take some generic image to use as my icon instead of having my own personalized one.
I feel like I could write for days on the challenges of this application, but I'll try to summarize a fair amount. I didn't have any serious issues with the application besides for the album artwork saving in to the audio files and the auto-detection working. TagLib# was very reliable in this sense so I didn't have any issues with populating or reading the metadata from the audio files.
The artwork population provided some issues simply because treating an image as a string of bytes is unnatural to us since to us an image is just that: an image. So I had to use the MemoryStream and the IPicture inferface to both read and populate the album artwork for the audio files.
Keeping track of the buttons being enabled/disabled and checking for certain conditions that must hold in order for certain features of the application to be usable was tricky at times. For example, you can't auto-detect for tags if you can't connect to last.fm, or you have no songs selected so these conditions had to be accounted for. Other conditions were you must be editing in order to change the data visible on the form to you.
The auto-detection was by far the largest challenge of this project. Honestly, in the first month I had everything but the auto-detection and the sorting implemented and working properly. The auto-detection was such a pain because it was something entirely new to me and I was unable to find any code samples in any language using any API for doing auto-detection of audio metadata. Finally with enough perseverance I discovered on my own how to use the last.fm web API in C#. For three days I had tried returning the metadata in the last.fm fingerprint client (as it is supposed to be a feature of it), but was unable to as it constantly said "The metadata server is down. Please try again later." It never did work in that way, but after using the -url flag while running it, I was able to retrieve the fingerprint ID last.fm assigned to the file and used that in the track.getFingerprintMetadata() method present in the last.fm web API to get the metadata present in my application.
At this moment, I don't have any improvements in mind for future implementations as I have already implemented all the features I wished to include. After some people use the application, I'm sure more and more features will be requested. Throughout my design and implementation of this project, I worked with my girlfriend on things that she would like to see included and she provided some very useful ideas like the auto-complete feature for when you're typing in the artist, genre, or album name manually. So it has some features present in it that one particular user would have liked to see that I hadn't thought of.
Besides future feature implementations, I would like to explore the route of making it multi-threaded so that the auto-detection would be much faster. Currently, it's a little too slow for my taste, averaging around 2 seconds per track on my computer at home. Also, I would like to explore using Mono to make the application cross-platform to work on Linux and Mac OSX instead of just Windows.
ID3 Hunter Download/Source -> http://id3hunter.codeplex.com/
Last.fm# -> https://code.google.com/p/lastfm-sharp/
Last.fm Web API Method Directory -> http://www.last.fm/api
TagLib# Code -> https://github.com/mono/taglib-sharp
Last.fm Fingerprint Client -> http://blog.last.fm/2010/07/09/fingerprint-api-and-app-updated