Skip to content

Commit

Permalink
Fix some issues with Airplay provider (#919)
Browse files Browse the repository at this point in the history
* Fix disable and remove of player

* set default codec to prevent white noise at pcm size limit

* Fix for config
  • Loading branch information
marcelveldt authored Nov 11, 2023
1 parent b51153e commit ea11434
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions music_assistant/server/providers/airplay/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
key="remove_timeout",
type=ConfigEntryType.INTEGER,
default_value=0,
range=(-1, 3600),
label="Remove timeout",
description="Player discovery is managed using mDNS protocol, "
"which means that a player sends regular keep-alive messages and a bye when "
Expand All @@ -93,11 +94,11 @@
advanced=True,
),
ConfigEntry.from_dict(
{**CONF_ENTRY_OUTPUT_CODEC.to_dict(), "default_value": "pcm", "hidden": True}
{**CONF_ENTRY_OUTPUT_CODEC.to_dict(), "default_value": "flac", "hidden": True}
),
)

NEED_BRIDGE_RESTART = {"values/read_ahead", "values/encryption", "values/alac_encode"}
NEED_BRIDGE_RESTART = {"values/read_ahead", "values/encryption", "values/alac_encode", "enabled"}


async def setup(
Expand Down Expand Up @@ -135,9 +136,11 @@ class AirplayProvider(PlayerProvider):
_closing: bool = False
_config_file: str | None = None
_log_reader_task: asyncio.Task | None = None
_removed_players: set[str] | None = None

async def handle_setup(self) -> None:
"""Handle async initialization of the provider."""
self._removed_players = set()
self._config_file = os.path.join(self.mass.storage_path, "airplay_bridge.xml")
# locate the raopbridge binary (will raise if that fails)
self._bridge_bin = await self._get_bridge_binary()
Expand Down Expand Up @@ -180,6 +183,11 @@ async def update_config():

asyncio.create_task(update_config())

def on_player_config_removed(self, player_id: str) -> None:
"""Call (by config manager) when the configuration of a player is removed."""
self._removed_players.add(player_id)
self.restart_bridge()

async def cmd_stop(self, player_id: str) -> None:
"""Send STOP command to given player."""
# simply forward to underlying slimproto player
Expand Down Expand Up @@ -473,15 +481,15 @@ async def _check_config_xml(self, recreate: bool = False) -> None:
# get/set all device configs
for device_elem in xml_root.findall("device"):
player_id = device_elem.find("mac").text
if player_id in self._removed_players:
xml_root.remove(device_elem)
self._removed_players.remove(player_id)
continue
# use raw config values because players are not
# yet available at startup/init (race condition)
raw_player_conf = self.mass.config.get(f"{CONF_PLAYERS}/{player_id}")
if not raw_player_conf:
continue
# prefer name from UDN because default name is often wrong
udn = device_elem.find("udn").text
udn_name = udn.split("@")[1].split("._")[0]
device_elem.find("name").text = udn_name
device_elem.find("enabled").text = "1" if raw_player_conf["enabled"] else "0"

# set some values that are not (yet) configurable
Expand Down

0 comments on commit ea11434

Please sign in to comment.