如何用Python持续监控Rhythmbox的曲目变化
我想用Python来监控Rhythmbox音乐播放器中的曲目变化。我希望能够不断检查曲目是否改变,如果有变化就执行一系列的功能。我写了一段代码,可以通过dbus获取Rhythmbox的接口,并获取当前曲目的详细信息。但是这个程序必须手动运行才能检查是否有变化。
我对这些还不太熟悉,想知道怎么才能创建一个后台进程,让它持续运行并检查Rhythmbox。
我不想做一个Rhythmbox的插件(虽然这样会让我的工作简单一些),因为我还打算扩展这个应用程序,让它能监听多个音乐播放器。
请告诉我具体需要做些什么才能实现这个功能。
4 个回答
我现在用的是Ubuntu 14.04.1,之前的那个脚本在Rhythmbox 3里已经不再使用了。我用这个脚本是为了把当前播放的歌曲写入到~/.now_playing文件里,方便BUTT读取,不过你也可以根据自己的需要来更新这个脚本。现在Rhythmbox使用的是MPRIS,你可以在这里获取相关信息:
http://specifications.freedesktop.org/mpris-spec/latest/index.html
#!/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 ()
看看这里的Conky脚本:
https://launchpad.net/~conkyhardcore/+archive/ppa/+files/conkyrhythmbox_2.12.tar.gz
这个脚本使用了dbus来和rhythmbox进行交流,具体是这样的:
bus = dbus.SessionBus()
remote_object_shell = bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Shell')
iface_shell = dbus.Interface(remote_object_shell, 'org.gnome.Rhythmbox.Shell')
remote_object_player = bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Player')
iface_player = dbus.Interface(remote_object_player, 'org.gnome.Rhythmbox.Player')
你可以在iface_player上调用很多函数来获取所需的信息。不过,从这个例子来看,你可能需要定期去检查一下。如果你想在曲目变化时接收来自dbus的消息,那就得用不同的方法来实现。这里讨论了一些可以探索的方向:
Rhythmbox播放器的对象(/org/gnome/Rhythmbox/Player
)会在当前播放的歌曲改变时发送一个叫做playingUriChanged
的信号。你可以把一个函数连接到这个信号上,这样每当收到这个信号时,那个函数就会被执行。下面是一个例子,每当开始播放新歌曲时,它会打印出这首歌的标题,使用GLib主循环来处理DBus消息:
#! /usr/bin/env 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 ()