From 7e2b26510d88269d47d4eb0bee9217ca85ea0c3f Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Mon, 10 Jun 2019 15:14:51 +0200 Subject: [PATCH] fix the queue stream --- music_assistant/models.py | 2 -- music_assistant/modules/http_streamer.py | 11 +++++-- music_assistant/modules/player.py | 4 ++- .../modules/playerproviders/chromecast.py | 31 +++++++++++++------ .../modules/playerproviders/lms.py | 5 ++- .../modules/playerproviders/pylms.py | 4 +++ 6 files changed, 40 insertions(+), 17 deletions(-) diff --git a/music_assistant/models.py b/music_assistant/models.py index 982b0a48..1de7e006 100755 --- a/music_assistant/models.py +++ b/music_assistant/models.py @@ -505,8 +505,6 @@ class MusicPlayer(): self.powered = False self.cur_item = None self.cur_item_time = 0 - self.cur_queue_index = 0 - self.next_queue_index = 0 self.volume_level = 0 self.shuffle_enabled = True self.repeat_enabled = False diff --git a/music_assistant/modules/http_streamer.py b/music_assistant/modules/http_streamer.py index 1effcbf8..0c89ee6f 100755 --- a/music_assistant/modules/http_streamer.py +++ b/music_assistant/modules/http_streamer.py @@ -134,7 +134,7 @@ class HTTPStreamer(): use case is enable crossfade support for chromecast devices ''' player_id = http_request.query.get('player_id') - startindex = int(http_request.query.get('startindex', 0)) + startindex = int(http_request.query.get('startindex')) cancelled = threading.Event() resp = web.StreamResponse(status=200, reason='OK', @@ -179,9 +179,14 @@ class HTTPStreamer(): await buffer.put(b'') # indicate EOF asyncio.create_task(fill_buffer()) + player = await self.mass.player.player(player_id) + + # retrieve player object player = await self.mass.player.player(player_id) queue_index = startindex + LOGGER.info("Start Queue Stream for player %s at index %s" %(player_id, queue_index)) last_fadeout_data = b'' + # report start of queue playback so we can calculate current track/duration etc. self.mass.event_loop.create_task(self.mass.player.player_queue_stream_update(player_id, queue_index, True)) while True: # get the (next) track in queue @@ -265,14 +270,14 @@ class HTTPStreamer(): while buffer.qsize() > 1 and not cancelled.is_set(): await asyncio.sleep(1) # end of the track reached - LOGGER.info("Finished Streaming queue track: %s - %s" % (track_id, queue_track.name)) - # update actual duration to the queue for more accurate now playing info + # WIP: update actual duration to the queue for more accurate now playing info accurate_duration = bytes_written / int(sample_rate * 4 * 2) queue_track.duration = accurate_duration self.mass.player.providers[player.player_provider]._player_queue[player_id][queue_index] = queue_track # move to next queue index queue_index += 1 self.mass.event_loop.create_task(self.mass.player.player_queue_stream_update(player_id, queue_index, False)) + LOGGER.info("Finished Streaming queue track: %s - %s" % (track_id, queue_track.name)) # break out the loop if the http session is cancelled if cancelled.is_set(): break diff --git a/music_assistant/modules/player.py b/music_assistant/modules/player.py index add13064..52fd7a68 100755 --- a/music_assistant/modules/player.py +++ b/music_assistant/modules/player.py @@ -392,7 +392,9 @@ class Player(): async def player_queue_index(self, player_id): ''' get current index of the player's queue ''' - return self._players[player_id].cur_queue_index + player = self._players[player_id] + player_prov = self.providers[player.player_provider] + return await player_prov.player_queue_index(player_id) async def player_queue_stream_update(self, player_id, cur_index, is_start=False): ''' called by our queue streamer when it started playing the queue from position x ''' diff --git a/music_assistant/modules/playerproviders/chromecast.py b/music_assistant/modules/playerproviders/chromecast.py index adb887b2..05c26d8a 100644 --- a/music_assistant/modules/playerproviders/chromecast.py +++ b/music_assistant/modules/playerproviders/chromecast.py @@ -52,7 +52,8 @@ class ChromecastProvider(PlayerProvider): self._players = {} self._chromecasts = {} self._player_queue = {} - self._player_queue_startindex = {} + self._player_queue_index = {} + self._player_queue_stream_startindex = {} self.supported_musicproviders = ['http'] asyncio.ensure_future(self.__discover_chromecasts()) @@ -87,12 +88,12 @@ class ChromecastProvider(PlayerProvider): elif cmd == 'next': enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0 if enable_crossfade: - await self.__play_stream_queue(player_id, self._players[player_id].cur_queue_index+1) + await self.__play_stream_queue(player_id, self._player_queue_index[player_id]+1) else: self._chromecasts[player_id].media_controller.queue_next() elif cmd == 'previous': if enable_crossfade: - await self.__play_stream_queue(player_id, self._players[player_id].cur_queue_index-1) + await self.__play_stream_queue(player_id, self._player_queue_index[player_id]-1) else: self._chromecasts[player_id].media_controller.queue_prev() elif cmd == 'power' and cmd_args == 'off': @@ -115,12 +116,16 @@ class ChromecastProvider(PlayerProvider): ''' return the current items in the player's queue ''' return self._player_queue[player_id][offset:limit] + async def player_queue_index(self, player_id): + ''' get current index of the player's queue ''' + return self._player_queue_index[player_id] + async def play_media(self, player_id, media_items, queue_opt='play'): ''' play media on a player ''' castplayer = self._chromecasts[player_id] - cur_queue_index = self._players[player_id].cur_queue_index + cur_queue_index = self._player_queue_index.get(player_id, 0) enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0 if queue_opt == 'replace' or not self._player_queue[player_id]: @@ -161,7 +166,8 @@ class ChromecastProvider(PlayerProvider): async def player_queue_stream_update(self, player_id, cur_index, is_start=False): ''' called by our queue streamer when it started playing a track in the queue at index X ''' if is_start: - self._player_queue_startindex[player_id] = cur_index + self._player_queue_stream_startindex[player_id] = cur_index + self._player_queue_index[player_id] = cur_index # schedule update a few times as we don't know how much time is prebuffered for i in range(0, 20): castplayer = self._chromecasts[player_id] @@ -308,17 +314,21 @@ class ChromecastProvider(PlayerProvider): player.state = PlayerState.Paused else: player.state = PlayerState.Stopped - if not 'stream_queue' in mediastatus.content_id: + if not mediastatus.content_id: + player.cur_item = None + player.cur_item_time = 0 + elif not 'stream_queue' in mediastatus.content_id: player.cur_item = await self.__parse_track(mediastatus) player.cur_item_time = mediastatus.adjusted_current_time - player.cur_queue_index = await self.__get_cur_queue_index(player_id, mediastatus.content_id) - else: + self._player_queue_index[player_id] = await self.__get_cur_queue_index(player_id, mediastatus.content_id) + elif 'stream_queue' in mediastatus.content_id: + # player is playing our special queue continuous stream # try to work out the current time # player is playing a constant stream of the queue so we need to do this the hard way cur_time_queue = mediastatus.adjusted_current_time total_time = 0 track_time = 0 - queue_index = self._player_queue_startindex[player_id] + queue_index = self._player_queue_stream_startindex[player_id] queue_track = None while True: queue_track = self._player_queue[player_id][queue_index] @@ -330,7 +340,7 @@ class ChromecastProvider(PlayerProvider): break player.cur_item = queue_track player.cur_item_time = track_time - player.cur_queue_index = queue_index + self._player_queue_index[player_id] = queue_index await self.mass.player.update_player(player) async def __parse_track(self, mediastatus): @@ -413,6 +423,7 @@ class ChromecastProvider(PlayerProvider): if not player_id in self._player_queue: # TODO: persistant storage of player queue ? self._player_queue[player_id] = [] + self._player_queue_index[player_id] = 0 chromecast.wait() @run_periodic(600) diff --git a/music_assistant/modules/playerproviders/lms.py b/music_assistant/modules/playerproviders/lms.py index a50595ad..5eb166ad 100644 --- a/music_assistant/modules/playerproviders/lms.py +++ b/music_assistant/modules/playerproviders/lms.py @@ -49,7 +49,6 @@ class LMSProvider(PlayerProvider): self._players = {} self._host = hostname self._port = port - self._players = {} self.last_msg_received = 0 self.supported_musicproviders = ['qobuz', 'file', 'spotify', 'http'] self.http_session = aiohttp.ClientSession(loop=mass.event_loop) @@ -127,6 +126,10 @@ class LMSProvider(PlayerProvider): items.append(track) return items + async def player_queue_index(self, player_id): + ''' get current index of the player's queue ''' + raise NotImplementedError() + ### Provider specific (helper) methods ##### async def __get_players(self): diff --git a/music_assistant/modules/playerproviders/pylms.py b/music_assistant/modules/playerproviders/pylms.py index bbaf6595..15c06088 100644 --- a/music_assistant/modules/playerproviders/pylms.py +++ b/music_assistant/modules/playerproviders/pylms.py @@ -101,6 +101,10 @@ class PyLMSServer(PlayerProvider): ''' return the current items in the player's queue ''' return self._player_queue[player_id][offset:limit] + async def player_queue_index(self, player_id): + ''' get current index of the player's queue ''' + return self._player_queue_index.get(player_id, 0) + async def play_media(self, player_id, media_items, queue_opt='play'): ''' play media on a player -- 2.34.1