zhenzhen-Doubao Voice Clone / ICL 2.0(平价小屋)
Clone a Voice, Then Make It Say Anything
- reference_audio
- api_config
- audio
- audio_url
- audio_path
- speaker
- task_id
- response
Voice cloning stopped being a novelty a while ago - Chatterbox and friends will clone you from five seconds of audio, locally and for free. The reason to reach for this node instead is the boring one: you want the words right, in the right language, on the first take, and you don't want to babysit a 0.5B model's install to get it.
This is the relay path to ByteDance's clone-and-synthesize stack - Doubao being their consumer model brand, and the two IDs in the model dropdown being the two halves of the job. Seed TTS 2.0's standard and expressive voices are what you're actually speaking with (seed-tts-2.0-standard, seed-tts-2.0-expressive).
It's two nodes wearing one trenchcoat
The model widget isn't a quality setting. It changes what the node does:
doubao-voice-clone- trains. You give it a recording, it registers a voice with the provider, and the ID of that voice comes back on thespeakeroutput.doubao-seed-icl-2.0- speaks. You give it aspeakerand a script, it gives you audio.
So the workflow is: run the clone pass once, keep the speaker string, switch model to synthesis, and wire the speaker output back into this node's own speaker input. That round trip is the whole trick, and it's why the field exists on both passes.
For the clone pass you need exactly one sample source: reference_audio (a local AUDIO, encoded to WAV, capped at 10 MB) or audio_url (a public URL, same cap). PCM needs to be 24 kHz mono or it gets rejected. Your prompt is the preview text - 4 to 300 characters - and reference_text is the transcript of the recording you supplied, up to 2000 characters. Feeding it the actual transcript is what makes the clone land; feed it a lazy guess and the prosody drifts.
On the synthesis pass, prompt becomes your script: 1 to 10,000 characters. speaker is required, and the tooltip is blunt about the constraint - it has to come from the same account. Someone else's voice ID won't resolve.
The dropdowns that mean "don't send this"
The node has more than twenty controls, and well over a dozen of them default to the same value: api_default. That's not a setting, it's an omit - the key is dropped from the request entirely and the provider keeps its own default. Choosing enabled or disabled sends a real boolean. Once you internalize that, the wall of enable_subtitle / disable_emoji_filter / tone_fidelity widgets stops looking like noise and starts looking like a compliance-and-quality panel you only open on purpose.
The handful you'll actually set: voice_model (standard vs expressive - expressive is the one for character work), output_format (mp3, wav, pcm, ogg_opus), sample_rate, explicit_language (zh-cn, en, ja, ko, de, fr, th and friends - this is the multilingual lever that local TTS still loses on), and the three prosody dials: speech_rate and loudness_rate from −50 to 100, pitch from −12 to 12. advanced_mode opens the rest.
There's a chain of quiet validation worth knowing before you fight an error: custom_speaker_id must be 8–256 characters starting with an English letter (blank lets the API assign one), training_speaker_id is a provider-side training ID and is a completely different field, bit_rate is either 0 (omit) or 16000–160000, context_texts only applies when voice_model is api_default and caps at 500 characters, and latex_parser=v2 refuses to run unless Markdown filtering is on.
Outputs
audio comes out as a real ComfyUI AUDIO, alongside audio_url, audio_path (a local file you can keep), speaker, task_id and a full response. The first three are lists, because a synthesis call can return more than one item - which is lovely until the next node in your chain doesn't accept lists.
Install
Manager → search zhenzhen, or:
cd ComfyUI/custom_nodes
git clone https://github.com/T8mars/Comfyui-zhenzhen
# restart ComfyUI, then wire a zhenzhen-seedance2-low-price-api-settings node into api_config
Heavy for a node that compiles nothing: requirements.txt includes transformers, aiohttp, opencv-python, matrix-client. Decoding MP3 is the one genuinely fragile part - the README notes the offline package ships FFmpeg specifically to handle it, so on a bare install a codec error is an environment problem, not a bad key.
Where people get burned
Pasting the whole script into the clone pass and being told the prompt is too long - that field is a 4–300 character preview, not your text. Forgetting to flip model before the second run, then wondering why the node wants a sample again. And sharing a speaker ID between accounts, which will simply not resolve.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | doubao-voice-clone | 2 options: doubao-voice-clone, doubao-seed-icl-2.0 |
| prompt | STRING | Clone preview: 4-300; synthesis: 1-10000 characters. | |
| speaker | STRING | Connect the training speaker output; same account required. | |
| audio_url | STRING | Public voice sample URL, <=10 MB; OR local AUDIO. PCM requires 24 kHz mono. | |
| custom_speaker_id | STRING | Optional 8-256 characters, English initial. Blank lets the API assign an ID. | |
| language | COMBO | api_default | Match the sample language: 0 Chinese, 1 English; api_default omits this code. |
| reference_text | STRING | Matching recording transcript, at most 2000 characters. | |
| enable_audio_denoise | COMBO | api_default | 3 options: api_default, enabled, disabled |
| disable_volume_normalization | COMBO | api_default | 3 options: api_default, enabled, disabled |
| voice_model | COMBO | seed-tts-2.0-standard | 3 options: api_default, seed-tts-2.0-standard, seed-tts-2.0-expressive |
| output_format | COMBO | mp3 | 4 options: mp3, wav, pcm, ogg_opus |
| sample_rate | COMBO | 24000 | 7 options: 8000, 16000, 22050, 24000, 32000, 44100, +1 |
| speech_rate | FLOAT | 0-50–100 | — |
| loudness_rate | FLOAT | 0-50–100 | — |
| pitch | FLOAT | 0-12–12 | — |
| explicit_language | COMBO | api_default | 17 options: api_default, zh-cn, en, ja, es-mx, id, +11 |
| context_texts | STRING | At most 500 characters; only with voice_model=api_default. | |
| advanced_mode | BOOLEAN | false | — |
| training_speaker_id | STRING | Provider training ID, separate from custom_speaker_id. | |
| bit_rate | INT | 00–160000 | 0 omits; explicit range 16000-160000. |
| max_length_to_filter_parenthesis | COMBO | api_default | 3 options: api_default, 0, 100 |
| silence_duration | INT | 00–30000 | — |
| enable_subtitle | COMBO | api_default | 3 options: api_default, enabled, disabled |
| disable_markdown_filter | COMBO | api_default | 3 options: api_default, enabled, disabled |
| disable_emoji_filter | COMBO | api_default | 3 options: api_default, enabled, disabled |
| enable_latex_tn | COMBO | api_default | 3 options: api_default, enabled, disabled |
| aigc_watermark | COMBO | api_default | 3 options: api_default, enabled, disabled |
| disable_default_bit_rate | COMBO | api_default | 3 options: api_default, enabled, disabled |
| tone_fidelity | COMBO | api_default | 3 options: api_default, enabled, disabled |
| aigc_metadata_enable | COMBO | api_default | 3 options: api_default, enabled, disabled |
| latex_parser | COMBO | api_default | 2 options: api_default, v2 |
| section_id | STRING | — | |
| aigc_metadata_content_producer | STRING | — | |
| aigc_metadata_produce_id | STRING | — | |
| aigc_metadata_content_propagator | STRING | — | |
| aigc_metadata_propagate_id | STRING | — | |
| reference_audioopt | AUDIO | Exactly one recording; encoded WAV <=10 MB. | |
| api_configopt | ZHENZHEN_SEEDANCE2_CONFIG | — | |
| skip_erroropt | BOOLEAN | false | — |
| seedopt | INT | 00–18446744073709550000 | Execution seed for ComfyUI cache control. Fixed reuses the cached result; randomize/increment/decrement requests a new run. This compatibility seed is not sent to APIs that do not expose a native seed parameter. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| audio_url | STRING | — |
| audio_path | STRING | — |
| speaker | STRING | — |
| task_id | STRING | — |
| response | STRING | — |