Just to enhance your interface a bit...
I have this one running on a linux box for some years. Plays mp3s via The Music Player Daemon, handles audio CDROMs and runs as a plain CGI with hand-crufted AJAX stuff. I did this before knowing about CGI::Ajax ;-)
Ah, and the rationale was that mpd clients for Windows were very unstable at that time, and mpd didn't handle audio CDs (at that time; does it now?). Don't beat me too much, it's a hack, but heck, it does its job.
CGI script:
#!/usr/bin/perl BEGIN { $ENV{'PERL5LIB'} = '/var/www/perllib'; # HTML::Writer lives there use lib '/var/www/perllib'; # first do it wrong, then d +o 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_"stylesh +eet"} } for (@js) { SCRIPT { src_ "/js/$_"; type_ "text/javascript" } + } }; BODY { H1 { "Musik!" }; DIV { A { id_ "stop"; onclick_ "sndReq('stop','all','0');"; "S +top";}; }; DIV { id_ "volume"; "Lautstärke: "; A { id_ "volup"; onclick_ "sndReq('volume','all','5');"; "Ra +uf";}; 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(<CD>) { undef $has_cd if /cooked: Read TOC : Input\/output error/; } $has_cd; } sub cdtoc { my $r = []; return unless has_cd(); open(CD,"$cdcmd |"); while(<CD>) { if (/cooked: Read TOC : Input\/output error/) { 1 while <CD>; 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__
req.js:
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<l.length; i++) { if(l[i] == 'refresh') { refresh = 1; } else { var n = l[i].split('_'); var m = n[0]; if(l[i]) { // alert(l[i]); for (var j = 0; j<t.length; j++) { var id = t[j].id; if(id) { if (id.indexOf(m) != -1) { if(id == l[i]) { t[j].style.color = '#f00'; } else { t[j].style.color = '#00f'; } } } } } } } if(refresh) document.location = document.location; } } }
HTML::Writer is here at PerlMonks. There are some bits of german in this cgi script, but they should be clear from context - and there's babelfish, also... ;-P
Have fun.
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
In reply to Re: Sharing Sound card / Remote Media PC.
by shmem
in thread Sharing Sound card / Remote Media PC.
by SkipHuffman
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |