[BACK]Return to playmp3s.pl CVS log [TXT][DIR] Up to [local] / mp3 / daemon

Annotation of mp3/daemon/playmp3s.pl, Revision 1.9

1.1       andrew      1: #!/usr/bin/perl
1.9     ! andrew      2: # $AFresh1$
1.1       andrew      3: ########################################################################
                      4: # PlayMP3.pl *** play's MP3s off a playlist using mp3play
                      5: #
                      6: # 04-14-00
                      7: # Written by andrew fresh <andrew@mad-techies.org>
                      8: ########################################################################
                      9:
                     10: use strict;
                     11: use warnings;
                     12: use diagnostics;
                     13:
                     14: use vars qw/ %cfgs /;
                     15:
                     16: my $config_file = shift || "/etc/playmp3s.conf";
                     17:
1.3       andrew     18: my %cfgs = readconfig($config_file);
                     19:
1.1       andrew     20: my $err_log = $cfgs{errors} || "/var/log/playmp3s.log";
                     21:
1.6       andrew     22: my $Num_History = 0;
1.4       andrew     23:
1.1       andrew     24: Print_PlayLog("Beginning playtime\n\n");
                     25:
                     26: my %Full_Playlist;
                     27: $Full_Playlist{last_mod} = 0;
                     28: my $playlist_last_mod = 0;
                     29:
                     30: my @playlist;
                     31:
1.9     ! andrew     32: my $playing = '';
1.8       andrew     33: for ( ;; ) {
                     34:
                     35:     #   while(1) {
                     36:     my $save_playlist;
                     37:
1.9     ! andrew     38:     if ( $cfgs{pausedfile} && -e $cfgs{pausedfile} ) {
        !            39:         Print_PlayLog("Paused\n");
        !            40:         DisplayPlaying( $cfgs{currenthtml}, "Paused" )
        !            41:             unless $playing eq 'paused';
        !            42:         $playing = 'paused';
        !            43:         sleep 10;
        !            44:         next;
        !            45:     }
        !            46:
1.8       andrew     47:     my ($last_mod) = ( stat( $cfgs{list} ) )[9];
                     48:     if ( $playlist_last_mod != $last_mod ) {
                     49:         @playlist          = ();
                     50:         $playlist_last_mod = $last_mod;
                     51:     }
                     52:
                     53:     while ( !@playlist ) {
                     54:         Print_PlayLog("Getting Playlist . . .\n");
                     55:
                     56:         #              bail("getting playlist");
                     57:         @playlist = get_playlist( $cfgs{list} );
                     58:         unless (@playlist) {
                     59:
                     60:             #                  bail("getting full playlist");
                     61:             @playlist = get_full_playlist( $cfgs{fulllist} );
                     62:
                     63:             Print_PlayLog("Got full playlist\n");
                     64:             $save_playlist = 0;
                     65:         }
                     66:         else {
                     67:             Print_PlayLog("Got normal playlist\n");
                     68:             $save_playlist = 1;
                     69:         }
                     70:         unless (@playlist) { sleep 10; }
                     71:     }
                     72:     Print_PlayLog("Got playlist\n");
                     73:
                     74:     Print_PlayLog("getting song to play . . .\n");
                     75:     my $song = int rand( scalar(@playlist) );
                     76:     my $filename = splice( @playlist, $song, 1 );
                     77:     Print_PlayLog("\tGot $song - filename is\n\t$filename\n");
                     78:
                     79:     Print_PlayLog("displaying file that is playing . . . ");
                     80:     DisplayPlaying( $cfgs{currenthtml}, $filename );
1.9     ! andrew     81:     $playing = $filename;
1.8       andrew     82:     Print_PlayLog("done\n");
                     83:
                     84:     Print_PlayLog("Adding Last. . .");
                     85:     AddLast(
                     86:         $filename,         $cfgs{playedlist}, $Num_History,
                     87:         $cfgs{playedhtml}, $cfgs{addurl}
                     88:     );
                     89:     Print_PlayLog("done\n");
                     90:
                     91:     if ($save_playlist) {
                     92:         Print_PlayLog("Saving Playlist. . .");
                     93:         save_playlist( $cfgs{list}, @playlist )
                     94:             || bail("Unable to save playlist!: $!");
                     95:         Print_PlayLog("done\n");
                     96:     }
                     97:
                     98:     Print_PlayLog("Playing: $filename . . .\n");
                     99:
                    100:     my $player;
                    101:     my $play = "$cfgs{basedir}$filename";
                    102:     if ( defined $filename && $filename =~ /\.mp3$/i ) {
                    103:         $player = $cfgs{mp3play};
                    104:     }
                    105:     elsif ( $filename =~ /\.ogg$/i ) {
                    106:         $player = $cfgs{oggplay};
                    107:
                    108:         #$play =~ s/(\(|\)|&|"|'| |-)/\\$1/g;
                    109:     }
                    110:
                    111:     if ( not $player =~ s/\{\}/"$play"/g ) {
                    112:         $player .= ' "' . $play . '"';
                    113:     }
                    114:     Print_PlayLog("$player\n");
                    115:     `$player`;
                    116:
                    117:     #  my $kid = 0;
                    118:     #    while ($kid ne -1 && ContinueRun()) {
                    119:     #     while ($kid ne -1) {
                    120:     #          print "waiting to end . . . ";
                    121:     #        my $kid = waitpid(-1,&WNOHANG);
                    122:     #       print "done.\n";
                    123:     #    }
                    124:
                    125:     Print_PlayLog("Displaying Nothing . . .");
                    126:     DisplayPlaying( $cfgs{currenthtml}, "Nothing" );
1.9     ! andrew    127:     $playing = 'nothing';
1.8       andrew    128:     Print_PlayLog("done\n");
                    129:
                    130:     #@playlist = ();
                    131:
                    132:     sleep 1;
1.1       andrew    133: }
                    134:
