VOID: Video Inpainting
Upload a video and mask the object you want to remove. Generate a clean video with the object and its physical interactions deleted.
查看工作流内部
源模板的只读预览。在 Cloud 中打开,即可查看节点并进行修改。
Loading the graph
Open full-size workflow preview- 输出
- 视频
- 作者
- ComfyUI
从代码中调用该模型
以下请求使用与体验区相同的预设图和设置。每次提交都可能开始一次付费运行;如果提交结果未知,请勿自动重试。
What you need
- Runs on
- Comfy Cloud
- 密钥
- COMFY_API_KEY
- 你的文件
- 由代码根据链接上传
需要付费的 Cloud 方案和额度。
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"4": {
"class_type": "LoadVideo",
"inputs": {
"file": "UPLOADED_video_FILENAME"
},
"_meta": {
"title": "Source video (ComfyUI/input/)"
}
},
"38": {
"class_type": "SaveVideo",
"inputs": {
"codec": "auto",
"filename_prefix": "video/VOID_pass2",
"format": "mp4",
"format.codec": "auto",
"video": [
"167:165",
0
]
},
"_meta": {
"title": "Save Video (Pass 12"
}
},
"48": {
"class_type": "SaveVideo",
"inputs": {
"codec": "auto",
"filename_prefix": "video/VOID_pass1",
"format": "auto",
"format.codec": "auto",
"video": [
"167:46",
0
]
},
"_meta": {
"title": "Save Video (Pass 1)"
}
},
"167:10": {
"class_type": "VOIDInpaintConditioning",
"inputs": {
"batch_size": 1,
"height": [
"167:148",
0
],
"length": [
"167:43",
2
],
"negative": [
"167:7",
0
],
"positive": [
"167:6",
0
],
"quadmask": [
"167:149:75",
0
],
"vae": [
"167:3",
0
],
"video": [
"167:145",
0
],
"width": [
"167:147",
0
]
},
"_meta": {
"title": "VOIDInpaintConditioning"
}
},
"167:133": {
"class_type": "VOIDSampler",
"inputs": {},
"_meta": {
"title": "VOIDSampler"
}
},
"167:134": {
"class_type": "VOIDSampler",
"inputs": {},
"_meta": {
"title": "VOIDSampler"
}
},
"167:136": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 6,
"model": [
"167:143",
0
],
"negative": [
"167:10",
1
],
"positive": [
"167:10",
0
]
},
"_meta": {
"title": "CFGGuider (Pass 2 cfg=6)"
}
},
"167:137": {
"class_type": "BasicScheduler",
"inputs": {
"denoise": 1,
"model": [
"167:143",
0
],
"scheduler": "simple",
"steps": 30
},
"_meta": {
"title": "BasicScheduler"
}
},
"167:138": {
"class_type": "BasicScheduler",
"inputs": {
"denoise": 1,
"model": [
"167:144",
0
],
"scheduler": "simple",
"steps": 30
},
"_meta": {
"title": "BasicScheduler"
}
},
"167:140": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 6,
"model": [
"167:144",
0
],
"negative": [
"167:10",
1
],
"positive": [
"167:10",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"167:141": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 43
},
"_meta": {
"title": "RandomNoise"
}
},
"167:142": {
"class_type": "OpticalFlowLoader",
"inputs": {
"model_name": "raft_large_C_T_SKHT_V2-ff5fadd5.safetensors"
},
"_meta": {
"title": "Load Optical Flow Model"
}
},
"167:143": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "void_pass2.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"167:144": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "void_pass1.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"167:145": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": [
"167:169",
1
],
"image": [
"167:166",
0
],
"length": [
"167:164",
1
]
},
"_meta": {
"title": "Get Image from Batch"
}
},
"167:147": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 672
},
"_meta": {
"title": "Int (Width)"
}
},
"167:148": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 384
},
"_meta": {
"title": "Int (Height)"
}
},
"167:149:75": {
"class_type": "SAM3_Detect",
"inputs": {
"bboxes": {
"height": 512,
"width": 512,
"x": 0,
"y": 0
},
"conditioning": [
"167:149:78",
0
],
"image": [
"167:145",
0
],
"individual_masks": False,
"model": [
"167:149:77",
0
],
"refine_iterations": 2,
"threshold": 0.5
},
"_meta": {
"title": "SAM3 Detect"
}
},
"167:149:77": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "sam3.1_multiplex_fp16.safetensors"
},
"_meta": {
"title": "Load Checkpoint"
}
},
"167:149:78": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"167:149:77",
1
],
"text": "dog"
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"167:150": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"167:36",
0
],
"on_true": [
"167:45",
0
],
"switch": [
"167:153",
0
]
},
"_meta": {
"title": "If/Else Switch"
}
},
"167:153": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Boolean (Skip Pass 2?)"
}
},
"167:158": {
"class_type": "TrimAudioDuration",
"inputs": {
"audio": [
"167:166",
1
],
"duration": [
"167:164",
0
],
"start_index": [
"167:169",
0
]
},
"_meta": {
"title": "Trim Audio Duration"
}
},
"167:163": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "Int (Video duration)"
}
},
"167:164": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a * b",
"values.a": [
"167:163",
0
],
"values.b": [
"167:166",
2
]
},
"_meta": {
"title": "Math Expression"
}
},
"167:165": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"167:158",
0
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"167:166",
2
],
"images": [
"167:150",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"167:166": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"4",
0
]
},
"_meta": {
"title": "Get Video Components"
}
},
"167:168": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 0
},
"_meta": {
"title": "Int (Index)"
}
},
"167:169": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a * b",
"values.a": [
"167:168",
0
],
"values.b": [
"167:166",
2
]
},
"_meta": {
"title": "Math Expression"
}
},
"167:2": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "t5xxl_fp16.safetensors",
"device": "default",
"type": "cogvideox"
},
"_meta": {
"title": "Load CLIP"
}
},
"167:3": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "cogvideox_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"167:31": {
"class_type": "VOIDWarpedNoise",
"inputs": {
"batch_size": 1,
"height": [
"167:148",
0
],
"length": [
"167:43",
2
],
"optical_flow": [
"167:142",
0
],
"video": [
"167:45",
0
],
"width": [
"167:147",
0
]
},
"_meta": {
"title": "Warped Noise (from Pass 1 output)"
}
},
"167:32": {
"class_type": "VOIDWarpedNoiseSource",
"inputs": {
"warped_noise": [
"167:31",
0
]
},
"_meta": {
"title": "Warped Noise → NOISE"
}
},
"167:35": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"167:136",
0
],
"latent_image": [
"167:10",
2
],
"noise": [
"167:32",
0
],
"sampler": [
"167:134",
0
],
"sigmas": [
"167:137",
0
]
},
"_meta": {
"title": "Pass 2 Sample"
}
},
"167:36": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"167:35",
0
],
"vae": [
"167:3",
0
]
},
"_meta": {
"title": "Pass 2 VAE Decode"
}
},
"167:43": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"167:145",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"167:45": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"167:49",
0
],
"vae": [
"167:3",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"167:46": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"167:158",
0
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"167:166",
2
],
"images": [
"167:45",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"167:49": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"167:140",
0
],
"latent_image": [
"167:10",
2
],
"noise": [
"167:141",
0
],
"sampler": [
"167:133",
0
],
"sigmas": [
"167:138",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"167:6": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"167:2",
0
],
"text": "An empty black volcanic sand beach at dawn, seen from a smooth sideways tracking camera at low height. Foamy steel-grey surf rolls in and slides back over the wet sand, leaving glossy reflections of the pale silver and lavender sky. Sea fog drifts along the shoreline while the distant basalt sea stacks and the long headland pass slowly behind. The dark sand is smooth, wet and undisturbed, with only fine ripples and scattered grains, and nothing moves across it. Cold, quiet, moody natural light."
},
"_meta": {
"title": "Positive Prompt"
}
},
"167:7": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"167:2",
0
],
"text": ""
},
"_meta": {
"title": "Negative Prompt"
}
}
})
workflow.set_input("4", "file", client.assets.from_url("https://comfy.org/catalog-media/d9f0dd91-f8de-4265-a705-15a3db24023b/0be332a2-d693-4583-9a5d-7e7adafe2e58"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)
for output in job.get_outputs("38"):
output.to_file(output.name)
for output in job.get_outputs("48"):
output.to_file(output.name)试试一个示例
关于此工作流
This ComfyUI tutorial shows how to remove objects from a video using the VOID: Video Inpainting workflow. The graph is simple and fast to learn: LoadVideo reads your clip, a single VOID inpainting node (c3157b75-484a-459e-b8de-57823bef5130) performs segmentation and temporal inpainting, and SaveVideo writes the cleaned result. A MarkdownNote in the canvas provides inline guidance. Under the hood, segmentation is powered by SAM3 (using the sam3.1_multiplex_fp16.safetensors checkpoint). You can guide what to erase with a text cue encoded by a T5-XXL text encoder, a hand-drawn mask, or both for maximum precision.
Technically, the core VOID node runs a two-pass, temporally-aware inpainting model from the Netflix/void-model project. Pass one removes the masked content per frame and estimates plausible backgrounds; pass two propagates structure over time to reduce flicker and preserve motion parallax. This makes it well-suited for real object removal rather than single-frame patching: reflections, shadows, and brief occlusions are handled more coherently across frames. Because it operates in fp16, it balances quality and speed on modern GPUs while keeping memory use manageable.
常见问答
You can do either. The VOID node supports text-guided segmentation via T5-XXL + SAM3 for quick selection, a hand-painted binary mask for precision, or both together (use text to localize and a mask to refine edges).
VOID uses a two-pass, temporally-aware inpainting process. The first pass removes the target per frame; the second propagates structure over time to reduce flicker and preserve motion cues. If you still see jitter, increase temporal consistency/window and soften mask edges.
Expand the mask slightly (dilation) and add a small feather to cover halos. If using text-only selection, make the cue more specific (color, size, location) or add a manual mask where reflections persist.
The model runs in fp16 but remains GPU-intensive. Higher resolutions, longer clips, and larger temporal windows increase VRAM and render time. For faster runs, downscale the input, shorten the clip, or reduce the temporal window. Consider chunking by hard cuts; process each shot separately.
No. SaveVideo outputs a silent render. To keep audio, remux the original track in your editor or with a tool like ffmpeg after export.