in reply to Re^2: Yet another music-related queue question
in thread Yet another music-related queue question
#!/usr/bin/perl use strict; $| = 1; use warnings; use Audio::Daemon::MPG321; use Config::Auto; use MP3::Info; use POSIX ':sys_wait_h'; use List::Util 'shuffle'; use Cwd; my @Players; { no strict 'refs'; for my $sub ( qw(Add Next Prev Restart Pause Resume Toggle Stop Fo +rward Backward) ) { my $meth = lc $sub; *{ $sub } = sub { return if ! @Players; return $meth eq 'forward' || $meth eq 'backward' ? $Players[-1]->$meth( shift ) : $meth eq 'Add' ? $Players[-1]->$meth( @_ ) : $Players[-1]->$meth(); }; } } mkdir '/tmp/jmd' if ! -d '/tmp/jmd'; open(LOCK, '<', '/var/lock/jmd' and do { kill 0, <LOCK> and die 'JMD a +lready running!' }; open(LOCK, '>', '/var/lock/jmd'), print LOCK $$, close LOCK; # Should +be checking return codes my $MixerPID; my %Config = %{ Config::Auto::parse('/etc/jmd') }; if ( $Config{mixer} eq 'esd' && system('esdctl standbymode >> /dev/nul +l) == 256 ) { $MixerPID = fork() or exec("esd -nobeeps"); system("echo $MixerPID >> /root/esd"); system("esdctl unlock"); } $SIG{ALRM} = sub { return if ! -s '/tmp/jmd/input'; open(INPUT, '<', '/tmp/jmd/input'); # should check return code chomp(my $Input = <INPUT>); close INPUT; no strict 'refs'; my ($Action, @Args) = split ' ', $Input; my $sub = ucfirst $Action; if ( grep { $Action eq $_ } qw<play rplay add radd> ) { my @Songs = map { FullPath($_) } index($Action, 'r') == 0 ? sh +uffle(@Args) : @Args; &$sub( @Songs ); } elsif ( grep $Action eq $_ } qw<next prev restart pause resume tog +gle stop> ) { &$sub; } else { &$sub(@Args) if $sub eq 'Forward' || $sub eq 'Backward'; List() if $Action eq "ls"; $SIG{QUIT}->() if $Action eq "quit"; } return; }; $SIG{CHLD} = sub { while ( waitpid(-1, &WNOHANG) > 0 ) { pop @Players; sleep $Config{lag}; Resume() if @Players; } }; $SIG{QUIT} = sub { unlink '/var/lock/jmd'; Stop() until ! @Players; kill 'INT', $MixerPID if $MixerPID; open (SONG, '>', '/tmp/jmd/song'), print SONG '[0]', cl +ose SONG; # should check return code open (TIMES, '>', '/tmp/jmd/times'), print TIMES '0:00 (0:00)', cl +ose TIMES; # should check return code exit 0; }; $SIG{INT} = $SIG{QUIT}; sub FullPath { my $Song = shift; return $Song if ! index($Song, '/') == 0; my $CWD = getcwd; return -f "$CWD/$Song" ? "$CWD/$Song" : "$Config{dir}/$Song" ? "$Config{dir}/$Song" : undef; } sub Play { my @Songs = @_; Pause() if @Players; push @Players, Audio::Daemon::MPG321->new(@Songs); } sub List { open(REPLY, '>', '/tmp/jmd/reply'); # should be checking return co +de select REPLY; print "START\n"; for ( @{$Players[-1]->{queue}} ) { my $Prelude = ' '; substr($Prelude, 0, 1, '>') if $_ eq $Players[-1]->{queue}->[$ +Players[-1]->{pointer}]; print "$Prelude$_\n"; } print "END\n"; close REPLY; } my $Title; while (1) { select(undef, undef, undef, 0.5); # sleep for .5 seconds next if ! @Players; while ( $Players[-1]->{player}->state() != 0) { $Players[-1]->{player}->poll(); my $Info = get_mp3tag( $Players[-1]->{queue}->[$Players[-1]->{ +pointer}] ); $Title = $Info ? $Info->{TITLE} : $Players[-1]->{queue}->[$Pla +yers[-1]->{pointer}; # seems redundant open(SONG, '>', '/tmp/jmd/song'), print SONG "[". $#Players + +1. "] $Title\n", close SONG; # return code open(TIMES, '>', '/tmp/jmd/times'); # return code print TIMES $Players[-1]->{player}->{sofar}. " ($Players[-1]-> +{player}->{remains})\n"; close TIMES; } ++$Players[-1]->{pointer}; if ( ! $Players[-1]->{queue}->[$Players[-1]->{pointer}] ) { Stop(); } else { $Players[-1]->load(); } }
Cheers - L~R
|
|---|