fix resume playback from off state
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 22 Aug 2021 17:07:02 +0000 (19:07 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 22 Aug 2021 17:07:02 +0000 (19:07 +0200)
music_assistant/constants.py
music_assistant/managers/players.py
music_assistant/providers/chromecast/player.py

index 2ffefab50af74c0c5729b3f2b36f5c08c9717df7..b3e29262d7995aa4018eca0f40e049605a837c33 100755 (executable)
@@ -1,6 +1,6 @@
 """All constants for Music Assistant."""
 
-__version__ = "0.2.7"
+__version__ = "0.2.8"
 REQUIRED_PYTHON_VER = "3.8"
 
 # configuration keys/attributes
index ec122903a5cd96c1a8e614562b4a98e0f89b517c..7b0c45ee921236b6b4c7e03b2fb3569ec379e030 100755 (executable)
@@ -309,8 +309,8 @@ class PlayerManager:
         """
         player = self.get_player(player_id, True)
         player_queue = self.get_active_player_queue(player_id, True)
-        if player_queue.queue_id != player_id and not player.calculated_state.powered:
-            # only force player on if its not the actual queue player
+        # power on player if needed
+        if not player.calculated_state.powered:
             await self.cmd_power_on(player_id)
         # a single item or list of items may be provided
         if not isinstance(items, list):
@@ -382,8 +382,8 @@ class PlayerManager:
             raise FileNotFoundError("Invalid uri: %s" % uri)
         player = self.get_player(player_id, True)
         player_queue = self.get_active_player_queue(player_id, True)
-        if player_queue.queue_id != player_id and not player.calculated_state.powered:
-            # only force player on if its not the actual queue player
+        # power on player if needed
+        if not player.calculated_state.powered:
             await self.cmd_power_on(player_id)
         # load item into the queue
         queue_item = player_queue.create_queue_item(
@@ -438,8 +438,8 @@ class PlayerManager:
                     player.calculated_state.name,
                 )
                 return
-        if player_queue.queue_id != player_id and not player.calculated_state.powered:
-            # only force player on if its not the actual queue player
+        # power on player if needed
+        if not player.calculated_state.powered:
             await self.cmd_power_on(player_id)
         # snapshot the (active) queue
         prev_queue_items = player_queue.items
@@ -539,8 +539,8 @@ class PlayerManager:
         """
         player = self.get_player(player_id, True)
         player_queue = self.get_active_player_queue(player_id)
-        if player_queue.queue_id != player_id and not player.calculated_state.powered:
-            # only force player on if its not the actual queue player
+        # power on player if needed
+        if not player.calculated_state.powered:
             await self.cmd_power_on(player_id)
         # unpause if paused else resume queue
         if player_queue.state == PlayerState.PAUSED:
@@ -567,9 +567,9 @@ class PlayerManager:
         """
         player_queue = self.get_active_player_queue(player_id, True)
         if player_queue.state == PlayerState.PLAYING:
-            await player_queue.pause()
+            await self.cmd_pause(player_queue.queue_id)
         else:
-            await player_queue.play()
+            await self.cmd_play(player_queue.queue_id)
 
     @api_route("players/{player_id}/cmd/next", method="PUT")
     async def cmd_next(self, player_id: str) -> None:
@@ -579,7 +579,10 @@ class PlayerManager:
             :param player_id: player_id of the player to handle the command.
         """
         player_queue = self.get_active_player_queue(player_id, True)
-        await player_queue.next()
+        if player_queue.state == PlayerState.PLAYING:
+            await player_queue.next()
+        else:
+            await self.cmd_play(player_queue.queue_id)
 
     @api_route("players/{player_id}/cmd/previous", method="PUT")
     async def cmd_previous(self, player_id: str):
@@ -589,7 +592,10 @@ class PlayerManager:
             :param player_id: player_id of the player to handle the command.
         """
         player_queue = self.get_active_player_queue(player_id, True)
-        await player_queue.previous()
+        if player_queue.state == PlayerState.PLAYING:
+            await player_queue.previous()
+        else:
+            await self.cmd_play(player_queue.queue_id)
 
     @api_route("players/{player_id}/cmd/power_on", method="PUT")
     async def cmd_power_on(self, player_id: str) -> None:
index 1a8cf650c3f2c8011fc012dca24abb3f8a4cf0ce..67ab1669e0683ef5b44eee0c12c7206d7ba8292d 100644 (file)
@@ -348,8 +348,11 @@ class ChromecastPlayer(Player):
             queue_item = QueueItem(
                 item_id=uri, provider="mass", name="Music Assistant", stream_url=uri
             )
-            return await self.cmd_queue_load([queue_item, queue_item])
-        await self.chromecast_command(self._chromecast.play_media, uri, "audio/flac")
+            await self.cmd_queue_load([queue_item, queue_item])
+        else:
+            await self.chromecast_command(
+                self._chromecast.play_media, uri, "audio/flac"
+            )
 
     async def cmd_queue_load(self, queue_items: List[QueueItem]) -> None:
         """Load (overwrite) queue with new items."""
@@ -367,6 +370,7 @@ class ChromecastPlayer(Player):
         await self.launch_app()
         await self.chromecast_command(self.__send_player_queue, queuedata)
         if len(queue_items) > 25:
+            await asyncio.sleep(5)
             await self.cmd_queue_append(queue_items[26:])
 
     async def cmd_queue_append(self, queue_items: List[QueueItem]) -> None:
@@ -378,8 +382,8 @@ class ChromecastPlayer(Player):
                 "insertBefore": None,
                 "items": chunk,
             }
-            await self.launch_app()
             await self.chromecast_command(self.__send_player_queue, queuedata)
+            await asyncio.sleep(2)
 
     def __create_queue_items(self, tracks) -> None:
         """Create list of CC queue items from tracks."""
@@ -421,32 +425,27 @@ class ChromecastPlayer(Player):
     async def launch_app(self):
         """Launch the default media receiver app and wait until its launched."""
         media_controller = self._chromecast.media_controller
-        if (
-            media_controller.is_active
-            and self.cast_status.app_id == pychromecast.APP_MEDIA_RECEIVER
-            and media_controller.status.media_session_id is not None
-        ):
-            # already active
-            return
-
         event = asyncio.Event()
 
-        def launched():
+        def launched_callback():
             self.mass.loop.call_soon_threadsafe(event.set)
 
         # pylint: disable=protected-access
         receiver_ctrl = media_controller._socket_client.receiver_controller
-        receiver_ctrl.launch_app(
+        await self.mass.loop.run_in_executor(
+            None,
+            receiver_ctrl.launch_app,
             media_controller.app_id,
-            callback_function=launched,
+            False,
+            launched_callback,
         )
         await event.wait()
 
-    async def chromecast_command(self, func, *args, **kwargs):
+    async def chromecast_command(self, func, *args):
         """Execute command on Chromecast."""
         if not self.available:
             LOGGER.warning(
                 "Player %s is not available, command can't be executed", self.name
             )
             return
-        await create_task(func, *args, **kwargs)
+        await self.mass.loop.run_in_executor(None, func, *args)