Scofti
← Board
SC-25DoneThe Rooms

Work out what the jukebox becomes

A player that keeps going while you walk off and read something else.

Press something, then leave the page and go read an article while it keeps playing, for as long as you are on the domain. The page stops being a player and becomes a picker.

This is the thinking ticket. Notes below rather than a plan.

The mechanism is positional, not clever

Everything rendered in src/app/layout.tsx survives client-side navigation — only the page slot swaps out. So an <audio> element in a client component in the layout keeps playing through every link click, with no handling at all. The old ribbon worked for that reason and no other.

The cost is furniture, not code

A player bar on every page, permanently, on a site this spare. That is the decision worth arguing about. Open: a ribbon at the top or a bar at the bottom, and whether it appears at all before anything is playing.

It dies on a hard refresh

A typed URL, a reload, or a return from an external link is a fresh document and the audio stops. sessionStorage can hold the track and the position and resume quietly, which makes "as long as you are on the domain" true in practice — but the honest version is "as long as you do not reload."

It has to yield to the video room

Two soundtracks at once is the failure case. Simplest rule: starting a video pauses the jukebox, and the jukebox does not resume on its own. Anything cleverer is guessing what someone wanted.

Built: the ribbon, and live stations

The audio moved into the layout, so it survives navigation. The ribbon only exists while something plays, which answers the furniture question above — the cost is zero until you press something.

Starting a show on ScofTV ends it. Two soundtracks at once was the failure case.

Stations, and why the two behave differently

Michael: the room was never meant to be a list of songs, it is a radio. So the rack now holds stations as well as recorded shows.

WTED Goose Radio serves its stream to a direct request, so it plays through our own player and rides in the ribbon like a channel.

JEMP Radio was built and then removed. Their stream answers 403 to a direct request from anywhere, on every radio.co host tried, with and without a referer — a station declining to be hotlinked, so it was not hotlinked. The framed player they do permit works, but dies on navigation.

Michael: "lost jemp if lose it on page change." So that is now the bar for the rack — a station goes in only if it survives leaving the page. One strip that went quiet on a link click would teach you not to trust any of them.

Still open: Goose A1 always starts at track one with no way to jump down the list. Michael parked it.

What is in the rack now

A1 is Billy Strings at Red Rocks, 2022-05-12, taped by HealthCov Chris. The Goose show that was in A1 came out; Goose is still here as the live station.

Titles came off the setlist in the item description rather than the file names, because the file names use -- where the setlist uses > and carry two typos the setlist does not (Wargasam, Die_). A file name is only ever used as a file name.

One real bug found on the way in: these file names contain spaces, and archive.org does not serve a path with a raw space — the request fails outright rather than returning a 404, which would have looked like dead audio. trackUrl now encodes. All 19 files were requested and returned audio before this shipped.

Correction: JEMP was never refusing to be hotlinked

The note above said JEMP declined direct streaming because every host tried answered 403. That was wrong, and the conclusion drawn from it was wrong.

radio.co pins each station to one stream host and the rest answer 403. WTED is on s4, JEMP is on streaming. The host was found in the open radio-browser directory, which also lists WTED at exactly the URL already in use here.

So JEMP is back in the rack at B2 as a plain stream, and it survives leaving the page like the rest.

GD Radio.net, and the mixed-content trap

C1 is GD Radio.net — Grateful Dead, Ratdog, Jerry Garcia Band, Phil and Friends, Furthur, around the clock. Around 200 people on it when it went in.

Their site only publishes http:// links to a bare IP. That cannot be used: the page is TLS, so a browser blocks an http stream as mixed content and the slot is silently dead with nothing in the console to chase. The working route is their Centova host over https, which serves the same stream.

So the test for any new station is two things, not one: the stream answers 200 audio/mpeg, and it does so over https.

Now-playing endpoints, parked

The Station type had an unused status field; it is gone rather than carried dead, and the providers do not agree on a shape anyway. If a now-playing readout is ever wanted, these are real:

Singles, and the store that had to be public

A2 is six tracks rather than a show, which needed a third type in the rack. A Shelf is not a Channel with the venue left blank: a channel is one artist, one taper, one archive item, while a shelf's artist changes with every track, so the credit under the title has to be read off the song. A union of three beats one shape whose empty fields you have to read to know what you are holding.

These are the only audio files the site hosts. Pixabay serves a download, not a stable address to point an <audio> element at, so a hotlinked slot would be the one strip that broke without warning.

That forced SC-20's parked question. scofti-blob was created private, and Vercel fixes access at creation — there is no flag to flip it. A jukebox file has to be fetchable with no cookie, so scofti-sound was created public alongside it and connected with the SOUND_BLOB prefix, the way the drop store got DROP_. Three stores now, each with one job: drop is private transfer, blob is private and still empty, sound is published audio. Nothing in the codebase reads BLOB_READ_WRITE_TOKEN — every call passes its own token — so the collision was only ever about naming.

Worth knowing: vercel blob create-store will not connect a store whose env var name is taken, and there is no CLI command to connect an existing one. That is a dashboard step, and the read-write token checkbox is off by default.

What is on the strips, and where it came from

Titles and artists were read off each track's own Pixabay page. Lengths were computed from the files by scripts/mp3-probe.mjs and then checked against the duration Pixabay states for the same track; they agree to the second. The uploaded files match the originals byte for byte.

Credit runs at /miracle, which is a standing page in the footer rather than anything the jukebox owns. A1 now reads "Billy Strings — Full Show" so a strip says what kind of thing it is before you press it, and pressing anything takes the lights down in the room the way ScofTV already did.

One licence note, on the record. Pixabay bars distributing content "on a Standalone basis... where no creative effort has been applied." Serving these from our own store sits closer to that line than embedding their player would, and their player cannot survive leaving the page. Michael made the call with that in view.

Each single got its own strip, and the rack plays on

The six were first built as one slot holding all of them, which was wrong: a collection is a thing you ask for by name, so each single has its own code. That retired the Shelf type entirely — a Song carries its own strip, and the player holds one rather than an index into a list.

Rows now mean something, which is what makes the rack extendable without renaming anything. A is full shows, B and C are radio, D and E are the collection. A2 and C2 are deliberately empty and staying that way — room for the next show and the next station, and the rack already says "slot empty" honestly rather than showing a title that does not play.

A single hands over to the next strip when it ends and wraps at the end, so pressing D1 and walking off to read something plays the whole collection in order. Rack order rather than shuffle, so the panel can say what is coming: "it plays on to D2." A channel still stops at the end of its show and a station still stops if it drops, because neither has an honest successor.

Known, not yet done: a second keypad

The keypad sits under the rack, so at twelve strips you scroll the whole collection to reach the buttons, and it gets worse with every song added. A second set near the top is the likely fix — they would share state, so both light up together and there is nothing to keep in sync. Not built yet; noted here so it is not rediscovered.