Reading iTunes Playlists using C#

Here is a quick project that I've chucked together in the last hour or so. Essentially, I've written a little program that reads a playlist from iTunes. The plan is to have a sidebar that shows the "Most played" and "Recently played" Lists, but more on that in future posts.

Now, let's start out simple. I have created a new Class Library named "iTunesStuff", and in this I have created a new Class "Song":

[Serializable()]
public class Song : IComparable<Song>
{
  public string Title { get; set; }
  public string Artist { get; set; }
  public string Album { get; set; }
  public int Year { get; set; }
  public int Length { get; set; }
  public int PlayCount { get; set; }
  public DateTime LastPlayed { get; set; }
  public string LengthAsString
  {
    get
    {
      TimeSpan ts = TimeSpan.FromSeconds(this.Length);
      if (ts.Hours > 0)
      {
        return string.Format("{0}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds);
      }
      else
      {
        return string.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds);
      }
    }
  }
  public override string ToString()
  {
    return string.Format("{0} - {1} ({2}, {3}) [{4}] {{Last Played: {5:dd/MM/yyyy HH:mm}, Total: {6}}}", Artist, Title, Album, Year, LengthAsString, LastPlayed, PlayCount);
  }
  #region IComparable<Song> Members
  public int CompareTo(Song other)
  {
    if (other.LastPlayed > this.LastPlayed) return 1;
    else
      if (other.LastPlayed < this.LastPlayed) return -1;
      else
        return 0;
  }
  #endregion
}

Nothing really spectacular here: The class implements some fields that describe a Song. The only interesting part is the IComparable Function. I want my list to be sorted by "Last Played Date". Therefore I have implemented a custom Compare-Function that will compare the LastPlayed Field. For more information, see here. The purpose is to have a List<Song> and use Sort() on that List.

Now, we need a function that reads the information from iTunes. Apple provides a COM Interface that makes this task quite easy, you can simply Add a Reference to iTunes.exe ("iTunes 1.x Type Library") and "using iTunesLib". I have written a PlaylistReader Class for this purpose:

public class PlaylistReader
{
  public List<Song> GetPlaylistSongs(string playlistName, int limit)
  {
    List<Song> result = new List<Song>();
    iTunesAppClass ita = new iTunesAppClass();
    IITPlaylistCollection playlists = ita.LibrarySource.Playlists;
    for (int i = 1; i < playlists.Count+1; i++) // iTunes starts counting from 1
    {
      if (playlists[i].Name.Equals(playlistName, StringComparison.OrdinalIgnoreCase))
      {
        IITTrackCollection tracks = playlists[i].Tracks;
        for (int j = 1; j < tracks.Count+1; j++)
        {
          if (tracks[j].Kind != ITTrackKind.ITTrackKindFile)
          {
            continue; // To filter out Web Radio URLs etc.
          }
          Song s = new Song();
          s.Title = tracks[j].Name;
          s.Album = tracks[j].Album;
          s.Artist = tracks[j].Artist;
          s.Year = tracks[j].Year;
          s.Length = tracks[j].Duration;
          s.PlayCount = tracks[j].PlayedCount;
          s.LastPlayed = tracks[j].PlayedDate;
          result.Add(s);
        }
        break;
      }
    }
    playlists = null;
    ita = null;
    result.Sort();
    if (limit > 0 && result.Count > limit)
    {
      result.RemoveRange(limit, result.Count - limit);
    }
    return result;
  }
}

Note that iTunes (or is it COM in General?) starts it's collections from 1 instead of 0, so trying to access playlists[0] gives you an error. Also note that the order of tracks is not necessarily the current order in your iTunes. For example, the "Recently played" Smart Playlist is ordered by Last Played, but the COM Interface gives you back the tracks in the order they were added to iTunes. Hence I added the call to result.Sort() at the end. This will in turn trigger my custom CompareTo function in the Song Class, which means that the list will be ordered by "Last Played", descending. The limit Parameter is just there to avoid returning a 300+ tracks list, which can be quite ugly on a Web Site...

The usage is then really straight forward:

private void button1_Click(object sender, EventArgs e)
{
  PlaylistReader rpl = new PlaylistReader();
  List<Song> songs = rpl.GetPlaylistSongs("Recently Played",25);
  StringBuilder sb = new StringBuilder();
  for(int i = 0; i<songs.Count; i++)
  {
    sb.AppendFormat("{0}: ",i+1);
    sb.AppendLine(songs[i].ToString());
  }
  textBox1.Text = sb.ToString();
}

Voilá, huge success:


In the next post, I'll try to get a custom IComperator up and running, so that we can sort the list by other criterias. I'll also export the list to a file which I then parse on the sidebar of this blog, at least that's the actual goal of this.

Comments (1)

[...] Grab the contents of a Playlist from iTunes [...]