USB presentation clicker (slide advancer) plugged into the Orange Pi.
Most commercial USB slide advancers emulate standard USB HID keyboard events, typically broadcasting PageDown or ArrowRight for the "Forward" button, and PageUp or ArrowLeft for "Back." We built a context-sensitive event dispatcher to map these simple physical inputs to complex state transitions:
| Clicker Button |
HID Key Codes |
Landing Screen |
Viewing Screen |
BSOD Crash Screen |
| Forward ▶ |
PageDown, ArrowRight, Enter
|
🔒 LOCK IN (Start) |
⏭ Skip Video
|
🔒 REBOOT BRAIN
|
| Back ◀ |
PageUp, ArrowLeft, Escape
|
(No Action) |
🌱 TOUCH GRASS (Exit) |
(No Action) |
const FORWARD_KEYS = new Set(['PageDown', 'ArrowRight', 'ArrowDown', 'Enter', '']);
const BACK_KEYS = new Set(['PageUp', 'ArrowLeft', 'ArrowUp', 'Escape', 'Backspace']);
document.addEventListener('keydown', (e) => {
if (FORWARD_KEYS.has(e.key)) {
e.preventDefault();
if (state.screen === 'landing') lockIn();
else if (state.screen === 'viewing') playNextVideo();
else if (state.screen === 'crash' || state.screen === 'exit') lockIn();
} else if (BACK_KEYS.has(e.key)) {
e.preventDefault();
// Visitors can only "Touch Grass" if the meltdown hasn't locked them in!
if (state.screen === 'viewing' && !dom.btnTouchGrass.disabled) {
touchGrass();
}
}
});
3. Optimizing for the Orange Pi Zero
Running heavy video streams and dynamic CSS filters on a modern MacBook M-series chip is trivial. Running them on an Orange Pi Zero—a tiny single-board computer with a low-frequency Allwinner ARM processor, 512MB of RAM, and minimal GPU acceleration—was an immediate performance bottleneck.
When I first tested the installation on the Orange Pi, videos stuttered heavily, frame rates dropped to single digits, and text rendered as an unreadable, blurry smudge on the ×ばつ480 display. Solving this required engineering a specialized low-power architecture.
Automatically detecting onboard hardware
Rather than maintaining two separate codebases, the application inspects browser concurrency and hardware memory capabilities on launch, automatically engaging low-power optimizations when running on embedded edge hardware:
const LOW_POWER = new URLSearchParams(window.location.search).get('lowpower') === '1' ||
(navigator.deviceMemory && navigator.deviceMemory <= 2) ||
(navigator.hardwareConcurrency && navigator.hardwareConcurrency <= 2);
Deep Video Prefetching
On weak Wi-Fi or limited CPU threads, waiting for a user to click "Skip" before fetching the next MP4 causes jarring black pauses. In low-power mode, we expanded the prefetch pipeline from 1 video to an asynchronous queue of 4 hidden <video> buffer elements. By setting preload="auto" and keeping them muted off-DOM, the browser silently saturates its media cache ahead of time, ensuring instant, zero-latency cuts between video transitions.
Killing GPU-Melting CSS Filters
Originally, as the visitor's brain rot progressed, the entire .screen--viewing container underwent intensifying CSS distortions: hue-rotate(), saturate(), and blur().
On ARM Linux without dedicated GPU compositing threads, CSS blur() forces software rendering, bringing the CPU to its knees. In low-power mode, we dynamically strip all CSS filters and fullscreen DOM overlays (such as CSS scanlines and glitch overlays), relying purely on lightweight opacity shifts and solid color contrast.
Throttling procedural canvas noise
The application features a live 2D <canvas> rendering analog TV white noise. A naive requestAnimationFrame loop firing at 60fps consumed over 40% of the Orange Pi's CPU cycles just calculating Math.random() pixel data.
To fix this, we introduced framerate throttling and resolution scaling. On low-power hardware, the canvas internal resolution is divided by 8 (scaling up smoothly via CSS) and throttled to render at just 8 frames per second—or bypassed entirely if needed:
const STATIC_FRAME_INTERVAL = LOW_POWER ? 125 : 0; // 125ms = ~8 FPS
const STATIC_RESOLUTION_DIVISOR = LOW_POWER ? 8 : 4;
4. ×ばつ480 CRT Typography
The final hurdle was visual typography. At ×ばつ480 resolution, custom web fonts (like Press Start 2P or stylized display fonts) rendered terribly on Linux ARM browsers. Without high-DPI screens or OS-level subpixel anti-aliasing, characters clumped together into illegible pixel soup. Furthermore, standard text-shadows (0 0 10px neon-green) blurred into muddy halos.
To guarantee crisp readability from three feet away in a dimly lit gallery, we executed a complete embedded typography overhaul:
-
System Fonts: We bypassed Google Fonts entirely on embedded devices, overriding DOM elements to use native OS font stacks (
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif). Native fonts carry built-in hinting rules that align perfectly to low-resolution pixel grids.
-
Scale Doubling: We doubled font sizes across the board. Headers scaled up to 72px–110px, control buttons to 36px, and telemetry badges to 24px.
-
Zero-Shadow: We stripped all glowing text shadows and replaced
backdrop-filter: blur() glassmorphism with 100% solid, pitch-black contrast backgrounds (#000 !important). Text never composites over moving video pixels.
-
Emojis: Lightweight ARM Linux OS builds often lack comprehensive Unicode emoji font tables, rendering emojis as hollow rectangular boxes (
□しろいしかく). We wrapped UI emojis in <span class="emoji"> tags and applied display: none !important in low-power mode, replacing them with clean cybergothic ASCII indicators like ///.
Slop is in the eyes of the beholder
Building BrainRot TV for the TIAT "Slop Epistemologies" exhibition was extremely fun, and a good reminder that hardware constraints can often drive the most impactful engineering and aesthetic decisions.
By stripping away heavy GPU abstractions and tailoring media pipelines specifically for a 15ドル Orange Pi Zero, BrainRot now has a rock-solid 60fps video playback loop that never stutters, never crashes prematurely, and delivers an intensely mesmerizing, inescapable critique of modern digital consumption.
If you're attending the exhibition in San Francisco, step up to the terminal, grab the clicker, and hit LOCK IN! Just remember to try and Touch Grass before the system takes you under. 😅
The complete codebase for BrainRot TV is containerized with Docker and deployed on Google Cloud Run.