#!/usr/bin/perl BEGIN { $ENV{'PERL5LIB'} = '/var/www/perllib'; # HTML::Writer lives there use lib '/var/www/perllib'; # first do it wrong, then do it right ;-) } use HTML::Writer qw(xhtml1-transitional.dtd); #!/usr/bin/perl $|=1; use IO::All; use CGI; my $q = new CGI; # mpd host and port my $host = '192.168.10.2'; my $port = '6600'; # command to read cd toc $cdcmd = 'cdda2wav -J cddb=1 -cddbp-server=freedb.freedb.org -v title -q -g 2>&1'; my @js = qw( req.js utils.js ); my @css = qw( style.css ); if(my @p = $q->param) { print STDERR $_ .': '.$q->param($_)."\n" for @p; print $q->header; my $d = $q->param('d'); my $a = $q->param('action'); my $t = $q->param('t'); if($a eq 'play') { if($d eq 'mpd') { system 'cdplay','stop'; mpdc("play $t"); $t++; } else { mpdc('stop'); cdplay("play $t"); } print "playing ($d) title number $t"; } elsif($a eq 'stop') { mpdc('stop'); cdplay('stop'); print "Also guuut..."; } elsif($a eq 'eject') { eject(); print "refresh\nCD ausgeworfen.\n *** Bitte aufräumen ***"; } elsif($a eq 'load') { mpdc("load \"$t\""); print "refresh\nListe \"$t\" wurde hinzugefügt."; } elsif($a eq 'clear') { mpdc('clear'); print "refresh\nPlaylist wurde gelöscht."; } elsif($a eq 'volume') { mpdc("volume $t"); } } else { print $q->header; render { HTML { HEAD { TITLE { "The Musical Box"; }; for (@css) { LINK {href_"/css/$_";type_"text/css";rel_"stylesheet"} } for (@js) { SCRIPT { src_ "/js/$_"; type_ "text/javascript" } } }; BODY { H1 { "Musik!" }; DIV { A { id_ "stop"; onclick_ "sndReq('stop','all','0');"; "Stop";}; }; DIV { id_ "volume"; "Lautstärke: "; A { id_ "volup"; onclick_ "sndReq('volume','all','5');"; "Rauf";}; A { id_ "voldown"; onclick_ "sndReq('volume','all','-5');"; "Runter";}; }; DIV { class_ "cd"; H2 { "CD" }; if(my $r = cdtoc()) { DIV { A { id_ "eject"; onclick_ "sndReq('eject','cd','0');"; "Auswerfen";}; }; OL { for(@$r) { my ($n,$p) = split/:/; LI { A { id_ "cd_$n"; onclick_ "sndReq('play','cd',$n);"; $p; }; } } } } else { P { "keine CD eingelegt." }; } }; DIV { id_ "playlist"; H2 { "MPD Playliste" }; my $r = mpdc('playlist'); if($r) { DIV {A{id_"mpd_clear";onclick_"sndReq('clear','mpd',0)";"Löschen"}}; OL { for(@$r) { my ($n,$p) = split/:/; $n += 0; $p =~ s/.*\///; $p =~ s/_/ /g; $p =~ s/\.(mp3|ogg)$//; LI { A { id_ "mpd_$n"; onclick_ "sndReq('play','mpd',$n);"; $p; }; } } }; } else { P { "Playliste leer" }; } }; DIV { id_ "browselist"; H2 { "MPD Inhaltsverzeichnis" }; my $r = mpdc('lsinfo'); if($r) { OL { for(@$r) { if(/playlist: (.*)/) { my $l = $1; LI { A { onclick_ "sndReq('load','mpd','$l');"; $l } } } } } }; }; } } }; } # -----+ # subs | <-- lousy box, don't do that # -----+ sub mpdc { my $cmd = shift; my $c = io("$host:$port"); my $r = []; "$cmd\n" > $c; while($_ = $c->getline) { next if /OK MPD [\d\.]+$/; last if $_ =~/^OK$/; chop; push(@$r,$_); } $c->close; @$r ? $r : undef; } sub has_cd { my $has_cd = 1; open(CD,"cdda2wav -J -v titles -q 2>&1 |"); while() { undef $has_cd if /cooked: Read TOC : Input\/output error/; } $has_cd; } sub cdtoc { my $r = []; return unless has_cd(); open(CD,"$cdcmd |"); while() { if (/cooked: Read TOC : Input\/output error/) { 1 while ; last; } # print STDERR $_; # T01: title 'All Souls Night' from '' if(/T(\d+): title '(.*)' from '(.*)'/) { my($n,$t,$a) = ($1,$2,$3); $n += 0; $t =~ s/^'|'$//g; $t ||= '(unbekannt)'; print STDERR "found: $t\n"; push(@$r,"$n:$t"); } } close(CD); @$r ? $r : undef; } sub eject { return unless has_cd(); system "eject"; } sub cdplay { return unless has_cd(); system "cdplay $_[0]"; } __END__ #### function createRequestObject() { var ro; var browser = navigator.appName; if(browser == "Microsoft Internet Explorer"){ ro = new ActiveXObject("Microsoft.XMLHTTP"); }else{ ro = new XMLHttpRequest(); } return ro; } // var http = createRequestObject(); function sndReq(action,dev,title) { clearInterval(update) // alert('action='+action+', dev='+dev+', title='+title); http.open('get', '/musik?action='+action+'&d='+dev+'&t='+title); http.onreadystatechange = handleResponse; http.send(null); } function handleResponse() { if(http.readyState == 4){ update = window.setInterval("poll()", 1000); var response = http.responseText; if(response.indexOf('refresh') != -1) { var upd = new Array(); upd = response.split('\n'); if(upd[1]) alert(upd[1]); if(upd[2]) alert(upd[2]); //document.getElementById(update[0]).innerHTML = update[1]; document.location = document.location; // force reload; } else { if(response != '') alert(response); } } } function poll () { clearInterval(update) http.open('get', '/musik?action=currentsong'); http.onreadystatechange = highlightTitle; http.send(null); } function highlightTitle () { if(http.readyState == 4) { update = window.setInterval("poll()", 1000); var refresh; var response = http.responseText; if(response) { var l = response.split("\n"); var t = document.getElementsByTagName('a'); for (var i = 0; i