1.8       andrew    135: sub Install {
1.1       andrew    136:
                    137:     # add your additional install messages or functions here
                    138:     print "\nThank you for installing this file\n";
                    139: }
                    140:
                    141: sub Remove {
1.8       andrew    142:
1.1       andrew    143:     # add your additional remove messages or functions here
                    144:     print "\nSorry you had to leave\n";
                    145: }
                    146:
                    147: sub Help {
1.8       andrew    148:
1.1       andrew    149:     # add your additional help messages or functions here
                    150:     print "\nYou don't really need help do you??\n";
                    151: }
                    152:
                    153: #########################################################################
                    154: # GetTime
                    155: sub GetTime {
1.8       andrew    156:     my $hours = shift || 0;
                    157:     my ( $sec, $min, $hour, $mday, $mon, $year,,, )
                    158:         = localtime( time - ( 3600 * $hours ) );    # 86400 seconds is one day
                    159:
                    160:     if ( $min < 10 )  { $min  = "0$min" }
                    161:     if ( $sec < 10 )  { $sec  = "0$sec" }
                    162:     if ( $hour < 10 ) { $hour = "0$hour" }
                    163:     if ( $mday < 10 ) { $mday = "0$mday" }
                    164:     if ( $mon < 10 )  { $mon  = "0$mon" }
                    165:
                    166:     my $time
                    167:         = ( $year + 1900 ) . '-'
                    168:         . ++$mon . '-'
                    169:         . $mday . ' '
                    170:         . $hour . ':'
                    171:         . $min . ':'
                    172:         . $sec;
                    173:     return $time;
1.1       andrew    174: }
                    175: #########################################################################
                    176:
                    177: #######################################################################
                    178: # read in the Playlist
                    179: sub get_full_playlist {
1.8       andrew    180:     my $FILE = shift;
                    181:     my ($last_mod) = ( stat($FILE) )[9];
1.1       andrew    182:
1.8       andrew    183:     if ( $Full_Playlist{last_mod} != $last_mod ) {
                    184:         my @list;
                    185:         @list = get_playlist($FILE);
                    186:
                    187:         @list = grep !m#$cfgs{skipregex}#io, @list;
                    188:
                    189:         my @played_list = get_playlist( $cfgs{playedlist} );
                    190:
                    191:         my %played;
                    192:         @played{@played_list} = ();
                    193:
                    194:         delete $Full_Playlist{list};
                    195:
                    196:         my $list_size = 0;
                    197:         foreach my $song (@list) {
                    198:             $list_size++;
                    199:             $Full_Playlist{list}{$song} = 1
                    200:                 unless ( exists $played{$song} );
                    201:         }
                    202:         my $history = int $list_size * 0.1;
                    203:         if ($history) {
                    204:             Print_PlayLog("New history is $history\n");
                    205:             $Num_History = $history;
                    206:         }
1.1       andrew    207:
1.8       andrew    208:         $Full_Playlist{last_mod} = $last_mod;
                    209:     }
1.1       andrew    210:
1.8       andrew    211:     return keys %{ $Full_Playlist{list} };
1.1       andrew    212: }
                    213: #######################################################################
                    214:
                    215: #######################################################################
                    216: # read in the Playlist
                    217: sub get_playlist {
1.8       andrew    218:     my $FILE = shift;
                    219:     my @lines;
1.1       andrew    220:
1.8       andrew    221:     #  open PLAYlistLOG, ">c:/ps/playlistlog.txt";
1.1       andrew    222:
1.8       andrew    223:     #   print PLAYlistLOG "Getting Playlist from file: $FILE\n";
                    224:     #  close PLAYlistLOG;
                    225:     if ( -e $FILE ) {
                    226:         open( FILE, $FILE ) || bail("Couldn't open $FILE: $!");
                    227:         chomp( @lines = <FILE> );
                    228:         close(FILE) || bail("Couldn't close $FILE: $!");
                    229:     }
                    230:     else {
                    231:         open( FILE, ">$FILE" ) || return @lines;
                    232:         close(FILE) || bail("Couldn't close $FILE: $!");
                    233:         return @lines;
                    234:     }
                    235:     return @lines;
                    236: }
1.1       andrew    237:
                    238: #######################################################################
                    239: # writes back the new playlist
                    240: sub save_playlist {
1.8       andrew    241:     my $FILE  = shift;
                    242:     my @lines = @_;
                    243:     open( FILE, ">$FILE" )
                    244:         || bail("Couldn\'t open playlist to save $FILE: $!");
                    245:     foreach (@lines) {
                    246:         print FILE "$_\n";
                    247:     }
                    248:     close(FILE) || bail("Couldn't close $FILE: $!");
                    249:     return 1;
1.1       andrew    250: }
                    251:
                    252: #######################################################################
                    253: # Prints a webpage with the currently playing song
                    254: sub DisplayPlaying {
1.8       andrew    255:
                    256:     my $htmlfile = shift;
                    257:     my $playing  = shift;
                    258:
                    259:     open BLANK, ">$htmlfile" or bail("Unable to open $htmlfile: $!");
                    260:     print BLANK "<html>\n<head>\n\t<title>' . $playing . '</title>\n";
                    261:     print BLANK "<meta HTTP-EQUIV=\"REFRESH\" CONTENT=\"5\">\n";
                    262:     print BLANK "<meta HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n";
                    263:     print BLANK "</head>\n";
                    264:     print BLANK '<body leftmargin="0"  topmargin="0" ',
                    265:         'marginwidth="0" marginheight="0">', "\n\n";
                    266:     print BLANK
                    267:         "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n";
                    268:     print BLANK "  <tr>\n";
                    269:     print BLANK
                    270:         "    <td align=\"left\"><b><i>Currently playing:</i> $playing</b></td>\n";
                    271:     print BLANK "    <td align=\"right\">Started at: "
                    272:         . GetTime()
                    273:         . "</td>\n";
                    274:     print BLANK "  </tr>\n";
                    275:     print BLANK "</table>\n";
1.1       andrew    276:
                    277: #      print BLANK "<center><b>Currently playing: $playing</b><br>\nStarted at: " . GetTime() . "</center>";
                    278:
1.8       andrew    279:     print BLANK "</body>\n</head>\n</html>\n";
                    280:     close BLANK || bail("Unable to close BLANK: $!");
1.1       andrew    281: }
                    282:
                    283: #######################################################################
                    284: # Prints a webpage with the previously played song
