Stitch
Turn a folder of short AI video generations into one continuous film.
What it is
Stitch is a Windows app for the last mile of AI video work: you have twenty, forty, a hundred short clips out of ComfyUI, and you need them to play as one piece rather than as a list of clips.
That last mile is mostly three problems, and Stitch is built around them.
The repeated frame. If you generate by feeding the last frame of one clip into the next, that frame exists twice. Played back it reads as a hitch at every single join — the most recognisable tell of a stitched sequence. Stitch compares the frames either side of each join, finds the duplicates and drops them.
Colour drift. Separate generations don't land on the same exposure or colour balance, and over a long sequence the drift compounds until the film visibly changes temperature. Stitch measures every clip and rescales it so the whole thing sits on one look. On a test set drifting from dark to blown out, this pulled the spread in mean brightness from 106 down to 5.
The join itself. Sometimes the frames genuinely continue and a hard cut is invisible. Sometimes they nearly continue, and a motion-tracked morph carries you across. Sometimes they don't relate at all and you want a dissolve. Stitch looks at each join and picks; you overrule it where you disagree.
Underneath, everything is FFmpeg. There is no timeline scrubbing, no effects rack, no node graph. It does one job.
Also in the box
Thirty picture transitions, including an optical-flow morph that generates in-between frames by tracking motion from one clip into the next.
Sound joins set independently of the picture — the image can dissolve for two seconds while the sound cuts, or the other way round.
Frame-rate and resolution normalisation, with optional motion interpolation.
Deflicker, denoise, sharpen, and a unified grain pass that hides texture differences between generations better than almost anything else.
Music bed with fades.
Export presets from YouTube to ProRes to vertical, plus hardware encoding.
Per-join preview that renders only the few seconds around the join, so tuning is a second or two rather than a full export.
What it isn't
Not a general video editor. No multi-track timeline, no keyframes, no titles, no colour wheels. If you need those, cut in a real NLE — Stitch is for getting a pile of generations into one clean piece first.
Requirements
Windows 10 or 11, 64-bit.
Python 3.10 or newer — from python.org. Tick "Add python.exe to PATH" during the install.
FFmpeg — Stitch will fetch it for you on first run if you haven't got it.
Disk space for working files. Stitch caches prepared clips in
%TEMP%; budget roughly the size of your source footage again, and clear it from the Help menu when you're done.
A GPU isn't required. If your FFmpeg build has NVENC, Quick Sync or AMF, Stitch will offer it for the final encode.
Installing
Unzip Stitch wherever you like.
Double-click
setup.bat. It builds a private Python environment in.venvalongside the app and installs the two dependencies. About a minute, once.Double-click
Stitch.bat.
Nothing is written outside the app's own folder and %TEMP% — your projects and exports, of course, go wherever you point them. To uninstall: Help → Clear working cache, then delete the folder.
If FFmpeg isn't on your PATH, Stitch says so on first launch and offers to download a build for you — one click, roughly 80 MB, lands in bin\ next to the app. If you already have one, choose I have it — locate… and point at the folder holding ffmpeg.exe and ffprobe.exe. Stitch also checks the usual places on its own, including the copy that ships with Shutter Encoder.
If the app doesn't start, run Stitch (console).bat instead. It keeps the console window open so you can read the error.
Optional: a standalone .exe
Run build_exe.bat once and you get dist\Stitch\Stitch.exe, which runs on machines without Python. Copy that folder anywhere. To bundle FFmpeg with it, drop ffmpeg.exe and ffprobe.exe into dist\Stitch\bin\.
Quick start
Four steps gets you a finished film.
Add folder (Ctrl+Shift+O) — point it at your ComfyUI output directory. Clips arrive in natural filename order, so
clip_2lands beforeclip_10rather than after it.Auto-fix joins (Ctrl+R) — the button that does the work. It removes repeated frames, chooses a transition for each join, and measures every clip's colour.
Preview join (Ctrl+P) — check one or two. Only the seconds around the join get rendered, so it comes straight back.
Export (Ctrl+Enter).
Everything below is refinement.
The interface
The window has four areas. Preview player top left, settings tabs top right, filmstrip timeline across the middle, joins table at the bottom. The status line along the base always shows clip count, running time, output size and frame rate.
The timeline
Your clips, left to right, in playback order.
Drag a thumbnail to reorder.
Drop files or a whole folder onto it to add more.
Double-click a clip to play the original in the preview pane.
Ctrl+E disables a clip without removing it — useful for auditioning a cut. It greys out and drops out of the film, and Ctrl+E again brings it back.
Ctrl+← and Ctrl+→ nudge the selection along.
Sort by name re-sorts everything into natural filename order if you've lost track.
Reverse clip order (Timeline menu) flips the whole sequence.
Make it loop (Timeline menu) appends a mirrored copy of the sequence, so the film runs forward then back and ends exactly where it started.
Hover a thumbnail for its resolution, frame rate, duration and codec.
The joins table
One row per join, and this is where the character of the film gets decided.
Each row is read as clip → next clip, and has its own Picture transition and length, its own Sound join and length, a Dup. frames count, a Lock and a Preview button.
Use the Set every join bar above the table to push one setting onto the lot. Tick Lock on a join you've already dialled in and both "Apply to all" and "Auto-fix" will step around it.
Dup. frames
The number of frames trimmed off the start of the next clip. Chained generations repeat one frame at every join; this is what removes it. Auto-fix fills these in, and you can override any of them by hand — set it to 2 or 3 if a join still stutters, or back to 0 if it's cutting into motion you wanted.
Picture transitions
Thirty of them, but four categories matter:
TransitionWhen to use itCut (hard)The frames already continue. Invisible, costs nothing, and what auto-fix picks when the last and first frames are near-identical.Morph (optical flow)The clips are close but not identical. Stitch generates in-between frames by tracking motion from the outgoing frame into the incoming one, so the join reads as movement rather than as a dissolve. The best tool for chained generations that drifted slightly.Crossfade, Dissolve, Blur dissolve, Luma distance, Desaturate throughThe clips don't line up. Reliable, unobtrusive, and the right answer more often than people expect.Dips, wipes, slides, circles, squeezes, zoomDeliberate scene changes, when you want the join to show.
Morph and crossfade both carve their length out of the neighbouring clips, so changing a transition never changes the film's total runtime.
Morph works well when the two frames are already similar — force it onto an unrelated cut and you'll get smearing. Auto-fix only chooses it where it fits.
Sound joins
The Sound column is independent of the picture. It has its own length too; leave that on follow to reuse the picture length, or type your own.
SoundWhat happensFollow the pictureCrossfades under a dissolve, cuts under a cut or morph. The default.Cut (hard)The sound switches instantly, wherever the picture happens to be. Under a two-second dissolve the switch lands halfway through it.CrossfadeBoth clips play together and cross over, on its own clock.Dip to silenceOutgoing sound fades away, incoming fades up. Good over a change of scene, and the one option that never needs spare material.
A real crossfade needs sound from both clips playing at once. A picture dissolve supplies that overlap for free; a cut or a morph only has whatever the dedupe trim or the morph carve took out of view. When a join hasn't got enough, the row is flagged ⚠ and the tooltip tells you what happened instead — shortened, or fell back to a dip. Picture and sound always come out the same length; Stitch will tell you it compromised rather than quietly drift.
Every hard sound join gets an 8 ms micro-fade, so butt joins can't click.
Clip tab
Properties of whichever clip is selected in the timeline.
Trim from start / end, in seconds, with Trim 1 frame off head/tail buttons for frame-accurate nudging.
Speed, 0.1× to 8×. Audio is pitch-corrected to match.
Play backwards.
Manual look — brightness, contrast, saturation and gamma, applied after the automatic colour match. For when one clip needs a nudge the automatic pass didn't give it. Reset look puts it back.
A note field, if you're working through a long sequence and want to leave yourself markers.
Look and motion tab
Canvas. One size and frame rate for the whole film. Auto by default — largest clip, most common frame rate. Letterbox never crops and bars anything that doesn't fit; fill and crop trims the edges instead; stretch distorts.
Motion-interpolate when changing frame rate. If your clips were generated at different frame rates, this synthesises the in-between frames rather than duplicating them. Noticeably smoother, noticeably slower.
Colour continuity. The single most valuable setting for AI clips.
Match everything to the average — the safe default, and right for most sequences.
Match everything to the first clip, or to a chosen clip — when one generation has the look you want the rest to adopt.
Chain: each clip to the one before — tracks gradual drift better over long sequences, with a pull back toward the average so it can't run away. Best continuity, slightly less predictable.
Strength eases the correction off if it's overcooking.
Brightness only corrects exposure and leaves hue alone — useful when the clips are meant to differ in colour.
Remove frame-to-frame flicker. Evens out the luminance wobble some models produce.
Denoise / Sharpen / Unified grain. Grain is the one to try: a light pass over the finished film papers over the texture differences between separate generations remarkably well. Start around 15–20%.
Audio tab
Keep the audio that came with the clips. On by default. Silent clips get a silent track so nothing drifts. Switching it off greys out the Sound column and speeds the render up a little when everything's silent anyway.
Music bed. Any audio file, with level, fade in, fade out, and looping to length. The music is one continuous track laid over the finished film, so join settings don't touch it.
Export tab
Presets:
PresetFormatYouTube / general 1080pMP4, H.264, CRF 18YouTube / general 4KMP4, H.264, CRF 17High quality HEVCMP4, H.265, CRF 20TikTok / Reels / ShortsMP4, forced 1080×1920Instagram / squareMP4, forced 1080×1080Master — ProRes 422 HQMOV, 10-bitMaster — losslessMKV, FFV1Web previewMP4, small and fastAnimated GIFGIF
Encoder. Software by default, which gives the best quality per byte. NVIDIA, Intel and AMD hardware encoders appear here automatically if your FFmpeg build has them — much faster, slightly larger files.
Intermediates. Stitch prepares each clip once and caches it. Balanced is near-lossless and quick; High and Lossless trade disk space for fidelity if you're mastering. This costs space, not much time.
Copy without re-encoding. When every clip already matches and every join is a plain cut with nothing else changed, Stitch skips encoding entirely and copies the streams — instant, zero generation loss.
How it works
Two passes.
Pass one prepares each clip on its own — trim, speed, colour match, frame rate, canvas, flicker and detail work — and caches the result on disk, keyed on every setting that went into it. Change a transition and nothing needs re-preparing. This is why join previews come back in about a second and a second export is much faster than the first.
Pass two joins the prepared clips. Cuts concatenate, blends cross-fade, morphs get a short generated bridge clip.
The sound takes a different route. The picture is a chain where each join eats into its neighbours; sound riding those same filters would be stuck with the picture's transition length. So instead each clip's audio is trimmed, faded and placed at its own absolute position on the timeline, and the whole lot is summed. Total length matches the picture by construction, which is why picture and sound can never drift apart no matter what you do to the joins.
Working files live in %TEMP%\stitch_cache. Help → Clear working cache empties it; Open cache folder shows you where it is.
Keyboard shortcuts
Ctrl+OAdd clipsCtrl+Shift+OAdd folderDelRemove selected clipsCtrl+← / Ctrl+→Move selected clipsCtrl+EEnable / disable selected clipsCtrl+RAuto-fix joinsCtrl+PPreview the selected joinCtrl+Shift+PPreview the whole film (draft)Ctrl+EnterExportCtrl+SSave projectCtrl+Shift+LOpen projectCtrl+QQuit
Working with ComfyUI output
Chaining last frame → next generation? Leave auto-fix on. That workflow repeats exactly one frame per join, and it's the single most visible artefact in a stitched sequence.
Colour drift gets worse the longer the chain. Chain mode tracks it better over long sequences; average is safer for a handful of clips.
Save the project (Ctrl+S) before a long export. It's a small file you can drop next to your clips, and it reopens with every trim, join and setting intact.
Preview the film (Ctrl+Shift+P) before the real export. It reuses the cached intermediates and encodes cheaply, so it costs almost nothing after the first run.
Keep intermediates on Balanced unless you're mastering. Lossless is genuinely lossless, but the cache grows fast.
Supported formats
Video in: mp4, mov, mkv, webm, avi, m4v, mpg, mpeg, wmv, flv, ts, mts, m2ts, ogv, mxf, gif.
Audio in (for the music bed): mp3, wav, m4a, aac, flac, ogg, opus, wma.
Out: mp4, mov, mkv, gif, per the export preset.
Troubleshooting
"Could not find ffmpeg." Help → Set up FFmpeg → Download it for me, or point it at a folder containing ffmpeg.exe and ffprobe.exe.
A clip was skipped when I added it. Stitch reports why — usually a zero-length file or a codec FFmpeg can't read. Re-encode it and add it again.
The preview stays black. Qt's video backend can be fussy on some Windows setups. Use Open in player to check the file in your usual media player; the export itself is unaffected.
A join still stutters after auto-fix. Raise that row's Dup. frames to 2 or 3. Some workflows repeat more than one frame.
Export failed with a filter error. The message includes FFmpeg's own output. The usual cause is a transition longer than one of the clips it sits between — shorten it.
A sound crossfade came out as a dip. There wasn't enough spare audio either side of that join. Give the picture a dissolve, or let auto-fix trim a repeated frame, and the crossfade has something to work with. The tooltip on the row explains what happened.
Disk filling up. Help → Clear working cache.
Credits
Stitch is a front end. FFmpeg does the video work, Qt draws the window.
Uses libraries from the FFmpeg project — https://ffmpeg.org
Built with Qt for Python (PySide6) — https://www.qt.io/qt-for-python
Frame analysis with NumPy
FFmpeg is not distributed with Stitch; it is downloaded from the FFmpeg project's Windows builds on first run, or supplied by you. It carries its own licence.
Description
FAQ
Comments (5)
Windows only, I'm guessing? Looks potentially great but I wonder if I could get it to run with Linux...
Just some feedback, when the files are on a local disk it works great, when they are on a mapped drive, it lets you do everything up to generate, but when it starts building the output file with ffmpeg it crashes, no error etc just dies.
Thank you for sharing this useful tool. I’ve accumulated quite a few short clips recently, so this will be very helpful.
Great posts. Will be useful to get tips from you on character consistency. Mine are not quite there.
@sAInd_man
Thanks for checking out my posts!
For me, including a front view, a back view, and a close-up of the face in the reference images seems to help keep the character consistent when using REF2VA of MinimaxH3.
reference images exp:
