Brethern --
I have been waiting for quite some time for an API into iTunes so that I could control it from my keyboard or X10 remote controls and they released an SDK awhile back that I just discovered.
I know that you Mac users have Mac::iTunes but Windows users can now control iTunes natively.
James Craig has done some excellent work with the SDK and I borrowed the "SearchiTunesWinForSong" routine from him.
I am going to come up with a more complete library of functions as time allows but wanted to get this out so folks know that they can start hacking away at iTunes.
Enjoy,
mdog
use Win32::OLE;
Win32::OLE->Option(Warn => \&OLEError);
#find and start a playlist
my $playlistHandle = GetPlaylistFromSource("Matt","Library");
$playlistHandle->PlayFirstTrack();
# find and rate a song
my $trackHandle = SearchiTunesWinForSong(
artist => "10,000 Maniacs",
title => "Candy Everybody Wants",
location => "F:\\backup1\\mp3\\10,000 Mani
+acs - Candy Everybody Wants.mp3"
);
#various methods and objects are case insenstive
my $status = $trackHandle->{RATing} = 80;
print $trackHandle->{rAting} . "\n";
print $trackHandle->Rating . "\n";
# get the current song playing
print GetCurrentlyPlayingSong() . "\n";
sub OLEError {
print (Win32::OLE->LastError() . "\n");
}
# you can this more directly if you reference the source and playlist
+directly
# but I prefer to have case insensitivity and partial source / playlis
+t naming available
sub GetPlaylistFromSource{
my($desiredPlaylist,$desiredSource) = @_;
my ($iTunes) = new Win32::OLE( "iTunes.Application");
my $sources = $iTunes->Sources;
my $count = $sources->{"Count"};
my $foundPlaylist;
# loop through all the sources: be it library, radio, ipod, etc
for(my $i = 1; $i <= $count; $i++){
my $source = $sources->Item($i);
my $sourceName = $source->{"name"};
# found the source
if($sourceName =~ /$desiredSource/i){
#print "$sourceName\n";
my $playlists = $source->Playlists;
my $playlistCount = $playlists->Count;
# now loop through all the playlist on that device / drive
for(my $i = 1; $i <= $playlistCount; $i++){
my $playlist = $playlists->Item($i);
my $playlistName = $playlist->{"name"};
if($playlistName =~ /$desiredPlaylist/i){
#print "\t$playlistName\n";
$foundPlaylist = 1;
return $playlist;
}
}
}
}
if(! $foundPlaylist){
print "Did not find desired playlist\n";
exit;
}
}
sub GetCurrentlyPlayingSong{
my ($iTunes) = new Win32::OLE( "iTunes.Application");
# find out what the current track playing is
my $currentTrack = $iTunes->CurrentTrack;
my $location = $currentTrack->Location;
my $filename = $location;
$filename =~ s/^.*\\//gis;
return $filename;
}
sub SearchiTunesWinForSong{
my %searchTerms=@_;
my $IITrackKindFile = 1;
my $ITPlaylistSearchFieldVisible = 1;
my $status;
my ($iTunes) = new Win32::OLE( "iTunes.Application");
# don't bother unless we have a location and at least one of title
+/artist/album
return 0 unless $searchTerms{location} and ($searchTerms{title} or
+ $searchTerms{artist} or $searchTerms{album});
# reverse the slashes in case SlimServer is running on UNIX
#$searchTerms{location} =~ s/\//\\/g;
#replace \\ with \ - not consistent within iTunes (not in my libra
+ry at least)
#$searchTerms{location} =~ s/\\\\/\\/;
my $mainLibrary = $iTunes->LibraryPlaylist;
my $tracks = $mainLibrary->Tracks;
#now find it
my $searchString = "";
if ($searchTerms{artist}) {
$searchString .= "$searchTerms{artist} ";
}
if ($searchTerms{album}) {
$searchString .= "$searchTerms{album} ";
}
if ($searchTerms{title}) {
$searchString .= "$searchTerms{title}";
}
#print( "Searching iTunes for *$searchString*\n");
my $trackCollection = $mainLibrary->Search($searchString,
$ITPlaylistSearchFieldVisible);
if ($trackCollection)
{
#print("Found ",$trackCollection->Count," track(s) in iTunes\n
+");
#print("Checking for: *$searchTerms{location}*\n");
for (my $j = 1; $j <= $trackCollection->Count ; $j++) {
#change double \\ to \
my $iTunesLoc = $trackCollection->Item($j)->Location;
$iTunesLoc =~ s/\\\\/\\/;
#watch out for blank space in iTunes (where did these come
+ from?)
my $iTunesName = $trackCollection->Item($j)->Name;
$iTunesName =~ s/\s*$//;
my $iTunesArtist = $trackCollection->Item($j)->Artist;
$iTunesArtist =~ s/\s*$//;
my $iTunesAlbum = $trackCollection->Item($j)->Album;
$iTunesAlbum =~ s/\s*$//;
# escape all problem characters for search coming up
my $searchLocation = $searchTerms{location};
$searchLocation =~ s/(\W)/\\$1/g;
#check the name, location and type
if ($trackCollection->Item($j)->Kind == $IITrackKindFile
and (!$searchTerms{title} or $searchTerms{title} eq
+$iTunesName)
and (!$searchTerms{album} or $searchTerms{album} eq
+$iTunesAlbum)
and (!$searchTerms{artist} or $searchTerms{artist} eq
+$iTunesArtist)
#and ($searchTerms{location} eq $iTunesLoc)
and ($iTunesLoc =~ m|$searchLocation$|)
)
{
#we have the file (hopefully)
#print("Found track in iTunes\n");
return $trackCollection->Item($j);
}
else {
#print("$j - False match: *$iTunesLoc*\n");
}
}
}
return 0;
}
READMORE tags added by Arunbear