stream: show the queue of upcoming tracks (/queue)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
126cb8f8ac
commit
62302ac21d
4 changed files with 98 additions and 11 deletions
|
|
@ -7,6 +7,8 @@ Endpoints:
|
|||
net; empty (→ silence) until something has played.
|
||||
GET /status -> JSON prefetch state {ready, prefetch}, surfaced to the
|
||||
player (proxied by the stream) so it can show buffering.
|
||||
GET /queue -> JSON list of the upcoming (prefetched) tracks, oldest
|
||||
first, surfaced to the player (proxied by the stream).
|
||||
GET /healthz -> "ok"
|
||||
"""
|
||||
|
||||
|
|
@ -61,6 +63,8 @@ class _Handler(BaseHTTPRequestHandler):
|
|||
self._serve_fallback()
|
||||
elif self.path == "/status":
|
||||
self._serve_status()
|
||||
elif self.path == "/queue":
|
||||
self._serve_queue()
|
||||
elif self.path == "/healthz":
|
||||
self._text(200, "ok\n")
|
||||
else:
|
||||
|
|
@ -93,6 +97,11 @@ class _Handler(BaseHTTPRequestHandler):
|
|||
})
|
||||
self._text(200, body + "\n", "application/json; charset=utf-8")
|
||||
|
||||
def _serve_queue(self):
|
||||
# Upcoming prefetched tracks, next first. A peek, nothing consumed.
|
||||
body = json.dumps(self.server.queue.snapshot())
|
||||
self._text(200, body + "\n", "application/json; charset=utf-8")
|
||||
|
||||
def _text(self, code: int, body: str, ctype: str = "text/plain; charset=utf-8"):
|
||||
data = body.encode("utf-8")
|
||||
self.send_response(code)
|
||||
|
|
|
|||
|
|
@ -81,6 +81,27 @@ class TrackQueue:
|
|||
with self._lock:
|
||||
return len(self._ready)
|
||||
|
||||
def snapshot(self) -> list[dict]:
|
||||
"""Display metadata of the upcoming tracks, oldest (next) first.
|
||||
|
||||
A peek at the prefetch buffer for the player's "up next" view; it does
|
||||
not consume anything. Mirrors the fields exposed for the current track
|
||||
(see ``annotate_uri``): a source ``url`` only for http(s) locators.
|
||||
"""
|
||||
with self._lock:
|
||||
ready = list(self._ready)
|
||||
items = []
|
||||
for _path, track in ready:
|
||||
entry = {
|
||||
"title": track.title,
|
||||
"artist": track.artist,
|
||||
"origin": track.origin,
|
||||
}
|
||||
if track.locator.startswith(("http://", "https://")):
|
||||
entry["url"] = track.locator
|
||||
items.append(entry)
|
||||
return items
|
||||
|
||||
# --- serving ----------------------------------------------------------
|
||||
|
||||
def pop_next(self) -> tuple[Path, Track] | None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue