Controlling Rhythmbox using D-Bus

On GNOME desktops, the D-Bus IPC standard has superseded the CORBA-based approach. Using D-Bus, the operating system can notify the desktop about hardware changes and applications can communicate with each other in a standardized, simple manner. Using signals it is also possible to get a notification in case there are changes in a remote application.

In this posting I'll give a simple example on how to control the Rhythmbox audio player remotely using the python bindings.

Similar to CORBA's IDL, there is an XML-based interface description language. Using this language, applications can announce the methods (including signatures) they provide for others to call. To execute a method, you have to know four things:

  1. The service (in this case org.gnome.Rhythmbox)
  2. The name of the remote object. Rhythmbox registers three objects for us to use: /org/gnome/Rhythmbox/Player, /org/gnome/Rhythmbox/Shell, and /org/gnome/Rhythmbox/PlaylistManager
  3. The interface (org.gnome.Rhythmbox.Player in this example)
  4. The method and its signature (getPlayingUri())

Strictly speaking, the interface isn't necessary, but an object is allowed to provide multiple methods with the same name and signature. In this case, the interface can be used to the access the desired method.

Let's use python to print the URI of the currently playing song:

#! /usr/bin/env python
import dbus

session_bus = dbus.SessionBus()

proxy_obj = session_bus.get_object(
    'org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Player')

player = dbus.Interface(proxy_obj, 'org.gnome.Rhythmbox.Player')

print player.getPlayingUri()

This is pretty straight forward. We obtain a dbus.Bus instance (additionally to the SessionBus there is also a SystemBus) and use it to get an object reference to the player. Like in CORBA, a proxy object is used which takes care of all the marshalling and unmarshalling for us. The first argument of get_object() is the name of the service, the second one names the object we're interested in using an object path.

We select the interface (the object supports more, but we don't care about them) and then call the getPlayingUri method. Pretty simple, hm?

Rhythmbox offers a lot more than that: You can pause the player, adjust the volume, or print the name of the currently playing song. The D-Bus interface definitions can be found in XML files in the source distribution. For more information about D-Bus see the D-Bus Tutorial.