Как постоянно отслеживать ритмбокс для смены треков с помощью python
Я хочу следить за сменой трека в Rhythmbox, используя python. Я хочу постоянно проверять смену дорожки и выполнять набор функций, если дорожка изменена. Я написал фрагмент кода, который получает интерфейсы Rhythmbox от dbus и получает текущие данные трека. Но эта программа должна быть запущена вручную, чтобы проверить наличие изменений.
Я новичок в этом, и я хотел бы знать, как мы можем создать фоновый процесс, который непрерывно запускается и проверяет Rhythmbox.
Я не хочу делать плагин Rhythmbox (который скорее упростил бы мою работу), так как я буду расширять приложение для прослушивания нескольких музыкальных проигрывателей.
Пожалуйста, предложите мне, что именно я должен сделать, чтобы достичь функциональности.
4 ответа
Объект игрока 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 ()
Я использую 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 об изменении маршрута, вам придется сделать это другим способом. Это обсуждает из путей для изучения:
Что-то вроде:
from time import sleep
execute = True
while execute:
your_function_call()
sleep(30) # in seconds; prevent busy polling
Должно работать просто отлично. Если это было подключено к чему-то, что слушало сигналы (import signal
), чтобы вы могли установить выполнение в False, когда кто-то ctrl-c работает с приложением, в основном это то, что вам нужно.
В противном случае, есть Google для демонизации (который включает в себя разветвление процесса пару раз); из памяти теперь есть даже приличная библиотека Python (для которой из памяти требуется 2.5/2.6 with
заявления), которые помогут сделать эту сторону вещей проще:).