Nodes/ComfyUI-VideoOverlayFFmpeg/Video Overlay with Subtitles (画中画+字幕)
ComfyUI Node

Video Overlay with Subtitles (画中画+字幕)

Picture-in-picture with burned-in subtitles, straight from Whisper timestamps

By GuardSkill·Created 10 months ago·Updated 9 months ago· 0
Video Overlay with Subtitles (画中画+字幕)
  • alignment
  • video_path
big_video_path
small_video_path
mask_video_path
opacity1.00
positionright_bottom
margin_x0
margin_y0
size_ratio0.25
big_video_audio_volume0.0
small_video_audio_volume1.0
video_fps24
big_video_speed1.8
small_video_speed1.0
font_pathYRDZST Semibold.ttf
font_size48
font_colorwhite
x_position0
y_position0
subtitle_positionbottom_center
max_subtitle_width0
subtitle_bg_opacity0.7
subtitle_bg_colorblack

This is the upgraded version of the pack's plain VideoOverlayNode, and the headline feature is the one that turns it from "handy compositing helper" into "auto-captioning machine": it can burn subtitles directly from Whisper-style alignment data. If your workflow already transcribes a video into timestamped segments, this node takes that data, overlays your picture-in-picture clip, renders the captions onto the frame, and hands back one finished MP4. No intermediate SRT file, no fiddling with an external subtitle tool.

What changed vs. the base node

Everything from VideoOverlayNode is here - same big_video_path / small_video_path / mask_video_path strings, same size_ratio, position, margins, opacity, and the same per-clip audio and speed controls, including the surprising defaults (base audio muted at 0.0, base speed at 1.8×). What's added is the alignment input plus the whole subtitle styling block, and one extra required field: video_fps (default 24), which the node uses when it builds the timeline.

How the subtitles work

The alignment input accepts a whisper_alignment custom type - a list of segments like {"value": "...", "start": 0.0, "end": 4.86} - either wired directly from a transcription node or pasted as a JSON string. The node parses it, word-wraps each segment against max_subtitle_width (0 = auto, about 80% of the video width), then renders each segment as an ffmpeg drawtext filter with escaping handled for you. Text is drawn between start and end, with a background box whose color and opacity you control. Output is the same libx264 + aac + +faststart MP4 written to ComfyUI/output/, and video_path is the only output.

The subtitle inputs worth touching

  • font_path - a dropdown that auto-detects the pack's fonts/ folder (it ships ~18 fonts, including a Chinese font) plus common system fonts. Default is "YRDZST Semibold.ttf".
  • font_size (12–200, default 48) and font_color (any ffmpeg color name or hex).
  • subtitle_position - bottom_center by default, with top/bottom-left/right, center, or custom, which activates x_position / y_position.
  • subtitle_bg_opacity / subtitle_bg_color - the caption backdrop. Defaults of 0.7 opacity over black give you the standard legible caption look.

The subtle trap: if you want subtitles and your alignment input is empty or fails to parse, the node silently proceeds and just doesn't draw text - it logs a [VideoOverlay] 警告 in the console but the MP4 still comes out. If your captions are missing, check that first.

Installing and the usual suspects

Same install as the whole pack: ComfyUI Manager (search "ComfyUI-VideoOverlayFFmpeg"), or clone into custom_nodes and pip install -r requirement.txt (that file is just ffmpeg-python - the real dependency is a system ffmpeg on your PATH). Then restart. There are no model downloads; the fonts ship inside the repo.

The classic failures: captions show as boxes or garbage - your font doesn't support the script, so pick a CJK font for Chinese text. Text runs off the edge - lower font_size or set max_subtitle_width to ~70–80% of the video width. Text appears for the whole clip or not at all - your alignment segments are missing proper start/end fields. And as with the base node, use absolute paths without spaces, or the file-existence check trips first.

If you're doing talking-head-over-B-roll content, this is the rare node that finishes the whole captioning+compositing job inside the graph. It's worth the two minutes of install.

Categoryvideo

Inputs (23)

NameTypeDefaultDescription
big_video_pathSTRING
small_video_pathSTRING
mask_video_pathSTRING
opacityFLOAT1.000–1
positionCOMBOright_bottom5 options: right_bottom, right_top, left_bottom, left_top, center
margin_xINT00–500
margin_yINT00–500
size_ratioFLOAT0.250.1–1
big_video_audio_volumeFLOAT0.00–2
small_video_audio_volumeFLOAT1.00–2
video_fpsFLOAT241–120
big_video_speedFLOAT1.80.25–4
small_video_speedFLOAT1.00.25–4
alignmentoptwhisper_alignment
font_pathoptCOMBOYRDZST Semibold.ttf18 options: YRDZST Semibold.ttf, YoungSerif-Regular.ttf, impact.ttf, Oswald-Bold.ttf, Roboto-Regular copy.ttf, PixelifySans-Bold.ttf, +12
font_sizeoptINT4812–200
font_coloroptSTRINGwhite
x_positionoptINT0-1000–3000
y_positionoptINT0-1000–3000
subtitle_positionoptCOMBObottom_center6 options: bottom_center, top_center, bottom_left, bottom_right, center, custom
max_subtitle_widthoptINT00–4000
subtitle_bg_opacityoptFLOAT0.70–1
subtitle_bg_coloroptSTRINGblack

Outputs (1)

NameTypeDescription
video_pathSTRING