Public setlist view · July 2026
The public setlist shows the track playing in the Pub and a searchable history of identified music. The page reads current state from Server-Sent Events and loads older D1 rows through a cursor API.
Current interface
Live state
| State | Page behavior |
|---|---|
| Playing | Shows album art, title, artist, and a Save action for the current track |
| Quiet | Shows Quiet right now when the pipeline is online but has reported silence |
| Offline | Shows an identification-service warning while leaving stored history available |
The live card appears only in the Today scope. Historical scopes keep the current-state card out of the browsing view.
History scopes
| Scope | Loading behavior |
|---|---|
| Today | Fetches enough cursor pages to cover the current local day |
| Yesterday | Fetches enough history to cover the previous local day |
| This week | Backfills up to seven local days |
| All time | Fetches the next cursor page when an IntersectionObserver sees the scroll sentinel |
Search filters title and artist within the active scope. Results remain grouped by local day with the newest track first.
Track rows
Each row shows album art, title, artist, local time, and a source label when available. Tapping the row or its actions button opens one bottom sheet with:
- Spotify, Apple Music, Tidal, and YouTube Music searches;
- Web Share when the browser supports it; and
- a copy-title-and-artist action.
Spotify searches by ISRC when the track record has one; the other services search by title and artist.
Audio-source labels
The Pi selects the loudest non-silent AES67 stereo pair and stores its source key with the track.
| Display label | Stored key | AES67 channels |
|---|---|---|
| HDMI | program | 1–2, Program L/R |
| Wall Stereo | wallstereo | 3–4, Wall Plate Stereo L/R |
| Wall XLR | wallxlr | 5–6, Wall Plate XLR 1/2 |
When every track in a day has the same source, the interface places the label beside the day heading. Mixed-source days show labels on individual rows. Older records without source data remain unlabeled.
See Audio sources and channel mapping for the Q-SYS and Pi path.
Live and historical data
flowchart LR CORE["Q-SYS Core<br/>6-channel AES67"] --> PI["Pub Raspberry Pi<br/>capture + identification"] PI -->|"POST /api/now-playing/ingest"| WORKER["Pub Worker"] WORKER --> D1[("SETLIST_DB")] WORKER -->|"SSE: track, status, ping"| PAGE["/setlist/"] PAGE -->|"GET /api/now-playing/setlist<br/>limit + before"| WORKER
The page initially reads /api/now-playing/setlist. Bounded scopes request additional pages until their time window is covered; All time waits for the scroll sentinel. New track events prepend without reloading the page. A track event with a null payload clears the live card; status events update connection state without changing stored history.
The complete capture, identification, storage, and SSE architecture is in Now Playing and setlist system.
Related setlist surfaces
Each surface reads a stored rollup from SETLIST_DB; the serve path does not compute analytics inline.
| Surface | Route | Purpose |
|---|---|---|
| Top Songs | /setlist/top-songs | Most-played tracks over selectable windows |
| The Vibe | /setlist/vibe-compass | Genre distribution built from enriched track metadata |
| Echo | /setlist/echo | A setlist snapshot from an earlier point in time |
| Tonight | /setlist/tonight | Live summary and share card for the current night |
| Wrapped | /setlist/wrapped | Period retrospective rendered as stat cards |
| Persona | /setlist/persona | Model-generated Pub personality text from music history |
| Stories | /setlist/stories | Model-generated cards about specific setlist moments |
The current wrangler.toml enables these seven surfaces. Each also has a gate that returns 404 when disabled; a surface can return 503 until its first rollup exists. The patron song-request surface is retired and remains disabled.
Data and privacy
The application records track metadata heard on the room’s public audio system: title, artist, album data, ISRC when available, source key, confidence, and timestamps. It does not attach a resident or listener identity to a setlist row.
Current limits
- Live performance and catalog misses do not create an identified-track row.
- Pre-AES67 records may have no source label.
- Streaming links are searches; only Spotify uses ISRC when available.
- The identification backend can miss short, quiet, or uncatalogued audio.
Sources: public/setlist/index.html, worker.js, wrangler.toml, pi/pi_capture/, verified at ihnyc-avi-pub-landing commit fb13cdf.