Sad iTunes Library
 
 
Script available at github here!

There's nothing more sad than an iTunes Library where the Coverflow is a deck of black musical notes. If you, like me, have a somehow irregular iTunes Library you have certainly experienced this sadness. Maybe you have tried using the iTunes built-in feature to fetch album artwork achieving poor results, or maybe you've tried some of the available software solutions out there and maybe they didn't work. Maybe that's because most of them rely on grabbing the name of the album in which that track is in and getting the cover.

In this blog post we will try to solve this problem with our own hands with a simple Ruby script. The advantage is that you know your own library, so you can tweak the code until it gives you optimal results, not relying on something made to work for everyone that ends up just doing great in regular libraries. For my library this script fetched artwork for 401 artists out of 682, so with a success of proximately 60%. Which is fairly good, given the fact that the most of the unsuccessful tracks didn't have the necessary ID3 tags specified for the script to work. I bet the result can reach far better in other libraries.

"But, what the hell is an irregular library? I do I know if mine's like that?" - you ask. Well, maybe if you have tried the built-in iTunes feature Get Album Artwork and you achieved nothing your library is probably pretty irregular. The built-in feature and many other software solutions simply try to extract the album ID3Tag of the track, accessing some large database and getting the image for you. But, what if you have a lot of tracks that don't belong to any album? What if you have a lot of recordings of live events or radio shows or dj sets or the music simplydoesn't have the album tag specified and you don't have time to go manually fix all the tracks? Well, the tools will probably not work.

 

Another sad iTunes
 

 

So in this script I tried a different approach. If the available tools fail at giving me the artwork for the albums, I would rather have another type of artwork there than facing black musical notes. So let's think, what all the tracks have in common?

They have an artist. It's unusual to have a track in a library which doesn't have the Artist ID3Tag specified. So, what if, instead of getting the artwork for the album, we get as the artwork an image of the artist? In my opinion that is far better. Since I don't care about the album, I rather have an image of the artist, some of them I didn't even know the face before I had it on the tracks.

So, how do we do this? First things first, where are the images for the artists? If you use Last.fm you know it consists of a large community of people who are constantly passively scrobbling (that is, sending) information about the music their hear in their favorite player to Last.fm. There are plugins available to almost all players in all operating systems so, if you use it, and you have listen to all of your iTunes Library, then Last.fm definitely has information for every track in your library in their database. People can access through Last.fm's website each artist's page and add images, most of them with pretty good quality (since their upvoted and downvoted by the users). You'll probably end up with images for almost all the artists in your library. Below you have an example of the type of images last.fm has on the artists, I think they're really good.

 

Armin van Buuren
 

 
Last.fm has an API which you can check out here. It has the method getimages in which you have to specify the artist name and it'll return a collection of links to the images. So that problem is solved.

