Nodes/ComfyUI_Adforge/Vertex Veo Insert Content
ComfyUI Node

Vertex Veo Insert Content

Swap anything into a video with a mask — no reshoot required

By Creditas-labs·Created 10 months ago·Updated 9 months ago· 1
Vertex Veo Insert Content
  • video
  • mask_image
  • videos
  • video_path_list
prompt
video_gcs_uri
mask_image_gcs_uri
negative_prompt
output_gcs_uriNone/videos/video-insert-content-20260720-202149.mp4
modelveo-3.1-generate-preview
aspect_ratio16:9
video_mime_typevideo/mp4
mask_mime_typeimage/png
duration_seconds8
resolution1080p
fps24
seed0
number_of_videos1
enhance_prompttrue
generate_audiofalse
person_generationallow_adult

This is the node that makes Adforge feel like an ad toolkit instead of just a wrapper around a video API. Vertex Veo Insert Content takes an existing video and a mask, and replaces whatever's inside the mask with new content - a product dropped into a shelf shot, a logo composited over footage, a new prop where an empty space was. It's video inpainting in the good sense: the masked region gets regenerated from your prompt, and everything outside the mask stays put.

If that sounds like the classic inpainting trade-off, it is, and the KB puts the case for masks well: instruction-based editing models drift on the bits you didn't ask about, while a mask leaves the rest of the frame alone. That "exact placement, boundary you decide" property is precisely what you want when the unmasked footage is expensive-to-reshoot b-roll. Veo 3.1 is the version that got serious about this granular editing.

How it works

The node builds a VideoGenerationMask in INSERT mode and passes it in the generation config. Your video comes from the video input (a VIDEO type, read to bytes and uploaded) or from video_gcs_uri - you need one. Your mask comes from the mask_image input or mask_image_gcs_uri, and you need one of those too. Then it's the same pipeline as the rest of the pack: async generate_videos call, polled every five seconds, Veo writes the edited clip to GCS, and the node downloads it back. Outputs are the standard videos (VIDEO list) and video_path_list (local paths).

The inputs that matter

  • prompt - required, and it's a description of the new content, not the video. "A matte black espresso machine on the counter," not "edit my kitchen video."
  • mask_image (or mask_image_gcs_uri) - the area of interest, an IMAGE. White or colored region on the area to replace; Veo treats it as the region to regenerate.
  • video (or video_gcs_uri) - the footage to edit. This pack's own LoadVideoGCS node is a natural upstream here: bucket footage → local path → into this node's video input.
  • video_mime_type / mask_mime_type - video/mp4 and image/png by default; match reality.
  • duration_seconds - 1 to 10 here, the widest range in the pack, since you're editing an existing clip rather than inventing one from scratch.
  • generate_audio - defaults to off for editing; you generally want the original clip's sound intact.

The rest of the config - model, aspect_ratio, resolution, fps, seed, number_of_videos, enhance_prompt, person_generation, negative_prompt - is shared across the Veo nodes. Defaults are fine to start.

Installing and authenticating

Search adforge in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Creditas-labs/ComfyUI-Adforge
cd ComfyUI-Adforge
pip install -r requirements.txt   # or: uv sync

Restart; Python 3.12+. Auth is the same Vertex setup as every generation node: copy .env.example to custom_nodes/comfyui_adforge/.env with GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_STORAGE_BUCKET, GOOGLE_CLOUD_LOCATION, API_KEY (or export them), and a bucket that actually exists - Veo writes output there first. GOOGLE_APPLICATION_CREDENTIALS with a service account works instead of the key.

Common issues

  • Mask too tight. Veo needs room to blend. A mask that hugs the object exactly gives you seams; a slightly generous mask gives you a believable composite.
  • Mask/video mismatch. If the mask doesn't line up with the frame - different resolution, rotated, the video got resized upstream - you'll get garbage in the masked region and it's not the model's fault. Keep the mask on the same canvas as the source frames.
  • Cost. It's a paid API call per edit, and iteration is the trap: fine-tuning what goes in the box means paying for the box each time. Batch your prompt ideas, then spend.
CategoryAdForge/Video Generation

Inputs (19)

NameTypeDefaultDescription
promptSTRINGThe text prompt used to guide video generation.
videooptVIDEOThe video to process.
video_gcs_urioptSTRINGNo documentation available
mask_imageoptIMAGEThe mask defining the area of interest.
mask_image_gcs_urioptSTRINGNo documentation available
negative_promptoptSTRINGOptional. A text string that describes anything you want to discourage the model from generating.
output_gcs_urioptSTRINGNone/videos/video-insert-content-20260720-202149.mp4GCS URI where the generated videos will be stored, in the format 'gs://BUCKET_NAME/SUBDIRECTORY'.
modeloptCOMBOveo-3.1-generate-preview7 options: veo-3.1-generate-preview, veo-3.1-fast-generate-preview, veo-3.0-generate-001, veo-3.0-fast-generate-001, veo-2.0-generate-001, veo-2.0-generate-exp, +1
aspect_ratiooptCOMBO16:9Optional. Specifies the aspect ratio of generated videos.
video_mime_typeoptCOMBOvideo/mp4Mime type of the input image or video, e.g., 'image/png' or 'video/mp4'.
mask_mime_typeoptCOMBOimage/pngMime type of the input image or video, e.g., 'image/png' or 'video/mp4'.
duration_secondsoptINT81–10
resolutionoptCOMBO1080p2 options: 1080p, 720p
fpsoptINT241–60
seedoptINT00–2147483647
number_of_videosoptINT11–4
enhance_promptoptBOOLEANtrue
generate_audiooptBOOLEANfalse
person_generationoptCOMBOallow_adult2 options: allow_adult, dont_allow

Outputs (2)

NameTypeDescription
videosVIDEO
video_path_listSTRING