1.6       andrew    285: # AddLast($filename, $cfgs{playedlist}, $Num_History, $cfgs{playedhtml}, $cfgs{addurl});
1.1       andrew    286: sub AddLast {
1.8       andrew    287:     my $lastsong = shift;
                    288:     my $lastlist = shift;
                    289:     my $history  = shift;
                    290:     my $htmlfile = shift;
                    291:     my $addurl   = shift;
                    292:
                    293:     my @LIST = get_playlist($lastlist);
                    294:
                    295:     DisplayPrevious( $htmlfile, $addurl, @LIST ) if $htmlfile;
                    296:
                    297:     unshift @LIST, $lastsong;
                    298:     splice( @LIST, $history ) if $history;
                    299:     save_playlist( $lastlist, @LIST );
1.7       andrew    300:
1.8       andrew    301:     # Remove song from full list so we don't play it again.
                    302:     delete $Full_Playlist{list}{$lastsong};
1.1       andrew    303: }
                    304:
                    305: #######################################################################
                    306: # Prints a webpage with the previously played song
                    307: sub DisplayPrevious {
                    308:
1.8       andrew    309:     my $htmlfile = shift;
                    310:     my $addurl   = shift;
                    311:     my $lastplay = shift;
                    312:     my @played   = @_;
                    313:     open BLANK, ">$htmlfile" or bail("Unable to open $htmlfile: $!");
                    314:     print BLANK "<html>\n<head>\n\t<title>' . $lastplay . '</title>\n";
                    315:     print BLANK "<meta HTTP-EQUIV=\"REFRESH\" CONTENT=\"30\">\n";
                    316:     print BLANK "<meta HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n";
                    317:     print BLANK "<body>\n\n";
                    318:
                    319:     print BLANK "<p>[ <a href=\"bin/ShowFiles.pl\">Beginning</a> | \n";
                    320:     print BLANK "<a href=\"bin/ShowAll.pl\">All MP3's</a> |\n";
                    321:     print BLANK "<a href=\"bin/ShowPlaylist.pl\">Playlist</a> |\n";
                    322:     print BLANK "<a href=\"ShowPlaylist.pl?newlist.lst\">New Files</a> |\n";
                    323:     print BLANK "<a href=\"played.htm\">Previously played</a> ]<p>\n";
                    324:
                    325:     print BLANK "<center><b>Last played: <a href=\"$addurl\?"
                    326:         . EncodeURL("$lastplay")
                    327:         . "\" target=\"bottom\">$lastplay</a></b><br>\nStarted at: "
                    328:         . GetTime()
                    329:         . "</center><p>\n";
                    330:
                    331:     print BLANK "before that:<br>\n";
                    332:
                    333:     print BLANK "<UL>\n";
                    334:
                    335:     foreach my $song (@played) {
                    336:         print BLANK "\t<li>Song: <a href=\"$addurl\?"
                    337:             . EncodeURL("$song")
                    338:             . "\" target=\"bottom\">$song</a></li>\n";
                    339:     }
1.1       andrew    340:
1.8       andrew    341:     print BLANK "</UL>\n";
1.1       andrew    342:
1.8       andrew    343:     print BLANK "</body>\n</head>\n</html>\n";
                    344:     close BLANK || bail("Unable to close played.htm: $!");
1.1       andrew    345: }
                    346:
                    347: ########################################################################
                    348: # *** EncodeURL: %encodes the parameters of the URL
                    349: sub EncodeURL {
1.8       andrew    350:     my $strURL = shift;
                    351:     $strURL =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
                    352:     return $strURL;
1.1       andrew    353: }
                    354:
                    355: ########################################################################
                    356: # read in config file.
                    357: sub readconfig {
1.8       andrew    358:     my $CONFIG = shift;
                    359:     my $delimter = shift || '=';
                    360:     my %configs;
                    361:     if ( -e $CONFIG ) {
                    362:         open( CONFIG, $CONFIG ) or bail("Couldn\'t open $CONFIG: $!");
                    363:         while (<CONFIG>) {
                    364:             chomp;       # no newline
                    365:             s/#.*//;     # no comments
                    366:             s/^\s+//;    # no leading  white space
                    367:             s/\s+$//;    # no trailing white space
                    368:             next unless length;    # anything left?
                    369:             my ( $var, $value ) = split( /\s*$delimter\s*/, $_, 2 );
                    370:
                    371:  #                     $var   =~ tr/A-Za-z0-9_\.\,\/\\ / /cd;  # delete all the non alphanumerics
                    372:  #                     $value =~ tr/A-Za-z0-9_\/\.\,\\ / /cd;  # delete all the non alphanumerics
                    373:             $var   =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
                    374:             $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
                    375:             $configs{$var} = $value;
                    376:         }
                    377:         close CONFIG or bail("Couldn't close $CONFIG: $!");
                    378:     }
                    379:     else {
                    380:         print '<!-- No config file: ' . $CONFIG;
                    381:         print ' -->';
                    382:         print "\n";
                    383:     }
                    384:     return %configs;
1.1       andrew    385: }
                    386: ########################################################################
                    387:
