December 29, 2004
iTunes and a “Now Playing” feature
[UPDATED - see below!]
Here’s some cool code I hacked together from the iTunes Windows COM SDK docs and some other sites - Dan Crevier’s Blog and ajc.
I had already posted how I did something like this in WinAmp, but I’ve been using iTunes a lot now and really like it. There are a few plugins and such out there to post the current track info to a file or site, but the main thing other scripts didn’t do was to post the stream info if iTunes was playing a stream.
Basically it’s some JavaScript that runs in the background listening for events from the iTunes applications. Currently I’m just using OnPlayerPlayEvent and OnQuittingEvent, but some of the other events might be cool to use. I just create a little XML and post it to the web server - this one’s real time, where my WinAmp one was polled.
I don’t know how good or efficient this code is, but it hasn’t crashed my box yet! I also am posting a simple cgi I hacked up in Perl to snag the bits of XML and output an HTML file that is included in my main page via SSI.
I just start iTunes, then run my script. When I exit iTunes, the JavaScript code exits as well - and it tells you it’s closing.
iTunes JavaScript code: (I think I got the html escaped - I need a better way to post code!)
var iTunesIsRunning = true;
function ITEventTest_OnPlayerPlayEvent(iTrack) {
getCurrentTrackInfo();
}
function ITEventTest_OnPlayerPlayingTrackChangedEvent(iTrack) {
getCurrentTrackInfo();
}
function ITEventTest_OnQuittingEvent() {
iTunesIsRunning = false;
}
function getCurrentTrackInfo() {
var current = iTunesApp.CurrentTrack;
var stream = iTunesApp.CurrentStreamTitle;
var trackType = "";
var trackName = "";
var trackArtist = "";
var trackAlbum = "";
if (stream != "") {
streamURL = iTunesApp.CurrentStreamURL;
trackType="stream";
trackName=stream;
trackArtist=current.Name;
trackAlbum=streamURL;
} else {
trackType="file";
trackName=current.Name;
trackArtist=current.Artist;
trackAlbum=current.Album;
}
var response = postTrack(trackType, trackName, trackArtist, trackAlbum);
}
function postTrack(trackType, trackName, trackArtist, trackAlbum) {
var xmlTrack = new ActiveXObject("MSXML2.DOMDocument.4.0");
xmlTrack.loadXML(’<?xml version="1.0" ?><track/>’);
var root = xmlTrack.documentElement;
root.setAttribute("type", trackType);
var textNode = xmlTrack.createElement("name");
textNode.text = trackName;
root.appendChild(textNode);
var textNode = xmlTrack.createElement("artist");
textNode.text = trackArtist;
root.appendChild(textNode);
var textNode = xmlTrack.createElement("album");
textNode.text = trackAlbum;
root.appendChild(textNode);
var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP.4.0");
xmlhttp.open("POST", "http://[cgi url]",false);
xmlhttp.send(xmlTrack);
if (xmlhttp.status != "200") {
WScript.Echo("Error posting to server. Code is: " + xmlhttp.status);
}
}
WScript.ConnectObject(iTunesApp, "ITEventTest_");
WScript.Echo("Waiting for changes…");
getCurrentTrackInfo();
while (iTunesIsRunning) {
WScript.Sleep(1000);
}
var response = postTrack("OFFLINE", "offline.", "", "");
WScript.DisconnectObject(iTunesApp);
WScript.Echo("iTunes was closed, iTunesListener exiting.");
Perl CGI on the server: (Beware: I’m not a great Perl coder!)
use XML::LibXML;
local $/;
my $parser = XML::LibXML->new();
my $request = <STDIN>;
my $xmlRequest = $parser->parse_string($request);
my $root = $xmlRequest->getDocumentElement;
my $type = $root->getAttribute("type");
my @nodes = $root->findnodes("name");
my $name = $nodes[0]->string_value();
@nodes = $root->findnodes("artist");
my $artist = $nodes[0]->string_value();
my @nodes = $root->findnodes("album");
my $album = $nodes[0]->string_value();
open(file,">[path writable by web server]/current_song.html");
print file $name;
print file "<br />";
print file $artist;
print file "<br />";
print file $album;
print file "\n";
close(file);
print "Content-type: text/html\n\n";
print "ok";
And the simple Server Side Include in my html:
Works for me and it’s pretty cool hack I think! I’m thinking about some other possiblities… If I can use iTunes to publish a stream, then I could have some playlist posting and even playlist manipulation - that could be cool.
Also I found a somewhat cool plugin for iTunes on Windows called “multi plugin”. I only really use the plugin for controlling iTunes with my laptop’s multimedia buttons when iTunes is minimized - iTunes should automatically do this like WinAmp did. I can’t figure out how to uninstall it though!
UPDATE:
Seems I deleted some code that is needed so that the getCurrentTrackInfo() function is called when listening to a stream. The “OnPlayerPlayEvent” event is not called when the track a stream is playing changes. You need to trap for “OnPlayerPlayingTrackChangedEvent”, so just add this:
getCurrentTrackInfo();
}
I’ve updated my code above to reflect this. The full title of the stream sometimes isn’t present when you first connect - just reconnect if that bothers you.
Also, I need to add some more error trapping too. The script crashes if you start the script and iTunes isn’t playing anything - at least this happens to me!
Enjoy!

This is perfect. I was going to work on getting my iTunes info up on my blog this week since we just got back to Tucson last night. I even had those “other” plugins bookmarked, but I like the hacked way much better. Thanks!
Merry Christmas to you and Jen.
Glad you liked it. And I’m finally glad to get a comment that’s not spam! Merry Christmas to you and Jenny too!
Hi,
I have been reading your posting about the Itunes SDK for Windows with interest.
Indeed, I would like to create a simple HTML interface to Itunes so I can remotely command Itunes from a pocket PC device within my appartment (list playlists, play, stop play list, next track…)
Programming wise, I can easily find my way with HTML, ASP, VBscript, web servers configuration but I have never used PERL or developped dll using C and a COM interface of some sort.
>From everything I have been reading about the Itunes SDK, there is nothing available that I could resuse into a VBscript. It seems that I need to either learn about perl or dig into some souvenirs or C programming and figure out how to create a dll, register it and then use it into an ASP page.
Any suggestion of an easier path would be appreciated.
Thanks in advance for your answer and Happy New Year.
Regards
Sylvain