Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Delete and Recreate iTunes Playlists Based on Artist/Album Names

0.00/5 (No votes)
31 Oct 2006Public Domain2 min read 1   179  
Create iTunes playlists.

Introduction

This small VB console application deletes existing playlists from iTunes (except for smart playlists), then recreates them using the Artist and Album names. I have a touch screen system, and iTunes has the uncontrollable habit of drag and drop with playlists, which means a momentary hover and the playlist you just selected copied to the one above/below it; let the kids loose on that one and say goodbye to sense and order.

Using the code

To use the code, you will need iTunes installed, the version I wrote it under was v7, and .NET Framework 2.0. An unusual feature is the use of ITDetectorLib which appeared with version 7: seems to allow you to detect iTunes is installed and a get version information without starting iTunes.

If you try to write your own program using Visual Studio, watch out for the IDE completing iTunes variable types. If you want to declare an IITSource, you have to press Escape, otherwise it will become IITSourceCollection, same for a few of the other IITxxx types.

The code contains lots of comments to help understand what is to be achieved, and is fairly self explanatory. I have added a few bells and whistles for my own personal preferences on playlists as often a multi-CD album has variations on its naming; disc one may have (Disc 1) in its album name and other [Disc x], there seems to be no adherence to a standard, so I eliminate "(Disc", "[Disc", " Vol" and some other strings to simplify the name and cause the tracks to come together under one playlist.

VB
Imports iTunesLib
Imports ITDETECTORLib
Imports System.Text
Imports System.Threading
 
