Nodes/Video PiP · 视频画中画/视频画中画 · 形状蒙版 / Video PiP
ComfyUI Node

视频画中画 · 形状蒙版 / Video PiP

Overlay two videos in one ComfyUI node, no ffmpeg detour

By jinny-wj·Created 6 days ago·Updated 3 days ago· 0
视频画中画 · 形状蒙版 / Video PiP
  • background_video
  • foreground_video
  • 合成视频
  • 静态小窗蒙版
shape
position
x0
y0
width240
height240
margin24
fit
opacity1.00
feather1
corner_radius32
border_width4
border_color#FFFFFF
short_video
audio_source

Two clips, and one should sit inside the other in a little rounded window - reaction-video style, second angle, a caption plate over a background plate. The honest answer in ComfyUI used to be "render both, finish it in ffmpeg or Resolve," because the native VIDEO pipe is great at making a clip and indifferent to compositing two of them. VideoPictureInPicture is the small, single-purpose fix.

It's one node from a one-node pack (jinny-wj's ComfyUI-Video-PiP, v0.2.0, September 2026), and so far it's completely unfamous - search the archives for the pack, the author, or "Video PiP" and you get nothing.

What it does, and what it refuses to do

Background video is the base layer and decides the canvas, duration and frame rate. Foreground video gets squeezed into a shaped window and pasted on top. Five shapes (圆形 circle, 椭圆 ellipse, 矩形 rectangle, 圆角矩形 rounded rectangle, 菱形 diamond), corner or centred positioning, feathering, an inner border whose colour you type by hand.

What it won't do: no keyframing the window, no automatic matting, no foreground audio mixing. Those omissions are the tell that the author knows the difference between a compositor and a PiP node. Cutting a subject out of its room is a job for a segmentation model upstream, not for this.

The mechanism is unglamorous. The node builds an alpha ramp once, at window size, from a signed-distance field for the chosen shape - a static mask, reused on every frame, computed at 240×240 or whatever you set rather than at canvas size. Then, per background frame, it picks the matching foreground frame by frame-rate ratio, resizes that one frame, and alpha-blends it into a clone of the background. That mask is also why there's no keyframing: geometry is baked, motion is out of scope.

The inputs that matter

Two wires, then a wall of widgets. These decide whether you get a result:

  • background_video - the canvas. Its resolution, frame rate and length are the output's.
  • foreground_video - the thing inside the window.
  • shape / position / width / height / margin - geometry. margin is the pixel gap from the canvas edge for the corner presets. With position on 自定义 (custom), x and y stop being offsets from a preset and become the window's top-left corner.

Then the fiddly bits. A circle takes the smaller of width/height as its diameter, so mismatched values quietly get squared off. corner_radius does nothing unless the shape is rounded rectangle. feather at 0 still applies about a pixel of antialiasing, so edges never go fully hard; opacity fades the whole window and is baked into the mask. And prefer fit's centre-crop unless the aspect already matches the window.

short_video covers a foreground shorter than the background: loop it, freeze its last frame, or hide the window after it ends. audio_source is background track or silence - the foreground's audio never comes along, so mux it in afterwards.

Outputs: 合成视频 (VIDEO) goes straight into Save Video, and 静态小窗蒙版 (MASK) is the window silhouette. Note the name - static. It encodes position, geometry and opacity and does not follow short_video's hiding, so don't wire it downstream expecting it to track what's visible per frame.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/jinny-wj/ComfyUI-Video-PiP

Restart ComfyUI. That's it - dependencies = [] in the pyproject, no model downloads, and the pack doesn't run pip or touch your environment. In ComfyUI Manager, search "Video PiP" or 视频画中画.

Do check your core version: the pack declares ComfyUI ≥ 0.33.1 because it uses the native video API, and host libraries import at execution time - on an older build the node registers fine and only falls over when you hit Queue. That's the symptom, not a mystery. The demo workflow (examples/video-pip.json) is two Load Video nodes, this, Save Video.

Traps and troubleshooting

Crash instead of a render, with a colour error. border_color is a plain text field with no picker and demands exactly #RRGGBB. #FFF or a missing hash raises and stops the run. border_width at 0 switches the border off entirely.

Nothing appears. Almost always the window is parked off-canvas: the node returns the untouched background and an empty mask when the window falls outside the frame. Clean run, no visible change. Pull x/y toward zero.

Heavier than you expect. Both clips are fully decoded and the background is cloned per frame, so cost scales with canvas pixels × frame count. The author's testing is refreshingly specific - 144 frames at 960×540, on CPU, CUDA untested, and explicitly "not a long-video streaming processor." Fine for a five-second clip; don't point it at an hour of footage.

Coming from the prototype. An earlier merged build bundled this node inside the comfyui-subtitle-safe-zone repo - move that out of custom_nodes first, or you'll register duplicate node IDs. And skip "update all dependencies": this pack installs nothing, so any dependency mess is ComfyUI's.

The verdict: a compositing node with no compositing ambitions, and that's the point. One file, no deps, and "export both and open Resolve" becomes four nodes on the canvas.

CategoryVideo/Picture in Picture

Inputs (17)

NameTypeDefaultDescription
background_videoVIDEO背景视频(底层):决定输出画布、时长和帧率。
foreground_videoVIDEO前景视频(上层):显示在蒙版小窗内。
shapeCOMBO5 options: 圆形, 椭圆, 矩形, 圆角矩形, 菱形
positionCOMBO6 options: 右下, 左下, 右上, 左上, 居中, 自定义
xINT0-4096–4096相对位置预设的水平偏移;自定义时为左上角 x。
yINT0-4096–4096相对位置预设的垂直偏移;自定义时为左上角 y。
widthINT2401–4096
heightINT2401–4096圆形取宽高较小值作为直径;椭圆分别使用宽高。
marginINT240–2048
fitCOMBO2 options: 居中裁切, 拉伸
opacityFLOAT1.000–1
featherFLOAT10–64
corner_radiusINT320–2048仅圆角矩形生效。
border_widthINT40–64
border_colorSTRING#FFFFFF
short_videoCOMBO前景比背景短时的处理方式;按两路各自帧率对齐时间。
audio_sourceCOMBO2 options: 背景声音, 静音

Outputs (2)

NameTypeDescription
合成视频VIDEO
静态小窗蒙版MASK