Zura · Verify Complete VHS Video
Trust the file, not the graph settings
- filenames
- completed_video
Video Helper Suite's combine node hands out a tuple of filenames, and most graphs just pass it along. That's fine right up until you're upscaling a 120-frame clip one frame at a time and you want to know that all 120 frames actually made it, at the resolution you asked for, at 24 fps, before you mux a soundtrack onto it. GenjVHSVideoFromFilenames ("Zura · Verify Complete VHS Video") turns that tuple into a VIDEO - but only after inspecting the encoded file itself.
The pack's comment on it is the design brief: "Read the actual encoded file; never infer delivery from graph settings." A graph can say 1920 wide. Only the file knows.
What it checks
Feed it filenames (VHS_FILENAMES, from VHS_VideoCombine) and it will:
- Wait for the combine to close. VHS's output tuple is
(save_output, paths). If that shape isn't complete - the file is still being written - the node returns anExecutionBlocker, which quietly skips everything downstream instead of throwing. In a batched upscale that's the difference between a clean skip and a wall of red. - Constrain the path. The file has to be inside your ComfyUI output directory, in the exact folder the prefix points to, and named
<prefix>_%05d.mp4. A prefix that tries to escape the output root (../) or a returned path from somewhere else raises rather than being trusted. This is_video_from_vhs, and it's the sort of path validation that most nodes skip. - Refuse ambiguity. Exactly one completed delivery file, or you get
Video Helper Suite returned more than one completed delivery file. - Open it with PyAV and count. One video stream, actual decoded frame count, actual raster, actual average frame rate, actual audio track count - the H3 enhancement route expects zero audio tracks at this stage. Any mismatch is a specific error:
The H3 delivery has an unexpected number of frames.,...unexpected raster width., and so on.
Inputs are filenames, filename_prefix (default genj/studio_h3_enhance), expected_frames (5–120), expected_width and expected_height (2–7680 each). One output: completed_video (VIDEO).
Why the frame cap is 120
Because this node is built for the H3 Enhanced 1080p path, where a take is up to five seconds at 24 fps. The 120-frame ceiling is a guard rail for that stage, not a general-purpose limit. If you want it as a general "verify my VHS output" node, remember you'll have to raise the expected frame count and stay under the input's maximum - 120 frames is the hard stop in the schema.
Install and prerequisites
ComfyUI Manager → search Zura Nodes → install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
python -m pip install -r ComfyUI/custom_nodes/ComfyUI_zura_nodes/requirements.txt
You need ComfyUI-VideoHelperSuite (it produces VHS_FILENAMES), and for the enhancement stage it's meant for you also need an upscale model - the pack uses 2xNomosUni_esrgan_multijpg.pth in models/upscale_models/, which its Setup_H3_Enhancement_Windows.cmd helper installs. The pack lists the full set of native nodes the stage needs (VHS_BatchManager, VHS_LoadVideoPath, VHS_VideoCombine, UpscaleModelLoader, ImageUpscaleWithModel, ImageScale), and if any are missing you get a message naming them rather than a mysterious failure.
Gotchas
- Prefix mismatch is the classic. The node derives the expected filename from
filename_prefixand demands an exact<prefix>_<5 digits>.mp4. If you change the prefix on the VHS node and not here, nothing is found. - Counting frames is not free. It fully decodes the file to count frames, so this node reads the whole clip. On a long delivery that's real seconds; on the 120-frame case it's meant for, it's nothing.
ExecutionBlockerlooks like a silent no-op. If downstream nodes simply don't run, the combine hasn't finished. That's the intended behaviour - a batched graph shouldn't error because one file is still closing.- It will not save the file for you. It returns a
VIDEO; the soundtrack muxing and the numbered take naming belong toGenjRestoreSoundtrack.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| filenames | VHS_FILENAMES | — | |
| filename_prefix | STRING | genj/studio_h3_enhance | — |
| expected_frames | INT | 1205–120 | — |
| expected_width | INT | 10802–7680 | — |
| expected_height | INT | 19202–7680 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| completed_video | VIDEO | — |