Rework static overlay as a procedural VHS glitch band

Replaced the sparse-noise-specks static effect with a jagged horizontal
glitch band (plus scattered specks), still procedurally generated with
Pillow -- no source footage involved. Tried deriving this look from a
real, explicitly free-to-use "VHS glitch" stock clip first, but dropped
that approach: even downsampled to 32x32 and thresholded for
transparency, recognizable footage content showed through at any opacity
that read as an actual band rather than noise, and it compressed
noticeably worse than procedural noise. Verified payload stays well
under the 460KB limit against the live station.
This commit is contained in:
poprhythm committed 2026-10-02 22:54:18 -04:00
1 parent 667899d258
commit 8e101b997e
2 files changed
+20 -11

No files matched your search

+20 -11
View File
@@ -31,8 +31,9 @@ app's config when adding it to a device.
to show off different sections of its art over time instead of being
stuck on one spot for its whole runtime.
- **Static overlay** — On (default) or Off. When on, shows a brief
TV-static effect (sparse noise specks) over the album art during the
first/last few seconds of a track, as a transition cue.
TV-glitch effect (a jagged horizontal static band, plus scattered noise
specks) over the album art during the first/last few seconds of a
track, as a transition cue.
## How it works
@@ -115,17 +116,25 @@ app's config when adding it to a device.
its full module list) — so there's no way to pre-bake or crop-at-render-
time from a source we don't have until the request hits the live
station.
- When enabled (Static overlay config), shows a brief TV-static effect
- When enabled (Static overlay config), shows a brief TV-glitch effect
over the album art during the first/last `STATIC_OVERLAY_SECONDS` (5s)
of a track, as a transition cue. Implemented as a small bundled animated
GIF (`images/static.gif` — sparse noise specks over a transparent
background, built with Pillow) composited over the zoomed art via
`render.Stack`, not generated at render time: pixlet's Starlark sandbox
has no per-frame procedural drawing hook, and `animation.Transformation`
only interpolates between fixed keyframes, so there's no way to get
genuine random noise out of it. `render.Image` plays back animated GIFs
natively, looping independently of the zoom's own animation timeline.
Like the progress bar, this only works correctly on a long-lived server
GIF (`images/static.gif` — a jagged horizontal static band plus
scattered noise specks, over a transparent background, procedurally
generated with Pillow, not sourced from any existing footage)
composited over the zoomed art via `render.Stack`, not generated at
render time: pixlet's Starlark sandbox has no per-frame procedural
drawing hook, and `animation.Transformation` only interpolates between
fixed keyframes, so there's no way to get genuine random noise out of
it. `render.Image` plays back animated GIFs natively, looping
independently of the zoom's own animation timeline. An earlier version
tried deriving this effect from a real "VHS glitch" stock-footage clip
(downloaded, downsampled, and thresholded for transparency) instead of
generating it — dropped because, even licensed as free-to-use, cropping
it down to 32x32 let recognizable footage content show through at any
opacity that read as an actual "band" rather than sparse noise, and it
compressed noticeably worse than procedural noise does. Like the
progress bar, this only works correctly on a long-lived server
with a persistent cache — a one-shot `pixlet render` CLI call always
sees `elapsed=0`, so it'll always show the "starting" static, never the
"ending" one. Tuned the GIF's frame count/density/flicker speed down
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.