SF VertexAI Veo 3.1 Image to Video
Animate a still into a Veo 3.1 clip, right inside a ComfyUI graph
- image
- last_frame
- video
Veo 3.1 is the state of the art in "I can't believe this is generated" video, and it is firmly closed - you're not running it on your 3090. SF VertexAI Veo 3.1 Image to Video is the practical middle path: you feed it a first frame as an actual ComfyUI IMAGE, describe the motion, and it hands back a generated clip. It runs through Google's Vertex AI, so the cost lands on your GCP billing rather than your GPU, and the workflow stays in ComfyUI instead of becoming a browser tab.
How it works
The node sends your image and prompt to the veo-3.1-generate-001 model through the google-genai SDK. It uploads your first frame as a temporary file, starts a long-running generation operation, and polls until it completes - an 8-second 1080p clip is a real generation, so this is not a fast node; budget minutes, not seconds. When it's done, if ComfyUI's video support is available it wraps the result in a VideoFromFile object so you get a previewable VIDEO in your graph. Without that, it falls back to returning a file path string and you'll need a video-loading node to display it.
Two things are easy to miss. Veo 3.1's headline trick is native audio - it generates sound effects and speech synced to the video, which no open model matches - but generate_audio defaults to false. Turn it on; it's the whole point of this model tier. And enhance_prompt (the prompt rewriter) defaults to true, so your prompt gets polished before the model sees it.
The inputs that matter
- project_id and location -
us-central1for Veo. - image - your first frame, wired from any node that outputs
IMAGE. This is the first frame, so frame it accordingly. - prompt - describe the motion and content. "Camera slowly pushes in, the woman turns toward the window" beats "make it move."
- aspect_ratio (16:9 or 9:16), resolution (720p or 1080p), duration_seconds (4, 6, or 8).
- Optional but useful: last_frame (an
IMAGEto transition toward), output_gcs_uri (save to a bucket and return the URI instead of bytes - handy for big renders), person_generation, and seed.
Installing it
It's in the SF ComfyUI Nodes pack from Stillfront. ComfyUI Manager → "SF ComfyUI Nodes" → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Stillfront/comfyui-sf-nodes.git
cd comfyui-sf-nodes
pip install -r requirements.txt
You need google-genai and google-cloud-storage (both in the pack's requirements), a GCP project with Vertex AI enabled and billing on, and Application Default Credentials:
gcloud auth application-default login
Common issues
Auth and billing are the usual first wall - "no Application Default Credentials" means the login step, "permission denied" usually means the Vertex AI API isn't enabled on the project. The subtler trap is the missing preview: if the output comes back as a string path instead of a video preview, install ComfyUI's video support (the VideoHelperSuite ecosystem) so the node can return a proper VIDEO object. And manage expectations on turnaround - this is a paid, minutes-per-clip generation. It's ideal for hero shots and reference motion, not for iterating fifty takes in an afternoon.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| project_id | STRING | Google Cloud project ID | |
| location | STRING | us-central1 | Google Cloud region (e.g., us-central1) |
| image | IMAGE | First frame image for the video | |
| prompt | STRING | Text description of the video motion/content | |
| model | COMBO | veo-3.1-generate-001 | Veo 3.1 model variant |
| aspect_ratio | COMBO | 16:9 | Video aspect ratio |
| resolution | COMBO | 1080p | Video resolution |
| duration_seconds | COMBO | 8 | Video duration in seconds |
| last_frameopt | IMAGE | Optional last frame for video transition effect | |
| output_gcs_uriopt | STRING | GCS URI to save output video (e.g., gs://bucket/path/). Leave empty for direct return. | |
| enhance_promptopt | BOOLEAN | true | Use prompt rewriter to enhance the prompt |
| generate_audioopt | BOOLEAN | false | Generate audio for the video |
| person_generationopt | COMBO | allow_adult | Person generation policy |
| seedopt | INT | 11692968740–4294967295 | Random seed for reproducible results |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |