Nodes/ComfyUI-OldTimeRadio/ SilentComposite (render -> one always-silent video)
ComfyUI Node

SilentComposite (render -> one always-silent video)

Every clip, flattened into one silent video

By jbrick2070·Created 5 months ago·Updated about 17 hours ago· 7
SilentComposite (render -> one always-silent video)
    • silent_video_path
    • report
    base_video_path
    canvas_w1472
    canvas_h832
    fps25
    ffmpegffmpeg
    output_path
    gate_in
    clip_manifest_json{}
    upscale_engineoff
    upscale_devicecpu

    The name is the contract: OTR_SilentComposite takes everything the render stage produced and flattens it into one always-silent canonical video - bt709 color, yuv420p, constant frame rate, audio stripped. It's the node between the raw per-beat clips and the captions/credits/mux stages, and it exists to guarantee the rest of the pipeline always receives a single, normal, silent MP4 no matter how many engines and aspects contributed clips.

    Audio is stripped here on purpose (V-1): the frozen master gets added only at the very end by OTR_MasterAudioMux. If you're hunting for a bug where the final video's audio is wrong, remember this node's output is supposed to be silent.

    How it works

    Two paths, one node. With just base_video_path (the OTR_SignalLostVideo radio-floor mp4) it's the single-base floor path: normalize that one video to the canvas. When clip_manifest_json from OTRVideoRenderBatch (mode=episode) is wired and carries per-beat clips, it assembles a frame-accurate CFR timeline: each beat is conformed to its audio-derived frame count, and gaps are filled from base_video_path. That's how a portrait HuMo clip, a landscape LTX clip, and the procedural floor end up as one continuous, correctly-timed video instead of a mash-up of mismatched resolutions.

    Canvas defaults are canvas_w 1472 × canvas_h 832 at 25 fps. output_path defaults to <output>/otr/episodes/<stem>_silent.mp4. gate_in is the ordering signal.

    The interesting optional is upscale_engine (default off, or spandrel_esrgan): a post-render upscale stage that runs inside the composite per-clip (sharpen branch only) - so a still- or low-res clip gets lifted before assembly. It uses spandrel 0.4.x (a pinned pack dependency), and upscale_device (cpu default, or cuda/cuda:N) picks where the model loads. The composite itself always runs on CPU - that's ffmpeg - so the upscale is the only part that can touch a GPU. Off is byte-identical to the classic lanczos+unsharp path, so you can A/B freely.

    Outputs: silent_video_path and report.

    Install and gotchas

    Pack-level install (ComfyUI Manager → ComfyUI-OldTimeRadio, restart; v2.0-alpha). Needs ffmpeg on PATH. The gotcha to respect is the audio-strip invariant: if you wire in a base video hoping its audio survives, it won't - and that's correct. And if you enable spandrel_esrgan on a card with a loaded video engine, the upscale runs after, one clip at a time with VRAM reclaimed between - don't be surprised by the pause. Keep upscale_device off/cpu unless you're on a machine with headroom and want the speed.

    CategoryOldTimeRadio/v2/video

    Inputs (10)

    NameTypeDefaultDescription
    base_video_pathSTRINGBase video to normalize (M1: the OTR_SignalLostVideo radio-floor mp4). Any audio is STRIPPED here (V-1).
    canvas_woptINT147216–7680Silent-composite canvas width (px). Profile/platform-owned: variants pin it per hardware tier; both dimensions must be even (yuv420p) or the encode refuses by name.
    canvas_hoptINT83216–4320Silent-composite canvas height (px). Profile/platform-owned, even values only -- see canvas_w.
    fpsoptINT251–120Fallback frame rate for the silent timeline. When the clip manifest carries its own fps (the audio-derived budget), the manifest wins and this value is ignored.
    ffmpegoptSTRINGffmpegDEPRECATED and IGNORED (2026-09-04). A workflow value cannot name the binary this pack runs -- it arrives over an unauthenticated /prompt request. Set the OTR_FFMPEG environment variable to pin a build.
    output_pathoptSTRINGSilent composite path. Empty -> <output>/otr/episodes/<stem>_silent.mp4.
    gate_inoptSTRINGOptional ordering signal (opaque STRING).
    clip_manifest_jsonoptSTRING{}OTR_VideoRenderBatch(mode=episode) clip manifest. When it carries per-beat clips the composite ASSEMBLES a frame-accurate CFR timeline (each beat conformed to its audio-derived frame count; gaps filled from base_video_path). Empty -> the single-base floor path.
    upscale_engineoptCOMBOoffPost-render upscale/enhance stage. Runs INSIDE the composite per-clip (sharpen=True branch only); floor / directory / black paths are unchanged. off = today's lanczos+unsharp, byte-identical.
    upscale_deviceoptSTRINGcpucpu | cuda | cuda:N. Composite itself runs on CPU (ffmpeg); this widget selects the device the model loads on. Rejected invalid tokens fail loud.

    Outputs (2)

    NameTypeDescription
    silent_video_pathSTRING
    reportSTRING