diff --git a/music_assistant/providers/airplay/const.py b/music_assistant/providers/airplay/const.py index ea106adc7..ff636979b 100644 --- a/music_assistant/providers/airplay/const.py +++ b/music_assistant/providers/airplay/const.py @@ -29,3 +29,15 @@ AIRPLAY_PCM_FORMAT = AudioFormat( content_type=ContentType.from_bit_depth(16), sample_rate=44100, bit_depth=16 ) + +IGNORE_RAOP_SONOS_MODELS = ( + # A recent fw update of newer gen Sonos speakers block RAOP (airplay 1) support, + # basically rendering our airplay implementation useless on these devices. + # This list contains the models that are known to have this issue. + # Hopefully the issue won't spread to other models. + "Era 100", + "Era 300", + "Move 2", + "Roam 2", + "Arc Ultra", +) diff --git a/music_assistant/providers/airplay/provider.py b/music_assistant/providers/airplay/provider.py index b4a5f5bb7..39f722a35 100644 --- a/music_assistant/providers/airplay/provider.py +++ b/music_assistant/providers/airplay/provider.py @@ -52,6 +52,7 @@ CONF_PASSWORD, CONF_READ_AHEAD_BUFFER, FALLBACK_VOLUME, + IGNORE_RAOP_SONOS_MODELS, ) from .helpers import convert_airplay_volume, get_model_from_am, get_primary_ip_address from .player import AirPlayPlayer @@ -450,17 +451,30 @@ async def _setup_player( return self.logger.debug("Discovered Airplay device %s on %s", display_name, address) manufacturer, model = get_model_from_am(info.decoded_properties.get("am")) + + default_enabled = not info.server.startswith("Sonos-") + if not self.mass.config.get_raw_player_config_value(player_id, "enabled", default_enabled): + self.logger.debug("Ignoring %s in discovery as it is disabled.", display_name) + return + if "apple tv" in model.lower(): # For now, we ignore the Apple TV until we implement the authentication. # maybe we can simply use pyatv only for this part? # the cliraop application has already been prepared to accept the secret. - self.logger.debug( - "Ignoring %s in discovery due to authentication requirement.", display_name + self.logger.info( + "Ignoring %s in discovery because it is not yet supported.", display_name ) return - if not self.mass.config.get_raw_player_config_value(player_id, "enabled", True): - self.logger.debug("Ignoring %s in discovery as it is disabled.", display_name) + if model in IGNORE_RAOP_SONOS_MODELS: + # for now completely ignore the sonos models that have broken RAOP support + # its very much unlikely that this will ever be fixed by Sonos + # revisit this once/if we have support for airplay 2. + self.logger.info( + "Ignoring %s in discovery as it is a known Sonos model with broken RAOP support.", + display_name, + ) return + self._players[player_id] = AirPlayPlayer(self, player_id, info, address) if not (volume := await self.mass.cache.get(player_id, base_key=CACHE_KEY_PREV_VOLUME)): volume = FALLBACK_VOLUME