You are on page 1of 5

Articles http://www.peachpit.com/articles/printerfriendly.asp?

p=375499&rl=1

Date: Mar 18, 2005 By Matthew David.

Like your iPod? But don't you wish it could do just one more thing? Stop complaining and start programming! Matthew David exposes you to the
fundamentals of programming iTunes to store more on your iPod.

Over the last few months, I have written a number of articles about extending the capabilities of the iPod. This article gives you Windows developers the
ultimate trip (yes, the secrets of developing iPod and iTunes solutions for the Windows platform!).

To begin developing solutions for iPod and iTunes, you need to download and review the Software Developers Kit, or SDK, developed by Apple for
Windows iTunes and iPod development.

After reviewing these materials, you need to jump into the development of your first application. Fortunately for you, my friends over at SharePod have
allowed us to use the Open Source code for their iPod tool. Yes, that means you get to see an entire application that you can develop today. No need to
dismantle code from meaningless examples in the SDK.

On to the code!

You have to review and then download the Apple SDK, and there are several you can look into. One that I really like is the iTunes' SDK. The iPod is really
a hard drive that lets you look at text, photos, and music. The only challenge is that unless you load LINUX onto your iPod (which you can do), you can't
program solutions directly to the OS running the software on your iPod. The tool that you can control is iTunes.

The iTunes SDK comes loaded with JScript code that you can use to add commonly used features on your iTunes. For instance, the following script allows
you to create a new album playlist:
var iTunesApp = WScript.CreateObject("iTunes.Application");
var mainLibrary = iTunesApp.LibraryPlaylist;
var mainLibrarySource = iTunesApp.LibrarySource;
var tracks = mainLibrary.Tracks;
var numTracks = tracks.Count;
var numPlaylistsCreated = 0;
var i;

// FIXME take a -v parameter eventually


var verbose = false;

// first, make an array indexed by album name


var albumArray = new Array();

for (i = 1; i <= numTracks; i++)


{
var currTrack = tracks.Item(i);
var album = currTrack.Album;

if ((album != undefined) && (album != ""))


{
if (albumArray[album] == undefined)
{
if (verbose)
WScript.Echo("Adding album " + album);
albumArray[album] = new Array();
}

// add the track to the entry for this album


albumArray[album].push(currTrack);
}
}

for (var albumNameKey in albumArray)


{
var albumPlayList;
var trackArray = albumArray[albumNameKey];

if (verbose)
WScript.Echo("Creating playlist " + albumNameKey);

numPlaylistsCreated++;

albumPlaylist = iTunesApp.CreatePlaylist(albumNameKey);

for (var trackIndex in trackArray)


{
var currTrack = trackArray[trackIndex];

if (verbose)
WScript.Echo(" Adding " + currTrack.Name);

albumPlaylist.AddTrack(currTrack);
}
}

if (numPlaylistsCreated == 0)
{
WScript.Echo("No playlists created.");
}
else if (numPlaylistsCreated == 1)
{
WScript.Echo("Created 1 playlist.");
}
else
{
WScript.Echo("Created " + numPlaylistsCreated + " playlists.");
}

Apple has done us a big favor: All its code is in JavaScript. In many ways, JavaScript is the universal scripting language. You can easily step through it and
build more robust solutions. For example, here is the same code modified to remove a playlist:
var ITPlaylistKindUser = 2;
var iTunesApp = WScript.CreateObject("iTunes.Application");
var deletedPlaylists = 0;
var mainLibrary = iTunesApp.LibrarySource;
var playlists = mainLibrary.Playlists;
var numPlaylists = playlists.Count;

while (numPlaylists != 0)
{
var currPlaylist = playlists.Item(numPlaylists);

// is this a user playlist?


if (currPlaylist.Kind == ITPlaylistKindUser)
{
// yes, is it a dumb playlist?
if (!currPlaylist.Smart)
{
try
{
// yes, delete it
currPlaylist.Delete();
deletedPlaylists++;
}
catch (exception)
{
// ignore errors (e.g. trying to delete a locked playlist)
}
}
}

1 of 5 3/2/2007 10:06 AM
Articles http://www.peachpit.com/articles/printerfriendly.asp?p=375499&rl=1

numPlaylists--;
}

if (deletedPlaylists > 0)
{
if (deletedPlaylists == 1)
{
WScript.Echo("Removed 1 user playlist.");
}
else
{
WScript.Echo("Removed " + deletedPlaylists + " user playlists.");
}
}
else
{
WScript.Echo("No user playlists were removed.");
}

Being able to control playlists is critical for your control over the iPod. The iPod builds its playlists from those constructed in iTunes. Being able to construct
playlists allows you to synchronize files that are downloaded over the Internetsuch as those from Pod Cast XML streamsright into iTunes and your
iPod.

The next step is to create your own application.

SharePod's application is built with VB code, so you have to make some modification going to C# or any of the other Visual Studio-supported languages.

