From a3eb493ee74c82912a95aabf7c5c7e168976da20 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Tue, 16 Aug 2022 01:26:54 +0200 Subject: [PATCH] Fix Qobuz media stream gets aborted (#456) --- music_assistant/controllers/streams.py | 22 +++++++++---------- music_assistant/helpers/audio.py | 14 +++++++++++- music_assistant/mass.py | 4 +++- .../music_providers/qobuz/qobuz.py | 2 +- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/music_assistant/controllers/streams.py b/music_assistant/controllers/streams.py index 98d73286..8c2b4342 100644 --- a/music_assistant/controllers/streams.py +++ b/music_assistant/controllers/streams.py @@ -224,7 +224,7 @@ class StreamsController: "Got stream request for unknown or finished stream: %s", stream_id, ) - return web.FileResponse(SILENCE_FILE) + return web.Response(status=404) # handle a second connection for the same player # this probably means a client which does multiple GET requests (e.g. Kodi, Vlc) @@ -631,12 +631,10 @@ class QueueStream: and prev_track.media_type == MediaType.TRACK and queue_track.media_type == MediaType.TRACK ): - prev_item = await self.mass.music.get_item_by_uri(prev_track.uri) - new_item = await self.mass.music.get_item_by_uri(queue_track.uri) if ( - prev_item.album is not None - and new_item.album is not None - and prev_item.album == new_item.album + prev_track.media_item.album is not None + and queue_track.media_item.album is not None + and prev_track.media_item.album == queue_track.media_item.album ): self.logger.debug("Skipping crossfade: Tracks are from same album") use_crossfade = False @@ -644,7 +642,7 @@ class QueueStream: self.logger.info( "Start Streaming queue track: %s (%s) for queue %s - crossfade: %s", - queue_track.uri, + streamdetails.uri, queue_track.name, self.queue.player.name, use_crossfade, @@ -731,7 +729,7 @@ class QueueStream: if bytes_written == 0: # stream error: got empy first chunk ?! - self.logger.warning("Stream error on %s", queue_track.uri) + self.logger.warning("Stream error on %s", streamdetails.uri) queue_track.streamdetails.seconds_streamed = 0 continue @@ -744,11 +742,13 @@ class QueueStream: # log warning if received seconds are a lot less than expected if (stream_duration - chunk_num) > 20: self.logger.warning( - "Unexpected number of chunks received for track %s: %s/%s - process_time: %s", - queue_track.uri, + "Unexpected number of chunks received for track %s: %s/%s - " + "process_time: %s - player_buffered: %s", + streamdetails.uri, chunk_num, stream_duration, process_time, + player_buffered, ) self.logger.debug( "end of track reached - chunk_num: %s - crossfade_buffer: %s - " @@ -791,7 +791,7 @@ class QueueStream: ) self.logger.debug( "Finished Streaming queue track: %s (%s) on queue %s", - queue_track.uri, + queue_track.streamdetails.uri, queue_track.name, self.queue.player.name, ) diff --git a/music_assistant/helpers/audio.py b/music_assistant/helpers/audio.py index f33547fd..ac244237 100644 --- a/music_assistant/helpers/audio.py +++ b/music_assistant/helpers/audio.py @@ -230,7 +230,7 @@ async def get_stream_details( param queue_id: Optionally provide the queue_id which will play this stream. """ streamdetails = None - if queue_item.streamdetails and (time() < queue_item.streamdetails.expires): + if queue_item.streamdetails and (time() < (queue_item.streamdetails.expires - 60)): # we already have fresh streamdetails, use these queue_item.streamdetails.seconds_skipped = None queue_item.streamdetails.seconds_streamed = None @@ -697,6 +697,18 @@ async def _get_ffmpeg_args( ] if streamdetails.direct: # ffmpeg can access the inputfile (or url) directly + input_args += [ + "-reconnect", + "1", + "-reconnect_streamed", + "1", + "-reconnect_on_network_error", + "1", + "-reconnect_on_http_error", + "5xx", + "-reconnect_delay_max", + "10", + ] if seek_position: input_args += ["-ss", str(seek_position)] input_args += ["-i", streamdetails.direct] diff --git a/music_assistant/mass.py b/music_assistant/mass.py index 66a386e1..a0807b67 100644 --- a/music_assistant/mass.py +++ b/music_assistant/mass.py @@ -157,7 +157,9 @@ class MusicAssistant: job = BackgroundJob(str(uuid4()), name=name, coro=coro) self._jobs.append(job) self._jobs_event.set() - self.signal_event(MassEvent(EventType.BACKGROUND_JOB_UPDATED, data=job)) + self.signal_event( + MassEvent(EventType.BACKGROUND_JOB_UPDATED, job.name, data=job) + ) return job def create_task( diff --git a/music_assistant/music_providers/qobuz/qobuz.py b/music_assistant/music_providers/qobuz/qobuz.py index 099a748b..a62f977e 100644 --- a/music_assistant/music_providers/qobuz/qobuz.py +++ b/music_assistant/music_providers/qobuz/qobuz.py @@ -361,7 +361,7 @@ class QobuzProvider(MusicProvider): sample_rate=int(streamdata["sampling_rate"] * 1000), bit_depth=streamdata["bit_depth"], data=streamdata, # we need these details for reporting playback - expires=time.time() + 600, # not sure about the real allowed value + expires=time.time() + 3600, # not sure about the real allowed value direct=streamdata["url"], callback=self._report_playback_stopped, ) -- 2.34.1