import os from dbus.mainloop.glib import DBusGMainLoop import dbus import dbus.service import requests from gi.repository import GLib OBJECT_PATH = '/org/mpris/MediaPlayer2' MEDIAPLAYER_INTERFACE = 'org.mpris.MediaPlayer2' MEDIAPLAYER_PLAYER_INTERFACE = 'org.mpris.MediaPlayer2.Player' MPRIS_URL = 'org.mpris.MediaPlayer2.top2000' def get_now_playing(): url = 'https://www.nporadio2.nl/api/miniplayer/info?channel=npo-radio-2' response = requests.get(url) data = response.json() return data['data']['radioTrackPlays']['data'][0] class MmprisApiPlayer(dbus.service.Object): def __init__(self): bus = dbus.service.BusName(MPRIS_URL, bus=dbus.SessionBus()) super().__init__(bus, OBJECT_PATH) self.last_song = None self._properties = dbus.Dictionary({ 'DesktopEntry': 'top2000', 'Identity': 'top2000', 'CanQuit': False, 'CanRaise': False, 'HasTrackList': False, 'SupportedUriSchemes': [], 'SupportedMimeTypes': [], }, signature='sv') self._current_position = 0 self._player_properties = dbus.Dictionary({ 'Metadata': dbus.Dictionary({ 'mpris:length': dbus.Int64(0), 'mpris:artUrl': '', 'xesam:artist': ['None'], 'xesam:title': 'None', 'xesam:url': '', 'xesam:album': 'None' }, signature='sv', variant_level=1), 'Rate': 1.0, 'MinimumRate': 1.0, 'MaximumRate': 1.0, 'CanGoNext': False, 'CanGoPrevious': False, 'CanControl': False, 'CanSeek': False, 'CanPause': False, 'CanPlay': True, 'Position': dbus.Int64(0), 'PlaybackStatus': 'Playing', 'Volume': 1.0, }, signature='sv', variant_level=2) @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') def Get(self, interface, prop): return self.GetAll(interface)[prop] @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv') def Set(self, interface, prop, value): self._player_properties[prop] = value if prop == 'Volume': self._app.player.volume = int(100 * value) @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') def GetAll(self, interface): if interface == MEDIAPLAYER_PLAYER_INTERFACE: return self._player_properties elif interface == MEDIAPLAYER_INTERFACE: return self._properties else: raise dbus.exceptions.DBusException( 'com.example.UnknownInterface', 'The TOP2000 mpris object does not implement the %s interface' % interface ) @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as') def PropertiesChanged(self, interface, changed_properties, invalidated_properties=[]): pass def _song_change(self, playing): if playing == self.last_song: return self.last_song = playing data = { 'xesam:artist': [playing['artist']], 'xesam:album': playing['album'] if 'album' in playing else '', 'xesam:title': playing['name'] if 'name' in playing else playing['song'], } if 'radioTracks' in playing and 'coverUrl' in playing['radioTracks'] and playing['radioTracks']['coverUrl']: data['mpris:artUrl'] = playing['radioTracks']['coverUrl'] print("Now playing", data) props = dbus.Dictionary({ 'Metadata': dbus.Dictionary(data, signature='sv'), 'Position': dbus.Int64(0), }, signature='sv') self._player_properties.update(props) self.PropertiesChanged(MEDIAPLAYER_PLAYER_INTERFACE, props, []) self.PropertiesChanged(MEDIAPLAYER_PLAYER_INTERFACE, {'PlaybackStatus': 'playing'}, []) def update_song_info(): data = get_now_playing() server._song_change(data) return True if __name__ == '__main__': DBusGMainLoop(set_as_default=True) mainloop = GLib.MainLoop() GLib.timeout_add(10000, update_song_info) server = MmprisApiPlayer() update_song_info() mainloop.run()