Episode Assembler
Where the episode becomes one 48 kHz master
- scene_audio
- opening_theme_audio
- closing_theme_audio
- music_cue_audio
- episode_audio
- output_path
- episode_info
- audio_done
The OldTimeRadio pipeline's core belief is audio is the source of truth. OTR_EpisodeAssembler is where that belief becomes a file: it takes the sequenced scene audio, the opening and closing themes, and the music cues, and assembles them into a single frozen 48 kHz master mix. That master defines the episode timeline; the video is rendered to fit it, and muxed in last. This node is the moment everything upstream converges and everything downstream is scheduled from.
It's also where the crossfades happen, and - subtly important - where the final peak normalization actually runs. OTR_AudioEnhance deliberately defers its normalize to here, post-crossfade, because normalizing earlier caused clipping during segment overlaps.
How it works
Three audio buses come in: scene_audio (required - the sequenced dialogue + music from OTR_SceneSequencer), the opening/closing themes, and the music-cue bus. When music_cue_manifest_json from OTR_StableAudioTheme is wired, the opening and closing themes are sliced out of that padded batch by sample count and fed through the same segment/crossfade machinery; the legacy opening_theme_audio/closing_theme_audio inputs stay declared but unlinked on the manifest path. opening_duration_sec (10) and closing_duration_sec (8) cap the themes; crossfade_ms (500) eases theme into content.
The critical output is audio_done. It's a STRING carrying the final episode metadata - length, sample rate, segment count - and it's a topological gate: downstream nodes wire it in to guarantee they run after the audio branch freezes. That's the structural way the pack stops the video branch from starting while audio still needs GPU, and it's why OTR_ShotLock and OTR_MasterAudioMux both have an audio_done input. episode_title defaults to "The Last Frequency" and is stamped into the episode.
Outputs: episode_audio (the AUDIO), output_path (the master WAV - this is exactly what OTR_MasterAudioMux consumes as master_audio_path), episode_info, and audio_done.
Install and gotchas
Pack-level install (ComfyUI Manager → ComfyUI-OldTimeRadio, restart). No model downloads here - it's pure audio assembly. The node is marked as an output node, so a stripped "audio-only" workflow can terminate at it and still land a playable master on disk.
The classic mistake is wiring a music cue manifest but leaving the legacy theme inputs connected too - the manifest path wins, and double-feeding themes is how you get an intro that's suddenly 20 seconds of layered music. Pick one bus. And remember the frozen master is frozen: after this node, the 48 kHz mix is the timeline, and any change upstream means re-freezing before the video stage trusts it again.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| scene_audio | AUDIO | — | |
| episode_title | STRING | The Last Frequency | Label for this node's episode_info output and log lines ONLY -- the published title comes from the ledger (the Writer's episode_title), not from here. Diagnostic field. |
| opening_theme_audioopt | AUDIO | — | |
| closing_theme_audioopt | AUDIO | — | |
| opening_duration_secopt | FLOAT | 100–60 | Max duration of opening theme |
| closing_duration_secopt | FLOAT | 80–60 | Max duration of closing theme |
| crossfade_msopt | INT | 5000–3000 | Crossfade between theme and content |
| music_cue_audioopt | AUDIO | Padded AUDIO batch of every music cue from OTR_StableAudioTheme. | |
| music_cue_manifest_jsonopt | STRING | Cue manifest JSON from OTR_StableAudioTheme (maps placement -> batch row). | |
| video_policy_jsonopt | STRING | Video policy JSON from OTR_VideoDirector. Read for ONE question: is any role on the LTX 2.5 foley lane? If so this node writes an UN-LEVELLED provisional master WAV and OTR_MasterAudioMux does the single delivery loudness pass after mixing the bed in. Empty -> today's behaviour, unchanged. | |
| replay_descriptoropt | STRING | v2_ledger_json from OTR_LedgerFreezeCascade. On a canonical replay the frozen master WAV is copied and verified against the bundle's SHA-256; otherwise ignored. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| episode_audio | AUDIO | — |
| output_path | STRING | — |
| episode_info | STRING | — |
| audio_done | STRING | — |