Nodes/Story JSON Nodes/Kokoro Scene Audio (local TTS)
ComfyUI Node

Kokoro Scene Audio (local TTS)

Kokoro TTS

By stepan-bogatorjov·Created 5 months ago·Updated about a month ago· 0
Kokoro Scene Audio (local TTS)
    • AUDIO
    text
    voiceam_michael
    speed1.00
    pitch0.0
    voice_name

    KokoroSceneAudio is the local, offline, free text-to-speech node in the Story JSON Nodes pack (stepan-bogatorjov/comfy_scenes_json_node) - and it's the one that replaces a paid voiceover API. Give it a line of narration and a voice, and it runs hexgrad's Kokoro-82M on your machine: no API key, no per-character billing, no network after the first model download.

    Kokoro is the right model for this job, not just a free one. At 82M parameters it's tiny, built on a StyleTTS2 backbone with a fast vocoder instead of a diffusion loop, so it's genuinely real-time and runs comfortably on CPU - the "best voice per unit of compute" pick in this ecosystem. The KB positions it as the open lightweight standard: displaced at the quality frontier by Chatterbox, but still the obvious choice when you're generating a lot of short narration lines on modest hardware, which is exactly what a per-scene story pipeline does. And it's Apache 2.0, so nothing stops you shipping the result. The one thing it won't do is clone a specific voice - you get a bank of 28 presets, which is all this workflow needs.

    The node is a drop-in for the pack's API-backed voiceover path (it even mirrors MockSceneAudio's interface), so you can swap it in and out without rewiring.

    How it works

    The heavy lifting happens in kokoro's KPipeline, imported lazily so the pack still loads if you haven't installed it. The pipeline is cached per language code - American English (a) and British English (b) - and built once, on CUDA if available else CPU. The node streams the text through Kokoro, concatenates the audio chunks, and applies your pitch shift with torchaudio's PitchShift (duration preserved, so you can raise a light voice into a convincing child timbre without speeding it up). Empty text returns half a second of silence instead of crashing. Output is the standard AUDIO dict at Kokoro's native 24 kHz.

    The inputs that matter

    • text - the narration line (multiline).
    • voice - 28 Kokoro voices, named like am_michael (American male), af_heart (American female), bf_lily (British female). Default am_michael.
    • speed - 0.5–2×.
    • pitch - −12 to +12 semitones. Positive shifts give that childlike timbre; negative deepens.
    • voice_name - optional override that wins over the dropdown: a friendly name like "Heart" or "Fenrir" (resolved via StringToKokoroVoice) or a raw Kokoro ID.
    • Output AUDIO → SaveAudioPassthrough to land it as scene_NNNN.wav, which StoryFinalCompile picks up per scene.

    Install

    The pack itself is trivial:

    cd ComfyUI/custom_nodes
    git clone https://github.com/stepan-bogatorjov/comfy_scenes_json_node
    

    Then the extra step that actually matters - install kokoro into the same Python that runs ComfyUI. On the Windows portable build that's python_embeded:

    # Windows portable:
    ComfyUI\python_embeded\python.exe -m pip install -U kokoro
    # otherwise:
    python -m pip install -U kokoro
    

    Restart, run the node once, and it downloads the Kokoro-82M weights from Hugging Face on first use. torchaudio (bundled with most ComfyUI installs) handles the pitch shift.

    Troubleshooting

    The classic failure is the environment mismatch: you pip-install kokoro into your system Python, ComfyUI runs a different one, and the node errors at first use with an import error. Install into python_embeded (or whatever interpreter ComfyUI actually uses) and it just works. The code also handles older kokoro versions that lack a device kwarg, so a stale package won't hard-fail. First run downloads weights - give it a minute, it's not hung. And remember the pitch caveat: when a story JSON names a child voice, the semitone shift comes through KokoroSceneAudio's pitch input via StringToKokoroVoice - wire that socket or child characters sound like adults.

    Categoryaudio

    Inputs (5)

    NameTypeDefaultDescription
    textSTRING
    voiceCOMBOam_michael28 options: af_heart, af_alloy, af_aoede, af_bella, af_jessica, af_kore, +22
    speedFLOAT1.000.5–2
    pitchFLOAT0.0-12–12
    voice_nameoptSTRING

    Outputs (1)

    NameTypeDescription
    AUDIOAUDIO