Multi Video Stitch
Four generated clips, four different sizes, one file
- video_1
- get_video_size
- video
You generated four shots. One came out of Wan at 832x480 and 16fps, one from an image-to-video model at 1280x720 and 24fps, one is a retake at a slightly different aspect ratio, and one is a title card. Every one of them is a VIDEO object sitting in your graph, and you want a single file out the other end.
The usual answer is a chain: Video to Image → Multi Image Batch → Save Video by Image, plus an Image Resize in the middle and an audio fixup you'll forget about. Multi Video Stitch collapses that into one node - dynamic video_X inputs, one video output. It's the video version of the pack's Multi Image Batch, and it landed in v3.30.0.
How it works
It walks your inputs by numeric suffix - video_1, video_2, video_3 - and sorts them, so the order you see on the canvas is the order in the file. Anything it can't decode is dropped rather than crashing the run, which is friendlier than it sounds at five ports.
Then it picks a target size. If get_video_size is connected, its width and height win; the node asks the video object for dimensions and only decodes a frame if that fails. Otherwise the first valid segment defines it. That ordering is the point: drop a canonical clip in as the reference and everything else conforms to it.
Frame rate resolves from the fps string. Each segment is resampled by picking evenly spaced frames across the clip while preserving its duration - a 5-second 8fps clip at 24fps becomes 120 frames, not a fifth of a second - then fitted to the target size, then concatenated. Encoding isn't a passthrough: if any segment carries alpha, all of them are promoted to RGBA and the result goes out as WebM/VP9 with yuva420p; otherwise MP4/H.264. Audio is resampled to a common rate and channel count, and segments with no track get silence of the right length so the timeline stays aligned. If nothing has audio, no track is written.
What you actually set
fit-padby default, pluscropandstretch.padscales to fit and letterboxes,cropscales to cover and centre-crops (so your framing changes),stretchjust distorts. For mixed aspect ratios,padis the honest choice.pad_color- and this is the trap. The default is"1.0", which is white, not black. Stitch a 16:9 clip into a vertical frame with defaults and you get bright white bars. Use0.0for black, a hex orr,g,bvalue for anything else, or a strategy:edgefills with the average edge colour,extendreplicates border pixels outward,mirrorreflects them,averagefills with the image mean.extendandmirrorgive you pseudo-outpaint bars instead of a matte.fps- a string, defaultvideo_1("inherit the first segment's rate"). You can also writevideo_2/v2/v_2/video 2to inherit a different segment, or type a number like29.5. If the referenced segment has no readable rate it falls back to the first valid one, then to 8.0.
video_1 is the first slot; add more ports in the UI (the pack's dynamic_port.js handles this - the node starts with one video port and no upper limit). get_video_size is pinned below all of them so it never gets confused with a real segment, and it is never stitched into the output - it only supplies dimensions.
Installing it
Manager → search ComfyUI 1hewNodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/1hew/ComfyUI-1hewNodes
This one genuinely does need PyAV - av is in the pack's requirements.txt and the encoder imports it directly. PyAV ships its own FFmpeg, so the codecs here (libx264, libvpx-vp9, aac, libopus) come along with the wheel rather than needing a system FFmpeg. You'll also inherit the rest of the pack's dependency list, which includes opencv-python, onnxruntime and rembg whether you want them or not.
Where it bites
Every output is a re-encode. The node decodes all segments to tensors, concatenates, and writes a fresh file into ComfyUI's temp directory. Join five clips that were already identical in size and rate and you're still paying a generation loss for nothing.
Resampling is nearest-frame, not interpolation. Going 8fps → 24fps triples frames by repetition. It preserves timing correctly, which is what the node promises; it won't make a choppy clip smooth. Generate at your target rate if smoothness matters.
Memory. Every frame of every segment lives in RAM at once before the concatenate. Five 1080p clips of a few hundred frames each is a lot of float32 - if your machine is already tight, stitch in two passes.
Alpha forces WebM. One transparent segment and everything lands in VP9/WebM whether you wanted it or not. Fine for editing, occasionally awkward for upload targets that prefer MP4.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| fps | STRING | video_1 | 输出帧率。默认 "video_1" 沿用第一段视频的帧率;可填 video_2 / v2 / v_2 / video 2… 取对应视频的帧率,也可直接填数字(如 8、29.5)。 |
| fit | COMBO | pad | 尺寸适配模式:crop 缩放覆盖后居中裁切;pad 缩放适配后居中补边;stretch 直接拉伸。 |
| pad_color | STRING | 1.0 | pad 模式的补边颜色,支持颜色名/HEX/RGB 以及 edge/average/extend/mirror 策略。 |
| video_1opt | VIDEO | 第一段视频;后续片段通过动态端口 video_2、video_3… 接入。 | |
| get_video_sizeopt | VIDEO | 可选的尺寸参考视频;连接后以它的宽高作为拼接目标尺寸,未连接时以第一段视频为准。 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |