Getting current track information from VLC (using Perl!)
So I’ve already done a post on getting track information from Rythmbox, but VLC felt cold and left out, so here it is. The process is pretty much the same, just tweaked a bit for VLC.
First, go into VLC, Tools -> Preferences, click the “All” radio button (near the bottom), Interface, click “Main interfaces” and check “HTTP…”. If you’re feeling adventurous, choose “HTTP” from the list and you can specify port (default is 8080), address to listen on, etc.. I’m not doing all of that.
Now, restart VLC and crank up a stream or MP3. You should be able to navigate to http://localhost:8080/requests/status.xml and see an XML file representing the current track information.
If you are listening to an MP3, the “Artist” and “Title” fields should be populated. If you are streaming music, the artist and title will appear in the now_playing field as “Artist – Title”. I have no clue why this is. It just is.
Simple enough.. Here is my Perl script to grab the info, thrash it about, and do what we want with it. Simple stick it in cron to run every minute (or whatever) – */1 * * * * /home/myuser/scripts/tuneUpdater.pl
#!/usr/bin/perl
use XML::Simple;
use LWP::Simple;
use DBI;
my $date = `date +"%D %r"`;
chomp $date;
## URL to vlc status.xml file
my $url = "http://localhost:8080/requests/status.xml";
my $data = get($url);
## exit if VLC isn't running
if ($data eq "") {
exit(0);
}
## get the xml and read in the appropriate values
my $xs = XML::Simple->new(SuppressEmpty => 1);
my $root = $xs->XMLin($data);
my $information = $root->{'information'};
my $meta = $information->{'meta-information'};
## this is what we are after
my $title = $meta{'title'};
my $artist = $meta{'artist'};
## if the title or artist is blank, we must be streaming, so grab the
## now_playing field.
if (($title eq "") || ($artist eq "")) {
my $nowplaying = $meta->{'now_playing'};
($artist, $title) = split(/\ -\ /, $nowplaying);
}
## strip out Amped FM "Enhanced MP3" stuff.
$title =~ s/\ Enhanced\ MP3//;
## if we got this far safely, connect to the database.
$dbh = DBI->connect('DBI:mysql:mydb;host=somewebhost', 'luser', 'notreally')
|| die "Could not connect to database: $DBI::errstr";
my ($last_artist, $last_title) = &getLastSong();
## update the db if the artist or title differ from the last one updated.
if (($last_artist ne $artist) || ($last_title ne $title)) {
&updateLastSong($artist, $title);
}
$dbh->disconnect();
## update the database to add the current artist and title
sub updateLastSong {
my ($artist, $title) = @_;
$sql_update = "INSERT INTO music_history (id, title, artiist, played) VALUES (null, '$title', '$artist', '$date')";
$out_update = $dbh->prepare($sql_update);
$out_update->execute;
$out_update->finish;
}
## get the last artist and title played.
sub getLastSong {
$sql_last = "SELECT artiist, title FROM music_history order by id desc limit 1";
$out_last = $dbh->prepare($sql_last);
$out_last->execute;
my ($last_artist, $last_title) = $out_last->fetchrow_array;
$out_last->finish;
return ($last_artist, $last_title);
}
Feel free to contact me with any questions or comments!