Browse Source

Music: Mehrere Tracks in Queue bei Kuenstler-Suche

"Spiele Musik von Rammstein" sucht jetzt bis zu 5 YouTube-Tracks
und fuegt alle in die Warteschlange:
- Erster Track wird sofort abgespielt
- Restliche werden im Hintergrund heruntergeladen und zur Queue hinzugefuegt
- Antwort: "Spiele 'Track' von Rammstein. 4 weitere in der Warteschlange."

Aenderungen:
- YouTube-Suche: limit 3 → 5 (lokal: 5 → 10)
- _queue_remaining_tracks(): Hintergrund-Task fuer Downloads
- Player.add_to_queue() statt nur play_track()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
patrick 1 week ago
parent
commit
7969a1e9ff
1 changed files with 62 additions and 21 deletions
  1. 62 21
      plugins/music/main.py

+ 62 - 21
plugins/music/main.py

@@ -298,12 +298,12 @@ class MusicPlugin(TrixyPlugin):
 
         # Lokal suchen
         if search_local and self._local:
-            local_results = await self._local.search(query, limit=5)
+            local_results = await self._local.search(query, limit=10)
             tracks.extend(local_results)
 
-        # YouTube suchen (wenn lokal nichts gefunden oder explizit YouTube)
-        if search_youtube and self._youtube and (not tracks or source == "youtube"):
-            yt_results = await self._youtube.search(query, limit=3)
+        # YouTube suchen (wenn lokal nichts/wenig gefunden oder explizit YouTube)
+        if search_youtube and self._youtube and (len(tracks) < 3 or source == "youtube"):
+            yt_results = await self._youtube.search(query, limit=5)
             tracks.extend(yt_results)
 
         if not tracks:
@@ -312,17 +312,15 @@ class MusicPlugin(TrixyPlugin):
                 response_text=f"Ich konnte keine Musik fuer '{query}' finden.",
             )
 
-        # Ersten Track verwenden
-        track = tracks[0]
-
-        # YouTube-Tracks muessen vorbereitet werden (Download)
-        if track.source_type == "youtube" and self._youtube:
-            pinfo(f"MusicPlugin: Lade YouTube-Track: {track.title}")
-            prepared = await self._youtube.prepare_track(track)
+        # Ersten Track vorbereiten und abspielen
+        first_track = tracks[0]
+        if first_track.source_type == "youtube" and self._youtube:
+            pinfo(f"MusicPlugin: Lade YouTube-Track: {first_track.title}")
+            prepared = await self._youtube.prepare_track(first_track)
             if not prepared:
                 return IntentResult.failure(
                     "YouTube-Download fehlgeschlagen",
-                    response_text=f"Der Download von '{track.title}' ist fehlgeschlagen.",
+                    response_text=f"Der Download von '{first_track.title}' ist fehlgeschlagen.",
                 )
 
         service = self._music_service
@@ -333,21 +331,64 @@ class MusicPlugin(TrixyPlugin):
             )
 
         satellite_ids = self._get_target_satellites(satellite_id)
-        success = await service.play_track(track, satellite_ids)
+        success = await service.play_track(first_track, satellite_ids)
 
-        if success:
-            artist = track.metadata.display_artist
-            title = track.metadata.display_title
+        if not success:
+            return IntentResult.failure(
+                "Wiedergabe fehlgeschlagen",
+                response_text="Die Wiedergabe konnte nicht gestartet werden.",
+            )
+
+        # Weitere Tracks in die Queue (im Hintergrund vorbereiten)
+        if len(tracks) > 1:
+            import asyncio
+            asyncio.create_task(
+                self._queue_remaining_tracks(tracks[1:], satellite_ids)
+            )
+
+        # Antwort
+        artist = first_track.metadata.display_artist
+        title = first_track.metadata.display_title
+        if len(tracks) > 1:
+            if artist and artist != "Unbekannter Kuenstler":
+                return IntentResult.success_with_response(
+                    f"Spiele '{title}' von {artist}. "
+                    f"{len(tracks) - 1} weitere Titel in der Warteschlange."
+                )
+            return IntentResult.success_with_response(
+                f"Spiele '{title}'. "
+                f"{len(tracks) - 1} weitere Titel in der Warteschlange."
+            )
+        else:
             if artist and artist != "Unbekannter Kuenstler":
                 return IntentResult.success_with_response(
                     f"Spiele '{title}' von {artist}."
                 )
             return IntentResult.success_with_response(f"Spiele '{title}'.")
-        else:
-            return IntentResult.failure(
-                "Wiedergabe fehlgeschlagen",
-                response_text="Die Wiedergabe konnte nicht gestartet werden.",
-            )
+
+    async def _queue_remaining_tracks(
+        self, tracks: list, satellite_ids: list[str],
+    ) -> None:
+        """Bereitet weitere Tracks vor und fuegt sie zur Queue hinzu."""
+        service = self._music_service
+        if not service:
+            return
+
+        for track in tracks:
+            try:
+                if track.source_type == "youtube" and self._youtube:
+                    prepared = await self._youtube.prepare_track(track)
+                    if not prepared:
+                        pdebug(f"MusicPlugin: Skip '{track.title}' (Download fehlgeschlagen)")
+                        continue
+
+                if hasattr(service, "_player") and service._player:
+                    await service._player.add_to_queue(track)
+                else:
+                    pdebug(f"MusicPlugin: Kein Player fuer Queue")
+                pdebug(f"MusicPlugin: Zur Queue: {track.title}")
+            except Exception as e:
+                pdebug(f"MusicPlugin: Queue-Fehler fuer '{track.title}': {e}")
 
     def _get_music_dirs(self, local_config: dict) -> list[Path]:
         """Ermittelt die Musik-Verzeichnisse."""