Announcer Voice (v2)
OTR_AnnouncerVoice
- announcer_audio
- render_log
- done
Every old-time-radio episode needs the voice that kicks it off: "Good evening, listeners." That's this node's entire job. It's the announcer side of the ComfyUI-OldTimeRadio voice pipeline - the character-dialogue twin is OTR_BatchCharacterVoices - and in the canonical workflow it renders the announcer bookends that open and close the show.
What makes it worth knowing: announcer lines never come out of the same TTS engine as your characters. They're routed here because a radio announcer is a role with its own voice stock, not just another speaker. If you've ever had a narrator accidentally sound like the hero, this is the split that keeps them apart.
How it works
It's a thin node. It reads a frozen v2 ledger (JSON) from OTR_LedgerFreezeCascade, filters to only the lines whose speaker_role is announcer, and pushes each through the engine you picked. The default is kokoro - a per-line path that chooses one British voice per episode, seeded from the episode seed, and verifies the voice .pt file is on disk before it runs rather than fetching it mid-render. chatterbox and dia are opt-in and flag-gated; bark, elevenlabs, and google_tts are there too but are the same fail-closed, off-by-default story as the rest of the pack's opt-in roster. The engine libraries are lazy-imported inside the node, so the pack loads cold even if you never use most of them.
The done output is the interesting plumbing bit. OldTimeRadio runs on ordering signals - wire an upstream node's done into gate_in to force ordering, and pass your own done downstream. That's how the graph guarantees voices finish before the scene sequencer starts.
The inputs that matter
You set almost nothing. The two required inputs are script_json (the frozen ledger from the freeze cascade) and engine (leave it on kokoro). The optional ledger_json comes from OTR_CastLock and carries voice_ref_id and the episode seed for the per-line path; if it's absent the node falls back to the raw script_json. gate_in is the ordering signal described above.
Outputs are announcer_audio (AUDIO - wire it to OTR_SceneSequencer's announcer_audio_clips), a render_log string, and done.
Install and gotchas
Same story as the whole pack: ComfyUI Manager → search ComfyUI-OldTimeRadio → install, or:
git clone https://github.com/jbrick2070/ComfyUI-OldTimeRadio
cd ComfyUI-OldTimeRadio && git checkout v2.0-alpha
Restart ComfyUI. The pack needs transformers>=5.10.4 (pinned via requirements.txt, not your torch) plus soundfile, numpy, and the rest - the Manager/registry install handles it. Announcer voices use the Kokoro weight; a missing file fails loudly and names exactly what it expects in the console, which is the pack's fail-closed contract. First run takes a while - this is a full episode pipeline, not a single image.
One honest caveat from the maintainer's own docs: character drift exists - occasionally a line lands with the wrong character. The announcer lane is the reliable part; don't blame it for a stray line elsewhere in an episode.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| script_json | STRING | [] | Frozen v2 ledger JSON from OTR_LedgerFreezeCascade (node 62 slot 1). Passed VERBATIM to the legacy engine on the byte-identical batch path. |
| engine | COMBO | kokoro | Voice engine for this role. The legacy engine is the byte-identical default; opt-in engines are flag-gated until the GPU dependency pilot promotes them. Unusable selections fail closed with a named error at queue time. |
| ledger_jsonopt | STRING | Cast-locked ledger from OTR_CastLock (carries voice_ref_id / episode_seed). Read on the per-line path; the batch path ignores it and delegates the raw script_json. No episode_seed widget (I-4). | |
| gate_inopt | STRING | Optional ordering signal. Wire an upstream 'done' here to force this node to run after it. Optional on the first chain node; the audio chain binds it node->node. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| announcer_audio | AUDIO | — |
| render_log | STRING | — |
| done | STRING | — |