Amarok 1.4 remote in Android using DCOP+Python PDF Print E-mail

We’ve all seen the Apple app that lets you control iTunes remotely, and there totally needs to be something like this for Android. I’m an avid fan of Amarok, so I’ve whipped together a simple remote control that runs on Android. It only took about 3 hours tonight, and I’m releasing everything GPLv3 here. First some details on the architecture:

 

Amarok can easily be controlled via DCOP, including fetching currently playing information and album art. DCOP is a local, safe IPC architecture that usually comes already enabled with KDE applications. Just a reminder that DCOP is being phased out in KDE 4 with D-Bus taking its place. Speaking of the D-Bus future, there is an awesome standard called Media Player Remote Interface Specification (MPRIS) that is being put together by the folks at XMMS, VLC, Amarok, and others. It doesn’t seem to be in stable releases yet, but will be soon. Back to the present, I’m going to just focus on getting Amarok 1.4 working with older DCOP calls.

First, I built a Python bridge that offers a simple HTTP REST-like API that will help us relay pre-approved DCOP commands from Android to Amarok. The Python is pretty simple:

 
  1. from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
  2. import pydcop, re 
  3.  
  4. port = 8484 
  5. allowed = ["status", "trackCurrentTime", "trackTotalTime", "album", "artist"
  6.     "title", "next", "playPause", "prev", "volumeDown", "volumeUp"
  7.     "coverImage", "seek"
  8. resafe = re.compile("[^A-Za-z0-9/]"
  9.  
  10. class AmarokHandler(BaseHTTPRequestHandler): 
  11.     def do_GET(self): 
  12.  
  13.         # pull out action and simple variable 
  14.         safe = resafe.sub('', self.path) 
  15.         blank, action, var = tuple(safe.split('/')) 
  16.  
  17.         # skip if action has not been approved 
  18.         if not action in allowed: return 
  19.  
  20.         # check if image request 
  21.         if action == "coverImage"
  22.             self.send_response(200
  23.             self.send_header('Content-type', 'image/jpeg'
  24.             self.end_headers() 
  25.  
  26.             cover = open((pydcop.DCOPMethod("amarok", "player", "coverImage"))()) 
  27.             self.wfile.write(cover.read()) 
  28.             cover.close() 
  29.             return 
  30.  
  31.         # make dcop call over to amarok 
  32.         if len(var) > 0: reply = (pydcop.DCOPMethod("amarok", "player", action))(int(var)) 
  33.         else: reply = (pydcop.DCOPMethod("amarok", "player", action))() 
  34.  
  35.         # write back any dcop response 
  36.         self.send_response(200
  37.         self.send_header('Content-type', 'text/plain'
  38.         self.end_headers() 
  39.         self.wfile.write(reply) 
  40.  
  41.         return 
  42.  
  43. try
  44.     server = HTTPServer(('', port), AmarokHandler) 
  45.     print 'started amarokremote server on port %s' % (port) 
  46.     server.serve_forever() 
  47. except KeyboardInterrupt: 
  48.     server.socket.close() 

Essentially we are using a URL of the form http://ipaddress:port/command/variable. For example, in the Android emulator you could call http://10.0.2.2:8282/volumeUp/ to increase the volume.

Carefully note that we are screening the commands against an “allowed” list before running off to Amarok with them. We’re also scrubbing the incoming calls to prevent any buffer overflows. Usually we are just calling the Amarok DCOP method and returning any result. One exception is for coverImage requests, because Amarok just returns a local path. We help that image over the Python bridge by sending the local JPEG as the response.

On the Android side of things, we have a simple screen layout and are hooking up the various API calls to buttons. There’s also a background thread that keeps Android in-sync with what Amarok is currently playing. Finally, we’re using some simple preferences to store the server string and update interval. (Tap the menu button to change these settings.)

Here’s a tarball of the Eclipse project, along with the APK that’s ready to run on the new 0.9 SDK. Start the Python server above on your the computer running Amarok, change the IP address if needed, and you should be ready to go.

Also, a reminder that 10.0.2.2 is magic on the Android emulator because it points to the loopback adapter of the parent computer. So, if you’re running the emulator and Amarok on the same computer, this IP address will work perfectly.

 

Source: http://www.jsharkey.org/blog/2008/08/20/amarok-14-remote-in-android-using-dcoppython/

Comments (0)Add Comment

Write comment
quote
bold
italicize
underline
strike
url
image
quote
quote
smile
wink
laugh
grin
angry
sad
shocked
cool
tongue
kiss
cry
smaller | bigger

security code
Write the displayed characters


busy
 

 

This domain is for sale! Please contact me via contact page!