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.
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()
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
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)
If currPlaylist.Kind = ITPlaylistKind.ITPlaylistKindUser Then
uPlaylist = currPlaylist
If uPlaylist.SpecialKind = _
ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindNone _
Or uPlaylist.SpecialKind = _
ITUserPlaylistSpecialKind.ITUserPlaylistSpecialKindFolder _
Then
Try
currPlaylist.Delete()
Catch ex As Exception
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)
For Each Track As IITTrack In LibSource.Playlists.Item(1).Tracks
If Mid(Track.KindAsString, 1, 13) = "Protected AAC" Then
ab = ".Purchased"
Else
If Track.Album <> Nothing Then
ab = Track.Album.ToLower
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
If InStr(ab, " vol") <> 0 Then
ab = Mid(ab, 1, InStr(ab, " vol") - 1)
End If
ab = StripQuote(ab)
ab = ab.Trim
Else
ab = ".No Album"
End If
End If
For x = 0 To Albums.Length
If Albums(x).Name = Nothing Then
Albums(x).Name = ab
ReDim Preserve Albums(x).TrackTable(1)
Albums(x).TrackTable(0) = Track
ReDim Preserve Albums(x + 1)
Exit For
Else
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
Console.WriteLine("Create Playlists in " + LibSource.Name)
Dim albumPlaylist As iTunesLib.IITPlaylist
For i = 0 To Albums.Length - 2
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
If ab.Length > 30 Then
If InStr(ab, ",") > 0 Then
ab = Mid(ab, 1, InStr(ab, ",") - 1)
Else
ab = ""
End If
End If
If ab <> "" Then
ab += " - "
End If
albumPlaylist = iTunesApp.CreatePlaylist(ab + _
StrConv(Albums(i).Name, VbStrConv.ProperCase))
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)
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-Catch
es 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.