Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I'm trying to write a relatively simple music-playing server with queue features, similar to Moosic or MPD. Jigstar Music Daemon, or JMD, simply listens for an ALRM signal and executes the commands in a file. It's different because it can play a song, pause it, play another, then resume the first when the second is finished. It can do this in a pretty much infinite manner. Operations will only occur to the most recent version of MPG321. (the program I'm using to actually play the songs.) I know MPG321 has a remote interface and that there's a POE module for controlling it, but it'd take a good deal more work because it can only play one song at once. I'm not experienced enough yet to construct a program that can do a real music queue yet. So I'm sticking with my current design. Here's the code of JMD. Be warned, it's not pretty and it doesn't run under strict.
#!/usr/bin/perl ######################## # Jigstar Music Daemon # ######################## #> #> = Temporary comment. #> Check for lock file to see if another instance of JMD is running. die "Error: Lock file exists!" if -e "/var/lock/jmd"; open LOCK, ">/var/lock/jmd"; print LOCK $$; close LOCK; #> Check to see if ESD is running. If not, start it. #> Remember, esdctl returns 1 if ESD isn't running. system("esdctl serverinfo >> /dev/null") and system("esd -nobeeps &") +; #> Exit cleanly when told to do so. $SIG{INT} = sub { #> Do I need to force my children to die so they won't become zombie +s? unlink "/var/lock/jmd", "/tmp/jmd"; system("killall esd"); exit; }; $SIG{QUIT} = $SIG{INT}; #> Use CHLD to simulate the 'done' thing. #> Declare subroutines. sub Play ($); sub Next (); sub Pause (); sub Resume (); sub Stop (); sub Debug (); #> When woken up by JMC, read the input and execute the commands. $SIG{ALRM} = sub { return unless -s "/tmp/jmd"; open INPUT, "/tmp/jmd"; chomp($Cmd = <INPUT>); close INPUT; open INPUT, ">/tmp/jmd"; print INPUT undef; close INPUT; $Cmd =~ s/^play // and Play $Cmd if $Cmd =~ m/^play /; Next if $Cmd eq "next"; Status == 1 ? Pause : Resume if $Cmd eq "toggle"; Pause if $Cmd eq "pause"; Resume if $Cmd eq "resume"; Stop if $Cmd eq "stop"; Debug if $Cmd eq "status"; $SIG{QUIT}->() if $Cmd eq "quit"; }; our @PIDs; sub Play ($) { my $Args = shift; Pause; #> Have MPG321 get all files from /root/mp3. Make it configurable lat +er. #> Change STDERR receiver. if (my $PID = fork()) { push @PIDs, $PID; } else { chdir "/root/mp3/"; exec("mpg321 -v $Args 2> /dev/tty12 &"); } } sub Next () { #> If it's stopped, resume it temporarily to change tracks. if (Status() == 2) { Resume; kill "INT", $PIDs[-1] if @PIDs; } kill "INT", $PIDs[-1] if @PIDs; } sub Pause () { kill "STOP", $PIDs[-1] if @PIDs; } sub Resume () { kill "CONT", $PIDs[-1] if @PIDs; } sub Stop () { kill 9, $PIDs[-1] if @PIDs; pop @PIDs; } sub Debug () { my $Counter = 0; for my $PID (@PIDs) { #> Print the ID, the PID, and the status. Don't need to check if not +hing is #> there, because there has to be. print "$Counter: $PID = " . Status($PID) . "\n"; $Counter++; } } #> Return status of a PID. 0 = Isn't running, 1 = Playing, & 2 = Pause +d. sub Status ($) { my $PID = shift || $PIDs[-1]; my $Line = +(split(/\n/, `ps $PID`))[1]; if ($Line !~ m/$PID/) { return 0; } elsif ($Line =~ m/T</) { return 2; } else { return 1; } } sleep while 1;
To control it, echo a command to /tmp/jmd and send the ALRM signal to JMD. The commands should do the following: play ARGS: Pass args to a new MPG321 instance. If the current instance is running, pause it. Next: Advance the songs. Pause: Force the current song to pause. Resume: Force the current song to resume. Toggle: If paused, resume, and vice versa. Stop: Stop the current instance. Debug: Print the list of PIDs and their status. Usually pausing a song, playing another, then resuming the first won't work under Linux using OSS. The dsp device is locked. So I run esd to mix the silence of the paused songs and the music of the running song. The problem is simple: Pausing, resuming, stopping, and advancing to the next track won't work. Every function that sends a signal to the current MPG321 instance doesn't do what it should. There are no errors. I know the methods I am using are messy, but I also now that they work. An older version of JMD that didn't use fork() to start mpg321 did work. I cannot find the difference between the two. Any help, suggestions, or code is much appreciated. I can also be found on #perl on irc.freenode.net generally, under the alias 'dabreegster'. Thanks.

In reply to Managing and sending signals to control MPG321 by dabreegster

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • 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.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-24 08:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found