Fun With Lirc

I wondered the other day if there was an easy way I could control mplayer on my linux box using my android phone, and came up with a ridiculous concotion that will actually allow anything with a web browser to control it (which includes my android phone).

Warning: the only security in what follows is provided by the security you get from isolating your local area network.

First, you need to setup mplayer to be controlled by lirc. This involves putting lots of junk like this in your ~/.lircrc file:

begin
    button = Pause
    prog = mplayer
    config = pause
end

This particular entry says that the remote button named "Pause" should execute the "pause" action of mplayer if mplayer happens to be listening for remote events from lirc.

Of course, you also need the lirc software installed and a lirc config file setup to have at least one remote control defined.

yum install lirc
chkconfig --level 5 lirc on

Since I am going to be simulating the remote, it doesn't matter which one I pick, but I need a valid config file for the lirc daemon to look at, so visit http://lirc.sourceforge.net/remotes/ and pick a valid config (random probably works - I used the IMON_RSC simply because my old computer had one built into the case and I was familiar with the file). Copy this file to /etc/lirc/lircd.conf.

You still need to fiddle some startup parameters for the lircdaemon. Fill in the /etc/sysconfig/lirc file with these changes:

LIRCD_OPTIONS="--allow-simulate"
LIRC_DRIVER="udp"

The --allow-simulate option is important for the web page to work. The udp driver was picked because there isn't a /dev/lirc device, so the simplest way to keep the daemon happy is to tell it to listen for network packets it will never get.

service lircd start

I you do a man irsend you can read about the SIMULATE command you can now use to have the lircd send out remote button presses just as if a real remote had actually pressed a button. Naturally, it is only one small step from a command I can run to a .cgi script to run the commands for me:

#!/usr/bin/perl
#
use CGI qw/:standard/;
use URI::Escape;

my $cols = 3;

my %button_codes;
$button_codes{'App.Exit'}='00000000000008F7';
$button_codes{'Power'}='000000000000F40B';
$button_codes{'ScreenSaver'}='00000000000052AD';
$button_codes{'Timer'}='000000000000926D';
$button_codes{'1'}='0000000000002AD5';
$button_codes{'2'}='000000000000AA55';
$button_codes{'3'}='0000000000006A95';
$button_codes{'4'}='000000000000EA15';
$button_codes{'5'}='0000000000001AE5';
$button_codes{'6'}='0000000000009A65';
$button_codes{'7'}='0000000000005AA5';
$button_codes{'8'}='000000000000DA25';
$button_codes{'9'}='0000000000003AC5';
$button_codes{'0'}='000000000000BA45';
$button_codes{'Desktop'}='000000000000817E';
$button_codes{'Max/Res'}='00000000000041BE';
$button_codes{'Esc'}='00000000000012ED';
$button_codes{'Windows'}='000000000000D22D';
$button_codes{'Menu'}='000000000000C13E';
$button_codes{'App.Launcher'}='000000000000A25D';
$button_codes{'Function'}='00000000000021DE';
$button_codes{'Task.Switcher'}='000000000000629D';
$button_codes{'Backspace'}='000000000000A15E';
$button_codes{'Mouse/Keyboard'}='000000000000619E';
$button_codes{'Space'}='000000000000E11E';
$button_codes{'Shift.Tab'}='0000000000007887';
$button_codes{'Enter'}='00000000000019E6';
$button_codes{'Tab'}='000000000000F807';
$button_codes{'L.Click'}='000000000000d827';
$button_codes{'DragNDrop'}='0000000000006897';
$button_codes{'R.Click'}='000000000000b847';
$button_codes{'Mute'}='00000000000011ee';
$button_codes{'Vol-'}='0000000000007a85';
$button_codes{'Vol+'}='000000000000fa05';
$button_codes{'Play'}='00000000000032cd';
$button_codes{'Pause'}='000000000000b24d';
$button_codes{'Open'}='000000000000f20d';
$button_codes{'Prev'}='0000000000000af5';
$button_codes{'Next'}='0000000000008a75';
$button_codes{'Stop'}='000000000000728d';
$button_codes{'Rew'}='0000000000004ab5';
$button_codes{'F.Fwd'}='000000000000ca35';
$button_codes{'Full.Screen'}='000000000000916e';

if (param()) {
   my $button_name = param('button_name');
   my $button_code = $button_codes{$button_name};
   system("irsend SIMULATE '$button_code 00 $button_name IMON_RSC'");
}

my @button_names = sort(keys(%button_codes));
my $i;

print header,
      start_html(-title=>'IRMON_RSC Buttons',
                 -style=>{'src'=>'/styles/bigbuttons.css'},),
      start_form,
      "<table border=\"0\" cellpadding=\"5\">\n";

   while (scalar(@button_names) > 0) {
      print "<tr>\n";
      for ($i = 0; $i < $cols; ++$i) {
         print "<td>";
         if (scalar(@button_names) > 0) {
            my $b = shift(@button_names);
            print submit(-name=>'button_name',-value=>$b);
         } else {
            print '&nbsp;';
         }
         print "</td>";
      }
      print "</tr>\n";
   }

print "</table>\n",
      end_form,
      end_html;

The bigbuttons.css stylesheet that cgi script points at is just used to crank up the size of the buttons so you don't have to zoom in on the web page when using it from the phone. It looks like:

input {
font-weight: bold;
font-size: 250%;
}

Naturally, for this to work, you also need to be running a web server that has .cgi scripts enabled (I use the fedora apache package), and have perl and the cgi modules installed (also available in the fedora repos).

Anyway, with all this running, I can connect to my LAN over Wi-Fi from my phone, bring up the cgi script in the web browser, and punch the Pause button when using mplayer, and mplayer will pause.

Spiffy custom web pages with button images rather than text are left as an exercise for the reader, as is implementing more buttons than just Pause, etc. :-).

Of course, if irsend were ported to android and used directly, a much snazzier interface would be possible (like one that automatically sends a Pause when a call is coming in :-).

Page last modified Wed Oct 5 19:19:55 2011