Four-Line Flip Subtitle (四行翻转字幕)
The four-line flip subtitle that's the pack's whole reason to exist
- image
- subtitle_data
- IMAGE
This is the one the pack is really about. The README calls it the core effect, and it's the hardest to describe: subtitles stack up four lines at a time, the newest line always the biggest, older lines shrinking and sliding up as new ones enter - and then when a group of four is complete, the entire accumulated old block flips over as one layer, with the next group starting to enter from behind it. It's the signature "四行翻转" look from CapCut-style edit-heavy videos, and nothing else in the pack does anything close to it.
It renders on CPU via Pillow, zero VRAM, compositing onto your IMAGE frames. It's also far and away the most parameter-heavy node in the pack - the author shipped a sub-folder README documenting the rules because there are so many.
How it works
Subtitles are grouped by group_size (default 4). New lines enter one by one with deterministic entry animations - the first line of the whole clip slides in from the left, group-boundary first lines hinge in, and the rest pick from a stable pool of motions like character-build, tracking-collapse, and fade-rise. Crucially, the same input always produces the same animation template: the entry style is derived from the text itself, so identical subtitles give identical motion.
The active (newest) line is scaled up to fit the horizontal safe area (font_layout_mode set to fit_active); older lines interpolate down through four font-size tiers and move up. When the group fills, the whole old layer flips as one - direction alternating (counter-clockwise, then clockwise) - and the next group's first line enters from behind it. The output timeline automatically extends until every group has been shown.
Highlighting is worth knowing: in auto mode the node scans each group and picks up to max_red_per_group words to color in highlight_color (red by default), skipping filler words like 今天/然后. Override with highlight_mode set to manual plus a highlight_words list, or inline marks [word] / *word* in your text. Set it to off for plain text.
The inputs that actually matter
With ~30 inputs, here's the short list a beginner sets:
text/srt_path/subtitle_data- one of these feeds the words. WireSUBTITLE_DATAfrom aSubtitleSourcefor the full pipeline.group_size(2–4, default 4) - how many lines accumulate before a flip. 4 is the signature look; 2 flips constantly.highlight_mode-auto/manual/off. Flip it toofffirst if the auto-red picks words you don't want.font_layout_mode-fit_active(active line fills the safe area, default) vsfixed(the olderbase_font_1..4tiers, no auto-fit).line_interval/group_hold/flip_duration/intro_duration- the rhythm: time between lines, how long a full group sits before flipping, flip speed, and line-entry speed. Defaults (0.68 / 1.05 / 0.44 / 0.26s) are a good starting beat.padding(84) - the horizontal safe-area margin the active line scales to fit. Shrink it to let long lines get bigger.background_mode-keep(composite over your footage) vsblack(black backdrop). Useful when testing the animation in isolation.
Everything else - the four base_font_* sizes, stroke_width, shadow_opacity/shadow_offset, trail_opacity, edge_visible_ratio, max_chars_per_line, center_y_ratio - is polish you tune after the first render. Output: a single IMAGE frame sequence.
Install
Same pack:
cd ComfyUI/custom_nodes
git clone https://github.com/liaowu-boos/ComfyUI-Subtitle-Effects.git
cd ComfyUI-Subtitle-Effects
pip install "Pillow>=9.0.0" "jieba>=0.42"
Or search liaowu-boos/ComfyUI-Subtitle-Effects in ComfyUI Manager, restart, and look under Subtitle Effects. No models to fetch; the seven bundled fonts cover Simplified Chinese and English, and anything you drop in fonts/ shows up in the dropdown after a restart.
Common issues
- The flip looks wrong on the first render. This node has the most motion parameters in the pack, and they interact -
group_holdtoo short,flip_durationtoo long, and the flip reads as a floaty tumble. Setbackground_modetoblackand dial rhythm parameters one at a time before compositing over real footage. - Auto-highlight colors words you don't want. The picker is opinionated about which words are "strong." Switch to
manualand passhighlight_words, oroff. - Your line is cut off. Long single lines hit the
max_chars_per_lineor safe-area limits. Setmax_chars_per_lineabove 0 to re-break long text, or increasepaddingand disablescale_font_to_width. - Memory on long clips. CPU rendering, ~95MB/sec of frames at 720p/30fps - render a minute-long video in segments or you'll hit roughly 5.5GB of frame tensors.
Honestly, the flip node is overkill for plain spoken-word captions - the cascade scroller handles those with a quarter of the knobs. Reach for this when you want the stacked-and-flipping look, because nothing else in the pack fakes it.
Inputs (34)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| font_name | COMBO | 7 options: Inter-Regular.otf, JetBrainsMono-Regular.ttf, LXGWWenKai-Regular.ttf, NotoSerifSC-Regular.otf, SmileySans-Oblique.ttf, SourceHanSansSC-Regular.otf, +1 | |
| fps | FLOAT | 30.001–120 | — |
| text_color | STRING | #F8F8F8 | — |
| highlight_color | STRING | #AA000C | — |
| stroke_color | STRING | #000000 | — |
| shadow_color | STRING | #606060 | — |
| highlight_mode | COMBO | auto | 3 options: auto, manual, off |
| highlight_words | STRING | — | |
| max_red_per_group | INT | 10–4 | — |
| group_size | INT | 42–4 | — |
| font_layout_mode | COMBO | fit_active | 2 options: fit_active, fixed |
| base_font_1 | INT | 6412–320 | — |
| base_font_2 | INT | 8212–340 | — |
| base_font_3 | INT | 10412–360 | — |
| base_font_4 | INT | 15612–420 | — |
| scale_font_to_width | COMBO | yes | 2 options: yes, no |
| padding | INT | 840–400 | — |
| line_gap | INT | 80–120 | — |
| center_y_ratio | FLOAT | 0.500.1–0.9 | — |
| intro_duration | FLOAT | 0.260.01–2 | — |
| flip_duration | FLOAT | 0.440.05–2 | — |
| line_interval | FLOAT | 0.680.05–5 | — |
| group_hold | FLOAT | 1.050.05–8 | — |
| stroke_width | INT | 10–12 | — |
| shadow_opacity | FLOAT | 0.000–1 | — |
| shadow_offset | INT | 20–30 | — |
| trail_opacity | FLOAT | 0.000–1 | — |
| edge_visible_ratio | FLOAT | 0.400–1 | — |
| max_chars_per_line | INT | 00–80 | — |
| background_mode | COMBO | keep | 2 options: keep, black |
| srt_path | STRING | — | |
| textopt | STRING | — | |
| subtitle_dataopt | SUBTITLE_DATA | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |