Moving Titles
Burn an SRT onto your frames and get a lyric video
- image
- audio_signal
- mask_image
- IMAGE
Moving Titles is where this pack's fantasy actually pays off. Feed it a sequence of frames and an SRT subtitle file, and it renders the subtitles onto every frame - with fonts, effects, entrance animations, and optional audio-reactive movement - and hands back a new image batch you can encode into a video. It's the "lyric video" node, and it pairs perfectly with the pack's VibeMusicEngine, which writes exactly the SRT files this node wants.
The mechanism is straightforward and worth understanding before you wire it up: for each input frame it computes the frame's time as frame_index / fps, looks up which subtitles are active at that time in your SRT, and draws them onto the image with PIL. It animates your existing frames - it doesn't create new ones. So the frame count and your fps setting have to match the video you're actually making, or your subtitles will drift out of sync. Generate the base frames at your chosen fps, then run this on top.
The inputs that matter
image(IMAGE) - your frame sequence. One output frame per input frame.srt_path(STRING) - path to the subtitle file. This is path-driven, no picker.font_name- eight built-in fonts (Roboto, OpenSans, Lato, Montserrat, PlayfairDisplay, SourceCodePro, Oswald, RobotoMono) that auto-download on first use, orcustom_font_pathfor your own.ttf/.otf.font_size(default 32),max_lines(1–5),line_spacing- the v1.3.0 additions for multiline subtitles: lines appear, build up, and drop off according to SRT timing.fps(default 24) - the clock for the whole thing. Get this right.position_x/position_y(0–1, defaults 0.5/0.8) - where text sits.
The fun knobs: text_effect (none, shadow, outline, glow, gradient, neon, metallic), animation_type (fade, four slides, typewriter, bounce, wave, rotate, scale), and blend_mode (eleven modes from normal to color-dodge). audio_signal is the optional hook that drives the wave animation - feed it the same audio you used to make the SRT and the text reacts to the track. mask_image lets you confine where text can render. Color overrides (text_color_hex, shadow_color_hex, gradients) are all hex strings.
Output: IMAGE - a frame batch, same count as input.
Install
Pack install as usual:
cd ComfyUI/custom_nodes
git clone https://github.com/lazniak/videoclipgenerator
cd videoclipgenerator
pip install -r requirements.txt
Restart, find it under "video/text". It pulls in pysrt (for SRT parsing) and requests (for the font downloads) - both in the pack's requirements.
Gotchas
The font download is the thing that'll stall you: pick a font and the first run reaches out to download it, so a working internet connection matters once. And this is the node where the pack's buy_me_a_coffee checkbox is most likely to be left on by accident - it opens a browser tab on every run. Leave it off. The README's wilder claims (GPU shaders, temporal supersampling) are not in the code; what you get is solid PIL-based text compositing, which for subtitles is more than good enough.
Inputs (29)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| srt_path | STRING | Path to SRT subtitle file | |
| font_name | COMBO | 8 options: Roboto, OpenSans, Lato, Montserrat, PlayfairDisplay, SourceCodePro, +2 | |
| font_size | INT | 328–200 | Font size in pixels |
| max_lines | INT | 11–5 | Maximum number of lines to display at once. Lines will appear sequentially. |
| line_spacing | FLOAT | 1.20.5–3 | Spacing between lines (multiplier of font size) |
| fps | FLOAT | 24.01–120 | Frames per second |
| text_effect | COMBO | 7 options: NONE, SHADOW, OUTLINE, GLOW, GRADIENT, NEON, +1 | |
| animation_type | COMBO | 11 options: NONE, FADE, SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN, +5 | |
| blend_mode | COMBO | 11 options: NORMAL, ADD, MULTIPLY, SCREEN, OVERLAY, DIFFERENCE, +5 | |
| text_alignment | COMBO | 3 options: LEFT, CENTER, RIGHT | |
| position_x | FLOAT | 0.500–1 | Horizontal position (0-1) |
| position_y | FLOAT | 0.800–1 | Vertical position (0-1) |
| custom_font_pathopt | STRING | Path to custom .ttf or .otf font file. Leave empty to use built-in fonts. | |
| audio_signalopt | AUDIO | — | |
| audio_sensitivityopt | FLOAT | 1.00–5 | — |
| text_color_hexopt | STRING | #FFFFFF | Text color in HEX format |
| shadow_color_hexopt | STRING | #000000 | Shadow color in HEX format |
| gradient_start_hexopt | STRING | #FFFFFF | Gradient start color in HEX format |
| gradient_end_hexopt | STRING | #000000 | Gradient end color in HEX format |
| outline_widthopt | INT | 20–10 | Width of text outline |
| glow_radiusopt | INT | 100–50 | Radius of glow effect |
| glow_intensityopt | FLOAT | 0.500–1 | Intensity of glow effect |
| animation_speedopt | FLOAT | 1.00.1–5 | Speed of animation effects |
| wave_amplitudeopt | INT | 100–50 | Amplitude of wave animation |
| wave_frequencyopt | FLOAT | 1.00.1–5 | Frequency of wave animation |
| mask_imageopt | IMAGE | — | |
| buy_me_a_coffeeopt | BOOLEAN | false | Support development with a coffee! ☕ |
| usage_counteropt | STRING | Usage count: 0 | Tracks how many times this node has been used |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |