Fix playlist playback: use MA enqueue and search resolution
The play_playlist_on_speaker function was sending text search queries to raw Cast entities which can't resolve them. Now uses enqueue: "replace" for the first track and "add" for subsequent tracks. Added 1s delay between requests so MA can process each Apple Music search. Increased HTTP timeout to 30s for search latency. The caller must pass a Music Assistant entity (_2 suffix) for text-based search to work. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
@@ -13,7 +14,7 @@ async def _ha_request(method: str, path: str, **kwargs) -> dict:
|
||||
"Authorization": f"Bearer {settings.ha_token}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.request(
|
||||
method, f"{settings.ha_url}{path}", headers=headers, **kwargs
|
||||
)
|
||||
@@ -81,37 +82,31 @@ async def play_playlist_on_speaker(
|
||||
tracks: list[dict],
|
||||
speaker_entity: str,
|
||||
) -> None:
|
||||
"""Play a list of tracks on a speaker. Each track dict has 'artist' and 'title'.
|
||||
"""Play a list of tracks on a speaker via Music Assistant.
|
||||
|
||||
Enqueues tracks via Music Assistant.
|
||||
Each track dict has 'artist' and 'title'. The speaker_entity MUST be a
|
||||
Music Assistant entity (the _2 suffix ones, e.g. media_player.living_room_speaker_2)
|
||||
so that text search queries are resolved via Apple Music.
|
||||
"""
|
||||
if not tracks:
|
||||
return
|
||||
|
||||
for i, track in enumerate(tracks):
|
||||
search_query = f"{track['artist']} {track['title']}"
|
||||
try:
|
||||
if i == 0:
|
||||
# Play first track
|
||||
await _ha_request(
|
||||
"POST",
|
||||
"/api/services/media_player/play_media",
|
||||
json={
|
||||
"entity_id": speaker_entity,
|
||||
"media_content_id": f"{track['artist']} - {track['title']}",
|
||||
"media_content_id": search_query,
|
||||
"media_content_type": "music",
|
||||
"enqueue": "replace" if i == 0 else "add",
|
||||
},
|
||||
)
|
||||
else:
|
||||
# Enqueue subsequent tracks
|
||||
await _ha_request(
|
||||
"POST",
|
||||
"/api/services/media_player/play_media",
|
||||
json={
|
||||
"entity_id": speaker_entity,
|
||||
"media_content_id": f"{track['artist']} - {track['title']}",
|
||||
"media_content_type": "music",
|
||||
"enqueue": "add",
|
||||
},
|
||||
)
|
||||
logger.info("Enqueued [%d/%d]: %s", i + 1, len(tracks), search_query)
|
||||
# Brief pause between requests so MA can process each search
|
||||
if i < len(tracks) - 1:
|
||||
await asyncio.sleep(1)
|
||||
except Exception:
|
||||
logger.exception("Failed to enqueue %s - %s", track["artist"], track["title"])
|
||||
|
||||
Reference in New Issue
Block a user