Re^2: Playing soundsby haukex (Abbot)
|on Nov 09, 2017 at 22:09 UTC||Need Help??|
I'm not sure which node you are replying to (there are per-node "reply" links next to each post), but I'll reply anyway.
But to have any hope of running my program on other machines, never mind other systems, I'd rather avoid that.
AFAIK sound is always going to be an OS-dependent thing, so any Perl code would at some level have to access an external OS-dependent library or tool. Yes, running an external program just to play a sound is a bit wasteful, but you said this was for a game, and unless you're playing hundreds of sounds a second, or you need high precision in playback (precise timing down to the millisecond of when the sounds are played), or this is going to be run on very low-end machines, then IMHO using an external program is probably fine, especially for background music. (Update: On the other hand, see Discipulus's and zentara's comments about SDL here.)
If it's running an external process anyway, I might as well do it with afplay, right?
Personally I'd look at it differently: If I'm going to be running an external process anyway, I'd like to use the same one no matter which OS, then I will only have to handle one interface (command line arguments etc.). Then, the "only" issues I'd have to worry about are possibly pathname issues, which can be handled with a cross-platform tool like Path::Class or at least the core File::Spec, and making it as easy as possible for a user of my program to install that external tool. Perhaps you can try installing the previously mentioned mpg123 or SoX on different machines to see how easily their installers handle, how easy it is for your Perl script to call those external programs after their installation (potential PATH issues etc.), and so on.
You might just simply document for your users, "if you want sound support, install package X and set configuration option Y to the installation path", and have your program gracefully handle the case of the sound playback tool not being installed (if having no sound is an option for you). Or, if your program has an installer, and you wanted to go this far, the installers of the audio software may support a "quiet" installation, which you can run during your program's installation, and depending on the license terms you might even distribute the audio package contained within yours.
As for your code, I don't quite understand why you want to go through an external file - is that for interprocess communication, or will your user be editing that file? Note that both aforementioned players can play multiple files one after the other if given on the command line, and play a single file multiple times (e.g. play sound.mp3 repeat 2 and mpg123 --loop 3 sound.mp3 both play the same file three times). If you want to monitor the playback and re-start after it is finished, then yes, one way to do that would be to fork a child and have it block until the sound stops playing, but on the other hand, since I assume your code is probably based on an event loop, then regularly polling the state of the playback of the music and re-starting if necessary is also an option (that's what I do in my code below). Anyway, as a fun little project I whipped up an OO package based on the code I linked to earlier (only tested on Linux so far):
(BTW, yet another option for commandline playback is from the powerful FFmpeg or libav packages, the command line tools ffplay/avplay can be used like so: avplay -vn -nodisp -autoexit -nostats -loglevel quiet sound.mp3, I believe the options are identical for ffplay.)