From e0c0c3ce3555e650989ec00ec580894888be8387 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sun, 18 Feb 2024 21:30:45 +0100 Subject: [PATCH] Some more fixes for the Airplay provider (#1088) --- .../server/providers/airplay/__init__.py | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/music_assistant/server/providers/airplay/__init__.py b/music_assistant/server/providers/airplay/__init__.py index 98042efd..643f8bd5 100644 --- a/music_assistant/server/providers/airplay/__init__.py +++ b/music_assistant/server/providers/airplay/__init__.py @@ -10,6 +10,8 @@ from random import randint, randrange from typing import TYPE_CHECKING, cast import aiofiles +import shortuuid +from aiofiles.os import wrap from pyatv import connect, exceptions, interface, scan from pyatv.conf import AppleTV as ATVConf from pyatv.const import DeviceModel, DeviceState, PowerState, Protocol @@ -38,7 +40,6 @@ from music_assistant.common.models.enums import ( from music_assistant.common.models.media_items import AudioFormat from music_assistant.common.models.player import DeviceInfo, Player from music_assistant.server.helpers.process import AsyncProcess, check_output -from music_assistant.server.helpers.util import create_tempfile from music_assistant.server.models.player_provider import PlayerProvider if TYPE_CHECKING: @@ -49,6 +50,8 @@ if TYPE_CHECKING: from music_assistant.server.controllers.streams import MultiClientStreamJob from music_assistant.server.models import ProviderInstanceType +DOMAIN = "airplay" + CONF_LATENCY = "latency" CONF_ENCRYPTION = "encryption" CONF_ALAC_ENCODE = "alac_encode" @@ -374,7 +377,7 @@ class AirPlayPlayer(DeviceListener): if not (mass_player := self.mass.players.get(self.player_id)): mass_player = Player( player_id=self.player_id, - provider="airplay", + provider=DOMAIN, type=PlayerType.PLAYER, name=self.discovery_info.name, available=True, @@ -871,7 +874,12 @@ class AirplayProvider(PlayerProvider): if discovery_info.address != atv_player.discovery_info.address: atv_player.address_updated(discovery_info.address) return - self.logger.info(f"Connecting to {discovery_info.address}") + if "_raop._tcp.local" not in discovery_info.properties: + # skip players without raop + return + self.logger.debug( + "Discovered Airplay device %s on %s", discovery_info.name, discovery_info.address + ) self._atv_players[player_id] = atv_player = AirPlayPlayer( self.mass, player_id, discovery_info ) @@ -1050,25 +1058,29 @@ class AirplayProvider(PlayerProvider): cmd = f"TITLE={title or 'Music Assistant'}\nARTIST={artist}\nALBUM={album}\n" cmd += f"DURATION={duration}\nACTION=SENDMETA\n" - async with asyncio.TaskGroup() as tg: - for atv_player in self._get_sync_clients(player_id): - tg.create_task(atv_player.send_cli_command(cmd)) + for atv_player in self._get_sync_clients(player_id): + await atv_player.send_cli_command(cmd) + + # temp test for not sending artwork + exists_func = wrap(os.path.exists) + if await exists_func("/tmp/do_not_send_artwork"): # noqa: S108 + return # get image if not queue.current_item.image: return - image_path = create_tempfile() + image_path = f"/tmp/{shortuuid.random(12)}" # noqa: S108 image_data = await self.mass.metadata.get_thumbnail( queue.current_item.image.path, 512, queue.current_item.image.provider, ) - async with aiofiles.open(image_path.name, "wb") as outfile: + async with aiofiles.open(image_path, "wb") as outfile: await outfile.write(image_data) - async with asyncio.TaskGroup() as tg: - for atv_player in self._get_sync_clients(player_id): - if image_path: - tg.create_task(atv_player.send_cli_command(f"ARTWORK={image_path.name}\n")) + for atv_player in self._get_sync_clients(player_id): + if image_path: + await atv_player.send_cli_command(f"ARTWORK={image_path}\n") # make sure the temp file gets deleted again - await asyncio.sleep(5) - image_path.close() + await asyncio.sleep(10) + rm_func = wrap(os.remove) + await rm_func(image_path) -- 2.34.1