Delete and Recreate iTunes Playlists Based on Artist/Album Names





0/5 (0 vote)
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.
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-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.