2006-09-23 15:49:33 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
## musictracklistener.py
|
|
|
|
##
|
|
|
|
## Copyright (C) 2006 Gustavo Carneiro <gjcarneiro@gmail.com>
|
|
|
|
## Copyright (C) 2006 Nikos Kouremenos <kourem@gmail.com>
|
|
|
|
##
|
|
|
|
## This program is free software; you can redistribute it and/or modify
|
|
|
|
## it under the terms of the GNU General Public License as published
|
|
|
|
## by the Free Software Foundation; version 2 only.
|
|
|
|
##
|
|
|
|
## This program is distributed in the hope that it will be useful,
|
|
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
## GNU General Public License for more details.
|
|
|
|
##
|
|
|
|
import gobject
|
2006-09-27 19:16:04 +02:00
|
|
|
if __name__ == '__main__':
|
|
|
|
# install _() func before importing dbus_support
|
|
|
|
from common import i18n
|
2006-09-27 17:39:05 +02:00
|
|
|
|
2006-09-30 15:09:41 +02:00
|
|
|
from common import dbus_support
|
2006-09-24 21:25:44 +02:00
|
|
|
if dbus_support.supported:
|
|
|
|
import dbus
|
|
|
|
import dbus.glib
|
2006-09-23 15:49:33 +02:00
|
|
|
|
|
|
|
class MusicTrackInfo(object):
|
|
|
|
__slots__ = ['title', 'album', 'artist', 'duration', 'track_number']
|
|
|
|
|
|
|
|
|
|
|
|
class MusicTrackListener(gobject.GObject):
|
2006-09-26 15:45:38 +02:00
|
|
|
__gsignals__ = {
|
|
|
|
'music-track-changed': (gobject.SIGNAL_RUN_LAST, None, (object,)),
|
|
|
|
}
|
2006-09-23 15:49:33 +02:00
|
|
|
|
|
|
|
_instance = None
|
|
|
|
@classmethod
|
|
|
|
def get(cls):
|
|
|
|
if cls._instance is None:
|
|
|
|
cls._instance = cls()
|
|
|
|
return cls._instance
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
super(MusicTrackListener, self).__init__()
|
2006-09-26 15:45:38 +02:00
|
|
|
self._last_playing_music = None
|
|
|
|
|
2006-09-23 15:49:33 +02:00
|
|
|
bus = dbus.SessionBus()
|
2006-09-26 15:45:38 +02:00
|
|
|
|
|
|
|
## Muine
|
2006-09-23 15:49:33 +02:00
|
|
|
bus.add_signal_receiver(self._muine_music_track_change_cb, 'SongChanged',
|
|
|
|
'org.gnome.Muine.Player')
|
2006-09-26 15:45:38 +02:00
|
|
|
bus.add_signal_receiver(self._player_name_owner_changed,
|
|
|
|
'NameOwnerChanged', 'org.freedesktop.DBus', arg0='org.gnome.Muine')
|
|
|
|
bus.add_signal_receiver(self._player_playing_changed_cb, 'StateChanged',
|
|
|
|
'org.gnome.Muine.Player')
|
|
|
|
|
|
|
|
## Rhythmbox
|
2006-09-23 15:49:33 +02:00
|
|
|
bus.add_signal_receiver(self._rhythmbox_music_track_change_cb,
|
|
|
|
'playingUriChanged', 'org.gnome.Rhythmbox.Player')
|
2006-09-26 15:45:38 +02:00
|
|
|
bus.add_signal_receiver(self._player_name_owner_changed,
|
|
|
|
'NameOwnerChanged', 'org.freedesktop.DBus', arg0='org.gnome.Rhythmbox')
|
|
|
|
bus.add_signal_receiver(self._player_playing_changed_cb,
|
|
|
|
'playingChanged', 'org.gnome.Rhythmbox.Player')
|
|
|
|
|
2006-09-26 16:01:34 +02:00
|
|
|
def do_music_track_changed(self, info):
|
|
|
|
if info is not None:
|
|
|
|
self._last_playing_music = info
|
|
|
|
|
2006-09-26 15:45:38 +02:00
|
|
|
def _player_name_owner_changed(self, name, old, new):
|
|
|
|
if not new:
|
|
|
|
self.emit('music-track-changed', None)
|
|
|
|
|
|
|
|
def _player_playing_changed_cb(self, playing):
|
|
|
|
if playing:
|
|
|
|
self.emit('music-track-changed', self._last_playing_music)
|
|
|
|
else:
|
|
|
|
self.emit('music-track-changed', None)
|
2006-09-23 15:49:33 +02:00
|
|
|
|
2006-09-23 16:39:58 +02:00
|
|
|
def _muine_properties_extract(self, song_string):
|
2006-09-26 15:45:38 +02:00
|
|
|
d = dict((x.strip() for x in s1.split(':', 1)) for s1 in \
|
|
|
|
song_string.split('\n'))
|
2006-09-23 15:49:33 +02:00
|
|
|
info = MusicTrackInfo()
|
|
|
|
info.title = d['title']
|
|
|
|
info.album = d['album']
|
|
|
|
info.artist = d['artist']
|
|
|
|
info.duration = int(d['duration'])
|
|
|
|
info.track_number = int(d['track_number'])
|
2006-09-23 16:39:58 +02:00
|
|
|
return info
|
|
|
|
|
|
|
|
def _muine_music_track_change_cb(self, arg):
|
|
|
|
info = self._muine_properties_extract(arg)
|
2006-09-23 15:49:33 +02:00
|
|
|
self.emit('music-track-changed', info)
|
|
|
|
|
2006-09-23 16:39:58 +02:00
|
|
|
def _rhythmbox_properties_extract(self, props):
|
2006-09-23 15:49:33 +02:00
|
|
|
info = MusicTrackInfo()
|
|
|
|
info.title = props['title']
|
|
|
|
info.album = props['album']
|
|
|
|
info.artist = props['artist']
|
|
|
|
info.duration = int(props['duration'])
|
|
|
|
info.track_number = int(props['track-number'])
|
2006-09-23 16:39:58 +02:00
|
|
|
return info
|
|
|
|
|
|
|
|
def _rhythmbox_music_track_change_cb(self, uri):
|
|
|
|
bus = dbus.SessionBus()
|
2006-09-26 15:45:38 +02:00
|
|
|
rbshellobj = bus.get_object('org.gnome.Rhythmbox',
|
|
|
|
'/org/gnome/Rhythmbox/Shell')
|
2006-09-23 16:39:58 +02:00
|
|
|
rbshell = dbus.Interface(rbshellobj, 'org.gnome.Rhythmbox.Shell')
|
|
|
|
props = rbshell.getSongProperties(uri)
|
|
|
|
info = self._rhythmbox_properties_extract(props)
|
2006-09-23 15:49:33 +02:00
|
|
|
self.emit('music-track-changed', info)
|
|
|
|
|
2006-09-23 16:39:58 +02:00
|
|
|
def get_playing_track(self):
|
|
|
|
'''Return a MusicTrackInfo for the currently playing
|
|
|
|
song, or None if no song is playing'''
|
|
|
|
|
|
|
|
bus = dbus.SessionBus()
|
|
|
|
|
|
|
|
## Check Muine playing track
|
2006-12-18 10:13:12 +01:00
|
|
|
test = False
|
|
|
|
if hasattr(bus, 'name_has_owner'):
|
|
|
|
if bus.name_has_owner('org.gnome.Muine'):
|
|
|
|
test = True
|
|
|
|
elif dbus.dbus_bindings.bus_name_has_owner(bus.get_connection(),
|
|
|
|
'org.gnome.Muine'):
|
|
|
|
test = True
|
|
|
|
if test:
|
2006-09-23 16:39:58 +02:00
|
|
|
obj = bus.get_object('org.gnome.Muine', '/org/gnome/Muine/Player')
|
|
|
|
player = dbus.Interface(obj, 'org.gnome.Muine.Player')
|
|
|
|
if player.GetPlaying():
|
|
|
|
song_string = player.GetCurrentSong()
|
|
|
|
song = self._muine_properties_extract(song_string)
|
2006-09-26 15:45:38 +02:00
|
|
|
self._last_playing_music = song
|
2006-09-23 16:39:58 +02:00
|
|
|
return song
|
|
|
|
|
|
|
|
## Check Rhythmbox playing song
|
2006-12-18 10:13:12 +01:00
|
|
|
test = False
|
|
|
|
if hasattr(bus, 'name_has_owner'):
|
|
|
|
if bus.name_has_owner('org.gnome.Rhythmbox'):
|
|
|
|
test = True
|
|
|
|
elif dbus.dbus_bindings.bus_name_has_owner(bus.get_connection(),
|
|
|
|
'org.gnome.Rhythmbox'):
|
|
|
|
test = True
|
|
|
|
if test:
|
2006-09-26 15:45:38 +02:00
|
|
|
rbshellobj = bus.get_object('org.gnome.Rhythmbox',
|
|
|
|
'/org/gnome/Rhythmbox/Shell')
|
2006-09-23 16:39:58 +02:00
|
|
|
player = dbus.Interface(
|
2006-09-26 15:45:38 +02:00
|
|
|
bus.get_object('org.gnome.Rhythmbox',
|
|
|
|
'/org/gnome/Rhythmbox/Player'), 'org.gnome.Rhythmbox.Player')
|
2006-09-23 16:39:58 +02:00
|
|
|
rbshell = dbus.Interface(rbshellobj, 'org.gnome.Rhythmbox.Shell')
|
|
|
|
uri = player.getPlayingUri()
|
|
|
|
props = rbshell.getSongProperties(uri)
|
|
|
|
info = self._rhythmbox_properties_extract(props)
|
2006-09-26 15:45:38 +02:00
|
|
|
self._last_playing_music = info
|
2006-09-23 16:39:58 +02:00
|
|
|
return info
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
2006-09-23 15:49:33 +02:00
|
|
|
# here we test :)
|
|
|
|
if __name__ == '__main__':
|
|
|
|
def music_track_change_cb(listener, music_track_info):
|
2006-09-26 15:45:38 +02:00
|
|
|
if music_track_info is None:
|
|
|
|
print "Stop!"
|
|
|
|
else:
|
|
|
|
print music_track_info.title
|
2006-09-23 16:39:58 +02:00
|
|
|
listener = MusicTrackListener.get()
|
|
|
|
listener.connect('music-track-changed', music_track_change_cb)
|
|
|
|
track = listener.get_playing_track()
|
|
|
|
if track is None:
|
|
|
|
print 'Now not playing anything'
|
|
|
|
else:
|
|
|
|
print 'Now playing: "%s" by %s' % (track.title, track.artist)
|
2006-09-23 15:49:33 +02:00
|
|
|
gobject.MainLoop().run()
|