videobox is a local-file VIDEO PLAYER: you drop (or pick) a video file from disk and it decodes the file each frame into the module's video output, while the file's stereo audio track is split out to the audio_l / audio_r jacks for patching back into the audio domain. The NODE owns the actual HTMLVideoElement and object-URL (a node-scoped controller created with the graph — the file keeps playing with no surface mounted at all); the engine samples that element through a decode-rate frame uploader (only re-uploading when a genuinely new frame lands, downscaled to the engine resolution) so playback stays smooth even at 1080p. Behind the file picker the surface uses File System Access handles (Chromium) to remember your pick and one-click-reload it next session; other browsers and other peers fall back to a "Re-link: drop <name>" prompt. The playhead is multiplayer-synced: play, pause and seek write a shared (isPlaying / lastSyncTime / lastSyncPosition) triple to the node so every peer's local copy follows, drift-correcting whenever it slips more than ~0.5s off the expected position. The picture well is drag-resizable from the bottom-right corner (default and minimum 360x360) so several videoboxes can be tiled into a wall of TVs; size persists on the node and syncs to peers. Right-click the picture for Fullscreen (a LOCAL per-peer state, NOT multiplayer-synced) or Full Frame (in-app, the video consumes the whole surface, hiding the picker/transport/seekbar; double-click to exit), where ONLY Full Frame is synced to peers. The faceplate also carries a SCREEN ON/OFF switch: OFF collapses the preview and reclaims its space while the file KEEPS PLAYING and keeps feeding the video and audio outs. Usage: drop a clip, hit Play, and patch video into a mixer/output and audio_l/audio_r into your audio chain; pulse the TRIG input from a clock or button to toggle play/pause hands-free. Idle (no file) shows a faint blue gradient so an empty module reads as alive-but-empty.
videobox is a local-file VIDEO PLAYER: you drop (or pick) a video file from disk and it decodes the file each frame into the module's video output, while the file's stereo audio track is split out to the audio_l / audio_r jacks for patching back into the audio domain. The NODE owns the actual HTMLVideoElement and object-URL (a node-scoped controller created with the graph — the file keeps playing with no surface mounted at all); the engine samples that element through a decode-rate frame uploader (only re-uploading when a genuinely new frame lands, downscaled to the engine resolution) so playback stays smooth even at 1080p. Behind the file picker the surface uses File System Access handles (Chromium) to remember your pick and one-click-reload it next session; other browsers and other peers fall back to a "Re-link: drop <name>" prompt. The playhead is multiplayer-synced: play, pause and seek write a shared (isPlaying / lastSyncTime / lastSyncPosition) triple to the node so every peer's local copy follows, drift-correcting whenever it slips more than ~0.5s off the expected position. The picture well is drag-resizable from the bottom-right corner (default and minimum 360x360) so several videoboxes can be tiled into a wall of TVs; size persists on the node and syncs to peers. Right-click the picture for Fullscreen (a LOCAL per-peer state, NOT multiplayer-synced) or Full Frame (in-app, the video consumes the whole surface, hiding the picker/transport/seekbar; double-click to exit), where ONLY Full Frame is synced to peers. The faceplate also carries a SCREEN ON/OFF switch: OFF collapses the preview and reclaims its space while the file KEEPS PLAYING and keeps feeding the video and audio outs. Usage: drop a clip, hit Play, and patch video into a mixer/output and audio_l/audio_r into your audio chain; pulse the TRIG input from a clock or button to toggle play/pause hands-free. Idle (no file) shows a faint blue gradient so an empty module reads as alive-but-empty.
the faceplate
1 inputs · 3 outputs · 2 params
inputs
id
cable
what it does
play_trigger
gate
TRIG (gate cable, edge: trigger). A rising edge across the gate threshold toggles play/pause — it does NOT hold; only the moment the level crosses high fires the toggle, so a clock or button pulse flips between Play and Pause. Routed through the CV bridge as the synthetic cv_play_trigger param, which the node's source controller edge-detects and writes into the shared multiplayer play state.
gate / trigger; modulates cv_play_trigger (summed directly (the destination DSP scales it)); trigger — fires once per rising edge
outputs
id
cable
what it does
video
video
VID (video cable) — the decoded video frames of the loaded file, sampled into the output at the engine resolution. Shows the faint blue idle gradient until a file is loaded and a frame has uploaded.
RGB video stream
audio_l
audio
A-L (audio cable) — the LEFT channel of the loaded file's audio track, split out of a MediaElementSource once a file is loaded. Emits silence (a flat ConstantSource placeholder) before any file is loaded or if audio wiring fails.
audio signal
audio_r
audio
A-R (audio cable) — the RIGHT channel of the file's audio track. Same silent placeholder until a file is loaded; a mono file effectively feeds the same content to both channels via the splitter.
audio signal
params
id
label
range
default
curve
gain
Gain
0..2
—
linear
cv_play_trigger
Play trigger
0..1
0
linear
controls
control
what it does
Play trigger
Play trigger (linear, 0 to 1, default 0). Synthetic hidden param — not a visible control. It is the bridge target for the play_trigger gate input: the CV bridge writes the gate level here and the node's source controller polls it for a rising edge across 0.5 to toggle play/pause. Has no on-screen UI.
Gain
Gain (linear, 0 to 2, default 1.0). Output level for the picture: the passthrough shader multiplies the sampled RGB by this (the uGain uniform), so 0 blacks the output, 1.0 is the identity and 2 doubles it (clipped at full scale by the 8-bit framebuffer). It scales the VIDEO only — the audio outs are unaffected.