Fix sonos play modes
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 10 Mar 2025 22:09:37 +0000 (23:09 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 10 Mar 2025 22:09:37 +0000 (23:09 +0100)
Fix some weird issues with Sonos repeat mode spontanuous reverting to single repeat

music_assistant/providers/sonos/player.py
music_assistant/providers/sonos/provider.py

index 97ae9005902fbffb1113694abccd14c66cb4d266..04a2acf6313223fb97fbaaac2c3996e480dcfe56 100644 (file)
@@ -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):
index 004e26832614dc9645e5911f4c369b050f1ce4c5..e0470a6399009b8f3eb3fe5657ac8b578a1a3193 100644 (file)
@@ -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",