SharePod is a tool that runs directly from your iPod. The SharePod.exe files sits in the root directory of your iPod and allows you to search through the iPod
playlists.

You begin by laying out the forms that will search through your files. (The sources for the application are included in a link at the end of this article.)

Next, the fun bit: adding the Visual Basic code. There are two main sections of code: the main form code and the extraction code that copies files from
your iPod to your hard drive. There are more than two thousand lines of code between these two files. For this article, we'll look only at the code that reads
the music database on your IPod and allows you to play back the tracks.

The main form code is called frmMain. There are nearly eleven hundred lines of code, so here are some highlights. The code opens with you declaring
your defaults:
VERSION 5.00
Object = "{5E9E78A0-531B-11CF-91F6-C2863C385E30}#1.0#0"; "MSFLXGRD.OCX"
Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx"
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "mscomctl.ocx"
Begin VB.Form frmMain
Caption = "SharePod 1.5"
ClientHeight = 6000
ClientLeft = 375
ClientTop = 765
ClientWidth = 9945
Icon = "frmMain.frx":0000
LinkTopic = "Form1"
ScaleHeight = 6000
ScaleWidth = 9945
StartUpPosition = 2 'CenterScreen
Begin VB.Timer tmrMenu
Enabled = 0 'False
Interval = 40
Left = 1920
Top = 120
End
Begin VB.Frame FilterFrame
Caption = "Filter"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
ForeColor = &H00800000&
Height = 855
Left = 2760
TabIndex = 3
Top = 120
Width = 7095
Begin VB.TextBox txtTitle
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 285
Left = 120
TabIndex = 7
Top = 480
Width = 1035
End
Begin VB.TextBox txtArtist
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 285
Left = 1200
TabIndex = 6
Top = 480
Width = 1035
End
Begin VB.TextBox txtAlbum
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 285
Left = 2280
TabIndex = 5
Top = 480
Width = 1035
End
Begin VB.TextBox txtGenre
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 285
Left = 3360
TabIndex = 4
Top = 480
Width = 1035
End
Begin VB.Label lblSongs
Caption = "Nbr songs"
BeginProperty Font
Name = "Tahoma"

2 of 5 3/2/2007 10:06 AM
Articles http://www.peachpit.com/articles/printerfriendly.asp?p=375499&rl=1

Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
ForeColor = &H00800000&
Height = 255
Left = 6000
TabIndex = 12
Top = 480
Width = 975
End
Begin VB.Label lblGenre
Caption = "Genre"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 3360
TabIndex = 11
Top = 240
Width = 735
End
Begin VB.Label lblAlbum
Caption = "Album"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 2280
TabIndex = 10
Top = 240
Width = 735
End
Begin VB.Label lblArtist
Caption = "Artist"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 1200
TabIndex = 9
Top = 240
Width = 735
End
Begin VB.Label lblTitle
Caption = "Title"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 120
TabIndex = 8
Top = 240
Width = 735
End
End
Begin MSComctlLib.ListView lstMusic
Height = 5295
Left = 120
TabIndex = 1
Top = 480
Width = 2595
_ExtentX = 4577
_ExtentY = 9340
View = 1
Arrange = 2
LabelEdit = 1
LabelWrap = -1 'True
HideSelection = 0 'False
FullRowSelect = -1 'True
_Version = 393217
Icons = "ImageList"
SmallIcons = "ImageList"
ForeColor = -2147483640
BackColor = -2147483643
BorderStyle = 1
Appearance = 1
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
NumItems = 0
End
Begin MSComDlg.CommonDialog dlg
Left = 1920
Top = 1800
_ExtentX = 847
_ExtentY = 847
_Version = 393216
End
Begin MSFlexGridLib.MSFlexGrid grdMusic
Height = 4695
Left = 2760
TabIndex = 0
Top = 1080
Width = 7215
_ExtentX = 12726
_ExtentY = 8281
_Version = 393216
Rows = 50
Cols = 7
FixedCols = 0
BackColorBkg = -2147483633
AllowBigSelection= 0 'False
ScrollTrack = -1 'True
FocusRect = 0
SelectionMode = 1
AllowUserResizing= 1
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
End
Begin MSComctlLib.ImageList ImageList
Left = 1920
Top = 720

3 of 5 3/2/2007 10:06 AM
Articles http://www.peachpit.com/articles/printerfriendly.asp?p=375499&rl=1

_ExtentX = 1005
_ExtentY = 1005
BackColor = -2147483643
ImageWidth = 16
ImageHeight = 16
MaskColor = 12632256
_Version = 393216
BeginProperty Images {2C247F25-8591-11D1-B16A-00C0F0283628}
NumListImages = 1
BeginProperty ListImage1 {2C247F27-8591-11D1-B16A-00C0F0283628}
Picture = "frmMain.frx":0ECA
Key = ""
EndProperty
EndProperty
End
Begin VB.Label Label2
Caption = "Playlists:"
BeginProperty Font
Name = "Tahoma"
Size = 8.25
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
ForeColor = &H00800000&
Height = 255
Left = 120
TabIndex = 2
Top = 120
Width = 735
End
Begin VB.Menu mnuExtractMenu
Caption = "ExtractMenu"
Visible = 0 'False
Begin VB.Menu mnuExtract
Caption = "Extract file(s)..."
End
Begin VB.Menu mnuExtractPlaylist
Caption = "Export to playlist..."
End
Begin VB.Menu mnuGoto
Caption = "Go to location..."
End
Begin VB.Menu mnuPlayFile
Caption = "Play file(s)..."
End
End
End

After the defaults are set, you can begin to examine the iTunes database installed on your iPod. The following function begins this process:
Public Sub loadiTunesDatabase()
On Error GoTo loaderr
Dim srcDrive As String, appPath As String
srcDrive = getSourceDrive(True)
Open srcDrive & "ipod_control\itunes\itunesdb" For Binary As #1
Dim offset As Long
Get #1, 209, nbrIPodSongs
ReDim iPodSongs(nbrIPodSongs)
offset = 293
Dim row As Long
row = 1
Dim x As Long
For x = 1 To nbrIPodSongs
If readSong(1, offset, row) = False Then 'finished reading song list
readPlaylists 1, offset
Exit For
End If
row = row + 1
Next
Close #1
loadOnTheGoPlayList
lstMusic.ListItems.Add , , "(All Songs)", , 1
For x = 0 To nbrIPodPlaylists - 1
lstMusic.ListItems.Add , , iPodPlaylists(x).title, , 1
Next
displayAllSongs
Me.MousePointer = vbNormal
Exit Sub
loaderr:
MsgBox "There was an error loading your iTunesDB file! Please make sure you are running SharePod from your iPod drive!" & vbCr & vbCr & "The error was: " & Err.Number & ", " & Err.Descr
End
End Sub

After you know where your files are, you can read them. The following code allows you to do this:
Private Function readSong(handle As Long, offset As Long, row As Long) As Boolean
Dim readWholeEntry As Boolean
Dim readWholeDB As Boolean
Dim entry As MHOD_ENTRY
Dim song As SONG_TYPE
Dim mhit As MHIT_ENTRY
readWholeEntry = False
readWholeDB = False
mhit = readMHitEntry(handle, offset)
While readWholeEntry = False And readWholeDB = False
entry = readMHodEntry(handle, offset)
If entry.Data = "-1" Then readWholeEntry = True
If entry.Data = "-2" Then
readWholeDB = True
End If
If entry.type = TYPE_SONG Then
song.title = entry.Data
ElseIf entry.type = TYPE_ARTIST Then
song.artist = entry.Data
ElseIf entry.type = TYPE_album Then
song.album = entry.Data
ElseIf entry.type = TYPE_GENRE Then
song.genre = entry.Data
ElseIf entry.type = TYPE_FILETYPE Then
song.fileType = entry.Data
ElseIf entry.type = TYPE_FILEPATH Then
song.filename = entry.Data
song.filename = Replace(song.filename, ":", "\")
ElseIf entry.type = TYPE_COMMENT Then
song.comment = entry.Data
End If
Wend
song.id = Trim(mhit.id)
iPodSongs(row - 1) = song
song.title = ""
song.artist = ""
song.album = ""
song.comment = ""
song.filename = ""
song.fileType = ""
song.genre = ""
readSong = Not readWholeDB
End Function

The data is sorted into ordered lists, such as album and title, so you can sort through your music more easily.

You can now select any song and right-click the mouse to select Play to hear the song in iTunes. This is the code that allows you to do this:
Private Sub mnuPlayFile_Click()

If grdMusic.row <> grdMusic.RowSel Then

writePlayList Environ("TEMP") & "\sharepod_temp.m3u"


ShellExecute hwnd, "open", Environ("TEMP") & "\sharepod_temp.m3u", vbNullString, "C:\", 1

Else
Dim filename As String
Dim srcDrive As String

srcDrive = getSourceDrive(False)

filename = srcDrive & grdMusic.TextMatrix(grdMusic.row, enmSongFileName)

4 of 5 3/2/2007 10:06 AM
Articles http://www.peachpit.com/articles/printerfriendly.asp?p=375499&rl=1

ShellExecute hwnd, "open", filename, vbNullString, "C:\", 1


End If

End Sub

" #

There are even more things you can do, and I encourage you to examine the code in more depth to give you a deeper understanding of what is going on
within your iPod.

Download the source code used for this article here.

As you can see from these examples, you can greatly extend the data and the way your iPod is used through your own code development. Check out the
many Open Source iTunes and iPod solutions at GotDotNet for working examples.

2006 Pearson Education, Inc. Informit. All rights reserved.


800 East 96th Street Indianapolis, Indiana 46240

5 of 5 3/2/2007 10:06 AM

You might also like