如何使用Python持续监控Rhythmbox的曲目变化
运行以下Python代码,来自于这个StackOverflow的回答
#!/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 ()
在Ubuntu 12.04和14.04上会出现以下错误:
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
我哪里做错了?
或者,如果有其他方法可以在Python中监听DBUS信号,那也会很有帮助。
2 个回答
2
结果我被那些缩写搞糊涂了,走了错路。
在Rhythmbox 3之前,Rhythmbox是通过它自己特有的API来控制的,这个API是基于DBUS协议的。
而在Rhythmbox 3之后,Rhythmbox通过MPRIS2 DBUS插件,使用一个通用的MPRIS2 API来控制,这同样是基于DBUS协议的。
所以我在网上搜索“Rhythmbox DBUS”其实是在浪费时间。
如果你也想做和我一样的事情:只需要搜索“MPRIS2 $你想用的编程语言$”,这样就能找到一个通用的方法来控制几乎所有的Linux音乐播放器。以Python为例,这里有一些链接:
https://github.com/hugosenari/mpris2
https://github.com/emesene/emesene-supported-plugins/blob/master/music/handler_mpris2.py
4
这个方法在 Rhythmbox 3 上可以用。我把它改成了把当前播放的歌曲写入一个文件( ~/.now_playing ),不过你可以根据自己的需要进行调整:
#!/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 ()