πͺ Lyric Sync β Word Mosaic
Turn your music video into a living word grid β and keep the singer visible underneath
- images
- timing
- palette_in
- images
If LyricSyncOverlay is the tasteful karaoke captions, LyricSyncMosaic (display "πͺ Lyric Sync - Word Mosaic") is the show-off sibling. It rebuilds your entire video frame as a scrolling grid of colored letter cells - think a giant text marquee - and then does the clever part: it detects the subject in each frame and keeps the current lyric's words glowing on top while the singer stays recognizable through the grid. It's the "lyrics as art direction" node, not the "lyrics as subtitles" node, and it's genuinely striking when it works.
How it works
Every frame is converted into a grid of cols letter cells (default 56 across - higher is finer and denser). The grid scrolls (scroll_dir and scroll_speed, default: drifting down at 0.12 cells per frame), and a fraction of cells light up with palette colors (color_density, flicker_period) to give it that animated LED-marquee shimmer. Meanwhile the lyrics are read from the same LYRIC_TIMING that drives the Overlay node - supplied by the pack's Lyric Sync - Align node - and the current line's words are drawn as highlighted word boxes whose size you control with wordbox_scale and density with wordbox_density.
The genuinely clever input is bg_key. The song's video frames usually have the singer or subject against some backdrop; bg_key keys out the background so the grid can sit under the subject, with bg_tol (0 = auto) controlling how much of the frame counts as background. Tonal controls - threshold_bias, invert_subject, posterize, subject_gamma - then shape how the subject reads through the text. It's a lightweight background-removal path tuned for the "person on a plain backdrop" case, and it's honest about its limits: best on plain backgrounds, as the tooltip says.
The inputs that matter
Beyond images + timing (LYRIC_TIMING from Align), the ones beginners actually set:
frame_rate- must match your video's fps, or word boxes drift off the vocals.cols- the density personality switch. Low (20β30) = chunky, readable marquee; 56 default is fine; higher gets fine-grained and busy.palette- comma-separated hex colors for the lit cells. The optional π¨ Lyric Sync - Palette input overrides this text field and is the cleaner way to tune colors without editing a comma string.bg_key/bg_tol- turn keying on and set tolerance; this is what makes the subject visible instead of a wall of letters.
scroll_speed, color_density, and wordbox_density control the liveliness - think of the defaults as "calm and legible" and raise them for energy.
Wiring it
LyricSyncAlign β LyricSyncMosaic β Save Video. Align needs your audio and pasted lyrics to produce the timing; Mosaic consumes it plus your frame batch and outputs images. Like the Overlay node, it returns frames only - connect audio separately to the encoder.
Install
Part of the unified MSCH Nodes pack (search "MSCH Nodes" in ComfyUI Manager, or msch-comfyui-nodes):
cd ComfyUI/custom_nodes
git clone https://github.com/mariobilly/msch-comfyui-nodes.git
cd msch-comfyui-nodes
python -m pip install -r requirements.txt
Restart ComfyUI afterward. No models download at startup. Note font_path defaults to a Windows font (tahoma.ttf); on Linux/macOS set it to a local .ttf or rendering fails.
Gotchas
This node has the longest control surface of the two lyric renderers, and the failure modes track the knobs. The subject disappears β your bg_key/bg_tol are off and the grid paints over the singer; dial bg_tol down toward keeping more of the frame as subject. Words drift β frame_rate mismatch, same as Overlay. And if the whole thing looks like static, your source video's background is probably too busy for keying to find the subject - the tooltip is not kidding that this is "best for plain backgrounds." Start there, get the singer reading through the grid, and only then start raising density and scroll speed.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | β | |
| timing | LYRIC_TIMING | β | |
| frame_rate | FLOAT | 25.0001β240 | β |
| cols | INT | 5610β220 | Letter cells across the frame (higher = finer/denser). |
| font_path | STRING | C:\Windows\Fonts\tahoma.ttf | β |
| letter_scale | FLOAT | 0.720.3β1 | β |
| scroll_dir | COMBO | down | 5 options: down, up, left, right, none |
| scroll_speed | FLOAT | 0.120β1 | Cells per frame the grid drifts. |
| color_density | FLOAT | 0.130β0.6 | Fraction of letter cells that light up with colour. |
| flicker_period | INT | 41β60 | Frames between colour-cell flicker changes (lower = faster). |
| wordbox_density | FLOAT | 0.600β1 | How many of the current line's word boxes show at once. |
| wordbox_scale | FLOAT | 2.31β5 | Word-box height relative to a letter cell. |
| bg_key | BOOLEAN | true | Key out the backdrop to find the subject (best for plain backgrounds). |
| bg_tol | FLOAT | 0.000β1 | 0 = auto. Lower keeps more of the frame as subject. |
| threshold_bias | FLOAT | 0.00-0.4β0.4 | β |
| invert_subject | BOOLEAN | false | β |
| fg_detail | FLOAT | 3.01β6 | β |
| posterize | INT | 72β32 | β |
| subject_max | FLOAT | 0.950.2β1 | β |
| subject_gamma | FLOAT | 0.600.3β3 | <1 brightens a dark subject; >1 darkens. |
| fg_gap | INT | 00β4 | β |
| text_color | STRING | #15151E | β |
| seed | INT | 70β99999 | β |
| palette_inopt | PALETTE | Connect a π¨ Lyric Sync β Palette node (overrides the text below). | |
| paletteopt | STRING | #FFFFFF,#FFFFFF,#7DEFA1,#5FE39A,#F25CC1,#FF74B8,#63D6F0,#9B5DE5,#B388F0,#F5B8D6 | Comma-separated hex colours (used if no Palette node connected). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | β |