Nodes/Confucius4-R2T2 Q8 ASR/Confucius4 Save Subtitle
ComfyUI Node

Confucius4 Save Subtitle

A real .srt, with timings you should still check

By T8mars·Created 21 days ago·Updated 9 days ago· 15
Confucius4 Save Subtitle
    • saved_path
    • subtitle_text
    • subtitle_json
    • cue_count
    ◄result_json—►
    ◄format▾►
    ◄prefixr2t2_subtitle►
    ◄offset_ms0►
    ◄chinese_chars16►
    ◄english_chars42►
    ◄allow_partialfalse►
    ◄whole_audio_draftfalse►

    From transcript to a file an editor will accept

    Transcription gives you text. Video work wants a subtitle file - cue numbers, timestamps, line breaks, the exact flavor VLC, Premiere, DaVinci and ffmpeg all agree on. Confucius4 Save Subtitle is the terminal node that bridges those two: feed it the result_json that Confucius4 Transcribe (or the Live microphone node) hands out, pick srt or vtt, and it writes the file into ComfyUI/output while previewing it inside the node.

    It earns its place next to Transcribe's own convenience srt output, which is deliberately dumb - it returns nothing rather than a half-broken file - whereas this node validates and tells you what it didn't like.

    How the cues get made

    The node parses result_json, walks the VAD/ASR segments, and turns each segment into one cue. That's the part to internalize, because the source comment above the builder says it plainly: segment timings are estimates, and the code refuses to subdivide a sentence's text across spans it invented. A long sentence that came through as one segment stays one cue - the node wraps it and flags it as too long instead of fabricating per-line timestamps.

    Wrapping is display-only and respects CJK width: chinese_chars (default 16) sets the budget for wide characters - effectively 32 columns - and english_chars (default 42) for Latin text. Words stay intact, CJK wraps between characters, and trailing punctuation like 。 hangs past the limit rather than stranding a line.

    The formats differ in more than the extension. SRT uses comma decimals (00:00:01,250); VTT uses dots, a WEBVTT header, and escaped text. So if your transcript contains angle brackets, use VTT - some players read <...> in an SRT as formatting tags.

    Inputs that matter, and the output you wire

    result_json is force-input, so you wire it from Transcribe (or a finished Live session - click Stop and finalize first). format is srt or vtt. prefix defaults to r2t2_subtitle and gets sanitized to [A-Za-z0-9_-], cut at 64 characters - use ASCII, a Chinese prefix won't survive.

    Then the optional ones worth knowing:

    • offset_ms - shifts every cue once. Negative shifts clip cues at zero or drop them, with a warning. This is your fix when a video's audio track is delayed or you cut from a longer recording.
    • chinese_chars / english_chars - line width, not timing. Lower them if your player chops off the second line.
    • allow_partial - the transcript was truncated and you want the file anyway; off by default.
    • whole_audio_draft - fallback for a transcript with no segments at all: one whole-audio cue, approximate timing. Only if segment collection was never on.

    cue_count (INT) and saved_path (STRING) tell you whether it worked before you go hunting in the output folder - saved_path is empty when no file was written. subtitle_text is the file's contents; subtitle_json is the cue document with per-cue timestamps and warnings. The node also previews and offers a download link.

    It almost always says "requires_review", and that's fine

    The node reports a subtitle_status - complete, partial, requires_review or empty - plus a warnings list in the preview. Unless your timings came from real forced alignment, every cue is tagged approximate_segment_timing, so a normal run reports requires_review. It's the author telling you the truth: the cues are VAD-derived estimates that want a human pass. If you need genuine word-level sync - karaoke, lyrics, tight cuts - that's a different toolchain (WhisperX-style forced alignment is what people reach for).

    Install

    Same pack, Windows + NVIDIA only.

    cd ComfyUI/custom_nodes
    git clone https://github.com/T8mars/comfyui-confucius-r2t2-t8
    cd comfyui-confucius-r2t2-t8
    .\scripts\setup_worker_windows.ps1
    

    Prerequisites: Python 3.12, Git, CMake, VS 2022 C++ build tools, CUDA Toolkit 12.8. The first run pulls and verifies about 2.19 GB of Q8 weights plus the audio projector, then compiles the llama.cpp CUDA backend - give it real time. Default target is RTX 50-series (arch 120); on an older card run setup_worker_windows.ps1 -SkipNativeBuild, then build_native_windows.ps1 -CudaArch 86. Restart ComfyUI afterward. Manager install works via publisher t8star once its registry review clears. Inference runs in its own Python 3.12 worker instead of pip-installing into your ComfyUI environment.

    Already have a transcript JSON with segments? Skip ComfyUI and use the same builder:

    python scripts/json_to_subtitle.py transcript.json --format srt --offset-ms 0
    

    Where it goes wrong

    You forgot subtitle_timings on Transcribe. Then result_json carries no segment text and the node stops with "Segment text is missing. Re-run transcription with subtitle_timings enabled." The transcript is fine; the timings just weren't collected. Same idea if you get "Only completed or finalized transcripts can become subtitles" - that's a cancelled run or a Live session you never finalized.

    Where is my file? Outputs are named <prefix>_<hash-of-content>.<ext> in ComfyUI/output. Same content reuses the same name; a new offset or an edit makes a new file, and existing files are never overwritten. Five runs with five offsets means five files - by design.

    saved_path is empty. No cues were produced, so nothing was written - usually honest silence, or an offset_ms negative enough to drop every cue. Check cue_count first; if it's a partial file you want, turn on allow_partial and re-run.

    One last note: this node invalidates itself every run, so it notices output files you moved or deleted and regenerates them - while Transcribe stays cached and doesn't touch the model again.

    CategoryConfucius4-R2T2

    Inputs (8)

    NameTypeDefaultDescription
    result_jsonSTRING—
    formatCOMBO2 options: srt, vtt
    prefixSTRINGr2t2_subtitle—
    offset_msoptINT0-86400000–86400000Shift all cues once. Negative times are clipped or dropped with a warning.
    chinese_charsoptINT164–80—
    english_charsoptINT428–160—
    allow_partialoptBOOLEANfalse—
    whole_audio_draftoptBOOLEANfalseExplicit fallback for a single-pass transcript without segments. One whole-audio cue; approximate timing.

    Outputs (4)

    NameTypeDescription
    saved_pathSTRING—
    subtitle_textSTRING—
    subtitle_jsonSTRING—
    cue_countINT—