Face Extractor
Pull every shot of one person out of a video, without melting your RAM
- reference_embedding
- images
- output_path
- output_info
- extracted_count
- preview_grid
You've got a long video - an interview, a movie scene, a stack of old home footage - and you need every clean face crop of one specific person. Not "a face." That face. That's the whole job of the FaceExtractor node, and it's the thing this pack is named after.
Think of it as a dataset-farming tool. You hand it an embedding of who you're looking for (from the Face Reference Embedding node) and it walks the video frame by frame, detects faces, compares each one to your reference, and writes the matches to disk as aligned crops plus masks. The output folder is laid out the way DeepFaceLab expects it, so you can copy the aligned/ directory straight into workspace/data_src/aligned/ and get on with a face-swap or training project. If you've ever spent an evening hand-cropping frames in a video editor, this is the boring work you don't have to do anymore.
Two things actually sell it. First, built-in video loading: the node takes a raw video_path string - no separate Video Loader node, no VHS dependency - and opens the file itself with OpenCV. Second, memory that doesn't grow with the clip: streaming mode (the default) reads one frame at a time and holds RAM at roughly 500MB no matter how long the video is, flushing the GPU every 500 frames. Chunked mode batches frames and flushes the GPU after every chunk - faster, but it can eat up to memory_threshold_percent (default 75%) of your RAM. For a 30-minute clip on a 16GB machine, streaming is the sane choice. Watch the console; it prints which mode is active and the auto-calculated chunk size.
How it works
The reference embedding is a 512-dim neural vector (FaceNet or InsightFace, depending on your backend). Each detected face in the video gets embedded the same way, and the node computes cosine similarity between the two. Faces scoring above similarity_threshold are kept, sorted best-first, and the top max_faces_per_frame are cropped. The crop preserves aspect ratio - it scales the face plus margin_factor of padding to output_size and centers it on a black canvas, so you don't get the squashed 512×512 distortion older tools produced (that was the v3 bug, fixed in v4).
The backend story is genuinely the most important thing to understand, because it's about licensing, not just quality. There are five: FaceNet (MIT), YOLOv8 (AGPL-3.0 - commercial closed-source use needs an Ultralytics license), InsightFace (non-commercial only), MediaPipe (Apache 2.0), and OpenCV cascade (BSD). If you're building anything commercial, the README's pick is FaceNet: MIT, GPU-accelerated, and quality that's effectively comparable to InsightFace. A handy detail - the backend dropdown only lists backends that are actually installed, and if you force one that isn't, it falls back (InsightFace → FaceNet → MediaPipe, and so on) and tells you on the console.
The inputs that matter
The two required ones are reference_embedding (from Face Reference Embedding) and video_path - though you can leave the path empty and wire the images input instead if you're processing an image batch; if both are provided, the video path wins. After that, the knobs you'll actually touch:
- similarity_threshold (0.6 default) - how close a match counts. This is the big one.
- margin_factor (0.4) - how much context around the face the crop keeps.
- max_faces_per_frame (1) - set higher for crowd shots.
- frame_skip (1) - process every Nth frame; great for a quick pass on a long video.
- start_frame / end_frame - work a slice of the video instead of all of it.
The node is an output node, and its four outputs are output_path (STRING - where the crops landed), output_info (STRING), extracted_count (INT), and preview_grid (IMAGE, capped at 16 faces). Wire output_path into a ShowText node so you know where to look, and preview_grid into a PreviewImage.
Installing it
Easiest is ComfyUI Manager - search "faceExtractor" (pack title "faceExtractor for ComfyUI"). Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/llikethat/ComfyUI-faceExtractor
cd ComfyUI-faceExtractor
pip install facenet-pytorch mediapipe psutil
Restart ComfyUI. The repo's requirements.txt also pulls ultralytics (YOLOv8) by default; InsightFace needs a manual pip install insightface onnxruntime-gpu (skip it unless you're sure about the non-commercial license).
Common issues
- "InsightFace not available" in the console isn't a crash - it's the fallback message. Install the package if you want that backend.
- GPU memory creeps up - switch to streaming mode or lower
memory_threshold_percent. - Faces look squashed - you're on an old version; v4 preserves aspect ratio, so update the pack.
- Threshold feels wrong - too high and you miss shots, too low and you collect strangers. That's exactly what the pack's Face Matcher node is for; tune it before you commit to a big extraction.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| reference_embedding | FACE_EMBEDDING | — | |
| video_path | STRING | — | |
| imagesopt | IMAGE | — | |
| similarity_thresholdopt | FLOAT | 0.600.3–0.95 | — |
| margin_factoropt | FLOAT | 0.400.1–1 | — |
| output_sizeopt | INT | 512128–1024 | — |
| max_faces_per_frameopt | INT | 11–10 | — |
| frame_skipopt | INT | 11–60 | — |
| start_frameopt | INT | 00–9999999 | — |
| end_frameopt | INT | -1-1–9999999 | — |
| processing_modeopt | COMBO | streaming | 2 options: streaming, chunked |
| memory_threshold_percentopt | FLOAT | 7530–90 | — |
| chunk_sizeopt | INT | 00–10000 | — |
| output_prefixopt | STRING | face_extract | — |
| save_debug_infoopt | BOOLEAN | true | — |
| detection_backendopt | COMBO | facenet | 5 options: facenet, yolov8, insightface, mediapipe, opencv_cascade |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |
| output_info | STRING | — |
| extracted_count | INT | — |
| preview_grid | IMAGE | — |