Public Movie Nights archive · July 2026
- When the pub screens a film, the bar-right TV shows a “Now Showing ·
” card and the public/screenpage archives the night — automatically, with no operator action in the common case. - When an identified soundtrack album is named for the film,
setlist.albumsupplies the candidate film title. This works only for music-identifiable films such as musicals, concert films, music documentaries, and scored films with soundtrack album metadata. - Dialogue-driven films and anything the audio can’t name fall back to a generic “On the big screen”, or the operator types the title (see Operator path).
Sources: worker.js (tickScreenings wiring, computeNowShowing, handleScreenPage, handleScreeningsApi), worker/lib/pub-screenings/{detect,store,state-machine}.js, public/tv/cinematic.js, migrations/0046_pub_screenings.sql
How detection works
- Open (audio). A 60-second cron (
tickScreenings) watches the recent setlist. When N or more plays (rows, not distinct titles) share one normalized album within a 20-minute window, it opens a candidate screening. Counting rows is deliberate: a single film can play few distinct titles many times. - Confirm (automatic). A candidate is promoted to confirmed when either:
- the projector is freshly on — the Pi’s heartbeat reports
projector_status.power == "on"and the heartbeat is recent (a stale, frozen “on” after a Pi outage does not confirm), or - a Notion event today has a title that matches the film.
- Projector power is the only device gate — a phone mirroring an app over HDMI reads as “video” to the matrix, so that signal is intentionally ignored.
- the projector is freshly on — the Pi’s heartbeat reports
- Re-tag. On confirm/close, the songs played during the screening window are re-tagged from
content_kind='music'to'video'so they leave Top Songs / The Vibe / Persona (they’re part of a movie, not the music charts). They’re stamped with a stablescreening_idso a later title edit or a re-screening of the same film never mis-targets the reversal. - Close. After the screening goes quiet (no same-album plays for ~35 min) the screening closes and lands in the
/screenarchive. A different film starting mid-stream force-replaces the current one (double-feature safe).
A candidate that never confirms is abandoned with no re-tag — if it was just someone playing a soundtrack album as bar music, nothing is shown and the charts are untouched.
Bar TV card
- On the bar-right TV, a confirmed screening leads the silent rotation with “Now Showing” (eyebrow) + the film title (large Playfair) + the poster rendered as a soft, dark-scrimmed background bloom behind the title (legible across a dim room; the title is the glanceable signal, not a small thumbnail).
- No poster → title-only. A live song always preempts the card (the song card wins), and the movie card returns when the music stops.
- The card only appears for a confirmed screening (the named film) or when the Pi’s live audio verdict is actually video (the generic “On the big screen” / a live game). A projector that’s simply powered on but idle does not light a card — “the screen is on” alone isn’t “something’s showing.”
/screen — the public archive
pub.ihnyc-rc.org/screen— a top-level page reached from the homepage (a peer of the music surfaces, not nested under/setlist). A reverse-chronological, month-grouped list of past screenings: poster, film title, the night, and the soundtrack track count. Tap a night to expand its tracklist.- An amber “Now Showing” strip appears at the top while a screening is live.
- Empty state, broken-poster fallback (a title-on-dark placeholder tile), and 0-track nights are all handled.
Operator path (the long tail)
- For a non-musical film, an off-Notion night, or a night the projector heartbeat is flaky, the auto-detector won’t open a candidate. The operator names it manually:
/admin/now-showing→ “Movie title…”, type the film (poster optional — auto-looked-up if blank). This both shows the card and creates the screening for/screen. - A revert (“this wasn’t a movie”) un-tags a screening’s songs back to music:
POST /api/admin/screenings/:id/revert(admin-gated).
Rollout & configuration
The feature is off until enabled, gated by two flags:
| Flag | Values | Purpose |
|---|---|---|
SCREENINGS_ENABLED | off (default) · shadow · on | shadow opens candidates and logs [pub-screenings] cron lines but does not re-tag songs or show a card — a safe tuning window with zero analytics impact. on goes live. |
NOW_SHOWING_ENABLED | flag | Must be on for the bar-TV “Now Showing” card to render (shared with the sports/now-showing card). |
TMDB_API_KEY | secret (optional) | Real film posters via TMDB. Without it, Deezer album covers are used (keyless). Both report to /admin/api-health. |
Recommended order: apply the migration → set SCREENINGS_ENABLED=shadow → run a real movie night and watch wrangler tail for [pub-screenings] (opened → confirmed) → if the threshold looks right, set SCREENINGS_ENABLED=on and ensure NOW_SHOWING_ENABLED is on.
Migration (manual)
wrangler d1 execute SETLIST_DB --local --file=./migrations/0046_pub_screenings.sql
wrangler d1 execute SETLIST_DB --remote --file=./migrations/0046_pub_screenings.sqlAdditive and nullable-safe (new pub_screenings table, setlist.screening_id, a seeded tmdb api-health row) — dormant until the flag flips, so applying it changes nothing on its own.