All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 43s
The player now holds a queue instead of a single item, so albums play through and single tracks share the same code path. Adds a "stream" item kind for expiring, remotely-hosted sources: Bandcamp signs its mp3 URLs for ~24h, so an item carries the page it came from and re-resolves itself on error or on a stale restored session, falling back to the iframe embed if that fails too. Gated behind GERBEUR_BANDCAMP_PLAYER (default "embed"), injected into a meta tag the same way as site-name/site-emoji. Also: player header gains artwork and a subtitle, volume persists across queue advances and reloads, and cross-origin streams get a plain seek bar rather than a waveform that can never decode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SbtjNsT5wvuABnfqhegZEJ
27 lines
1.0 KiB
TypeScript
27 lines
1.0 KiB
TypeScript
import { Router } from "@oak/oak";
|
|
import { resolveBandcamp } from "../services/bandcamp-stream-service.ts";
|
|
|
|
const bandcampRouter = new Router();
|
|
|
|
/**
|
|
* Resolve a Bandcamp page to its streamable tracks.
|
|
*
|
|
* Public, like /api/preview: it only reads a public page and returns URLs the
|
|
* same page already hands any visitor. Errors are thrown as APIException and
|
|
* rendered by errorMiddleware; the client treats any failure as "fall back to
|
|
* the iframe embed".
|
|
*/
|
|
bandcampRouter.get("/api/bandcamp/tracks", async (ctx) => {
|
|
const url = ctx.request.url.searchParams.get("url") ?? "";
|
|
const force = ctx.request.url.searchParams.get("force") === "1";
|
|
|
|
const album = await resolveBandcamp(url, { force });
|
|
|
|
// Private: the signed URLs in the body are per-fetch, so they must not be
|
|
// held in a shared cache. Well inside the 24h signature life either way.
|
|
ctx.response.headers.set("Cache-Control", "private, max-age=3600");
|
|
ctx.response.body = { success: true, data: album };
|
|
});
|
|
|
|
export default bandcampRouter;
|