I am using a hand-rolled MP3 player for the console to circumvent the limitations that mpg123
has. It's using the brilliant MPEG::MP3Play
as backend which even has such goodies as a nice equalizer etc. With the help of Term::ReadKey
my players response to single key-strokes: 'e' for editing the tag, '>' for next song, '<' for previous song, '+' turning volume up and so on.
My playlist however has too many songs I prefer to skip. Since I always have my player on a virtual console I have to switch to it when skipping a song and being under X. I am a little concerned with the lifetime of my monitor if I do that a few hundred times a day (you probably know this 'click' of the relais inside a monitor).
So I thought it'd be cool if I had a sort of remote control that I could associate with a WindowMaker application icon: one click and the song is skipped or so. I thought: Hey, that's easy, I just need to integrate a socket server into my player so I went for IO::Socket::INET
and IO::Select
.
The event loop of the player is actually simple: two nested while loops:
while () {
my $k;
while (not defined ($k = ReadKey(-1))) {
# process the updating of the display with MPEG::MP3Play
# methods: yes, my player even has a counter for the playing time
...
}
# process key-strokes here
}
Making my player networkish just required a few lines of code and no change of the overal control-flow. The above now looks as follows:
while () {
my $k;
while (not defined $k and not defined ($k = ReadKey(-1))) {
my @s = $select->can_read(0.1/10);
for my $fh (@s) {
if ($fh == $socket) {
$select->add($socket->accept);
} else {
$fh->sysread($k, 1);
}
}
# display update
}
# key-stroke processing
}
Along with two lines for the creation of the IO::Socket::INET
and IO::Select
object this is a total addition of just 10 lines of code!
A simple text mode client adds another couple of key-strokes. Same pattern really:
while () {
my $key;
while (not defined ($key = ReadKey(-1))) { }
exit if $key eq '#';
syswrite $sock, $key, 1;
if ($key eq 'q') {
$sock->close;
exit;
}
}
I am pretty pleased!