1.8       andrew    388: #sub ForkMP3Player { # This forks the MP3 player.
1.1       andrew    389: ##     KillPlaying(0);
1.8       andrew    390: #
1.1       andrew    391: #      my $player = shift;
                    392: #      my $song = shift;
                    393: #
                    394: #      $player =! s/%%f%%/\"$song\"/ig;
                    395: #
1.8       andrew    396: #
1.1       andrew    397: #      FORK: {
                    398: #              if ($Mp3Playerpid = fork) {
                    399: #                      # parent here
                    400: ##                     print "\nMp3Playerpid: ", $Mp3Playerpid;
                    401: #                      # child process pid is available in $pid
                    402: #                      print "Parent PID: $Mp3Playerpid\n";
                    403: #              } elsif (defined $Mp3Playerpid) { # $pid is zero here if defined
                    404: #                      # child here
                    405: #                      print "\nPlaying $song\n";
                    406: ##                     exec("$configs{mp3play} -b 16384 --reopen --aggressive -m \"$song\"");
                    407: #                      print "\n";
                    408: ##                     exec("$player \"$song\"");
                    409: #                      exec("$player");
                    410: #                      exit(0);
                    411: #                      # parent process pid is available with getppid
1.8       andrew    412: #              } elsif ($! =~ /No more process/) {
1.1       andrew    413: #                      # EAGAIN, supposedly recoverable fork error
                    414: #                      sleep 5;
                    415: #                      redo FORK;
                    416: #              } else {
                    417: #                      # weird fork error
                    418: #                      bail("\nCan't fork: $!");
                    419: #              }
                    420: #      }
                    421: #}
                    422:
1.8       andrew    423: #######################################################################
                    424: # Bail: this subrouting dies and displays the error to the browser.
                    425: # gotten from the example in the O'Reilly
                    426: # _Learning_Perl_on_Win32_Systems_
                    427: sub bail {
                    428:     open ERR, '>>$err_log';
                    429:
                    430:     #  open ERR, ">>c:/ps/error.txt";
1.1       andrew    431:
1.8       andrew    432:     my $error = "@_";
                    433:     print "Unexpected Error: $error\n";
                    434:     print ERR "Unexpected Error: $error\n";
                    435:     close ERR;
1.1       andrew    436:
1.8       andrew    437:     #  exit;
                    438: }
1.1       andrew    439:
1.8       andrew    440: sub Print_PlayLog {
                    441:     open PLAYLOG, ">>/tmp/playlog" or bail("Unable to open PLAYLOG");
                    442:     print GetTime(), "\t", @_;
                    443:     print PLAYLOG GetTime(), "\t", @_;
                    444:     close PLAYLOG;
1.1       andrew    445: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>