Next one. How can we traverse an iTunes Library and how can we get the name of the artist for each track? iTunes solves this problem for us by having an iTunes Library.xml file inside your iTunes Library folder, in there you will find <dict> tags for each track with a bunch of <key> tags exposing the ID3 tags of the file, including artist name and location of the file on disk. We can simply parse it with a XML parser (I couldn't do it with regexp) and use that data.

Sample text of the iTunes XML file

 
The last problem is just how do we apply artwork to a track. There was two possible ways you could do this. One of them was using the iTunes closed system for artwork, the .itc files, which store the artwork you get when you use the Get Album Artwork function. Those files are not documented although some have tried to do it reaching some conclusions. I won't go that way, it's undocumented territory and the artwork would just be visible in iTunes.

The other way is having the image itself stored in the MP3 file. ID3 tags allow you to store a couple of images inside of a single file. To do that, we simply need a Ruby library for editing ID3 tags that supports the picture frames. I found this one which we will be using (more details on the instalation in a minute).

For the script to work you will have to install or have the following:

- iTunes
- Ruby
- Rack::Utils gem
- CGI gem
- URI gem
- Net/Http gem
- REXML Ruby XML parser
- ID3Lib Ruby


Most of the gems come built-in with Ruby. The ones you'll prabably have to install will be Rack::Utils, REXML and ID3Lib. If you're using Ruby 1.8 the id3lib available through http://id3lib-ruby.rubyforge.org/ should work fine. But if you use Ruby 1.9 I found that version to crash a lot. I was almost giving up when I caught this pseudo-fork at github. I recommend you install that one, the installation process is the same as the one documented in the ID3Lib website.

I won't use this post for explaining the code, but rather what you have to define in it and how you can interact with the script. Right at the start of the code you'll see this:

@itunes_xml_path = "/Users/miguel/Music/iTunes 1/iTunes Library.xml" 
@logfile_path = "/Users/miguel/Desktop/errors.txt"
@image_path = "/Users/miguel/Desktop/images/"
@in_control_mode = true
@cuts = ["with", "With", "Feat", "feat", "pres", "Pres", ",", "vs", "&"]


You'll have to define those ones.

  • @itunes_xml_path is the path for your iTunes Library.xml file which should be pretty similar to mine.
  • @logfile_path is the path were there will be stored the logfile of the process which will document throughly what's happening to each track. I recommend you open a terminal tab with tail -f /.../logfile so you can see what's happening as the script is runing.
  • @image_path is the path of a folder you'll have to create manually where the images fetched will be stored. Each image will have as name an escaped version of the artist name
  • in_control_mode is very important. If it is set to true, the program won't do anything automatically. It will check the artist name of a track, fetch the image and ask you if you accept it. You can answer no and it will fetch another image for that artist, and it will automatically return to the beginning when all the images were fetched until either you answer y (yes) or 'leave' which will skip that track. Your answers should be stored for that artist name, so you don't have to answer the same thing everytime. If that mode is off the script will just apply the first image of Last.fm to your track without giving you any control.

 

Example of the script running
  • @cuts is an array of words that will be used to split artist tags which are composed of more than one artist such as Linkin Park with Jay-Z, or Gareth Emery vs John O'Bir such that the considered artist will just be the one before the splitting word. Define your own based on your library.

At last, after you have run the script, you will have to be able to make iTunes reload the files so it can update the images and use them on Coverflow. I noticed the images were update when you played the track. Of course you won't need to do it manually to our whole library, although it may be faster that way. Just fire up Script Editor, put iTunes in the default Music Playlist sorted by album (this may reduce the disk needle jumping back and forth), select the first track of the list, disable shuffle, and insert the following text in Script Editor:

tell application "iTunes"
    repeat 2133 times
        play
        pause
        next track
    end repeat
end tell


The number after "repeat" should be the number of songs in your library which you can check at the bottom of the iTunes window. The script will then play pause every song in the library, enough for the images to be recognized. It's a hack, but it works. Hit play and stop the process when we reach the beginning again.

 

Script Editor script

 

At last I have to say this script was tested on Mac Os X Leopard. I expect it to work on another operating systems but not without some changes, so if you're on another OS start testing the code bit by bit and seeing if it works or making the appropriate changes.

 

A happy iTunes
 

 

So that's it. I think the result was pretty good. You can understand the process better by reading the code which is available at github here for you to fork or integrating in some sort of Cocoa App (it would be awesome) which could make the process more visual.

 

Another happy iTunes
 

 

Known Issues: Every time the script run it happened to something like 20 tracks an introduction of a strange char at the beginning of the name, artist and sometimes album and genre ID3Tag. I think that is related to either the version of the ID3 tag of those tracks or problems with the ID3Lib. That should be no reason for you to try the script, just do it in 'in control mode' and verifying if everything is going ok (that char can be seen when you play the track on iTunes). Anyway, I absolutely don't recommend you running this script unless you have something like a Time Machine backup done of all your iTunes Library.




Go to Blog