Nodes/RyanOnTheInside/Whisper Text Renderer βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
ComfyUI Node

Whisper Text Renderer βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜

Burn animated, word-synced captions onto video

By ryanontheinsideΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 852
Whisper Text Renderer βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
  • images
  • feature
  • IMAGE
β—„font_size32β–Ί
β—„font_namearialβ–Ί
β—„positionbottomβ–Ί
β—„horizontal_aligncenterβ–Ί
β—„margin20β–Ί
β—„animation_typefadeβ–Ί
β—„animation_duration15β–Ί
β—„max_width0β–Ί
β—„bg_color#000000β–Ί
β—„text_color#FFFFFFβ–Ί
β—„opacity0.80β–Ί

Those animated, word-highlighted captions you see on short-form video - the ones where text pops in synced to exactly when each word is spoken - are what this node builds directly inside ComfyUI. It's not just subtitles dumped on screen; it draws text onto your frames using per-word timing data, so the caption's appearance is locked to the actual speech, not an estimated block of time.

How it works

The timing data comes in through feature, a FEATURE object carrying Whisper alignment - the per-word start/end timestamps a Whisper transcription step upstream in this pack produces. This node then overlays styled text onto images frame by frame, using that alignment to know exactly which frames each word should be visible on. Everything else is presentation: font_name (a handful of built-in, system-independent fonts, so the look is consistent regardless of what's installed on the machine running it), font_size, position (top/middle/bottom) and horizontal_align (left/center/right) for placement, margin for spacing off the frame edges, and bg_color/text_color/opacity for the actual look of the text.

animation_type is where this stops being static subtitles: none is flat static text, fade smooth-fades each word or line in and out, pop does a scale/bounce-in, and slide animates text sliding into position - all timed to animation_duration (in frames). max_width handles wrapping - 0 uses the full frame width, anything above that constrains text to a narrower column and wraps it.

Inputs and outputs

  • images (required, IMAGE) - the video frames to render text onto.
  • feature (required, FEATURE) - the Whisper alignment data; this has to come from an upstream Whisper transcription node in this pack, not a plain transcript string.
  • font_size, position, animation_type - the three settings most beginners actually touch; everything else has sensible defaults.
  • Output - a single IMAGE, the same frames with text composited on.

Note that the required feature input is typed FEATURE, not the pack's TRIGGER_SET type - this node consumes a different upstream product than Trigger Builder does, even though both live in the same Whisper-source category. Don't expect to wire a TRIGGER_SET directly into this node's feature slot; the types won't match.

Installing it

Install through ComfyUI Manager (search RyanOnTheInside) or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside

Then pip install -r requirements.txt and restart ComfyUI. Whisper itself downloads its model automatically from Hugging Face the first time any Whisper-based node in this pack runs - budget for that one-time delay, especially on a slower connection, before assuming the node is hung.

Common issues

The most common mistake is trying to feed this a plain string or a generic transcript rather than the proper Whisper FEATURE output - the alignment data (per-word timing) has to come from this pack's own Whisper transcription node, since that's what makes the captions sync to speech instead of just appearing all at once.

If text renders but looks cut off or oddly wrapped, check max_width before fiddling with font_size - leaving it at 0 uses the full frame, which can run text edge-to-edge on a narrow or vertical video; a modest max_width plus horizontal_align: center usually reads better for short-form formats. And if the animation looks too abrupt or too slow, animation_duration is a frame count, not a percentage or seconds value - tune it relative to your actual frame rate, not a fixed number that "felt right" on a different clip.

CategoryRyanOnTheInside/FlexFeatures/Sources/Whisper

Inputs (13)

NameTypeDefaultDescription
imagesIMAGEInput video frames to overlay text on
featureFEATUREWhisper feature containing alignment data
font_sizeINT328–256Size of the rendered text (8-256 pixels)
font_nameCOMBOarialFont to use for rendering. Uses system-independent built-in fonts.
positionCOMBObottomVertical position of text: - top: Align to top of frame - middle: Center vertically - bottom: Align to bottom of frame
horizontal_alignCOMBOcenterHorizontal text alignment: - left: Align to left edge - center: Center horizontally - right: Align to right edge
marginINT200–200Distance from frame edges in pixels
animation_typeCOMBOfadeType of text animation: - none: Static text - fade: Smooth fade in/out - pop: Scale animation - slide: Sliding animation
animation_durationINT151–60Length of animation in frames
max_widthoptINT0Maximum width for text wrapping. 0 = use full frame width
bg_coloroptSTRING#000000Background color in hex format (#RRGGBB)
text_coloroptSTRING#FFFFFFText color in hex format (#RRGGBB)
opacityoptFLOAT0.800–1Overall opacity of text overlay (0.0-1.0)

Outputs (1)

NameTypeDescription
IMAGEIMAGEβ€”