Nodes/ComfyUI_zura_nodes/Zura · Verify Complete VHS Video
ComfyUI Node

Zura · Verify Complete VHS Video

Trust the file, not the graph settings

By ZURAVFX·Created about a month ago·Updated a day ago· 2
Zura · Verify Complete VHS Video
  • filenames
  • completed_video
◄filename_prefixgenj/studio_h3_enhance►
◄expected_frames120►
◄expected_width1080►
◄expected_height1920►

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 an ExecutionBlocker, 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_prefix and 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.
  • ExecutionBlocker looks 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 to GenjRestoreSoundtrack.
CategoryZura/Artist Studio

Inputs (5)

NameTypeDefaultDescription
filenamesVHS_FILENAMES—
filename_prefixSTRINGgenj/studio_h3_enhance—
expected_framesINT1205–120—
expected_widthINT10802–7680—
expected_heightINT19202–7680—

Outputs (1)

NameTypeDescription
completed_videoVIDEO—