From: Marcel van der Veldt Date: Mon, 8 Apr 2024 09:19:26 +0000 (+0200) Subject: Announcements improvements (#1209) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=e8d2d1b69a98797bf6f31b7f3896601384e1ce38;p=music-assistant-server.git Announcements improvements (#1209) * Prefer group for announcements * Fix some issues with Google cast and announcements * ensure announce volume is int * fallback image for cast metadata --- diff --git a/music_assistant/server/controllers/players.py b/music_assistant/server/controllers/players.py index 264a8d6d..056c98ee 100644 --- a/music_assistant/server/controllers/players.py +++ b/music_assistant/server/controllers/players.py @@ -643,24 +643,26 @@ class PlayerController(CoreController): ) return if player.type in (PlayerType.SYNC_GROUP, PlayerType.GROUP) and not player.powered: - # announcement request sent to inactive group, - # redirect to all underlying players instead - self.logger.warning( - "Detected announcement request to an inactive playergroup, " - "this will be redirected to the individual players." - ) - async with asyncio.TaskGroup() as tg: - for group_member in player.group_childs: - tg.create_task( - self.play_announcement( - group_member, - url=url, - use_pre_announce=use_pre_announce, - volume_level=volume_level, + # announcement request sent to inactive group, check if any child's are playing + if len(list(self.iter_group_members(player, True, True))) > 0: + # just for the sake of simplicity we handle this request per-player + # so we can restore the individual players again. + self.logger.warning( + "Detected announcement request to an inactive playergroup, " + "while one or more individual players are playing. " + "This announcement will be redirected to the individual players." + ) + async with asyncio.TaskGroup() as tg: + for group_member in player.group_childs: + tg.create_task( + self.play_announcement( + group_member, + url=url, + use_pre_announce=use_pre_announce, + volume_level=volume_level, + ) ) - ) - return - + return # determine pre-announce from (group)player config if use_pre_announce is None and "tts" in url: use_pre_announce = self.mass.config.get_raw_player_config_value( @@ -859,7 +861,8 @@ class PlayerController(CoreController): CONF_ENTRY_ANNOUNCE_VOLUME_MAX.default_value, ) volume_level = min(announce_volume_max, volume_level) - return volume_level + # ensure the result is an integer + return int(volume_level) def _check_redirect(self, player_id: str) -> str: """Check if playback related command should be redirected.""" diff --git a/music_assistant/server/providers/chromecast/__init__.py b/music_assistant/server/providers/chromecast/__init__.py index 7bb06958..fd5511e8 100644 --- a/music_assistant/server/providers/chromecast/__init__.py +++ b/music_assistant/server/providers/chromecast/__init__.py @@ -36,6 +36,7 @@ from music_assistant.constants import ( CONF_CROSSFADE, CONF_FLOW_MODE, CONF_PLAYERS, + MASS_LOGO_ONLINE, VERBOSE_LOG_LEVEL, ) from music_assistant.server.models.player_provider import PlayerProvider @@ -70,8 +71,7 @@ PLAYER_CONFIG_ENTRIES = ( CONF_ENTRY_CROSSFADE_DURATION, ) -DEFAULT_APP_ID = "CC1AD845" -ALT_APP_ID = "46C1A819" +MASS_APP_ID = "46C1A819" # use the cast receiver app from philippe44 for now until we get our own # Monkey patch the Media controller here to store the queue items @@ -237,14 +237,12 @@ class ChromecastProvider(PlayerProvider): ) -> None: """Handle PLAY MEDIA on given player.""" castplayer = self.castplayers[player_id] - is_flow_mode = "/flow/" in media.uri queuedata = { "type": "LOAD", "media": self._create_cc_media_item(media), } - # make sure that the media controller app is launched - app_id = ALT_APP_ID if is_flow_mode else DEFAULT_APP_ID - await self._launch_app(castplayer, app_id) + # make sure that our media controller app is launched + await self._launch_app(castplayer) # send queue info to the CC media_controller = castplayer.cc.media_controller await asyncio.to_thread(media_controller.send_message, data=queuedata, inc_session_id=True) @@ -542,7 +540,7 @@ class ChromecastProvider(PlayerProvider): ### Helpers / utils - async def _launch_app(self, castplayer: CastPlayer, app_id: str = DEFAULT_APP_ID) -> None: + async def _launch_app(self, castplayer: CastPlayer, app_id: str = MASS_APP_ID) -> None: """Launch the default Media Receiver App on a Chromecast.""" event = asyncio.Event() @@ -610,28 +608,47 @@ class ChromecastProvider(PlayerProvider): return if castplayer.player.state != PlayerState.PLAYING: return - if castplayer.cc.app_id != ALT_APP_ID: + if castplayer.player.announcement_in_progress: return queue = self.mass.player_queues.get_active_queue(castplayer.player_id) if not (current_item := queue.current_item): return + if not (queue.flow_mode or current_item.media_type == MediaType.RADIO): + return media_controller = castplayer.cc.media_controller # update metadata of current item chromecast if media_controller.status.media_custom_data["queue_item_id"] != current_item.queue_item_id: - image_url = self.mass.metadata.get_image_url(current_item.image) + image_url = ( + self.mass.metadata.get_image_url(current_item.image) + if current_item.image + else MASS_LOGO_ONLINE + ) + if (streamdetails := current_item.streamdetails) and streamdetails.stream_title: + album = current_item.media_item.name + if " - " in streamdetails.stream_title: + artist, title = streamdetails.stream_title.split(" - ", 1) + else: + artist = "" + title = streamdetails.stream_title + elif media_item := current_item.media_item: + album = _album.name if (_album := getattr(media_item, "album", None)) else "" + artist = getattr(media_item, "artist_str", "") + title = media_item.name + else: + album = "" + artist = "" + title = current_item.name queuedata = { "type": "PLAY", "mediaSessionId": media_controller.status.media_session_id, "customData": { "metadata": { "metadataType": 3, - "albumName": album.name - if (album := getattr(current_item.media_item, "album", None)) - else "", - "songName": current_item.media_item.name, - "artist": getattr(current_item.media_item, "artist_str", ""), - "title": current_item.media_item.name, - "images": [{"url": image_url}] if image_url else None, + "albumName": album, + "songName": title, + "artist": artist, + "title": title, + "images": [{"url": image_url}], } }, }