From 4739233a4cf94eb6560df94d2ffadc514d1d2b1f Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Mon, 28 Dec 2020 15:48:27 +0100 Subject: [PATCH] fix radio playback --- music_assistant/helpers/process.py | 33 ++++++++++++++++++----------- music_assistant/managers/players.py | 7 ++++++ music_assistant/managers/streams.py | 12 +++++------ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/music_assistant/helpers/process.py b/music_assistant/helpers/process.py index 7c029272..e2e57151 100644 --- a/music_assistant/helpers/process.py +++ b/music_assistant/helpers/process.py @@ -37,7 +37,7 @@ class AsyncProcess: stdout=subprocess.PIPE, stdin=subprocess.PIPE if enable_write else None, # bufsize needs to be very high for smooth playback - bufsize=64000000, + bufsize=4000000, ) self.loop = asyncio.get_running_loop() self._cancelled = False @@ -53,7 +53,7 @@ class AsyncProcess: # process needs to be cleaned up.. await self.loop.run_in_executor(None, self.__close) - return exc_type not in (GeneratorExit, asyncio.CancelledError) + return exc_type async def iterate_chunks( self, chunksize: int = DEFAULT_CHUNKSIZE @@ -93,9 +93,7 @@ class AsyncProcess: def __read(self, chunksize: int = DEFAULT_CHUNKSIZE): """Try read chunk from process.""" try: - chunk = self._proc.stdout.read(chunksize) - self._proc.stdout.flush() - return chunk + return self._proc.stdout.read(chunksize) except (BrokenPipeError, ValueError, AttributeError): # Process already exited return b"" @@ -104,6 +102,7 @@ class AsyncProcess: """Write data to process stdin.""" try: self._proc.stdin.write(data) + self._proc.stdin.flush() except (BrokenPipeError, ValueError, AttributeError): # Process already exited pass @@ -119,17 +118,27 @@ class AsyncProcess: def __close(self): """Prevent subprocess deadlocking, make sure it closes.""" LOGGER.debug("Cleaning up process %s...", self._id) - try: - self._proc.stdout.close() - except BrokenPipeError: - pass - if self._proc.stdin: + # close stdout + if not self._proc.stdout.closed: + try: + self._proc.stdout.close() + except BrokenPipeError: + pass + # close stdin if needed + if self._proc.stdin and not self._proc.stdin.closed: try: self._proc.stdin.close() except BrokenPipeError: pass - self._proc.kill() - self._proc.wait() + # send terminate + self._proc.terminate() + # wait for exit + try: + self._proc.wait(5) + LOGGER.debug("Process %s exited with %s.", self._id, self._proc.returncode) + except subprocess.TimeoutExpired: + LOGGER.error("Process %s did not terminate in time.", self._id) + self._proc.kill() LOGGER.debug("Process %s closed.", self._id) diff --git a/music_assistant/managers/players.py b/music_assistant/managers/players.py index d3593e1a..a9243ce2 100755 --- a/music_assistant/managers/players.py +++ b/music_assistant/managers/players.py @@ -282,6 +282,13 @@ class PlayerManager: tracks = await self.mass.music.async_get_playlist_tracks( media_item.item_id, provider_id=media_item.provider ) + elif media_item.media_type == MediaType.Radio: + # single radio + tracks = [ + await self.mass.music.async_get_radio( + media_item.item_id, provider_id=media_item.provider + ) + ] else: # single track tracks = [ diff --git a/music_assistant/managers/streams.py b/music_assistant/managers/streams.py index 202dd5f9..2b17bde5 100755 --- a/music_assistant/managers/streams.py +++ b/music_assistant/managers/streams.py @@ -66,11 +66,12 @@ class StreamManager: output_format = [output_format.value, "-c", "2"] else: output_format = [output_format.value] - args = ( - ["sox", "-t", streamdetails.content_type.value, "-", "-t"] - + output_format - + ["-"] - ) + if streamdetails.content_type in [ContentType.AAC, ContentType.MPEG]: + input_format = "flac" + else: + input_format = streamdetails.content_type.value + + args = ["sox", "-t", input_format, "-", "-t"] + output_format + ["-"] if gain_db_adjust: args += ["vol", str(gain_db_adjust), "dB"] if resample: @@ -356,7 +357,6 @@ class StreamManager: # support for AAC/MPEG created with ffmpeg in between if streamdetails.content_type in [ContentType.AAC, ContentType.MPEG]: stream_type = StreamType.EXECUTABLE - streamdetails.content_type = ContentType.FLAC stream_path = f'ffmpeg -v quiet -i "{stream_path}" -f flac -' # signal start of stream event -- 2.34.1