arkennemasis fal · ElevenLabs TTS Turbo v2.5 · $0.05/1k chars
The bulk-rate voiceover node
- audio
- audio_path
- timestamps
- info
Five cents per thousand characters. In a pack where the music nodes charge sixty cents a minute and Seedance charges a dollar-plus a second of video, this is the node you point at volume work: thirty scenes of narration, a week of social clips, a batch of product videos where every listing gets a spoken description.
It's the same widget set as the Multilingual v2 node - all eleven of them, including the previous_text/next_text continuity pair - at half the price, on a model built for speed rather than for the last increment of naturalness. The tradeoff is exactly what the name says.
How it works
A generated fal node: FAL_KEY from the install's .env, input checks, a cost estimate from the character count, one billed call, polling with live status, and output into output/fal/fal-ai_elevenlabs_tts_turbo-v2.5/. Every request is appended to output/fal/_requests.jsonl, which is the honest way to find out what a hundred-scene batch cost - read the ledger rather than adding up node badges.
The inputs that matter
text is required; voice is a plain string defaulting to Rachel. Then the dials, in the order you'll actually touch them:
stability- 0.5 by default. Higher for batch consistency, lower for performance.similarity_boost- 0.75 by default, pulling the output toward the reference voice at a small cost in naturalness.styleandspeed- style exaggeration (default 0 - leave it there unless you mean it) and 0.7–1.2 speed, with the tooltip's warning that extremes hurt quality. Speeding up a read to fit a runtime is the classic misuse; cut the script instead.previous_text/next_text- pass the neighbouring sentences in and the delivery stops resetting at every chunk boundary. The single biggest quality win available on this node, and it costs nothing.language_code(ISO 639-1, enforced - an unsupported code errors rather than falling back),apply_text_normalization(auto/on/offfor numbers and dates), andtimestampsfor word-level timing you can drive captions with.
Outputs: audio, audio_path, timestamps, info. In a fan-out workflow - the pack's Shot Selector and Scene List nodes are built for exactly this - audio_path is what you pass along so a later stage can read the file without re-rendering.
Money
$0.05 per 1,000 characters. Ten thousand characters of narration is fifty cents. That's low enough that batching becomes practical: at the default max_concurrent of 1 the fal nodes run one paid call at a time across the whole run, which keeps you inside rate limits but serialises a big job. Raise it to 4 or 8 on the TTS nodes of a narration-heavy graph and a fifty-scene render stops being an afternoon.
Install
Manager → search comfyui-arkennemasis, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
Restart, then FAL_KEY=your-key-from-fal.ai/dashboard/keys in the .env in the folder holding run_nvidia_gpu.bat (or the ComfyUI folder - those are the only two places it looks, and there's no key box on the node, deliberately).
Common issues & troubleshooting
It sounds flatter than the Eleven v4 nodes. It is. Turbo trades a little naturalness for speed and price; when the job is 200 short lines, that's the right trade, and when it's one hero narration, it isn't.
Every chunk sounds like a new speaker. previous_text and next_text are empty. Wire them and the seams disappear.
Numbers read as individual digits. apply_text_normalization - force it on.
Identical audio returned instantly with no charge. reuse_identical_run is on by default. For batch work that's a feature - a re-run of an unchanged branch costs nothing - and for auditioning it's the thing you have to remember to switch off.
A 429 or a stream that dropped mid-run. The pack retries rate limits, 5xx errors and interrupted streams with exponential backoff, so a blip usually resolves itself without a re-run. If it doesn't, the failure is logged with the request id, and fal's own answer is in info.
Cheaper still, locally. If the text is not sensitive and your voice isn't specific, Kokoro runs in real time on a CPU and Chatterbox runs well under 8 GB of VRAM - free after electricity. The honest case for this node is a pipeline that must not fail mid-batch, and a voice you don't have locally.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | The text to convert to speech | |
| voice | STRING | Rachel | The voice to use for speech generation Empty leaves it out. |
| stability | FLOAT | 0.500–1 | Voice stability (0-1) |
| similarity_boost | FLOAT | 0.750–1 | Similarity boost (0-1) |
| style | FLOAT | 0.000–1 | Style exaggeration (0-1) |
| speed | FLOAT | 1.000.7–1.2 | Speech speed (0.7-1.2). Values below 1.0 slow down the speech, above 1.0 speed it up. Extreme values may affect quality. |
| timestamps | BOOLEAN | false | Whether to return timestamps for each word in the generated speech |
| previous_text | STRING | The text that came before the text of the current request. Can be used to improve the speech's continuity when concatenating together multiple generations or to influence the speech's continuity in the current generation. Empty leaves it out. | |
| next_text | STRING | The text that comes after the text of the current request. Can be used to improve the speech's continuity when concatenating together multiple generations or to influence the speech's continuity in the current generation. Empty leaves it out. | |
| language_code | STRING | Language code (ISO 639-1) used to enforce a language for the model. An error will be returned if language code is not supported by the model. Empty leaves it out. | |
| apply_text_normalization | COMBO | auto | This parameter controls text normalization with three modes: 'auto', 'on', and 'off'. When set to 'auto', the system will automatically decide whether to apply text normalization (e.g., spelling out numbers). With 'on', text normalization will always be applied, while with 'off', it will be skipped. |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| audio_path | STRING | — |
| timestamps | STRING | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |