MiniMax H3 Disk Video Stream
Build a long video without hoarding every frame in RAM
- images
- audio
- session
- manifest_path
- video_path
- total_frames
The problem this actually solves
MiniMax H3 generates short clips - a handful of seconds at a time - with picture and audio produced jointly, which is the whole reason it's interesting. Long video is therefore a chaining problem: generate a segment, keep its tail as context, generate the next one that continues from it. Same fight people had with Wan 2.2's 81-frame window: once you're past the native context, everything becomes a restitching job.
The stock MiniMax H3 Long Video Stitcher does that job in memory. It hands you one IMAGE batch that grows with every clip you feed it. A two-minute sequence at 24fps is roughly 2,900 frames of float32 - and the next sampling pass needs VRAM on top of that. Around clip five or six your machine starts swapping and "long video" turns into a machine-watching hobby.
This node sidesteps it. Instead of accumulating frames, it writes each decoded segment to disk as it's produced and only assembles the MP4 at the end. Peak memory stays roughly "one clip", no matter how long the final video gets.
How it works
Each time the node executes, it takes the decoded images (and optionally audio) for the current clip, trims the leading overlap frames off both, and encodes that segment to an MKV on disk using FFmpeg - libx264, yuv420p, audio as PCM. Frames are piped into FFmpeg in batches of eight so the conversion itself doesn't spike memory. The segment filename is appended to a manifest.json in output/minimax_h3_bins/<project_name>/.streams/<stream_name>/, along with its frame count and the stream's geometry (resolution, fps, sample rate, channels).
When you turn on export, the node writes a concat.txt from that manifest - each clip with an explicit duration - and runs FFmpeg's concat demuxer with -c:v copy (no re-encode of the video) and AAC at 192k for the audio. The PCM intermediates are deliberate: encoding every join to AAC and back would stack up encoder delay at each seam.
Important framing: this is a hard-cut assembler - no brightness matching, no crossfade. Its own docstring points you at the IMAGE stitcher for seam effects. Disk mode buys memory and costs seam polish.
The inputs that matter
Three of them are the whole configuration:
project_name- the bin folder. Keep it constant for a given piece of work.stream_name- defaults tolong_video. Letters, digits, underscores and hyphens only (the code validates this and rejects spaces), and it must stay identical across runs of the same video.export-Falsewhile you're appending,Truefor the final assembly run.
The rest: trim_frames chops the leading overlap. Leave it at 0 if you connect session and the node will pull the rolling-context length off the session automatically. fps must match what you actually decoded. images and audio are the current clip - not the accumulated timeline, just this segment. session is optional and only there for that automatic trim.
Outputs are manifest_path, video_path (empty until an export run succeeds) and total_frames, the running total across appended segments.
Install
The pack installs like any other; ComfyUI Manager → search ComfyUI-MiniMaxH3-PrefixStream, or:
cd ComfyUI/custom_nodes
git clone https://github.com/knoic/ComfyUI-MiniMaxH3-PrefixStream.git
cd ComfyUI-MiniMaxH3-PrefixStream
pip install -r requirements.txt
Then restart ComfyUI - the nodes land under MiniMaxH3/PrefixStream. The Python dependencies are light (torch, safetensors, pillow - no PyAV, no moviepy), because all video work shells out to a system FFmpeg. FFmpeg must be on PATH, and that's a real requirement here rather than a nicety: with no ffmpeg binary the encode returns failure and the node raises Segment encoding failed; stream manifest was not changed.
Workflow rules worth internalizing
The node writes to disk on every execution, and it deliberately opts out of ComfyUI's cache by returning NaN from IS_CHANGED - the standard "always run me" idiom. That's what makes appending work, and it's also the trap: queue the same clip twice and you get two segments.
- Keep
export=Falsewhile generating. Every run withimagesconnected appends another clip. - To assemble without appending again, build a node with the same
project_nameandstream_name, disconnectimages/audio, and setexport=True. - New video, new
stream_name. Reusing one continues the old stream.
Where people get burned
Geometry has to stay fixed for the whole stream. Resolution (and it must be even - H.264 needs it), fps, sample rate and channel count all have to match, and audio has to be present in every segment or none, otherwise you get a clear "must remain consistent" error instead of a subtly broken file. If you connect session and you already ran the clip through Trim Prefix upstream, you'll trim the same overlap twice - leave trim_frames at 0 and don't connect session in that case.
Last one: the project lock that keeps the manifest writes atomic is per ComfyUI process. Two ComfyUI instances writing the same project folder is not supported.
Reach for this when the sequence is getting long enough that memory is the limit, and switch to the stitcher when the seams are the limit.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| project_name | STRING | Default_Project | — |
| stream_name | STRING | long_video | — |
| trim_frames | INT | 00–192 | — |
| fps | FLOAT | 24.001–120 | — |
| export | BOOLEAN | false | — |
| imagesopt | IMAGE | — | |
| audioopt | AUDIO | — | |
| sessionopt | MINIMAX_SESSION | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| manifest_path | STRING | — |
| video_path | STRING | — |
| total_frames | INT | — |