π SBS Video Combiner by SamSeen
From a stack of SBS frames to a real 3D video file
- images
- audio
- video_path
The last node in the SideBySide_Stereoscope video pipeline, and the one that finally produces a file you can drop into a VR headset. The middle of that flow is weirdly anticlimactic: the SBS node chews through your video one frame at a time and hands back a giant batch of side-by-side images. This node is where that batch stops being a pile of tensors and becomes an actual mp4, webm, or gif.
What it does
It's an output node. You feed it the batch of processed frames (images), it writes each one to a temporary PNG, then shells out to ffmpeg to mux them into a video at the frame rate you specify. Output lands in ComfyUI/output by default - or a temp directory if you flip save_output off - and it auto-increments the filename (SBS_Video_00001.mp4) so you never accidentally overwrite a previous render.
The encoding details are handled for you: mp4 gets libx264 with crf 23 and yuv420p, webm gets libvpx-vp9 at crf 30, and gif runs the palettegen/paletteuse two-pass trick that keeps it from looking like a posterized mess. It even pads odd-sized frames to even dimensions so encodes don't silently fail.
The audio part that matters
Since v2.1.8 the combiner takes an optional AUDIO input. Wire up the audio output of the pack's SBS Video Uploader and your source video's soundtrack rides along - extracted, trimmed to stay in sync with any frame skipping you did, and muxed with -shortest so the audio ends when the video does (AAC for mp4, libopus for webm). It's the difference between "3D video, silent" and something you can actually watch.
Inputs you'll actually touch
images- the frame batch. Usually straight out of the SBS node.frame_rate(1β120, default 30) - this is a FLOAT now, so 23.976 and 29.97 work. If you processed every Nth frame in the uploader, wire the uploader'starget_fpsoutput straight in; it's already adjusted for your frame skipping, and you'll get perfect sync instead of judder.format-mp4is the default and the right call for most headsets.webmif you want smaller/slower-encoding VP9,giffor a quick shareable preview.save_output- leave true unless you're just testing and don't want files piling up in output.audio- optional, from the Video Uploader.
The single output is video_path, a STRING with the saved file's location - handy to pipe somewhere or just confirm where it went.
Install and the ffmpeg gotcha
Same install as the whole pack:
cd ComfyUI/custom_nodes
git clone https://github.com/SamSeenX/ComfyUI_SSStereoscope.git
pip install -r ComfyUI_SSStereoscope/requirements.txt
# restart ComfyUI
or search "SideBySide_Stereoscope" in ComfyUI Manager. But this is the one node in the pack that genuinely needs ffmpeg. The README spells out the priority: it tries your system ffmpeg first, then falls back to the imageio-ffmpeg binary that ships with the pack's dependencies. If you hit RuntimeError: ffmpeg not found. Please install ffmpeg to use video functionality, the fallback failed - on Windows, install ffmpeg from ffmpeg.org and add it to your system PATH; that's the fix the author explicitly recommends.
Troubleshooting worth knowing
- "No images provided" - the batch is empty, which usually means the Video Uploader returned zero frames (check
frame_load_capandskip_first_framesrather than blaming this node). - No libx264 in your ffmpeg - common with conda/anaconda non-GPL builds. The node auto-detects and falls back to libopenh264, so you get a file either way.
- Audio missing - the source video simply had no audio track; the node logs a warning and proceeds silent.
- Odd resolutions - handled automatically with an even-dimension pad filter.
You could write this ffmpeg incantation yourself, and plenty of people do. But this keeps the whole video flow inside the graph, handles the boring edge cases, and pairs with the uploader's audio/fps outputs so nothing drifts out of sync. When I want to ship a SBS clip, it's the one I use.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | β | |
| frame_rate | FLOAT | 30.001β120 | β |
| filename_prefix | STRING | SBS_Video | β |
| format | COMBO | mp4 | 3 options: mp4, webm, gif |
| save_output | BOOLEAN | true | β |
| audioopt | AUDIO | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | β |