TS Whisper
Local transcription with SRT out — no API key, no cloud
- audio
- srt_content
- text_content
- ttml_content
The name is a lie in the best way: it doesn't call any API and needs no key. TS Whisper is speech-to-text on the native OpenAI Whisper engine, running entirely on your machine, and it hands you subtitles in three formats at once. Wire in an AUDIO clip - from a loader, from the pack's audio loader, from anywhere - and out come SRT, plain text, and TTML. Transcribe a voiceover, generate subtitles for a video you just saved, or pull the text out of a podcast before feeding it to an LLM node. It's the kind of node you reach for constantly once it's in your graph.
How it works
Under the hood is a shared engine (nodes/_whisper_engine.py) that this node and TS Super Prompt's voice input both use - same weights, same on-disk folder (models/whisper/), and an in-memory model cache so loading large-v3 here and again for Super Prompt voice reuses the same model object instead of holding two copies in memory. That shared-engine detail is why bug fixes land in both nodes at once.
The two model choices are simple: large-v3 (default) for best quality, or turbo (the distilled large-v3-turbo) for speed. Weights download on first use into models/whisper/.
The inputs that matter
audio- a ComfyUIAUDIOinput (waveform + sample rate).model- large-v3 or turbo.task-transcribe(recognize in the source language) ortranslate_to_english. One gotcha: turbo cannot translate and falls back to transcription, so if you need English out of Russian audio, use large-v3.source_language-autofor detection, or set it (rufor Russian) - setting it speeds things up and avoids misdetection.timestamps-segment(per-segment timecodes),word, ornone. Withnone, the SRT/TTML outputs come back empty; the plain text always works.precision- fp16 on GPU, fp32 for stability. CPU always uses fp32. And on a Mac this node always runs on CPU - openai-whisper doesn't run reliably on Metal, so the option is just not offered rather than offered and broken.initial_prompt- a genuinely useful field: it biases vocabulary, names and style. Feed it a list of proper nouns from your domain and watch the spelling stop mangling them.save_srt_file/output_filename_prefix- whether to also write SRT/TTML files tooutput/subtitles, and under what name.
The deeper decoding controls - beam_size (1 is greedy, higher is more accurate but slower), temperature and the temperature_fallbacks ladder, condition_on_previous_text, and the three hallucination thresholds (compression_ratio_threshold, logprob_threshold, no_speech_threshold) - are Whisper's standard dials, exposed with sensible defaults. Leave them alone until you hit a problem; the threshold trio is what you tune when the model starts inventing words on silence.
The outputs are srt_content, text_content, and ttml_content - all STRING, all wireable straight into save nodes, note nodes, or an LLM.
Installing it
Part of comfyui-timesaver: ComfyUI Manager → search Timesaver, or
cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt
then restart ComfyUI. openai-whisper is in the base requirements, so a plain install covers it. No system ffmpeg needed - the pack ships imageio-ffmpeg's static binary, and the node asks for that binary before ever looking at your PATH.
Gotchas
If transcription fails with an ffmpeg-ish error, it's the dependency, not you: python -m pip install --upgrade imageio-ffmpeg (with the same Python ComfyUI runs from). If you're getting hallucinations on silence, that's the thresholds - raise no_speech_threshold a bit, and feed an initial_prompt for domain names. And if you're on a Mac, don't chase GPU speed here; the node deliberately runs on CPU because Metal is unreliable with this engine, and it says so instead of pretending otherwise.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | ComfyUI audio input (waveform + sample_rate). | |
| model | COMBO | large-v3 | Whisper model: large-v3 (best quality) or turbo (faster). Weights and cache are shared with TS Super Prompt. |
| task | COMBO | transcribe | transcribe = recognize in the source language; translate_to_english = translate to English (turbo cannot translate and falls back to transcription). |
| source_language | COMBO | ru | Language of the input audio. auto = auto-detect. Use ru for Russian. |
| timestamps | COMBO | segment | segment = per-segment timecodes; word = per-word; none = no timecodes (SRT/TTML disabled). |
| precision | COMBO | fp16 | fp16 is faster on GPU; fp32 is more stable. CPU always uses fp32. |
| beam_size | INT | 51–10 | Beam search width (used when temperature=0). 1 = greedy. Higher = more accurate but slower. |
| temperature | FLOAT | 0.00–1 | Decoding temperature. 0 = deterministic. |
| temperature_fallbacks | STRING | 0.0,0.2,0.4,0.6,0.8,1.0 | Comma-separated temperature ladder (e.g. 0.0,0.2,0.4,0.6,0.8,1.0). Overrides temperature. |
| condition_on_previous_text | BOOLEAN | true | Feed context from previous segments (more coherent, but can amplify drift). |
| compression_ratio_threshold | FLOAT | 2.40–10 | zlib compression threshold for the hallucination detector (whisper default 2.4). |
| logprob_threshold | FLOAT | -1.0-10–0 | Average log-probability threshold (whisper default -1.0). |
| no_speech_threshold | FLOAT | 0.600–1 | No-speech probability threshold (whisper default 0.6). |
| initial_prompt | STRING | Initial prompt to bias vocabulary, names, and style. | |
| save_srt_file | BOOLEAN | true | Save SRT/TTML files to the output/subtitles folder. |
| output_filename_prefix | STRING | transcribed_audio | Filename prefix for SRT/TTML. |
| output_diropt | STRING | /tmp/ComfyUI/output | Output folder for SRT/TTML. Empty = default output directory. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| srt_content | STRING | Subtitles in SRT format (empty when timestamps=none). |
| text_content | STRING | Full transcription as plain text. |
| ttml_content | STRING | Subtitles in TTML format (empty when timestamps=none). |