From: Marcel van der Veldt Date: Tue, 26 Mar 2024 09:29:41 +0000 (+0100) Subject: a few small optimizations for airplay X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=7cc6dce3473377b43f9aff598c0cafe8c10a8b42;p=music-assistant-server.git a few small optimizations for airplay --- diff --git a/music_assistant/server/helpers/process.py b/music_assistant/server/helpers/process.py index 4f2bf61e..533cb9e7 100644 --- a/music_assistant/server/helpers/process.py +++ b/music_assistant/server/helpers/process.py @@ -110,7 +110,7 @@ class AsyncProcess: while self.returncode is None: chunk = await self.readexactly(n) if chunk == b"": - raise StopAsyncIteration + break yield chunk async def iter_any(self, n: int = DEFAULT_CHUNKSIZE) -> AsyncGenerator[bytes, None]: @@ -118,7 +118,7 @@ class AsyncProcess: while self.returncode is None: chunk = await self.read(n) if chunk == b"": - raise StopAsyncIteration + break yield chunk async def readexactly(self, n: int) -> bytes: @@ -229,7 +229,7 @@ class AsyncProcess: try: line = await self.proc.stderr.readline() if line == b"": - raise StopAsyncIteration + break yield line except ValueError as err: # we're waiting for a line (separator found), but the line was too big diff --git a/music_assistant/server/providers/airplay/__init__.py b/music_assistant/server/providers/airplay/__init__.py index 4db18fd8..119908b1 100644 --- a/music_assistant/server/providers/airplay/__init__.py +++ b/music_assistant/server/providers/airplay/__init__.py @@ -18,7 +18,7 @@ from zeroconf import IPVersion, ServiceStateChange from zeroconf.asyncio import AsyncServiceInfo from music_assistant.common.helpers.datetime import utc -from music_assistant.common.helpers.util import get_ip_pton, select_free_port +from music_assistant.common.helpers.util import empty_queue, get_ip_pton, select_free_port from music_assistant.common.models.config_entries import ( CONF_ENTRY_CROSSFADE, CONF_ENTRY_CROSSFADE_DURATION, @@ -294,6 +294,7 @@ class AirplayStream: async def stop(self, wait: bool = True): """Stop playback and cleanup.""" self.running = False + empty_queue(self._buffer) async def _stop() -> None: # ffmpeg MUST be stopped before cliraop due to the chained pipes @@ -358,7 +359,12 @@ class AirplayStream: # send metadata to player(s) if needed # NOTE: this must all be done in separate tasks to not disturb audio now = time.time() - if queue and queue.current_item and queue.current_item.streamdetails: + if ( + mass_player.elapsed_time > 2 + and queue + and queue.current_item + and queue.current_item.streamdetails + ): metadata_checksum = ( queue.current_item.streamdetails.stream_title or queue.current_item.queue_item_id @@ -385,7 +391,7 @@ class AirplayStream: self.mass.players.update(airplay_player.player_id) if "lost packet out of backlog" in line: lost_packets += 1 - if lost_packets == 50: + if lost_packets == 100: logger.error("High packet loss detected, stopping playback...") await self.stop(False) elif lost_packets % 10 == 0: @@ -612,7 +618,8 @@ class AirplayProvider(PlayerProvider): # always stop existing stream first for airplay_player in self._get_sync_clients(player_id): if airplay_player.active_stream and airplay_player.active_stream.running: - await airplay_player.active_stream.stop(wait=False) + wait = not queue_item.streamdetails or queue_item.streamdetails.seek_position == 0 + await airplay_player.active_stream.stop(wait=wait) if queue_item.queue_id.startswith(UGP_PREFIX): # special case: we got forwarded a request from the UGP