VeniceWAN Image-to-Video
One still in, one clip out (with an optional landing frame)
- image
- last_frame
- VIDEO
I2V is how most people actually use video models - you already have a still you like, and you want it to move. This node does that with Venice.ai's hosted Wan 3.0 instead of a checkpoint on your disk. No downloads, no VRAM, but a key, a meter, and your frame going to a server.
Why it's the one worth reaching for
The strongest argument for image-to-video in general is that the still does the hard part. A good starting image locks composition, face and lighting; the model only supplies motion. That's why "I2V from a strong still" is the default workflow in the local Wan world, and it holds here - except that you can make the still locally with whatever you already run and let Venice handle only the part you can't afford to run.
The second argument is the last frame. You get one optional socket for an ending image, which turns the node into a crude interpolation tool: two stills and a duration, and the model fills the middle. When it works, it's the cheapest storyboard-to-clip trick in ComfyUI. When it doesn't, see the trap below.
How the mechanism works
Same shape as the text-to-video node in this pack, with one extra job. On startup the pack pulls Venice's video model list and keeps the wan-3-0-* IDs ending in -image-to-video, so the combo only offers I2V-capable models - and the controls (duration, resolution, aspect ratio, audio toggle) are the constraints Venice reports for whichever one you picked.
Your frame is read from the socket, converted to a single PNG, base64-encoded into a data URL and inlined in the queue request. There's no upload host and no separate transfer step; the frame rides along in the POST that starts the job. Then it polls, streams the mp4 into ComfyUI/output/VeniceWAN/, and returns it as a native VIDEO you can feed straight into Save Video.
Inputs that matter
image - one starting frame. Shown as first_frame in the UI, and required; without it the node refuses before spending anything.
last_frame - optional, sent as Venice's end_image_url. Read the author's own tooltip before you build a workflow around it: it requires support from the selected Venice model and it is not live-verified across every Wan 3 variant. The node will happily send it regardless of what the model supports, so if your clip just ends wherever it wants, that's the provider, not your wiring.
model - the combo everything else hides inside. Choosing it is choosing your duration and resolution, which is the real cost dial on a metered API.
generation_id and resume_job - a cache nonce and a rescue rope. generation_id is not a seed and never reaches Venice, so a clip you loved is not reproducible, only rerollable. resume_job takes the 32-character token the console prints when a job starts, and fetches that job without a fresh charge - the correct move when ComfyUI crashes sixty seconds into a two-minute render.
Output is one VIDEO socket.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/nakedfighter3d/ComfyUI-VeniceWAN.git
python -m pip install -r ComfyUI-VeniceWAN/requirements.txt
aiohttp, numpy, Pillow - nothing exotic, no model files. Run pip with ComfyUI's Python, restart, then Settings → VeniceWAN, paste your key, Save & connect. (VENICE_API_KEY in the environment overrides the settings file; while it's set, the UI won't save a key.)
It's written against ComfyUI's V3 node API and needs native VIDEO support, so an old build won't register it at all.
The traps
Batches. Each image socket wants exactly one RGB or RGBA image. Load Image is fine. A loader that emits a stack of video frames is not - that's an immediate "IMAGE socket requires exactly one image, not a batch" error.
Wrong model for the node. I2V runs on its own model IDs. Drop a -text-to-video ID into this node and you get "selected model is unavailable for this node"; the fix is to pick a model in the node's own combo, not to fight it.
Stale controls after switching models. Duration and resolution reset because you're now looking at a different model's options. If a value you had set is rejected, restart ComfyUI to refresh the catalog rather than guessing.
Two frames, one size cap. Both frames are base64'd into the same request and the pack checks the combined size before sending. Full-resolution PNGs can trip the ~100 MiB ceiling - and an oversized pair fails before the job is queued, which is at least the cheap way to fail.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | 1 options: [object Object] | |
| image | IMAGE | One starting frame. Existing image connections remain compatible. | |
| generation_id | INT | 00–18446744073709550000 | Local cache nonce. Increment to generate again; never sent as a seed. |
| resume_job | STRING | Local job token from the console. Retrieves that existing job and ignores generation inputs. | |
| last_frameopt | IMAGE | Optional ending frame, sent as Venice end_image_url. Requires support from the selected Venice model; not live-verified for every Wan 3 variant. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| VIDEO | VIDEO | — |