0: #!/usr/bin/perl -w
1: # I have no idea if it will display ok on unusual term size.
2: # There are a few functions not implemented yet. Playlists
3: # can not be saved/loaded, and songs cannot me added. Instead
4: # cursebox will recursively parse the dir it is started in
5: # and find all *.mp3 files. It will consider them to be mp3
6: # files no matter what. It will not follow sym links.
7: # There are no safeguards despite forks, etc, so it is not
8: # gauranteed to work properly (although it seems to). It is
9: # after all v0.9.
10: # cursebox requires the following:
11: # -- ncurses
12: # -- CPAN Curses module
13: # -- A term capable of color
14: # Sorry for the ugly and messy code... =)
15:
16: use Curses;
17: $SIG{CHLD} = 'IGNORE';
18:
19: # CURSES INIT
20: initscr;
21: start_color;
22: noecho;
23: halfdelay(1);
24: nl();
25: intrflush(stdscr, 0);
26: keypad(stdscr, 1);
27: init_pair(1,1,0);
28: init_pair(2,2,0);
29: init_pair(3,3,0);
30: init_pair(5,5,0);
31:
32: # CURSEBOX INIT
33: $mark = -1;
34: $centersongnr = 0;
35: $randplay = 0;
36: $pid=0;
37: $playingon = 0;
38: $playno = 0;
39: $mode = "play"; # play, help, add, ver
40: $pwd=`pwd`;
41: chop($pwd);
42: &parsedir($pwd);
43: &refreshmid;
44: &setup;
45:
46: # MAIN
47: &loop;
48: exit(1);
49:
50: sub parsedir {
51: my $pwd=$_[0];
52: chdir($pwd);
53: opendir(DIR, $pwd);
54: my @files=readdir(DIR);
55: closedir(DIR);
56: foreach (@files) {
57: unless ( $_ =~ m/^\.$/ || $_ =~ m/^\.\.$/ ) {
58: if ( -d $_ && !-l $_ ) {
59: $npwd="$pwd/$_";
60: parsedir($npwd);
61: chdir("..");
62: } else {
63: if ( $_ =~ m/\.mp3$/i ) {
64: $mp3s[$#mp3s+1]="$pwd/$_";
65: }
66: }
67: }
68: }
69: }
70:
71: sub loop {
72: while ( 1 ) {
73: $char = getch();
74: unless ($char eq "-1") {
75: &interpret;
76: }
77: unless ( kill 0 => $pid ) {
78: if ($playingon) {
79: if ( $randplay ) {
80: &playrand;
81: } else {
82: &skip;
83: }
84: }
85: }
86: }
87: }
88:
89: sub interpret {
90: SWITCH: {
91: if ( $mode eq "help" ) { &interprethelp ; last SWITCH;}
92: if ( $mode eq "play" ) { &interpretplay ; last SWITCH;}
93: if ( $mode eq "cred" ) { &interpretcred ; last SWITCH;}
94: }
95: }
96:
97: sub interpretcred {
98: SWITCH: {
99: if ( $char eq "c" ) { &setmode("play") ; last SWITCH; }
100: &invalid;
101: }
102: }
103:
104: sub interprethelp {
105: SWITCH: {
106: if ( $char eq "h" ) { &setmode("play") ; last SWITCH; }
107: &invalid;
108: }
109: }
110:
111: sub interpretplay {
112: SWITCH: {
113: if ( $char eq "n" ) { &skip ; last SWITCH; }
114: if ( $char eq "m" ) { &movesong ; last SWITCH; }
115: if ( $char eq "b" ) { &back ; last SWITCH; }
116: if ( $char eq "r" ) { &rand ; last SWITCH; }
117: if ( $char eq "c" ) { &setmode("cred") ; last SWITCH; }
118: if ( $char eq "s" ) { &stop ; last SWITCH; }
119: if ( $char eq "p" ) { &play ; last SWITCH; }
120: if ( $char eq "q" ) { &quit ; last SWITCH; }
121: if ( $char eq "d" ) { &delsong ; last SWITCH; }
122: if ( $char eq "h" ) { &setmode("help") ; last SWITCH; }
123: if ( $char eq "g" ) { &gotocent ; last SWITCH; }
124: if ( $char eq "259" ) { &up ; last SWITCH; }
125: if ( $char eq "258" ) { &down ; last SWITCH; }
126: if ( $char eq "\n" ) { &goto ; last SWITCH; }
127: &invalid;
128: }
129: }
130:
131: sub setmode {
132: $mode=$_[0];
133: &refreshmid;
134: }
135:
136: sub refreshmid {
137: if ($mode eq "play") {
138: &midplay;
139: }
140: if ($mode eq "help") {
141: &midhelp;
142: }
143: if ($mode eq "cred") {
144: &midcred;
145: }
146: if ($mode eq "add") {
147: &midadd;
148: }
149: }
150:
151: sub midplay {
152: if ( $#mp3s == -1 ) {
153: &emptylist;
154: } else {
155: $nooflines = $LINES-7;
156: $centerline = int($nooflines/2);
157: $songnumber = $centersongnr-$centerline;
158: while ($songnumber < 0) {
159: $songnumber = $songnumber + $#mp3s+1;
160: }
161: for ( $i=0 ; $i<$nooflines ; $i++ ) {
162: if ($songnumber>$#mp3s) { $songnumber=0; }
163: $shownumber = $songnumber+1;
164: $playname = $mp3s[$songnumber];
165: $nr = length($playname) - ($COLS-8);
166: if ( $nr > 0 ) {
167: $playname =~ s/^.{$nr}//;
168: $playname =~ s/^.{3}/\.\.\./;
169: }
170: $printwidth = $COLS-3;
171: $sprintstring = "%-".$printwidth."s";
172: $printnum = sprintf("%-4s", $shownumber);
173: $playname = sprintf($sprintstring, " ".$printnum.$playname);
174: $attrm=0;$attrc=0;$attrp=0;
175: if ($songnumber==$mark && $mark!=-1 ) {$attrm=1;}
176: if ($songnumber==$playno || ($songnumber==-1 && $playno==$#mp3s)){$attrp=1;}
177: if ($i==$centerline) {$attrc=1;}
178: if ($attrm) {attron(COLOR_PAIR(1))}
179: if ($attrc) {attron(A_BOLD)}
180: if ($attrp) {attron(COLOR_PAIR(2))}
181: addstr((6+$i), 1, $playname);
182: if ($attrm) {attroff(COLOR_PAIR(1))}
183: if ($attrc) {attroff(A_BOLD)}
184: if ($attrp) {attroff(COLOR_PAIR(2))}
185: $songnumber++;
186: }
187: refresh;
188: }
189: }
190:
191: sub playsong {
192: if ( $#mp3s >= 0 ) {
193: if ( $pid == 0 ) {
194: if ( $playno < 0 ) {
195: $playno = $#mp3s;
196: }
197: if ( $playno > $#mp3s ) {
198: $playno = 0;
199: }
200: $playname=$mp3s[$playno];
201: $playnameqtd = quotemeta( $playname );
202: $mpgcommand="mpg123 -q $playnameqtd";
203: &refreshmid;
204: $pid = fork();
205: if ( $pid == 0 ) {
206: open(STDERR, "/dev/null");
207: exec($mpgcommand);
208: exit 1;
209: }
210: }
211: }
212: }
213:
214: sub setup {
215: attron(COLOR_PAIR(1));
216: box(stdscr, 0, 0);
217: move(5,1);
218: hline(0, 78);
219: attroff(COLOR_PAIR(1));
220: $sprintstring = "The Cursed JukeBox ( cursebox v0.9 )";
221: $nr = $COLS/2-length($sprintstring)/2;
222: $nr = int($nr);
223: attron(COLOR_PAIR(2));
224: addstr(0, $nr, $sprintstring );
225: attroff(COLOR_PAIR(2));
226: addstr(1, 2, "COMMANDS: (N)ext (B)ack (S)top (P)lay".
227: " (R)andom (M)ark/(M)ove");
228: addstr(2, 2, " (Q)quit (D)elete (H)elp (C)redits (G)oto");
229: addstr(3, 2, " Arrow Keys to scroll, <ENTER> to Select.");
230: addstr(4, 2, "RANDOM: PLAYING: ");
231: attron(COLOR_PAIR(1));
232: addstr(4, 12, "OFF");
233: addstr(4, 31, "OFF");
234: attroff(COLOR_PAIR(1));
235: refresh;
236: }
237:
238: sub emptylist {
239: $nooflines = $LINES-7;
240: $centerline = int($nooflines/2-1);
241: $songnumber = $centersongnr-$centerline;
242: $clearpatt = "%".($COLS-2)."s";
243: $clearline = sprintf($clearpatt, "");
244: for ( $i=0 ; $i<$nooflines ; $i++ ) {
245: addstr(($i+6),1,$clearline);
246: }
247: $sprintstring = "SONGLIST EMPTY";
248: $nr = int($COLS/2-length($sprintstring)/2);
249: addstr(($LINES/2+3), $nr, $sprintstring );
250: refresh;
251: }
252:
253: sub midcred {
254: $nooflines = $LINES-7;
255: $centerline = int($nooflines/2-1);
256: $songnumber = $centersongnr-$centerline;
257: $clearpatt = "%".($COLS-2)."s";
258: $clearline = sprintf($clearpatt, "");
259: for ( $i=0 ; $i<$nooflines ; $i++ ) {
260: addstr(($i+6),1,$clearline);
261: }
262: addstr(6,1,"The Cursed Jukebox ( cursebox v0.9 )");
263: addstr(8,1,"Cursebox uses:");
264: addstr(9,1," mpg123");
265: addstr(10,1," perl");
266: addstr(11,1," Curses, the perl ncurses interface ( Yes, you".
267: " need a color Term .)");
268: addstr(13,1,"Tools used in coding:");
269: addstr(14,1," vim ( VI Improved )");
270: addstr(15,1," man ( RTFM... )");
271: addstr(17,1,"Cursebox has been created in vga text mode on a".
272: " debian linux i386 machine");
273: addstr(18,1,"by Mats Ström. ( d99msr\@efd.lth.se )");
274: addstr(20,1,"A big \"hooray\" goes to www.perlmonks.org. Good".
275: "place to ask questions.");
276: addstr(22,1,"Press C to exit this screen.");
277: refresh;
278: }
279:
280: sub midhelp {
281: $nooflines = $LINES-7;
282: $centerline = int($nooflines/2-1);
283: $songnumber = $centersongnr-$centerline;
284: $clearpatt = "%".($COLS-2)."s";
285: $clearline = sprintf($clearpatt, "");
286: for ( $i=0 ; $i<$nooflines ; $i++ ) {
287: addstr(($i+6),1,$clearline);
288: }
289: addstr(6,1,"Use Up/Down arrow keys to scroll in the playlist.");
290: addstr(7,1,"Enter will start playing the song on the highlighted line.");
291: addstr(9,1,"N Next: Play next song. If random is on, it skips to".
292: "a random song.");
293: addstr(10,1,"B Back: Play previous song. If random is on, it skips".
294: "to a random song.");
295: addstr(11,1,"S Stop: Stop playing.");
296: addstr(12,1,"P Play: Start playing.");
297: addstr(13,1,"R Random: Toggle random play on/off.");
298: addstr(14,1,"Q Quit: Exit program. ( Yes, CTRL-C works as well. )");
299: addstr(15,1,"G Goto: This will move your view to the playing song.");
300: addstr(16,1,"H Help: Display this text.");
301: addstr(17,1,"C Credits: Show credits and information about cursebox.");
302: addstr(18,1,"M Mark: Pressing M once will mark a message for moving.".
303: "The line will");
304: addstr(19,1," turn red. Move with the arrow keys to another song".
305: "and press M again.");
306: addstr(20,1," The marked line will be removed and inserted at new".
307: "position.");
308: addstr(22,1,"Press H to exit help.");
309: refresh;
310: }
311:
312: sub playrand {
313: $playno=int(rand($#mp3s+1));
314: if ( $playno == $#mp3s+1 ) {
315: $playno=$#mp3s;
316: }
317: &stop;
318: &play;
319: }
320:
321: sub delsong {
322: if ( $#mp3s >= 0 ) {
323: splice(@mp3s,$centersongnr,1);
324: if ( $centersongnr == $playno ) {
325: $playno = $centersongnr;
326: if ( $playingon ) {
327: &stop;
328: &play;
329: }
330: }
331: if ( $centersongnr < $playno ) {
332: $playno--;
333: }
334: if ( $centersongnr == ($#mp3s+1) ) {
335: $centersongnr = 0;
336: }
337: if ( $playno > ($#mp3s+1) ) {
338: $playno=$#mp3s+1;
339: }
340: &refreshmid;
341: } else {
342: &invalid;
343: }
344: }
345:
346: sub up {
347: $centersongnr--;
348: if ( $centersongnr < 0 ) {
349: $centersongnr = $#mp3s;
350: }
351: &refreshmid;
352: }
353:
354: sub down {
355: $centersongnr++;
356: if ( $centersongnr > $#mp3s ) {
357: $centersongnr = 0;
358: }
359: &refreshmid;
360: }
361:
362: sub movesong {
363: if ( $#mp3s >= 0 ) {
364: if ( $mark == -1 ) {
365: $mark = $centersongnr;
366: } else {
367: $tmp = $mp3s[$mark];
368: splice(@mp3s,$mark,1);
369: splice(@mp3s,$centersongnr,0,$tmp);
370: SWITCH: {
371: if ( $playno == $centersongnr ) { $playno = $mark; ; last SWITCH; }
372: if ( $playno == $mark ) { $playno = $centersongnr; ; last SWITCH; }
373: $playno=$playno;
374: }
375: $mark=-1;
376: }
377: &refreshmid;
378: } else {
379: &invalid;
380: }
381: }
382:
383: sub goto {
384: if ( $#mp3s >= 0 ) {
385: &play;
386: $playno = $centersongnr;
387: if ( kill 0 => $pid ) {
388: if ( $pid != 0 ) {
389: &killsong;
390: }
391: &playsong;
392: }
393: } else {
394: &invalid;
395: }
396: }
397:
398: sub gotocent {
399: if ( $#mp3s >= 0 ) {
400: $centersongnr = $playno;
401: &refreshmid;
402: }
403: }
404:
405: sub stop {
406: attron(COLOR_PAIR(1));
407: addstr(4, 31, "OFF");
408: attroff(COLOR_PAIR(1));
409: refresh;
410: if ($pid != 0) {
411: &killsong;
412: }
413: $playingon = 0;
414: }
415:
416: sub play {
417: if ( $#mp3s >= 0 ) {
418: attron(COLOR_PAIR(2));
419: addstr(4, 31, "ON ");
420: attroff(COLOR_PAIR(2));
421: refresh;
422: unless ($playingon) {
423: &playsong;
424: }
425: $playingon = 1;
426: } else {
427: &invalid;
428: }
429: }
430:
431: sub skip {
432: if ( $#mp3s >= 0 ) {
433: &play;
434: unless ( $randplay ) {
435: $playno++;
436: unless ( $pid == 0 ){
437: &killsong;
438: }
439: &playsong;
440: } else {
441: unless ( $pid == 0 ){
442: &killsong;
443: }
444: &playrand;
445: }
446: } else {
447: &invalid;
448: }
449: }
450:
451: sub back {
452: if ( $#mp3s >= 0 ) {
453: &play;
454: unless ( $randplay ) {
455: $playno--;
456: unless ( $pid == 0 ) {
457: &killsong;
458: }
459: &playsong;
460: } else {
461: unless ( $pid == 0 ){
462: &killsong;
463: }
464: &playrand;
465: }
466: } else {
467: &invalid;
468: }
469: }
470:
471: sub rand {
472: if ( $randplay ) {
473: attron(COLOR_PAIR(1));
474: addstr(4, 12, "OFF"); refresh;
475: attroff(COLOR_PAIR(1));
476: $randplay = 0;
477: } else {
478: attron(COLOR_PAIR(2));
479: addstr(4, 12, "ON ");
480: attroff(COLOR_PAIR(2));
481: refresh;
482: $randplay = 1;
483: }
484: }
485:
486: sub killsong {
487: unless ( $pid == 0 ){
488: while ( kill 0 => $pid ) {
489: kill TERM, $pid;
490: }
491: }
492: $pid=0;
493: }
494:
495: sub quit {
496: &killsong;
497: endwin;
498: exit(1);
499: }
500:
501: sub invalid {
502: beep;
503: refresh;
504: }
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.