keep MPRIS always alive

This commit is contained in:
Martin Wagner 2020-09-25 17:13:39 +02:00
parent 76e149b04b
commit 375fe48fa0

View File

@ -64,6 +64,9 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
self._metadata={} self._metadata={}
self._bus=dbus.SessionBus() self._bus=dbus.SessionBus()
# start
self._bus_name=dbus.service.BusName(self._name, bus=self._bus, allow_replacement=True, replace_existing=True) # TODO
# connect # connect
self._client.emitter.connect("state", self._on_state_changed) self._client.emitter.connect("state", self._on_state_changed)
self._client.emitter.connect("current_song_changed", self._on_song_changed) self._client.emitter.connect("current_song_changed", self._on_song_changed)
@ -71,7 +74,7 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
self._client.emitter.connect("repeat", self._on_loop_changed) self._client.emitter.connect("repeat", self._on_loop_changed)
self._client.emitter.connect("single", self._on_loop_changed) self._client.emitter.connect("single", self._on_loop_changed)
self._client.emitter.connect("random", self._on_random_changed) self._client.emitter.connect("random", self._on_random_changed)
self._client.emitter.connect("disconnected", self._on_disconnected) self._client.emitter.connect("connection_error", self._on_connection_error)
self._client.emitter.connect("reconnected", self._on_reconnected) self._client.emitter.connect("reconnected", self._on_reconnected)
# Interfaces # Interfaces
@ -88,10 +91,13 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
} }
def __get_playback_status(self): def __get_playback_status(self):
if self._client.connected():
status=self._client.wrapped_call("status") status=self._client.wrapped_call("status")
return {"play": "Playing", "pause": "Paused", "stop": "Stopped"}[status["state"]] return {"play": "Playing", "pause": "Paused", "stop": "Stopped"}[status["state"]]
return "Stopped"
def __set_loop_status(self, value): def __set_loop_status(self, value):
if self._client.connected():
if value == "Playlist": if value == "Playlist":
self._client.wrapped_call("repeat", 1) self._client.wrapped_call("repeat", 1)
self._client.wrapped_call("single", 0) self._client.wrapped_call("single", 0)
@ -106,6 +112,7 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
return return
def __get_loop_status(self): def __get_loop_status(self):
if self._client.connected():
status=self._client.wrapped_call("status") status=self._client.wrapped_call("status")
if int(status["repeat"]) == 1: if int(status["repeat"]) == 1:
if int(status.get("single", 0)) == 1: if int(status.get("single", 0)) == 1:
@ -114,46 +121,52 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
return "Playlist" return "Playlist"
else: else:
return "None" return "None"
return "None"
def __set_shuffle(self, value): def __set_shuffle(self, value):
if self._client.connected():
self._client.wrapped_call("random", value) self._client.wrapped_call("random", value)
return return
def __get_shuffle(self): def __get_shuffle(self):
if self._client.connected():
if int(self._client.wrapped_call("status")["random"]) == 1: if int(self._client.wrapped_call("status")["random"]) == 1:
return True return True
else: else:
return False return False
return False
def __get_metadata(self): def __get_metadata(self):
return dbus.Dictionary(self._metadata, signature="sv") return dbus.Dictionary(self._metadata, signature="sv")
def __get_volume(self): def __get_volume(self):
vol=float(self._client.wrapped_call("status").get("volume", 0)) if self._client.connected():
if vol > 0: return float(self._client.wrapped_call("status").get("volume", 0))/100
return vol / 100.0
else:
return 0.0 return 0.0
def __set_volume(self, value): def __set_volume(self, value):
if self._client.connected():
if value >= 0 and value <= 1: if value >= 0 and value <= 1:
self._client.wrapped_call("setvol", int(value * 100)) self._client.wrapped_call("setvol", int(value * 100))
return return
def __get_position(self): def __get_position(self):
if self._client.connected():
status=self._client.wrapped_call("status") status=self._client.wrapped_call("status")
if "time" in status: return dbus.Int64(float(status.get("elapsed", 0))*1000000)
current, end=status["time"].split(":")
return dbus.Int64((int(current) * 1000000))
else:
return dbus.Int64(0) return dbus.Int64(0)
def __get_can_next_prev(self): def __get_can_next_prev(self):
if self._client.connected():
status=self._client.wrapped_call("status") status=self._client.wrapped_call("status")
if status["state"] == "stop": if status["state"] == "stop":
return False return False
else: else:
return True return True
return False
def __get_can_play_pause_seek(self):
return self._client.connected()
__player_interface="org.mpris.MediaPlayer2.Player" __player_interface="org.mpris.MediaPlayer2.Player"
__player_props={ __player_props={
@ -168,9 +181,9 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
"MaximumRate": (1.0, None), "MaximumRate": (1.0, None),
"CanGoNext": (__get_can_next_prev, None), "CanGoNext": (__get_can_next_prev, None),
"CanGoPrevious": (__get_can_next_prev, None), "CanGoPrevious": (__get_can_next_prev, None),
"CanPlay": (True, None), "CanPlay": (__get_can_play_pause_seek, None),
"CanPause": (True, None), "CanPause": (__get_can_play_pause_seek, None),
"CanSeek": (True, None), "CanSeek": (__get_can_play_pause_seek, None),
"CanControl": (True, None), "CanControl": (True, None),
} }
__prop_mapping={ __prop_mapping={
@ -357,12 +370,15 @@ class MPRISInterface(dbus.service.Object): # TODO emit Seeked if needed
self._update_property("org.mpris.MediaPlayer2.Player", "Shuffle") self._update_property("org.mpris.MediaPlayer2.Player", "Shuffle")
def _on_reconnected(self, *args): def _on_reconnected(self, *args):
self._bus_name=dbus.service.BusName(self._name, bus=self._bus, allow_replacement=True, replace_existing=True) # TODO properties=("CanPlay","CanPause","CanSeek")
for p in properties:
self._update_property("org.mpris.MediaPlayer2.Player", p)
def _on_disconnected(self, *args): def _on_connection_error(self, *args):
if hasattr(self, "_bus_name"):
del self._bus_name
self._metadata={} self._metadata={}
properties=("PlaybackStatus","CanGoNext","CanGoPrevious","Metadata","Volume","LoopStatus","Shuffle","CanPlay","CanPause","CanSeek")
for p in properties:
self._update_property("org.mpris.MediaPlayer2.Player", p)
###################### ######################
# MPD client wrapper # # MPD client wrapper #