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