How to continuously monitor rhythmbox for track change using python revisited

1.5k views Asked by At

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.

2

There are 2 answers

0
Joshua Besneatte On BEST ANSWER

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 ()
0
My other car is a cadr On

Turns out I got confused by the all the acronyms and barked up the wrong tree.

Before Rhythmbox 3, Rhythmbox is controlled through its own special API over the DBUS protocol.

After Rhythmbox 3, Rhythmbox (through the MPRIS2 DBUS plugin) is controlled through the universal MPRIS2 API over the DBUS protocol.

So Googling "Rhythmbox DBUS" just sent me on a wild goose chase.

To anyone trying to accomplish the same thing as me: just Google "MPRIS2 $DESIRED LANGUAGE$" for a universal solution on controlling almost all Linux music players. In python's case, there are:

https://github.com/hugosenari/mpris2

https://github.com/emesene/emesene-supported-plugins/blob/master/music/handler_mpris2.py