There are two reasons I wanted to post this article. One of them is to suggest a solution to the problem of sync-ing large iTunes libraries with not-so-large iPods. The other is to introduce a reusable progress window form, that can cancel the process it is called from and can be forced to close upon the finishing of the process.
If you are reading this article, chances are you too are a fellow victim of a huge MP3 song library, a portion of which you never even have played! To make things worse, you bought an iPod that can handle only a portion of these songs, so you cannot simply put all those songs into the iPod.
Now you are stuck either syncing your iPod completely manually, or sitting down and cleaning your iTunes library from unwanted songs. I couldn't have done that, since I am usually at the computer for a reason, generally more important than cleaning up my MP3 files.
Here is my approach to go about cleaning your iTunes library.
To be carried out once:
- Start by removing duplicates (i.e., multiple library entries that map to the same physical MP3 file).
- Delete library entries with missing files.
To be carried out while listening on your iPod or computer:
- Have you found a song you want deleted? Rate it with 1 star.
- Have you found a song you want to keep only on your computer, but not on your iPod? Rate it with 2 stars.
- Have you found a song you would like to keep on your iPod? Rate it with 3 to 5 stars depending on how much you like it.
To be carried out before iPod Sync:
- Have a separate playlist that will sync with iPod. Put all the songs that are 3 stars and above in it. Depending on the capacity of iPod, put random songs into the playlist to fill up the iPod (can be very time-consuming).
Fortunately, iTunes has provided the SDK for iTunes as a COM component, so we can manipulate the library from .NET code. And that is exactly what this project is about. All steps described above, with the exception of rating the songs, are handled by the project.
When you run the application, it will display the number of songs that are in your iTunes library.
Let's take a look at what each of these buttons do, starting from the ones that we are likely to use once.
Delete entries with missing files:
This button starts a process that will remove all the library entries with missing files. These tracks are generally a result of moving files around from the Windows Explorer.
This button removes multiple track entries in the library that map to the same physical MP3 file.
The superstar! Create favourites playlists:
This button is the reason I wrote the application. Here is a list of playlists it creates:
- Your iPod!: This playlist consists of songs that you have rated 3 and above, along with a selection of random songs that are not rated, to fill up your iPod.
- Your Favourites!: All tracks rated 3 or above will be in this playlist.
- The Rest!: All files that are not rated will be in this playlist.
Once you click the button, the system is going to ask you for your iPod capacity.
Then it will start to delete the entries within the playlists it will create, so they will be refreshed.
Then it will start to fill the playlists up with the songs.
It will then fill up the remaining space on the Your iPod! playlist.
Now you can sync your iPod with the playlists above (and optionally with the iTunes automatic playlist of "My Top Rated", since all files in it will already be in both Your iPod! and Your Favourites! playlists) and your iPod is set to go!
My suggestion is to sync your iPod before using the Create Favourites Playlists button so that the newest rated songs will be taken into account when creating the playlists.
Progress window and its usage
The heart of the form is the code below. Once started, it binds itself to two events:
StatusDone. These are declared on a Module called
Public Event UpdateStatus(ByRef Cancel As Boolean, ByVal CurrentNumber As Integer)
Public Event StatusDone(ByVal ForceClose As Boolean)
Private mbCancel As Boolean = False
Public Shared Sub Start(ByVal Headline As String, ByVal Total As Integer)
Dim oStatus As New frmStatus
oStatus.lblHeadline.Text = Headline
oStatus.Text = Headline
oStatus.pb.Maximum = Total
AddHandler MLibrary.UpdateStatus, AddressOf oStatus.UpdateProgress
AddHandler MLibrary.StatusDone, AddressOf oStatus.StatusDone
Private Sub UpdateProgress(ByRef Cancel As Boolean, _
ByVal CurrentNumber As Integer)
pb.Value = CurrentNumber
lblStatusText.Text = CurrentNumber & " of " & pb.Maximum
btnOk.Enabled = CurrentNumber = pb.Maximum
btnCancel.Enabled = Not btnOk.Enabled
Cancel = mbCancel
If Cancel Then Me.Close()
Private Sub StatusDone(ByVal ForceQuit As Boolean)
If ForceQuit Then
btnOk.Enabled = True
btnCancel.Enabled = False
Private Sub btnCancel_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnCancel.Click
mbCancel = True
Private Sub btnOk_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnOk.Click
RemoveHandler MLibrary.UpdateStatus, AddressOf Me.UpdateProgress
RemoveHandler MLibrary.StatusDone, AddressOf Me.StatusDone
Here is how the code is used. Let's take a simple example as finding the tracks with missing files:
Dim iCounter As Integer = 0
For Each oTrack As IITTrack In moTunes.LibraryPlaylist.Tracks
If oTrack.Kind = ITTrackKind.ITTrackKindFile Then
Dim oFileTrack As IITFileOrCDTrack = oTrack
If oFileTrack.Location = "" Then
iCounter += 1
Dim bCancel As Boolean = False
RaiseEvent UpdateStatus(bCancel, iCounter)
If bCancel Then Exit For
RaiseEvent StatusDone(alTracksToBeDeleted.Count > 0)
The above code is pretty self-explanatory. On every iteration, we raise the
UpdateStatus event. When we are done, we raise the
StatusDone event with an optional parameter for closing the form without the user's intervention.
If you have any questions on how to use the form or how to use the iTunes Library Manager, let me know.