Search code examples
pythondbusrhythmbox

How to continuously monitor rhythmbox for track change using python revisited


Running the following Python code from this SO answer

#!/usr/bin/python

import dbus
import dbus.mainloop.glib
import glib

# This gets called whenever Rhythmbox sends the playingUriChanged signal
def playing_song_changed (uri):
    global shell
    if uri != "":
    song = shell.getSongProperties (uri)
    print "Now playing: {0}".format (song["title"])
    else:
    print "Not playing anything"

dbus.mainloop.glib.DBusGMainLoop (set_as_default = True)

bus = dbus.SessionBus ()

proxy = bus.get_object ("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
player = dbus.Interface (proxy, "org.gnome.Rhythmbox.Player")
player.connect_to_signal ("playingUriChanged", playing_song_changed)

proxy = bus.get_object ("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Shell")
shell = dbus.Interface (proxy, "org.gnome.Rhythmbox.Shell")

# Run the GLib event loop to process DBus signals as they arrive
mainloop = glib.MainLoop ()
mainloop.run ()

on both Ubuntu 12.04 and 14.04 gets me the following error:

Traceback (most recent call last):
  File "./test.py", line 20, in <module>
    proxy = bus.get_object ("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 241, in get_object
    follow_name_owner_changes=follow_name_owner_changes)
  File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 248, in __init__
    self._named_service = conn.activate_name_owner(bus_name)
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 180, in activate_name_owner
    self.start_service_by_name(bus_name)
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 278, in start_service_by_name
    'su', (bus_name, flags)))
  File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Rhythmbox was not provided by any .service files

What am I doing wrong?

Or alternatively if there's a another way to listen to DBUS signals on Python that would also help.


Solution

  • This works with Rhythmbox 3. I changed it to write the current song to a file ( ~/.now_playing ) but you can update it for your needs:

    #!/usr/bin/python
    
    import dbus
    import dbus.mainloop.glib
    import glib
    
    # This gets called whenever Rhythmbox sends the playingUriChanged signal
    def playing_song_changed (Player,two,three):
        global iface
        global track
        global home
        track2 = iface.Get(Player,"Metadata").get(dbus.String(u'xesam:artist'))[0] + " - "+ iface.Get(Player,"Metadata").get(dbus.String(u'xesam:title'))
    
        if track != track2:
            track = iface.Get(Player,"Metadata").get(dbus.String(u'xesam:artist'))[0] + " - "+ iface.Get(Player,"Metadata").get(dbus.String(u'xesam:title'))
            f = open( home + '/.now_playing', 'w' )
            f.write( track + '\n' )
            f.close()
    
    
    dbus.mainloop.glib.DBusGMainLoop (set_as_default = True)
    
    bus = dbus.SessionBus ()
    from os.path import expanduser
    home = expanduser("~")
    player = bus.get_object ("org.mpris.MediaPlayer2.rhythmbox", "/org/mpris/MediaPlayer2")
    iface = dbus.Interface (player, "org.freedesktop.DBus.Properties")
    
    track = iface.Get("org.mpris.MediaPlayer2.Player","Metadata").get(dbus.String(u'xesam:artist'))[0] + " - "+ iface.Get("org.mpris.MediaPlayer2.Player","Metadata").get(dbus.Strin$
    f = open( home + "/.now_playing", 'w' )
    f.write( track + '\n' )
    f.close()
    
    iface.connect_to_signal ("PropertiesChanged", playing_song_changed)
    
    # Run the GLib event loop to process DBus signals as they arrive
    mainloop = glib.MainLoop ()
    mainloop.run ()