Signal Lost Video
The zero-VRAM CRT engine behind the whole aesthetic
- audio
- video_path
- title_card_plan_json
This node is the reason OldTimeRadio can render video at all on a machine that can't run a video model. OTR_SignalLostVideo is a procedural audio-reactive CRT engine: pure numpy + PIL math, piped frame by frame into ffmpeg, with zero VRAM and no AI video generation involved. It's the "SIGNAL LOST" floor video - the scanlines, the title bar, the oscilloscope, the frequency bars, the vignette - and in the canonical workflow it's the shipped default for every video role until you dial in a real video engine.
Don't read "procedural" as "cheap-looking." It's a deliberately art-directed retro broadcast aesthetic, and it's fully deterministic: render a given episode twice and the visuals agree. It's also the pack's guaranteed-to-complete path - when a heavier engine OOMs on your card, this is the lane that still finishes.
How it works
The mechanism is a master clock: audio duration × fps = exact frame count. It analyzes the audio (per-frame RMS volume plus a 32-bin FFT spectrum), then renders each frame as a CRT picture: title bar, procedural art center, frequency bars, oscilloscope, scan lines, vignette. The center area is pure procedural art - no script text, no dialogue cards - driven by audio energy and math. Raw RGB frames go to ffmpeg's stdin, and the audio is muxed in (the v1 encoder hard-requires audio).
Inputs: audio (required), script_json and news_used (pipeline compat - feed them whatever you have), plus the real knobs: fps (24 = cinematic default), resolution (1920×1080 default delivery res; 832×480 was the old legacy default; 1280×720/854×480/3840×2160 retained for one-offs), episode_title (last-resort override - normally resolved from the script's title token), and draw_scopes (true). That last one matters if you use the v2 pipeline: set draw_scopes off when OTR_SceneAwareScopes is handling the scopes downstream, or you get two scope systems.
Outputs: video_path (the procgen mp4) and title_card_plan_json (the hero title-card plan - feed it to OTR_CaptionBurn, which burns the title regardless of its caption setting).
Install and gotchas
Pack-level install (ComfyUI Manager → ComfyUI-OldTimeRadio, restart). Pillow and ffmpeg are the real dependencies - the module raises a named ImportError if Pillow's missing, and it shells out to ffmpeg to encode. First render takes as long as the episode is, since it's frame-by-frame math - a 20-minute episode is a real wait, but it's CPU-only, so it won't compete with the audio branch for GPU. If you see a black video, check the ffmpeg pipe, not the math: this node is the one place a pipe deadlock shows up. And when you switch a role to a GPU engine in OTR_VideoDirector, the procedural path stops being the default for that role - it's a selected lane, not a safety net.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| script_json | STRING | [] | Parsed script JSON (pipeline compat) |
| news_used | STRING | [] | News JSON (pipeline compat) |
| fpsopt | INT | 2412–60 | Frames per second (24 = cinematic) |
| resolutionopt | COMBO | 1920x1080 | Procgen output resolution. 1920x1080 = delivery res for the final procgen blend (BUG-030 Phase B default). 832x480 was the prior default (rendered cheap, then upscaled with everything else; legacy mode). 1280x720 / 854x480 / 3840x2160 retained for one-off needs. |
| episode_titleopt | STRING | Episode title for the title bar. Normally resolved from the script_json title token; widget acts as a last-resort override. | |
| draw_scopesopt | BOOLEAN | true | Draw the floor's in-frame scopes (centre ring, orbit particles, waveform, freq bars). Default ON (v1). Set OFF for the v2 scene-aware-scopes pipeline, where OTR_SceneAwareScopes draws the scopes in the real per-beat gutters downstream. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | — |
| title_card_plan_json | STRING | — |