Module TidyPlayLists
   Structure bums
      Dim Name As String
      Dim TrackTable() As iTunesLib.IITTrack
   End Structure
 
   Dim Albums(0) As bums
   Dim WithEvents iTunesApp As iTunesLib.iTunesApp
   Dim mainLibrary As IITSource
   Dim LibPlayLists As IITPlaylistCollection
 
   Sub Main()
      '
      ' Uses ITDetector to determine if iTunes
      ' is installed, seems to be new in v7 iTunes.
      '
      ' iTunes will start when iTunesApp initialised,
      ' if it is not already started
      '
      Dim iDetect As ITDETECTORLib.iTunesDetector = _
                  New ITDETECTORLib.iTunesDetector
 
      If iDetect.IsiTunesAvailable Then
         Try
            iTunesApp = New iTunesLib.iTunesApp
            mainLibrary = iTunesApp.LibrarySource
            LibPlayLists = mainLibrary.Playlists
 
            iTunesApp.BrowserWindow.Minimized = True
            iTunesApp.ForceToForegroundOnDialog = True
            '
            ' Enumerate sources and delete
            ' playlists for type = library only
            '
            Dim Sources As IITSourceCollection
            Dim i As Integer
 
            Sources = iTunesApp.Sources
 
            For i = 1 To Sources.Count
               If Sources.Item(i).Kind = _
                     ITSourceKind.ITSourceKindLibrary Then
                  KillPlayLists(Sources.Item(i))
 
                  BuildPlayLists(Sources.Item(i))
               End If
            Next
 
            Console.WriteLine("Done...")
            iTunesApp.BrowserWindow.Maximized = True
 
         Catch ex As Exception
            Console.WriteLine("iTunes may be busy...")
         End Try
      Else
         Console.WriteLine("iTunes not installed, closing")
      End If
   End Sub
 
   Private Sub KillPlayLists(ByVal LibSource As IITSource)
      Dim currPlaylist As IITPlaylist
      Dim uPlaylist As IITUserPlaylist
      Dim Count As Integer = 1
 
      Console.WriteLine("Delete PlayLists in " + LibSource.Name)
 
      Do While Count <= LibSource.Playlists.Count
         currPlaylist = LibSource.Playlists.Item(Count)
         '
         ' Do we have a user playlist
         '
         If currPlaylist.Kind = ITPlaylistKind.ITPlaylistKindUser Then
            '
            ' Coy it to a userplaylist to get access to specialkind
            '
            uPlaylist = currPlaylist
            '
            ' If it is not special
            ' (ITUserPlaylistSpecialKindNone) or it is a folder
            ' delete it, you can safely try to
            ' delete other kinds (video etc.) as the 
            ' delete will be ignored for SYSTEM playlists,
            ' just nice to be polite and
            ' only try to delete user list/folder
            '
            If uPlaylist.SpecialKind = _
                  ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindNone _
                  Or uPlaylist.SpecialKind = _
                  ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindFolder _
                  Then
               Try
                  currPlaylist.Delete()
               Catch ex As Exception
                  ' Ignore errors
               End Try
            Else
               Count += 1
            End If
         Else
            Count += 1
         End If
      Loop
   End Sub
 
   Private Sub BuildPlayLists(ByVal LibSource As IITSource)
      Dim i As Integer
      Dim x As Integer
      Dim ab As String
 
      Console.WriteLine("Build Album Names from " + LibSource.Name)
      '
      ' The first item in the LibSource.PlayLists.Item() is THE Library
      ' to be safe we should enumerate it and compare it to kind
      ' library, or use the playlist specialkind music for just music.
      '
      ' Example:
      '
      'Dim pl As IITPlaylist
      'Dim ul As IITUserPlaylist
      '
      'For i = 1 To LibSource.Playlists.Count
      '   pl = LibSource.Playlists.Item(i)
      '
      ' CHOOSE THE FOLLOWING TO PROCESS ENTIRE LIBRARY
      '
      '   If pl.Kind = ITPlaylistKind.ITPlaylistKindLibrary Then
      '      ...Do it for a Library
      '      For Each Track As IITTrack In pl.Playlists.Tracks
      '      Next
      '   End If
      '
      ' OR THE FOLLOWING TO JUST PROCESS MUSIC PART OF LIBRARY
      '
      '   If pl.Kind = ITPlaylistKind.ITPlaylistKindUser Then
      '      ul = pl
      '      If ul.SpecialKind = _
      '       ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindMusic Then
      '         ...Do it for just the Music part of the Library
      '      For Each Track As IITTrack In ul.Playlists.Tracks
      '      Next
      '      End If
      '   End If
      'Next
      '
      For Each Track As IITTrack In LibSource.Playlists.Item(1).Tracks
         '
         ' This next part is a personal string tidy,
         ' if a trackkindasstring has protect aac
         ' as the first part of its name then
         ' it is likely to be a purchased track so add
         ' to our own special playlist called ".Purchased"
         '
         If Mid(Track.KindAsString, 1, 13) = "Protected AAC" Then
            ab = ".Purchased"
         Else
            '
            ' If the album has a name lowercase it for compare purposes.
            '
            If Track.Album <> Nothing Then
               ab = Track.Album.ToLower
               '
               ' Tidy up a few name odds
               ' and sods to even the comparison out
               ' Multi disc sets often have (Disc x)
               ' or [Disc x] or even a mixture
               ' of both types in the same set,
               ' this would result in each disc being
               ' placed in a separate playlist,
               ' so remove that part of the name.
               '
               If InStr(ab, "(disc") <> 0 Then
                  ab = Mid(ab, 1, InStr(ab, "(disc") - 1)
               End If
 
               If InStr(ab, "[") <> 0 Then
                  ab = Mid(ab, 1, InStr(ab, "[") - 1)
               End If
               '
               ' Some multidisc sets use Vol x, remove that too.
               '
               If InStr(ab, " vol") <> 0 Then
                  ab = Mid(ab, 1, InStr(ab, " vol") - 1)
               End If
               '
               ' Finally remove a few odd characters
               '
               ab = StripQuote(ab)
               ab = ab.Trim
            Else
               '
               ' No album name add to special list ".No Album"
               '
               ab = ".No Album"
            End If
         End If
         '
         ' Find/Add to the album array
         '
         For x = 0 To Albums.Length
            If Albums(x).Name = Nothing Then
            ' End of the array, album not found add new one
               Albums(x).Name = ab
               '
               ' Dim the track table in the new
               ' element to one and add the track
               '
               ReDim Preserve Albums(x).TrackTable(1)
               Albums(x).TrackTable(0) = Track
               '
               ' Add extra element to albums
               '
               ReDim Preserve Albums(x + 1)
               Exit For
            Else
               '
               ' If the album item is the same name as the
               ' one we are looking for
               ' add the track to its tracklist
               '
               If Albums(x).Name = ab Then
                  Albums(x).TrackTable(Albums(x).
                     TrackTable.GetUpperBound(0)) = Track
                  ReDim Preserve Albums(x).TrackTable(
                     Albums(x).TrackTable.GetUpperBound(0) + 1)
                  Exit For
               End If
            End If
         Next
      Next
      '
      ' Built the album array, now make playlists
      ' for each album in the array.
      '
      Console.WriteLine("Create Playlists in " + LibSource.Name)
 
      Dim albumPlaylist As iTunesLib.IITPlaylist
 
      For i = 0 To Albums.Length - 2
         '
         ' See if Artist Name is Same For Every Track in the List
         ' if it is prefix the album name with the artist name
         '
         ab = Albums(i).TrackTable(0).Artist
 
         For x = 0 To Albums(i).TrackTable.Length - 2
            If ab <> Albums(i).TrackTable(x).Artist Then
               ab = ""
 
               Exit For
            End If
         Next
         '
         ' Some artist names are huge (orchestra,
         '    conductor, lead singer and his wife)
         ' Shorten long ones to nearest comma.
         '
         If ab.Length > 30 Then
            If InStr(ab, ",") > 0 Then
               ab = Mid(ab, 1, InStr(ab, ",") - 1)
            Else
               ab = ""
            End If
         End If
         '
         ' If we have an artist name add a hyphen
         '
         If ab <> "" Then
            ab += " - "
         End If
         '
         ' Create Playlist
         '
         albumPlaylist = iTunesApp.CreatePlaylist(ab + _
            StrConv(Albums(i).Name, VbStrConv.ProperCase))
         '
         ' Add Tracks to New Playlist
         '
         For x = 0 To Albums(i).TrackTable.Length - 2
            albumPlaylist.AddTrack(Albums(i).TrackTable(x))
         Next
      Next
   End Sub
 
   Public Function StripQuote(ByVal Source As String) As String
      Dim strX As New StringBuilder(Source)
      '
      ' Remove a few character types from
      ' the album name string passed as argument
      ' Some multi CD albums do not stick
      ' to the same naming convention, the characters
      ' stripped here are one or two I have
      ' notice in my own albums, you may find more
      ' and add them as you wish to make your
      ' lists tidier. Personally the person who
      ' created the album names in the online
      ' database should be punished for every variation
      ' in the naming of CD's in an album set.
      '
      strX.Replace("!", "")
      strX.Replace("'", "")
      strX.Replace("`", "")
      strX.Replace("´", "")
      strX.Replace(" - ", " ")
      strX.Replace("...", " ")
 
      StripQuote = strX.ToString
   End Function
End Module

Points of Interest

An important part of the iTunes interface is the events, particularly being able to know when the COM interface is busy, for which two events are supplied. Unfortunately, I have been unable to get it to work, it will pass the event to the application but nothing executes. If you use a debug trap, it will pop up at the appropriate moment and you can try to step through the instructions to no avail. The first step returns control to the caller without execution. To circumvent this, you will need to do lots of Try-Catches around every attempt to use the interface. As I am exploring this for my own use, I have not done so except at the start to see if iTunes is available before the code tries anything.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication