Nodes/CMK Flow/CMK FaceSwap Video
ComfyUI Node

CMK FaceSwap Video

The Node That Started CMK, Still Doing Full-Length Video

By CMKFlow·Created 3 months ago·Updated a day ago· 6
CMK FaceSwap Video
  • SEGMENTS
  • IMAGE SOURCE
  • LOG
  • SEGMENTS
  • LOG
  • diagnostic
◄FACE SWAPtrue►
◄SEGMENT SELECTIONFull Path (Batch)►
◄SWAP MODEL▾►
◄DETECT MODEL▾►
◄FACE ENHANCEROff►
◄TARGET FACELargest►
◄SOURCE FACELargest►
◄BLEND1.00►
◄bbox_dilation0►
◄crop_factor1.5►
◄drop_size10►
◄feather0►
◄max_missing_frames12►
◄tracking_iou_threshold0.08►
◄tracking_embedding_threshold0.35►

The pack's own documentation says this node is where CMK began, and that it was deliberately not modernised. That reads like a warning, but it's actually the pitch: it's the one piece of the flow that does the entire job in a single node, and it has had years of use to knock the edges off.

What it is

Give it a set of video segments plus a source face image, and it swaps the target face across every frame - decode, detect, track, swap, re-encode, streaming through ffmpeg pipes so a five-minute clip never lands in RAM as a tensor.

It's not a frame-by-frame detector. That distinction is the whole design. A per-frame "Largest" would jump to a different person the moment someone walks past the camera. This node picks a target once, then tracks it: bounding-box IoU plus an ArcFace embedding comparison, with max_missing_frames (default 12) letting it survive occlusions and bad frames without dropping the identity, and tracking_iou_threshold (0.08) and tracking_embedding_threshold (0.35) deciding when a detection is still the same person. Loosen the embedding threshold and tracking gets clingier; loosen IoU and it survives wilder motion.

Face detection on every frame is exactly the expensive thing in this pipeline - and this pack runs InsightFace through ONNX Runtime's CPU provider by default - so tracking isn't a nicety, it's what makes long clips tractable at all.

What you feed it

SEGMENTS is the pack's CMK_VIDEO_SEGMENTS context - the persistent video project that CMK Split Video into Segments (or the FaceSwap Video Loader) produces. IMAGE SOURCE is your face reference, LOG is the log pipe. All three are required, and the node type-checks them: feed it the wrong dict and you get a TypeError naming the input rather than a mystery crash three modules later.

SEGMENT SELECTION controls scope, and it's the control you'll use most:

  • Full Path (Batch) - every segment, the whole video.
  • Randomize - one random segment, and it deliberately avoids re-picking the one it used last time.
  • Last Used Segment - re-process exactly the segment Randomize landed on. Handy for iterating on one trouble spot without re-running twenty minutes of video.

Randomize forces the node to re-execute every queue (there's no caching a random choice), which is expected behaviour rather than a bug.

The swap controls are the set you know from the image node - SWAP MODEL, DETECT MODEL, FACE ENHANCER (Off or GPEN), TARGET FACE, SOURCE FACE, BLEND, plus the advanced bbox_dilation, crop_factor, drop_size and feather. FACE SWAP off is a real bypass: the segments come back untouched and the log says BYPASSED, so you can park the node in a workflow without deleting it.

Outputs

SEGMENTS is the swapped project context, ready for CMK Merge and Save Video to reassemble and publish. LOG accumulates the per-segment report, and diagnostic carries the run summary including the segment count and selection mode.

The resume behaviour is the good bit

Each run writes a manifest under output/video/face_swap/<video>/<signature>/ keyed on a signature that includes the source manifest, the source image hash, the swap model file and every setting. Per segment, a fingerprint combines that base with the segment's file id and time range. If the fingerprint matches a completed record and the output file is still there, the segment logs REUSED and is skipped.

Practical consequence: you can interrupt a long video swap, restart ComfyUI, run it again, and it picks up instead of starting over. Change one setting and only that changes - everything else is still a hit. This is the one place in the pack where a cache genuinely survives a restart, and it's worth structuring your video work around.

Install

Manager: search CMK Flow, install, restart. Manual, from your ComfyUI root:

git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/ComfyUI-Shared"

You need inswapper_128.onnx and the buffalo_l detector in ComfyUI/models/insightface, plus an ffmpeg binary on the system - the pack depends on imageio-ffmpeg, but it shells out to ffmpeg for the streaming decode/encode. Videos are read from ComfyUI/input/video/.

Where people get burned

The ContentGuard runs on every target frame. It's mandatory, it's local (NudeNet plus InsightFace age estimation), and it aborts the whole run rather than skipping a frame. On a long clip that's a real risk of burning twenty minutes to a hard stop - so run a short segment range first.

CPU inference. The pack's detector and swapper default to CPU providers. Budget accordingly; the tracking keeps detection from dominating, but the swap itself is per frame.

Licensing. The library is MIT, the models are not, and inswapper is research-only. Local experiments, yes. Product, no.

CategoryCMK/Toolbox/Video

Inputs (18)

NameTypeDefaultDescription
SEGMENTSCMK_VIDEO_SEGMENTS—
IMAGE SOURCEIMAGE—
LOGCMK_LOG_PIPE—
FACE SWAPBOOLEANtrue—
SEGMENT SELECTIONCOMBOFull Path (Batch)3 options: Full Path (Batch), Randomize, Last Used Segment
SWAP MODELCOMBO1 options: inswapper_128.onnx
DETECT MODELCOMBO1 options: buffalo_l
FACE ENHANCERCOMBOOff2 options: Off, GPEN
TARGET FACECOMBOLargest6 options: Largest, Leftmost, Rightmost, Topmost, Bottommost, Center
SOURCE FACECOMBOLargest6 options: Largest, Leftmost, Rightmost, Topmost, Bottommost, Center
BLENDFLOAT1.000–1—
bbox_dilationINT0-512–512—
crop_factorFLOAT1.51–3—
drop_sizeINT101–8192—
featherINT00–100—
max_missing_framesINT120–300—
tracking_iou_thresholdFLOAT0.080–1—
tracking_embedding_thresholdFLOAT0.35-1–1—

Outputs (3)

NameTypeDescription
SEGMENTSCMK_VIDEO_SEGMENTS—
LOGCMK_LOG_PIPE—
diagnosticCMK_DIAGNOSTIC—