changed_values = self.__calculate_player_state()
if prev_media_checksum != self._get_player_media_checksum():
# current media changed, call the media updated callback
- self._on_player_media_updated()
+ # debounce the callback to avoid multiple calls when multiple
+ # state updates happen in a short time
+ self.mass.call_later(
+ 1, self._on_player_media_updated, task_id=f"player_media_updated_{self.player_id}"
+ )
# ignore some values that are not relevant for the state
changed_values.pop("elapsed_time_last_updated", None)
changed_values.pop("extra_attributes.seq_no", None)
self._total_bytes_sent = 0
self._stream_bytes_sent = 0
self._connected = asyncio.Event()
+ self._metadata_checksum = ""
+ self._last_metadata_sent: float = 0.0
@property
def running(self) -> bool:
# to ignore it the first time
# https://github.com/music-assistant/support/issues/3330
self.mass.call_later(2, self.send_cli_command(f"VOLUME={self.player.volume_level}"))
+ # we also need to send the metadata after connection, because some players (e.g. Sonos)
+ # simply won't start playback until they receive the metadata ?!
+ self.mass.call_later(2, self.player._on_player_media_updated)
async def stop(self, force: bool = False) -> None:
"""
title = metadata.title or ""
artist = metadata.artist or ""
album = metadata.album or ""
+
+ metadata_checksum = f"{title}|{artist}|{album}|{duration}|{metadata.image_url}"
+ if (
+ metadata_checksum == self._metadata_checksum
+ and time.time() - self._last_metadata_sent <= 2
+ ):
+ # metadata has not changed since last time, skip sending to CLI
+ return
+ self._metadata_checksum = metadata_checksum
+ self._last_metadata_sent = time.time()
+
cmd = f"TITLE={title}\nARTIST={artist}\nALBUM={album}\n"
cmd += f"DURATION={duration}\nPROGRESS=0\nACTION=SENDMETA\n"
+
await self.send_cli_command(cmd)
# get image
if metadata.image_url: