From fc5e5a51b8e3a01cb57dd661966ba36363ed469d Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Mon, 10 Mar 2025 23:09:37 +0100 Subject: [PATCH] Fix sonos play modes Fix some weird issues with Sonos repeat mode spontanuous reverting to single repeat --- music_assistant/providers/sonos/player.py | 12 +++++++++-- music_assistant/providers/sonos/provider.py | 22 ++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/music_assistant/providers/sonos/player.py b/music_assistant/providers/sonos/player.py index 97ae9005..04a2acf6 100644 --- a/music_assistant/providers/sonos/player.py +++ b/music_assistant/providers/sonos/player.py @@ -510,7 +510,11 @@ class SonosPlayer: if not self.client.player.is_coordinator: return # sync crossfade and repeat modes - queue = self.mass.player_queues.get(event.object_id) + await self.sync_play_modes(event.object_id) + + async def sync_play_modes(self, queue_id: str) -> None: + """Sync the play modes between MA and Sonos.""" + queue = self.mass.player_queues.get(queue_id) if not queue or queue.state not in (PlayerState.PLAYING, PlayerState.PAUSED): return crossfade = await self.mass.config.get_player_config_value(queue.queue_id, CONF_CROSSFADE) @@ -521,10 +525,14 @@ class SonosPlayer: play_modes.crossfade != crossfade or play_modes.repeat != repeat_all_enabled or play_modes.repeat_one != repeat_single_enabled + or play_modes.shuffle != queue.shuffle_enabled ): try: await self.client.player.group.set_play_modes( - crossfade=crossfade, repeat=repeat_all_enabled, repeat_one=repeat_single_enabled + crossfade=crossfade, + repeat=repeat_all_enabled, + repeat_one=repeat_single_enabled, + shuffle=queue.shuffle_enabled, ) except FailedCommand as err: if "groupCoordinatorChanged" not in str(err): diff --git a/music_assistant/providers/sonos/provider.py b/music_assistant/providers/sonos/provider.py index 004e2683..e0470a63 100644 --- a/music_assistant/providers/sonos/provider.py +++ b/music_assistant/providers/sonos/provider.py @@ -331,6 +331,7 @@ class SonosPlayerProvider(PlayerProvider): item_id=media.queue_item_id, queue_version=sonos_player.queue_version, ) + self.mass.call_later(5, sonos_player.sync_play_modes, media.queue_id) return # play a single uri/url @@ -497,20 +498,18 @@ class SonosPlayerProvider(PlayerProvider): "reports": { "sendUpdateAfterMillis": 1000, "periodicIntervalMillis": 30000, - "sendPlaybackActions": True, + "sendPlaybackActions": False, }, "playbackPolicies": { "canSkip": True, "limitedSkips": False, "canSkipToItem": True, "canSkipBack": True, - "canSeek": False, # somehow not working correctly, investigate later + "canSeek": True, "canRepeat": True, "canRepeatOne": True, "canCrossfade": True, - "canShuffle": False, # handled by our queue controller itself - "showNNextTracks": 5, - "showNPreviousTracks": 5, + "canShuffle": True, }, } return web.json_response(result) @@ -542,14 +541,23 @@ class SonosPlayerProvider(PlayerProvider): async def _parse_sonos_queue_item(self, queue_item: QueueItem) -> dict[str, Any]: """Parse a Sonos queue item to a PlayerMedia object.""" + stream_url = await self.mass.streams.resolve_stream_url(queue_item) return { "id": queue_item.queue_item_id, "deleted": not queue_item.available, - "policies": {}, + "policies": { + "canCrossfade": True, + "canSkip": True, + "canSkipBack": True, + "canSkipToItem": True, + "canSeek": True, + "canRepeat": True, + "canRepeatOne": True, + }, "track": { "type": "track", "mediaUrl": await self.mass.streams.resolve_stream_url(queue_item), - "contentType": "audio/flac", + "contentType": f"audio/{stream_url.split('.')[-1]}", "service": { "name": "Music Assistant", "id": "8", -- 2.34.1