#!/usr/bin/perl -wT # JAmpg123 scrobbler wrapper - andy white 20080614 # you are free to print this out and use it in place of TP $|=1; use MP3::Info qw(get_mp3info get_mp3tag); use Audio::Scrobbler; my ($pid, $data, $last, %colours, $dataok); my %keywordmap = qw(length secs); my @id_fields = qw/album title length artist playtime/; my @colours = qw(red green yellow blue magenta cyan white); for (0 .. $#colours) { $colour{$colours[$_]} = "\e[" . (31+$_) . 'm'; } my $scrob = new Audio::Scrobbler( cfg=>{ username => 'ilikebunnies', password => 'formydindins', progname=> 'roc', progver =>'0.1'} ); while (1) { $pid = get_player_id(); $data = get_media_file($pid); if (scalar keys %$data) { for (keys %$data) { $$data{lc($_)} = delete $$data{$_}; } for (keys(%keywordmap)) { $$data{$_} = delete $$data{$keywordmap{$_}}; } print "\n$colour{blue}Scrobbling$colour{white}... "; $$data{length} = int($$data{length}); $$data{playtime} = gmtime(); $data = { map { $_, $$data{$_} } @id_fields }; $dataok = 1; for (@id_fields) { $dataok = 0 unless length($$data{$_}||''); $$data{$_}||='*** MISSING ***'; print "'$colour{yellow}$_$colour{white}' =>" . " $colour{magenta}$$data{$_}$colour{white} "; } if ($dataok) { if ($scrob->handshake()) { if ($scrob->submit($data)) { print "$colour{green}Success$colour{white}!"; } else { print "$colour{red}Scrobbling error? " . $scrob->err() . $colour{white} } } else { print "$colour{red}Handshake failed, data not submitted: " . $scrob->err() . $colour{white}; } } else { print "$colour{red}Missing metadata: not submitted$colour{white}"; } } sleep(20); } sub get_player_id { my $pid =-1; opendir(D,'/proc'); for (grep /^\d+$/, readdir(D)) { open(C,"/proc/$_/cmdline"); $pid = $_ if ( ((split(/\0/,))[0] || '') =~ /^mpg[13]2[13]$/); close(C); } closedir(D); return $pid; } sub get_media_file { my $pid = shift; my $file = undef; return if $pid == -1; opendir(D,"/proc/$pid/fd"); for (grep /^\d+$/, readdir(D)) { next if $_ < 3; $file = $_ if (readlink "/proc/$pid/fd/$_") =~ /\.mp3/i; } closedir(D); $file = int($file||0) ? readlink "/proc/$pid/fd/$file" : ''; return unless length $file; return unless track_change("$pid-$file"); my %data = %{get_mp3info($file)}; %data = (%data, %{get_mp3tag($file)}); return \%data; } sub track_change { my $cur = shift; if ($cur ne ($last||'')) { $last = $cur; return 1; } return 0; }