Lyrics Scroll Effect
Scrolling lyric videos out of a single ComfyUI node — feed it an MP3 or an SRT
- audio
- video_path
- subtitles
If your workflow needs a karaoke-style lyrics video - active line enlarged in the middle, upcoming lines fading below it, everything sliding with a smooth ease-out - this node does the whole job in one box. You don't render text frames and then fight your way through a video editor; you drop in a track (or paste an SRT) and out comes a finished .mov with a transparent background, ready to overlay on a music video in Resolve or Premiere. It's a niche node from a small pack with basically zero community footprint, so think of it as "does the thing, with rough edges," not a polished commercial plugin.
How it works
The node is really two tools behind one UI. First it figures out what to say and when: if you connect the lyrics input with SRT-format text (cue number, timestamp, line), it uses that verbatim - that's the reliable path. If lyrics is empty but you connect audio, it falls back to running OpenAI Whisper on the track. Note it loads the base Whisper model, which downloads roughly 145 MB to your cache on the first run, and the whisper_prompt dropdown (简体中文 / 繁体中文 / English / 日本語 / 한국어) steers the transcription's language style. There's also a reference_text input: if Whisper's timestamps are right but its words are garbled, paste your real lyrics there and it realigns them to the timeline instead of the transcription.
Once the subtitles exist, it renders each frame as an RGBA PNG - transparent background, slot-based scrolling, the active line scaled up and highlighted, a small triangle marker pointing at it - and hands the frame sequence to FFmpeg to encode a ProRes 4444 .mov (yuva444p10le, the alpha-carrying pixel format) into ComfyUI's outputs directory. That's worth knowing: this node is self-contained, encoding the video itself and returning two strings, video_path (where the movie landed) and subtitles (the final SRT text, handy to save for later).
The inputs that matter
audio/lyrics- the source. SRT wins if both are present; audio alone triggers Whisper.y_pos- the vertical position of the active line; 640 on a 720×1280 canvas puts it mid-frame. Tune this to where you want the "reading line."font_size/active_font_size- inactive vs. highlighted line. The 30/40 defaults give a classic karaoke contrast.max_chars_per_line- controls wrapping, so long lines don't run off the margins.batch_size- a memory knob, not a visual one. Default 250; the author's notes suggest 50–100 on an 8 GB system, more if you're rendering a ten-minute track.font_filename- populated from whatever.ttf/.otffiles you drop inComfyUI/models/fonts/.
Installing it
ComfyUI Manager: search for Comfyui-Lyrics and install. Manually:
cd ComfyUI/custom_nodes/
git clone https://github.com/ahkimkoo/Comfyui-Lyrics.git
cd Comfyui-Lyrics
pip install -r requirements.txt
That pulls openai-whisper, Pillow, torchaudio, numpy, torch. The real hidden dependency is FFmpeg on your PATH - the code prefers a bin/ffmpeg sitting next to the pack (the author bundled one for testing), but for everyone else the system FFmpeg is what gets called. Make sure ffmpeg -version works.
Where people get burned
The classic failures are all grounded in the README and code. Chinese (or any CJK) text renders as boxes - that's a missing font, not a bug; drop something like msyh.ttf into ComfyUI/models/fonts/ or you'll get glyph rectangles. FFmpeg errors mid-render (CalledProcessError) usually mean FFmpeg isn't installed or is too old for ProRes alpha. Whisper mangles your lyrics - honestly expected with the base model on accented singing; either set whisper_prompt to the right language or skip transcription entirely and paste the SRT. And don't panic when QuickTime Player or VLC show the output as a solid black rectangle: they don't render alpha. Check it in Resolve/Premiere, or verify with ffprobe that the pixel format is yuva444p10le / yuva444p12le. Long audio hammers memory, so if a render dies mid-way, drop batch_size before anything else.
Inputs (24)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 72064–4096 | — |
| height | INT | 128064–4096 | — |
| margin_left | INT | 500–4096 | — |
| margin_right | INT | 500–4096 | — |
| y_pos | INT | 6400–4096 | — |
| font_size | INT | 3010–200 | — |
| active_font_size | INT | 4010–200 | — |
| letter_spacing | INT | 0-10–200 | — |
| line_gap | INT | 200–1000 | — |
| text_color | STRING | #FFFFFF | — |
| stroke_width | INT | 10–20 | — |
| stroke_color | STRING | #000000 | — |
| shadow_color | STRING | #000000 | — |
| shadow_offset_x | INT | 2-100–100 | — |
| shadow_offset_y | INT | 2-100–100 | — |
| shadow_alpha | FLOAT | 0.80–1 | — |
| font_filename | COMBO | 1 options: Arial.ttf | |
| frame_rate | FLOAT | 25.001–120 | — |
| max_chars_per_line | INT | 205–100 | — |
| batch_size | INT | 25010–2000 | — |
| whisper_prompt | COMBO | 5 options: 简体中文, 繁体中文, English, 日本語, 한국어 | |
| audioopt | AUDIO | — | |
| lyricsopt | STRING | 1 00:00:00,000 --> 00:00:05,000 第一行字幕 2 00:00:05,000 --> 00:00:10,000 第二行字幕 | — |
| reference_textopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | — |
| subtitles | STRING | — |