Как постоянно отслеживать ритмбокс для смены треков с помощью 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 об изменении маршрута, вам придется сделать это другим способом. Это обсуждает из путей для изучения:

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

Что-то вроде:

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 заявления), которые помогут сделать эту сторону вещей проще:).

Другие вопросы по тегам