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.
Inside the workflow
A read-only preview of the source template. Open it in Cloud to explore the nodes and make changes.
Loading the graph
Open full-size workflow preview- Output
- Video
- Author
- ComfyUI
Call this model from your code
The request below uses the same prepared graph and settings as the Playground. Each submission can start a paid run; do not automatically retry a submission whose outcome is unknown.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
- Your files
- Uploaded by the code from their urls
Needs a paid Cloud plan and credits.
# 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)Try an example
About this workflow
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.
Questions & answers
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.