#!/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__