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