Fix: auto try next track if stream fails
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 6 Mar 2025 14:00:22 +0000 (15:00 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 6 Mar 2025 14:00:22 +0000 (15:00 +0100)
When we try to start media and we couldnt get the streamdetails for whatever reason, automatically try the next track

music_assistant/controllers/player_queues.py
pyproject.toml
requirements_all.txt

index ac4eb0eefd6f8502023738cac552067163f8cdaf..88139612f16aa276ef9bff0b7af152cdfbfc9bd6 100644 (file)
@@ -792,14 +792,25 @@ class PlayerQueuesController(CoreController):
         # NOTE that we debounce this a bit to account for someone hitting the next button
         # like a madman. This will prevent the player from being overloaded with requests.
         async def play_media() -> None:
-            next_index = self._get_next_index(queue_id, index, allow_repeat=False)
-            await self._load_item(
-                queue_item,
-                next_index,
-                is_start=True,
-                seek_position=seek_position,
-                fade_in=fade_in,
-            )
+            try:
+                next_index = self._get_next_index(queue_id, index, allow_repeat=False)
+                await self._load_item(
+                    queue_item,
+                    next_index,
+                    is_start=True,
+                    seek_position=seek_position,
+                    fade_in=fade_in,
+                )
+            except MediaNotFoundError:
+                # edge case: the requested index can not be played.
+                # we allow one single retry to skip to the next track (if any)
+                self.logger.warning(
+                    "Skipping unplayable item %s (%s)", queue_item.name, queue_item.uri
+                )
+                queue_item.available = False
+                await self.play_index(queue_id, index + 1, seek_position=0, debounce=False)
+                return
+
             await self.mass.players.play_media(
                 player_id=queue_id,
                 media=await self.player_media_from_queue_item(queue_item, queue.flow_mode),
@@ -977,6 +988,7 @@ class PlayerQueuesController(CoreController):
                 self.logger.info(
                     "Skipping unplayable item %s (%s)", queue_item.name, queue_item.uri
                 )
+                queue_item.available = False
                 idx += 1
         if next_item is None:
             raise QueueEmpty("No more (playable) tracks left in the queue.")
@@ -1741,14 +1753,6 @@ class PlayerQueuesController(CoreController):
             ):
                 task_id = f"fill_radio_tracks_{queue_id}"
                 self.mass.call_later(5, self._fill_radio_tracks, queue_id, task_id=task_id)
-            # auto clean up streamdetails from previously played items
-            prev_item_id = prev_state["current_item_id"]
-            if (
-                prev_item_id
-                and (prev_index := self.index_by_id(queue_id, prev_item_id))
-                and (prev_prev_item := self.get_item(queue_id, prev_index - 1))
-            ):
-                prev_prev_item.streamdetails = None
 
     def _get_flow_queue_stream_index(
         self, queue: PlayerQueue, player: Player
index ebbd1330a04dc859e7702a3586b220165be38729..97878d72a0ba9afa44c3a368f9b18c1ceece2e53 100644 (file)
@@ -24,7 +24,7 @@ dependencies = [
   "ifaddr==0.2.0",
   "mashumaro==3.15",
   "music-assistant-frontend==2.12.2",
-  "music-assistant-models==1.1.33",
+  "music-assistant-models==1.1.34",
   "mutagen==1.47.0",
   "orjson==3.10.12",
   "pillow==11.1.0",
index f7968d0d37e5a4cc89e3c8ec0d35cc45cadd601c..ebfa0f36b5116e6dc0c3097c2fe384c9c8eac209 100644 (file)
@@ -26,7 +26,7 @@ ibroadcastaio==0.4.0
 ifaddr==0.2.0
 mashumaro==3.15
 music-assistant-frontend==2.12.2
-music-assistant-models==1.1.33
+music-assistant-models==1.1.34
 mutagen==1.47.0
 orjson==3.10.12
 pillow==11.1.0