Mar 16, 2011

Controlling Rhythmbox with your Wiimote

I've been fiddling with one of my Wiimotes tonight to try and get it to control Rhythmbox. Turns out it's actually really easy! You can do it via the cwiid library for Python, and with a Rhythmbox plugin.

For this to work, you need a Wiimote and some sort of Bluetooth device for your computer that works with Ubuntu. You'll also need the correct package:
sudo apt-get install python-cwiid
Here's the step-by-step guide to getting it to work:
  1. Create a folder at ~/.gnome2/rhythmbox/plugins if it doesn't already exist.
  2. Create a file in there called WiimoteControl.rb-plugin, and put the following in it:
    [RB Plugin]
    Loader=python
    Module=WiimoteControl
    IAge=1
    Name=Wiimote Control
    Description=A way to control Rhythmbox with your Wiimote
    Authors=Rob Britton 
    Copyright=Copyright (c) 2011 Rob Britton
    Website=http://lovehateubuntu.blogspot.com/
    You can replace my name with yours if you want, I won't mind ;)
  3. Create a file called __init__.py, and put the following in it:
    import rb
    import cwiid
    
    rbshell = None
    
    def callback(mesg_list, time):
      # Called whenever a button is pushed on the Wiimote
      global rbshell
      for mesg in mesg_list:
        if mesg[0] == cwiid.MESG_BTN:
          if mesg[1] == cwiid.BTN_A:
            rbshell.props.shell_player.playpause()
          if mesg[1] == cwiid.BTN_LEFT:
            rbshell.props.shell_player.do_previous()
          if mesg[1] == cwiid.BTN_RIGHT:
            rbshell.props.shell_player.do_next()
    
    
    class WiimoteControlPlugin (rb.Plugin):
      def __init__(self):
        rb.Plugin.__init__(self)
    
      def activate(self, shell):
        # called when Rhythmbox starts
        global rbshell, bus
        self.shell = shell
        rbshell = self.shell
        self.wiimote = None
    
        print "looking for wiimote..."
        self.wiimote = cwiid.Wiimote()
    
        print "found wiimote"
        self.wiimote.enable(cwiid.FLAG_MESG_IFC)
        self.wiimote.mesg_callback = callback
        self.wiimote.rpt_mode = cwiid.RPT_BTN
    
      def deactivate(self, shell):
        # called when Rhythmbox closes
        self.wiimote.close()
    This code sets up the Wiimote and binds left/right to previous/next song, and the A button to Play/Pause.
  4. Open Rhythmbox, and while it is opening push the 1 and 2 buttons on the Wiimote. It will take a sec for Rhythmbox to open since it is looking for the Wiimote.
All this should make it so that your Wiimote can connect and control Rhythmbox. To get debug messages, you can run Rhythmbox from the command line:
rhythmbox -D WiimoteControl
The program isn't ideal, since if you don't connect the Wiimote in time it will not properly set everything. It might be better to put some sort of timer that goes periodically to check to see if the Wiimote is there and if it is not, attempts to connect it. Also I think it would be neat to be able to control the volume using the up and down buttons, but I'm not quite sure how to do that yet. It doesn't seem to be in the Rhythmbox plugin guide, and the other plugins don't really do that sort of thing.

No comments: