4

我想使用 python 来监控 Rhythmbox 中音轨的变化。我想不断检查轨道的变化并在轨道发生变化时执行一组函数。我编写了一段代码,它从 dbus 获取 Rhythmbox 接口并获取当前音轨详细信息。但是这个程序必须手动运行以检查是否有任何变化。

我是新手,我想知道我们如何创建一个持续运行和检查 Rhythmbox 的后台进程。

我不想制作一个 Rhythmbox 插件(这会让我的工作变得简单),因为我将扩展应用程序以收听多个音乐播放器。

请建议我要实现该功能究竟需要做什么。

4

4 回答 4

13

The Rhythmbox player object (/org/gnome/Rhythmbox/Player) sends a playingUriChanged signal whenever the current song changes. Connect a function to the signal to have it run whenever the signal is received. Here's an example that prints the title of the song whenever a new song starts, using the GLib main loop to process DBus messages:

#! /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 ()
于 2010-11-06T03:20:39.137 回答
1

看看这里的 Conky 脚本:

https://launchpad.net/~conkyhardcore/+archive/ppa/+files/conkyrhythmbox_2.12.tar.gz

它使用 dbus 与节奏盒对话,如下所示:

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

于 2010-10-12T23:58:14.427 回答
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 ()
于 2014-12-08T07:03:07.000 回答
-2

就像是:

from time import sleep

execute = True
while execute:
    your_function_call()
    sleep(30) # in seconds; prevent busy polling

应该工作得很好。如果这与侦听信号(import signal)的东西相关联,以便您可以在某人 ctrl-c 的应用程序时将 execute 设置为 False,那基本上就是您所追求的。

否则,请使用 Google 进行守护进程(这涉及多次分叉该进程);从内存中,现在甚至有一个不错的 Python 库(从内存中,它需要 2.5/2.6with语句)这将有助于使这方面的事情变得更容易:)。

于 2010-10-12T23:13:10.033 回答