🎬 YC Subtitle (Optimized)
Burn Subtitles Straight Into Your Frame Batch
- images
- images
The annoying truth about AI video is that it comes out of ComfyUI as raw frames, and getting words onto those frames usually means exporting, opening a video editor, and doing the whole round trip again. 🎬 YC Subtitle (Optimized) is the node that skips that: give it your image batch plus a plain-text subtitle track, and it bakes the text into the frames - stroke, shadow, background box and all - before you ever hit the encoder. If you're making short-form content or explainer clips, this is the most useful thing in the whole SwiftCut pack.
The "(Optimized)" is the honest part of the name. The node pre-renders each unique subtitle string once into an RGBA overlay, caches it, then composites over the frame slices with vectorized tensor math instead of redrawing text per frame. Same line repeated across 30 frames gets drawn once. On long clips that's the difference between "fast" and "watch it crawl."
How to drive it
Two text fields do the work, both plain-delimiter separated:
subtitle_text- your lines in order, e.g.Opening line|Second line|Last lineframe_durations- how many frames each line lasts, e.g.30|15|60
So line 1 holds frames 0–29, line 2 holds 30–44, and so on. Output is images: the same batch with text composited in, ready for VHS_VideoCombine.
Then the styling inputs, which are self-explanatory and plentiful: font_size, text_color, stroke_width/stroke_color, background_color, horizontal_align (left/center/right), vertical_align (top/center/bottom), offset_x/offset_y for nudging, and a shadow section (shadow_enabled, shadow_distance, shadow_blur, shadow_expand, shadow_color). background_color takes an 8-digit hex where the last two digits are alpha - #00000000 (the default) is fully transparent, so no box; give it #00000080 and you get a semi-transparent caption band.
The font situation
The pack ships one font, a 11MB Chinese brush typeface (三极泼墨体.ttf), and the font dropdown only lists what's inside the pack's font/ folder. That default explains the Chinese demo text in the box. Want Latin type? Drop any .ttf or .otf into ComfyUI/custom_nodes/ComfyUI_SwiftCut/font/ and restart - it'll show up in the dropdown. If the folder's empty it falls back to PIL's built-in font, which is fine for a placeholder and ugly for anything you'll actually ship.
Quirks worth knowing
The default demo values are a trap if you take them literally: subtitle_text defaults to 第一段字幕(30帧)||第二段字幕(60帧) with the delimiter set to | - so splitting on | yields two visible lines and one empty segment in the middle. That's why frame_durations ships as 30|15|60: three durations, two actual lines, the empty segment just consumes its slot and renders nothing. It's harmless, but it confused me for a solid minute.
Also note the segment mapping is purely frame-based - no easing, no fade-in/out per subtitle, no per-line styling. Text appears and disappears on the frame boundaries. Fine for captions, wrong for a title sequence.
Installing it
Standard pack install - ComfyUI Manager (search "ComfyUI_SwiftCut") or:
cd ComfyUI/custom_nodes
git clone https://github.com/yichengup/ComfyUI_SwiftCut
Restart, and it's under YC_VideoCutHelper → Subtitle. Dependencies are just torch/Pillow/numpy, zero models. Nobody on reddit is talking about this pack (I checked), so you're not going to find a tutorial for it - but this node is simple enough that the two text fields above are the whole tutorial.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| subtitle_text | STRING | 第一段字幕(30帧)||第二段字幕(60帧) | — |
| frame_durations | STRING | 30|15|60 | — |
| delimiter | STRING | | | — |
| font | COMBO | 三极泼墨体.ttf | 1 options: 三极泼墨体.ttf |
| font_size | INT | 488–500 | — |
| text_color | STRING | #FFFFFF | — |
| stroke_width | INT | 00–20 | — |
| stroke_color | STRING | #000000 | — |
| background_color | STRING | #00000000 | — |
| horizontal_align | COMBO | center | 3 options: left, center, right |
| vertical_align | COMBO | bottom | 3 options: top, center, bottom |
| offset_x | INT | 0-16384–16384 | — |
| offset_y | INT | -50-16384–16384 | — |
| shadow_enabled | COMBO | enabled | 2 options: disabled, enabled |
| shadow_distance | INT | 20–50 | — |
| shadow_blur | INT | 30–50 | — |
| shadow_expand | INT | 00–30 | — |
| shadow_color | STRING | #000000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |