Nodes/Protoface/Protoface Seed Speech TTS 2.0 · Text to Speech
ComfyUI Node

Protoface Seed Speech TTS 2.0 · Text to Speech

Forty voices, one kilobyte of text per call

By protoface-ai·Created 22 days ago·Updated 13 days ago· 0
Protoface Seed Speech TTS 2.0 · Text to Speech
    • audio
    • files
    • run id
    ◄text►
    ◄language▾►
    ◄output_formatmp3►
    ◄pitch0►
    ◄sample_rate24000►
    ◄speed1.0►
    ◄voicestokie_en►
    ◄voice_instruction▾►
    ◄volume1.0►
    ◄generation_id0►
    ◄request_scope►

    Why pay for TTS when Kokoro is free

    Fair question, and the KB's answer is that local TTS in ComfyUI is genuinely viable now - Kokoro and Piper run on CPU, Chatterbox clones a voice under 8GB, and TTS Audio Suite wraps several engines. The catch is what that layer costs you in maintenance: dependency conflicts between engines are the default failure mode of audio in ComfyUI, and the whole thing exists because TTS was never designed into the graph.

    Seed Speech TTS 2.0 is the other trade. One node, no engines, no transformers version roulette - and forty voice presets across ten-ish languages, which is more than most local stacks will hand you without downloading another suite. The bill is per character, with a minimum of one credit a request, and the catalog's units suggest you're paying in fractions of a cent per word. For a voiceover on a project that has a budget, that's fine. For "read me this paragraph forty times while I tune the timing," it isn't.

    The mechanism

    Every Protoface node is a client: the pack posts your text and settings to the Protoface API, polls the async job, downloads the result and returns a native ComfyUI AUDIO object. Controls are generated from the provider's public request schema, so each field maps to something their API takes. Your script text leaves your machine - worth a thought if it's an unreleased client document.

    The controls

    text is a single-line string, not a multiline box, and this is where the big constraint lives: the provider clips a request at 1000 characters. Long scripts need chunking into several nodes and a concatenation step, or a local engine. Nothing in the node warns you when you paste 4000 characters; you get one clipped reading.

    voice defaults to stokie_en and the preset list is a trip: forty entries with language suffixes like mindy_en_es_id_pt_zh, sven_de, minimi_ja, usseau_fr, pinky_es_ko_mixed_en_zh. Decoding the names tells you which voices are multilingual - _mixed_ presets are built for multi-language output, single-language ones for clean delivery in one.

    language is optional and exists to override detection; leave it unset and the model figures it out from the text. Override it for mixed-language scripts where you know what the body of the text is.

    voice_instruction is the sleeper feature: a free-text direction like "tired, quiet, slightly impatient" that shapes delivery and is not spoken aloud. That's the local-model gap - most open TTS gives you a speed dial, not a mood.

    speed (0.5–2.0), volume (0.5–2.0) and pitch (−12 to +12 semitones) are the knobs to reach for before rerolling a whole take. sample_rate is 8000 to 48000 with 24000 default - go higher if the audio will be processed or slowed down. output_format is mp3 or opus.

    generation_id handles the paid job: fixed ID with identical inputs resumes the recorded run; increment for a fresh generation. request_scope is auto-assigned per node, non-secret, only relevant headless.

    Outputs: audio (list, native AUDIO), files (originals), run id.

    Install

    ComfyUI 0.41.0+ and Python 3.10+.

    cd ComfyUI
    git clone --branch v0.1.0 --depth 1 https://github.com/protoface-ai/protoface-comfyui.git custom_nodes/protoface
    python -m pip install -r custom_nodes/protoface/requirements.txt
    

    Manager route works too: search Protoface, install protoface-nodes, restart, reload. Pip with ComfyUI's interpreter. Then click Protoface bottom-right and paste your key, or export PROTOFACE_API_KEY. Requirements are httpx, jsonschema, Pillow and PyAV - PyAV being the one that actually gets touched when decoding returned audio.

    Where it goes wrong

    The 1000-character clip. Split long narration yourself. And note the per-request minimum: five short chunks cost more than one full request.

    Wiring the output somewhere that wants a file. audio is a native ComfyUI AUDIO object; the sibling files output is where the actual downloaded file lives, and Protoface Save File writes originals to ComfyUI's output directory.

    Iterating by re-queueing. Same inputs plus a fixed generation_id resumes rather than re-bills - but changing the text is a new request by definition. Get the text settled before you start tuning delivery.

    Expecting a clone. This is a preset TTS model, not a voice-cloning one. If you need a specific person's voice, that's a different tool.

    Timeout ≠ failed job. Requeue unchanged or use run id in Resume Run; don't increment generation_id and pay twice for one render.

    Verdict

    The most boringly useful node in the pack. Feed it to a video node's audio input and you've got narration for a clip without leaving ComfyUI or installing a speech stack. Keep your lines under a thousand characters and use voice_instruction more than you think you should - it's the part that sounds like direction rather than a text box.

    CategoryProtoface/Speech/bytedance

    Inputs (11)

    NameTypeDefaultDescription
    textSTRINGThe text to synthesize into speech.
    languageCOMBOOptional language override. Leave unset for automatic language detection.
    output_formatCOMBOmp3Output audio format.
    pitchINT0-12–12Voice pitch shift in semitones. 0 is normal pitch.
    sample_rateCOMBO24000Sample rate of the output audio in Hz.
    speedFLOAT1.00.5–2Speech speed. 1.0 is normal speed.
    voiceCOMBOstokie_enVoice preset to use for speech synthesis.
    voice_instructionCOMBOOptional natural-language instruction for tone, emotion, pace, or volume. It is not spoken aloud.
    volumeFLOAT1.00.5–2Speech volume. 1.0 is normal volume.
    generation_idINT00–9007199254740991Keep fixed to reuse/resume this paid job. Increment for a fresh paid generation; independent of the model seed.
    request_scopeSTRINGAutomatically assigned per node. Headless clients must supply a stable unique workflow/node ID. This is not a secret.

    Outputs (3)

    NameTypeDescription
    audioAUDIO—
    filesPROTOFACE_FILE—
    run idSTRING—