Traktor to Snarkatron!
Awhile back I gave a talk about The Snarkatron at Ignite SF. It’s a digital sign, installed facing the crowd at the DNA Lounge here in San Francisco. I DJ a number of nights there, and my recent transition from CD and Vinyl to Laptop/MP3 with M-Audio’s Xponent has given me many more chances to do things with the playlist that I create each night. The main reason why I bought the sign was to let the public know what songs we were playing, but we were never able to do this without typing in each song name. The holy grail of getting the song titles onto the Snarkatron, automaticaly, has never been fulfilled until now.
The trick here is that you connect Traktor to a local Icecast2 install, turn on audio broadcast (with no listeners) in Traktor, and then read XML off the Icecast2 install to extract which song is playing from Traktor. Traktor is very smart about the current song as well. It looks at the decks and crossfader to determine the current, live song, and forwards that to Icecast.
We can extract this and use it for our digital display!
The source for this dumb trick follows below…
(Sorry for the bad layout of this code; I have to fix our CSS file after the recent site upgrade)
#!/usr/bin/perl -w
#
#
# Pull the current song from my local icecast server and forward the
# song data to the snarkatron.
#
# Whatever you set the server name to in Traktor, it will be used as
# the ‘dj subtitle’ on the 2nd line of the display.
#
# J. Adams
#
#
use strict;
use LWP;
use XML::Simple;
use HTTP::Request::Common;
my $lastartist = “”;
my $lasttitle = “”;
while (1) {
# fetch icecast stats.
my $browser = LWP::UserAgent->new;
$browser->credentials(
‘localhost:8000′,
‘Icecast2 Server’,
‘admin’ => ‘XXXXXXXXXXX’
);
my $url = “http://XXXXXXXXXX:8000/admin/stats.xml”;
my $response = $browser->get($url);
die “Error: “, $response->header(‘WWW-Authenticate’) ||
‘Error accessing’,
“\n “, $response->status_line, “\n at $url\n Aborting”
unless $response->is_success;
# parse it
my $xs = new XML::Simple;
my $data = $xs->XMLin( $response->content );
# no source, means no connection to icecast!
if (defined($data->{source})) {
if (($lastartist ne $data->{source}->{artist}) &&
($lasttitle ne $data->{source}->{title}) ) {
print “Update…\n”;
print $data->{source}->{server_name} . “\n”;
print $data->{source}->{artist} . “\n”;
print $data->{source}->{title} . “\n”;
# update snarkatron
my $ua = LWP::UserAgent->new;
my $req = (POST ‘http://XXXXXXXXXXXX/addsong.cgi’,
["djname" => $data->{source}->{server_name},
"band" => $data->{source}->{artist},
"sngtitle" => $data->{source}->{title},
"Add" => "Add"
]);
my $postrequest = $ua->request($req);
my $postcontent = $postrequest->content;
}
$lastartist = $data->{source}->{artist};
$lasttitle = $data->{source}->{title};
} else {
print “WARNING: Traktor is not transmitting to Icecast! Enable the Broadcast! (sleeping for retry…)\n”;
}
# increase for production
sleep(5);
}