H3RelayEditWindow
Cutting your source clip into windows the model can swallow
- source
- previous
- source_audio
- source_window
- generated_history
- generated_history_audio
- source_window_audio
You have a 45-second clip you want to restage, and a model that thinks in 5-second chunks. Someone has to do the slicing, the padding, the audio bookkeeping and the "which frames does this window actually carry from the last one" arithmetic. That's H3RelayEditWindow, and it is deliberately boring.
It's an internal node: H3 Relay Windowed Edit · Character Swap generates one of these per window when it expands into a real graph. You'll meet it in the graph view, or in an error, and nowhere else.
What comes out of it
Four outputs, and the naming is doing real work:
source_window- the slice of your footage this window is being conditioned against, up towindow_frameslong, padded at the tail by repeating the last frame if the clip ends mid-window. This is the<Video 1>reference in the edit prompt.generated_history- the frames the model itself produced earlier, from the previous window's state. Not your source pixels. When there's no previous window this is just the window's own first frame, which is the honest answer: there's nothing generated yet.generated_history_audio- the audio prefix matching that stretch, sliced at 24 fps sample offsets so it lines up with the picture.source_window_audio- the same slice taken from your original audio, so you can put the real soundtrack back at the end instead of the model's re-synthesised sound.
The distinction between the source window and the generated history is the whole point of the node. A character swap keeps the source person's motion and framing as the driving reference but does not pin the source person's pixels as a guide - that's the difference between "restage this" and the removal workflow's "erase this". Feeding generated history forward is what keeps identity stable across the seam; feeding source frames as history would fight the edit.
The inputs
source (your prepared frames), start (this window's source-frame index) and the two grid sizes, window_frames and history_frames. Optionally previous - the running state from the window before - and source_audio.
Both sizes are validated: window_frames must be a real H3 size (17n+5: 22, 39, 56 … 362), history_frames must be 0, 1 or 17k+1 (18, 35, 52 …), and history must be strictly smaller than the window. The parent node sets both; hand-wiring this node with a made-up number gets you an immediate error rather than a mysterious 20-minute render.
One worth-understanding rule: with history enabled, a continuation window can't start earlier in the source than history - 1. At 18, start must be at least 17. Otherwise there aren't enough generated frames behind the window to supply the history, and the node says so - Missing generated history at the exact source boundary - instead of passing a short prefix down the chain.
The plan is the interesting part
With window_frames=124 and history_frames=18 on a 144-frame (six-second) source, window one covers source frames 0–123 with no history. Window two rounds the remaining 21 frames up to a 22-frame target, carries history from frame 106 to 123, and pads one tail frame. Its Ref2VA allocation is 39 frames - a 22-frame target plus the 17 frame history - and the padding and repeated boundary are trimmed during assembly, so you get exactly 144 frames back.
That adaptive shrinking is why a short tail doesn't produce a stretched, resampled last window. If you want to see it spelled out, the parent node also emits a window_plan string describing every range, target size, padding count and discarded boundary.
Installing
Comes with the pack:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/h3-relay.git
or Manager → search H3 Relay. Needs ComfyUI 0.32.0+, FFmpeg on PATH, MiniMax H3 weights per the pack's MODELS.md, and no pip packages.
Common snags
- 24 fps only. The parent node rejects anything else up front. Resample before you load the clip - a 30 fps source run through this graph gives you garbage audio alignment.
- Dimensions must divide by 32. That's H3's grid, not an H3 Relay preference.
H3 Prepare Video · Auto Size & Lengthwill do the scale-and-crop for you. - Tail padding is expected, not a bug. If the summary shows repeated final frames, that's the H3 grid being filled;
source_framesfrom the preparation node tells the parent how much to actually keep. - Wrong audio at the end. If your output sounds like the model's invented soundtrack rather than your original, you connected the wrong audio output. Use
source_window_audio→ final Create Video, not the generated history audio.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| source | IMAGE | — | |
| start | INT | — | |
| window_frames | INT | — | |
| history_frames | INT | — | |
| previousopt | H3_REMOVAL_STATE | — | |
| source_audioopt | AUDIO | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| source_window | IMAGE | — |
| generated_history | IMAGE | — |
| generated_history_audio | AUDIO | — |
| source_window_audio | AUDIO | — |