Video Captioner (Advanced)
Native-video captioning when your backend can, frames when it can't
- config
- video
- caption
- info
Video Captioner (Advanced) is the full-control version of the video captioning workflow, and it's where the pack's smartest mechanism lives: it decides how the VLM sees your video based on what the backend actually supports, instead of assuming. The simple Video Captioner sets sensible defaults; this node exposes every knob, and it's worth understanding even if you never touch it, because the info output tells you what path your video actually took.
The video_mode input is the headline feature:
auto- the default. The node checks llama-server's/propsendpoint. If the backend explicitly advertises typed native video (input_video), it sends the video natively; otherwise it falls back to sampled frames. Missing or incomplete capability metadata is treated as unknown, and unknown defaults to sampling - conservative by design.native_video- force native video. Errors if the backend reports no support; if support is unknown, it attempts it anyway and can fail.sampled_frames- force the sampling path: the clip is decoded into timestamped JPEG frames and sent as an image sequence. Works with any vision-capable model.
Because native video depends on both the model/projector and your llama.cpp build, auto mode quietly saves you from a whole class of "why is my video request rejected" confusion - and when it does fall back, the info output reports native_fallback=<reason>.
When sampling, two inputs control the extraction. sampling_mode is uniform (spread sample_frames evenly across the clip) or fixed_fps (grab at sample_fps, up to max_frames). Defaults: 12 samples at 2 fps, capped at 24 frames. The sample settings matter more than they look: too few frames and the model can't see the action, too many and you blow the token budget. For file-backed clips the extraction uses PyAV seek sampling, so memory tracks the sampled frames, not the total clip length - a real virtue on long source footage.
The rest is the captioner panel you'd expect: instruction, caption_style (same six options as the image captioner plus video-aware wording - no invented audio or dialogue), max_tokens, temperature, seed, and optional reasoning_effort, system_prompt_override, caption_prefix, banned_phrases, image_max_edge, jpeg_quality. Note the two outputs: caption and info. info is genuinely useful - it reports mode, fps, duration, frame count, how many frames were sampled, their timestamps, and the fallback reason if any. When a caption comes out wrong, that string is where you start diagnosing.
Same prerequisites as every captioner: the config from Local AI Model (Advanced) must have a matching mmproj projector, or the node errors before any video processing. And the "no audio/dialogue inference" rule holds here too - these captions describe what's visible, period.
Install is the pack standard: ComfyUI Manager, search WepeNerd, or git clone https://github.com/WepeNerd/ComfyUI-WepeNerd.git into custom_nodes, pip install -r requirements.txt (the av dependency is real and used), restart. llama-server on PATH is the usual hard requirement.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| config | GGUF_LLM_CONFIG | — | |
| video | VIDEO | — | |
| instruction | STRING | Describe this video accurately, including subjects, actions, camera motion, setting, and meaningful changes over time. | — |
| caption_style | COMBO | 5 options: dataset_natural, detailed_visual, short, motion_camera, custom | |
| video_mode | COMBO | 3 options: auto, native_video, sampled_frames | |
| sampling_mode | COMBO | 2 options: uniform, fixed_fps | |
| sample_frames | INT | 122–96 | — |
| sample_fps | FLOAT | 2.000.01–120 | — |
| max_frames | INT | 242–96 | — |
| max_tokens | INT | 5121–4096 | — |
| temperature | FLOAT | 0.200–2 | — |
| seed | INT | 00–18446744073709550000 | — |
| system_prompt_overrideopt | STRING | — | |
| caption_prefixopt | STRING | — | |
| banned_phrasesopt | STRING | — | |
| image_max_edgeopt | INT | 102464–4096 | — |
| jpeg_qualityopt | INT | 901–100 | — |
| reasoning_effortopt | COMBO | none | 5 options: default, none, low, medium, high |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| caption | STRING | — |
| info | STRING | — |