如何用Python持续监控Rhythmbox的曲目变化

4 投票
4 回答
3010 浏览
提问于 2025-04-16 05:23

我想用Python来监控Rhythmbox音乐播放器中的曲目变化。我希望能够不断检查曲目是否改变,如果有变化就执行一系列的功能。我写了一段代码,可以通过dbus获取Rhythmbox的接口,并获取当前曲目的详细信息。但是这个程序必须手动运行才能检查是否有变化。

我对这些还不太熟悉,想知道怎么才能创建一个后台进程,让它持续运行并检查Rhythmbox。

我不想做一个Rhythmbox的插件(虽然这样会让我的工作简单一些),因为我还打算扩展这个应用程序,让它能监听多个音乐播放器。

请告诉我具体需要做些什么才能实现这个功能。

4 个回答

1

我现在用的是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 ()
1

看看这里的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的消息,那就得用不同的方法来实现。这里讨论了一些可以探索的方向:

http://ubuntuforums.org/showthread.php?t=156706

13

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 ()

撰写回答