From 6d0988e1896125249e8f1f785fb490883ba799a5 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sat, 13 Feb 2021 12:44:38 +0100 Subject: [PATCH] fixes for queue streams and players --- music_assistant/constants.py | 2 +- music_assistant/helpers/compare.py | 2 +- music_assistant/managers/players.py | 11 +++--- music_assistant/managers/streams.py | 10 +++--- music_assistant/models/player_queue.py | 36 ++++++++++++------- .../providers/chromecast/__init__.py | 7 ++-- .../providers/chromecast/player.py | 10 +----- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/music_assistant/constants.py b/music_assistant/constants.py index 186735fd..93738cea 100755 --- a/music_assistant/constants.py +++ b/music_assistant/constants.py @@ -1,6 +1,6 @@ """All constants for Music Assistant.""" -__version__ = "0.0.83" +__version__ = "0.0.84" REQUIRED_PYTHON_VER = "3.7" # configuration keys/attributes diff --git a/music_assistant/helpers/compare.py b/music_assistant/helpers/compare.py index 1e357437..098fe704 100644 --- a/music_assistant/helpers/compare.py +++ b/music_assistant/helpers/compare.py @@ -64,7 +64,7 @@ def compare_album(left_album: Album, right_album: Album): ): return True if left_album.upc and right_album.upc: - if left_album.upc in right_album.upc or right_album.upc in left_album.upc: + if (left_album.upc in right_album.upc) or (right_album.upc in left_album.upc): # UPC is always 100% accurate match return True if not compare_strings(left_album.name, right_album.name): diff --git a/music_assistant/managers/players.py b/music_assistant/managers/players.py index bc6a7456..a8ba7164 100755 --- a/music_assistant/managers/players.py +++ b/music_assistant/managers/players.py @@ -149,15 +149,14 @@ class PlayerManager: async def async_add_player(self, player: Player) -> None: """Register a new player or update an existing one.""" - if not player or not player.available or self.mass.exit: + # guard for invalid data or exit in progress + if not player or self.mass.exit: return + # redirect to update if player already exists if player.player_id in self._player_states: return await self.async_update_player(player) - player_enabled = self.mass.config.get_player_config(player.player_id)[ - CONF_ENABLED - ] - if not player_enabled: - # do not add the player to states if it's disabled/unavailable + # do not add the player to states if it's disabled/unavailable + if not self.mass.config.get_player_config(player.player_id)[CONF_ENABLED]: return # set the mass object on the player and call on_add function player.mass = self.mass diff --git a/music_assistant/managers/streams.py b/music_assistant/managers/streams.py index df649df6..a0c810da 100755 --- a/music_assistant/managers/streams.py +++ b/music_assistant/managers/streams.py @@ -152,17 +152,17 @@ class StreamManager: LOGGER.info("Start Queue Stream for player %s ", player_id) - is_start = True last_fadeout_data = b"" + queue_index = None while True: # get the (next) track in queue - if is_start: + if queue_index is None: # report start of queue playback so we can calculate current track/duration etc. - queue_track = await player_queue.async_start_queue_stream() - is_start = False + queue_index = await player_queue.async_queue_stream_start() else: - queue_track = player_queue.next_item + queue_index = await player_queue.async_queue_stream_next(queue_index) + queue_track = player_queue.get_item(queue_index) if not queue_track: LOGGER.info("no (more) tracks left in queue") break diff --git a/music_assistant/models/player_queue.py b/music_assistant/models/player_queue.py index bcc916de..c6015fc3 100755 --- a/music_assistant/models/player_queue.py +++ b/music_assistant/models/player_queue.py @@ -72,8 +72,8 @@ class PlayerQueue: self._cur_index = 0 self._cur_item_time = 0 self._last_item = None - self._next_queue_startindex = 0 - self._last_queue_startindex = 0 + self._queue_stream_start_index = 0 + self._queue_stream_next_index = 0 self._last_player_state = PlaybackState.Stopped # load previous queue settings from disk self.mass.add_job(self.__async_restore_saved_state()) @@ -315,8 +315,9 @@ class PlayerQueue: index = self.__index_by_id(index) if not len(self.items) > index: return + self._cur_index = index + self._queue_stream_next_index = index if self.use_queue_stream: - self._next_queue_startindex = index queue_stream_uri = self.get_stream_url() return await self.player.async_cmd_play_uri(queue_stream_uri) if self.supports_queue: @@ -502,7 +503,6 @@ class PlayerQueue: # process new index if self._cur_index != new_index: # queue track updated - self._next_queue_startindex = self.next_index self._cur_index = new_index # check if a new track is loaded, wait for the streamdetails if ( @@ -524,11 +524,22 @@ class PlayerQueue: {"queue_id": self.queue_id, "cur_item_time": track_time}, ) - async def async_start_queue_stream(self) -> None: + async def async_queue_stream_start(self) -> None: """Call when queue_streamer starts playing the queue stream.""" - self._last_queue_startindex = self._next_queue_startindex self._cur_item_time = 0 - return self.get_item(self._next_queue_startindex) + self._cur_index = self._queue_stream_next_index + return self._queue_stream_next_index + + async def async_queue_stream_next(self, cur_index: int) -> None: + """Call when queue_streamer loads next track in buffer.""" + next_index = 0 + if len(self.items) > (next_index): + next_index = cur_index + 1 + elif self._repeat_enabled: + # repeat enabled, start queue at beginning + next_index = 0 + self._queue_stream_next_index = next_index + 1 + return next_index def to_dict(self) -> dict: """Instance attributes as dict so it can be serialized to json.""" @@ -555,9 +566,9 @@ class PlayerQueue: elapsed_time_queue = self.player.elapsed_time total_time = 0 track_time = 0 - if self.items and len(self.items) > self._last_queue_startindex: + if self.items and len(self.items) > self._queue_stream_start_index: queue_index = ( - self._last_queue_startindex + self._queue_stream_start_index ) # holds the last starting position queue_track = None while len(self.items) > queue_index: @@ -593,8 +604,8 @@ class PlayerQueue: self._shuffle_enabled = cache_data["shuffle_enabled"] self._repeat_enabled = cache_data["repeat_enabled"] self._items = cache_data["items"] - self._cur_index = cache_data["cur_item"] - self._next_queue_startindex = cache_data["next_queue_index"] + self._cur_index = cache_data.get("cur_index", 0) + self._queue_stream_next_index = self._cur_index # pylint: enable=unused-argument @@ -605,8 +616,7 @@ class PlayerQueue: "shuffle_enabled": self._shuffle_enabled, "repeat_enabled": self._repeat_enabled, "items": self._items, - "cur_item": self._cur_index, - "next_queue_index": self._next_queue_startindex, + "cur_index": self._cur_index, } await self.mass.cache.async_set(cache_str, cache_data) LOGGER.info("queue state saved to file for player %s", self.queue_id) diff --git a/music_assistant/providers/chromecast/__init__.py b/music_assistant/providers/chromecast/__init__.py index f6efdc4e..12ae3ab5 100644 --- a/music_assistant/providers/chromecast/__init__.py +++ b/music_assistant/providers/chromecast/__init__.py @@ -1,7 +1,6 @@ """ChromeCast playerprovider.""" import logging -import uuid from typing import List import pychromecast @@ -74,8 +73,8 @@ class ChromecastProvider(PlayerProvider): def __chromecast_add_update_callback(self, cast_uuid, cast_service_name): """Handle zeroconf discovery of a new or updated chromecast.""" # pylint: disable=unused-argument - if uuid is None: - return # Discovered chromecast without uuid + if cast_uuid is None: + return # Discovered chromecast without uuid? service = self._listener.services[cast_uuid] cast_info = ChromecastInfo( @@ -94,7 +93,7 @@ class ChromecastProvider(PlayerProvider): if not player: player = ChromecastPlayer(self.mass, cast_info) # if player was already added, the player will take care of reconnects itself. - self.mass.add_job(player.async_set_cast_info, cast_info) + player.set_cast_info(cast_info) self.mass.add_job(self.mass.players.async_add_player(player)) @staticmethod diff --git a/music_assistant/providers/chromecast/player.py b/music_assistant/providers/chromecast/player.py index 43748c29..84d47d6d 100644 --- a/music_assistant/providers/chromecast/player.py +++ b/music_assistant/providers/chromecast/player.py @@ -194,14 +194,6 @@ class ChromecastPlayer(Player): async def async_on_add(self) -> None: """Call when player is added to the player manager.""" - # Only setup the chromecast once, changes will automatically be picked up. - if self._chromecast is not None: - return - LOGGER.debug( - "[%s] Connecting to cast device by service %s", - self._cast_info.friendly_name, - self.services, - ) chromecast = await self.mass.loop.run_in_executor( None, pychromecast.get_chromecast_from_service, @@ -227,7 +219,7 @@ class ChromecastPlayer(Player): chromecast.mz_controller = mz_controller self._chromecast.start() - async def async_set_cast_info(self, cast_info: ChromecastInfo) -> None: + def set_cast_info(self, cast_info: ChromecastInfo) -> None: """Set (or update) the cast discovery info.""" self._cast_info = cast_info -- 2.34.1