Nodes/MKRShift_Nodes/Video Watermark
ComfyUI Node

Video Watermark

Burn text or a logo onto every frame — the client-preview watermark

By criskb·Created 7 months ago·Updated 5 months ago· 0
Video Watermark
  • video
  • watermark_image
  • video
  • output_path
  • summary
text
text_size32
text_color#FFFFFF
text_bg_color#000000
text_bg_opacity0.35
positionbottom_right
margin24
watermark_opacity0.80
logo_scale0.20
logo_rotation_deg0.0
fallback_fps24.0
output_formatauto
filename_prefixMKR_video_watermark
subfolder
overwritefalse
filename_label

MKRVideoWatermark draws text - or a logo image - onto every frame of a clip and writes out the watermarked version. This is the "don't send the client the clean master" node: burn a preview mark, a studio tag, or a timestamp onto the footage so the unwatermarked render stays yours until the invoice clears.

It works as a per-frame PIL draw. The text input is the string to draw; the text_size (8–512), text_color (hex like #FFFFFF), text_bg_color (hex, the pill behind the text), and text_bg_opacity (0.35 default) control the label. position picks one of five spots - bottom_right (default), bottom_left, top_right, top_left, center - and margin sets the inset in pixels. watermark_opacity (0–1, default 0.8) fades the whole mark, which is how you get a watermark that sits on top of the footage instead of shouting over it.

The input most people miss is watermark_image - an IMAGE tensor (so it chains straight off any image node or an image loader). Give it a logo and it scales it to logo_scale (default 0.2 - that's 20% of the frame's smaller dimension, so it stays proportionate at any resolution) and rotates it by logo_rotation_deg if you want a tilted brand mark. Text and logo can both be on at once, or just one. Give it neither and the node passes the clip through unchanged with a warning - it won't invent a mark for you.

The inputs that matter

  • text - the string to burn in. Leave empty if you're only using a logo.
  • watermark_image - an IMAGE tensor of your logo, scaled via logo_scale.
  • position / margin - where it sits.
  • watermark_opacity - the fade. 0.5–0.8 is the sweet spot for a preview mark that stays readable without wrecking the image.
  • video, output_format, filename_prefix, subfolder, overwrite - standard.

Outputs: video (MKR_VIDEO payload), output_path, summary (which reports whether text and/or logo were actually used).

Install

Ships in MKRShift Nodes - install the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

or ComfyUI Manager → search MKRShift_Nodes → restart. mp4/mov/webm needs system ffmpeg on PATH; gif/webp work without it. No pip dependencies.

Where people get burned

Colors are hex strings - #FFFFFF, not white. The font loader tries DejaVuSans then Arial and falls back to a built-in bitmap default, so on a system with neither, text will render chunkier than you asked for (that's a system font thing, not a bug). And the text is drawn at text_size in pixels, not relative to frame size - if you watermark a 4K master with the same node settings you used on a 512px preview, the text will look tiny. The image-logo path avoids that by scaling with the frame; the text path doesn't.

CategoryMKRShift Nodes/Media/Watermark

Inputs (18)

NameTypeDefaultDescription
video*
textSTRING
text_sizeINT328–512
text_colorSTRING#FFFFFF
text_bg_colorSTRING#000000
text_bg_opacityFLOAT0.350–1
positionCOMBObottom_right5 options: bottom_right, bottom_left, top_right, top_left, center
marginINT240–2048
watermark_opacityFLOAT0.800–1
logo_scaleFLOAT0.200.02–1
logo_rotation_degFLOAT0.0-180–180
fallback_fpsFLOAT24.01–240
output_formatCOMBOauto6 options: auto, gif, webp, mp4, mov, webm
filename_prefixSTRINGMKR_video_watermark
subfolderSTRING
overwriteBOOLEANfalse
watermark_imageoptIMAGE
filename_labeloptSTRING

Outputs (3)

NameTypeDescription
videoMKR_VIDEO
output_pathSTRING
summarySTRING