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

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

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

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