From: Marcel van der Veldt Date: Tue, 27 Aug 2019 06:42:27 +0000 (+0200) Subject: chromecast discovery X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=69768254dfab888e3266b8d667fd45ab4e23b91e;p=music-assistant-server.git chromecast discovery trigger rescan if command fails --- diff --git a/music_assistant/modules/player.py b/music_assistant/modules/player.py index da0e50a4..0276c9ea 100755 --- a/music_assistant/modules/player.py +++ b/music_assistant/modules/player.py @@ -199,10 +199,24 @@ class Player(): player_childs = [item for item in self._players.values() if item.group_parent == player_id] if player.settings['apply_group_volume']: player_details.volume_level = await self.__get_group_volume(player_childs) - # compare values to detect changes + # detect current track changes if player.cur_item and player_details.cur_item and player.cur_item.name != player_details.cur_item.name: + # track changed + player_changed = True + LOGGER.info("%s -- STOP PLAYING %s -- SECONDS PLAYED: %s" %(player.name, player.cur_item.name, player.cur_item_time)) + LOGGER.info("%s -- START PLAYING %s" %(player.name, player_details.cur_item.name)) + player.cur_item = player_details.cur_item + elif not player.cur_item and player_details.cur_item: + # player started playing player_changed = True - player.cur_item = player_details.cur_item + LOGGER.info("%s -- START PLAYING %s" %(player.name, player_details.cur_item.name)) + player.cur_item = player_details.cur_item + elif player.cur_item and not player_details.cur_item: + # player queue cleared + player_changed = True + LOGGER.info("%s -- STOP PLAYING %s -- SECONDS PLAYED: %s" %(player.name, player.cur_item.name, player.cur_item_time)) + player.cur_item = player_details.cur_item + # compare values to detect changes for key, cur_value in player.__dict__.items(): if key != 'settings': new_value = getattr(player_details, key) diff --git a/music_assistant/modules/playerproviders/chromecast.py b/music_assistant/modules/playerproviders/chromecast.py index 6e1898bb..cbc11cf2 100644 --- a/music_assistant/modules/playerproviders/chromecast.py +++ b/music_assistant/modules/playerproviders/chromecast.py @@ -49,8 +49,9 @@ class ChromecastProvider(PlayerProvider): self._player_queue = {} self._player_queue_index = {} self._player_queue_stream_startindex = {} + self._discovery_running = False self.supported_musicproviders = ['http'] - self.mass.event_loop.create_task(self.__chromecast_discovery()) + self.mass.event_loop.create_task(self.__periodic_chromecast_discovery()) ### Provider specific implementation ##### @@ -65,48 +66,52 @@ class ChromecastProvider(PlayerProvider): async def player_command(self, player_id, cmd:str, cmd_args=None): ''' issue command on player (play, pause, next, previous, stop, power, volume, mute) ''' - if cmd == 'play': - self._players[player_id].powered = True - if self._chromecasts[player_id].media_controller.status.player_is_playing: - pass - elif self._chromecasts[player_id].media_controller.status.player_is_paused: - self._chromecasts[player_id].media_controller.play() - else: - await self.__resume_queue(player_id) - await self.mass.player.update_player(self._players[player_id]) - elif cmd == 'pause': - self._chromecasts[player_id].media_controller.pause() - elif cmd == 'stop': - self._chromecasts[player_id].media_controller.stop() - 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._player_queue_index[player_id]+1) - else: - self._chromecasts[player_id].media_controller.queue_next() - elif cmd == 'previous': - enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0 - if enable_crossfade: - 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': - self._players[player_id].powered = False - if not self._players[player_id].group_parent: - self._chromecasts[player_id].quit_app() # power is not supported so send quit_app instead - await self.mass.player.update_player(self._players[player_id]) - elif cmd == 'power': - self._players[player_id].powered = True - await self.mass.player.update_player(self._players[player_id]) - elif cmd == 'volume': - new_volume = try_parse_int(cmd_args) - self._chromecasts[player_id].set_volume(new_volume/100) - self._players[player_id].volume_level = new_volume - await self.mass.player.update_player(self._players[player_id]) - elif cmd == 'mute' and cmd_args == 'off': - self._chromecasts[player_id].set_volume_muted(False) - elif cmd == 'mute': - self._chromecasts[player_id].set_volume_muted(True) + try: + if cmd == 'play': + self._players[player_id].powered = True + if self._chromecasts[player_id].media_controller.status.player_is_playing: + pass + elif self._chromecasts[player_id].media_controller.status.player_is_paused: + self._chromecasts[player_id].media_controller.play() + else: + await self.__resume_queue(player_id) + await self.mass.player.update_player(self._players[player_id]) + elif cmd == 'pause': + self._chromecasts[player_id].media_controller.pause() + elif cmd == 'stop': + self._chromecasts[player_id].media_controller.stop() + 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._player_queue_index[player_id]+1) + else: + self._chromecasts[player_id].media_controller.queue_next() + elif cmd == 'previous': + enable_crossfade = self.mass.config['player_settings'][player_id]["crossfade_duration"] > 0 + if enable_crossfade: + 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': + self._players[player_id].powered = False + if not self._players[player_id].group_parent: + self._chromecasts[player_id].quit_app() # power is not supported so send quit_app instead + await self.mass.player.update_player(self._players[player_id]) + elif cmd == 'power': + self._players[player_id].powered = True + await self.mass.player.update_player(self._players[player_id]) + elif cmd == 'volume': + new_volume = try_parse_int(cmd_args) + self._chromecasts[player_id].set_volume(new_volume/100) + self._players[player_id].volume_level = new_volume + await self.mass.player.update_player(self._players[player_id]) + elif cmd == 'mute' and cmd_args == 'off': + self._chromecasts[player_id].set_volume_muted(False) + elif cmd == 'mute': + self._chromecasts[player_id].set_volume_muted(True) + except pychromecast.error.NotConnected: + # CC is not connected, trigger rescan + self.mass.event_loop.create_task(self.__chromecast_discovery()) async def player_queue(self, player_id, offset=0, limit=50): ''' return the current items in the player's queue ''' @@ -388,9 +393,16 @@ class ChromecastProvider(PlayerProvider): self._players[member].group_parent = str(mz._uuid) self.mass.event_loop.create_task(self.mass.player.update_player(self._players[member])) - @run_periodic(300) + @run_periodic(1800) + async def __periodic_chromecast_discovery(self): + ''' run chromecast discovery on interval ''' + await self.__chromecast_discovery() + async def __chromecast_discovery(self): ''' background non-blocking chromecast discovery and handler ''' + if self._discovery_running: + return + self._discovery_running = True # remove any disconnected players... removed_players = [] for player_id, cast in self._chromecasts.items(): @@ -399,9 +411,9 @@ class ChromecastProvider(PlayerProvider): removed_players.append(player_id) for player_id in removed_players: self._chromecasts[player_id].socket_client.stop.set() + await asyncio.sleep(1) self._chromecasts.pop(player_id, None) await self.mass.player.remove_player(player_id) - await asyncio.sleep(5) # search for available chromecasts from pychromecast.discovery import start_discovery, stop_discovery def discovered_callback(name): @@ -418,6 +430,7 @@ class ChromecastProvider(PlayerProvider): await asyncio.sleep(15) # run discovery for 15 seconds stop_discovery(browser) LOGGER.debug("Chromecast discovery completed...") + self._discovery_running = True async def __chromecast_discovered(self, player_id, discovery_info): ''' callback when a (new) chromecast device is discovered ''' diff --git a/music_assistant/web/components/headermenu.vue.js b/music_assistant/web/components/headermenu.vue.js index eda7b28e..f0e8566f 100755 --- a/music_assistant/web/components/headermenu.vue.js +++ b/music_assistant/web/components/headermenu.vue.js @@ -26,9 +26,6 @@ Vue.component("headermenu", { arrow_back - - -