ES Video Transfer
The node that carries your keyframes through the whole video
- source_video
- style_images
- source_mask
- result_video
- error_video
EbSynth is the old trick that still refuses to die, and this is the node that brings it into ComfyUI properly. You style a handful of frames however you want - img2img, a ControlNet pass, an upscale, or actual hand-painting - drop those frames in as keyframes, and EbSynth propagates the look to every other frame in the clip. No diffusion at inference time, no video model churning for minutes per clip, just fast, shockingly consistent style transfer. If you've ever spent an afternoon fighting temporal flicker with AnimateDiff or a video model, this is the antidote: the motion is whatever your source video already has, so the style warps with it instead of fighting it.
How it works
EbSynth (Jamriska, 2018) is patch-based example synthesis, not a neural network running per-frame. It matches small image patches between your source video and your stylized keyframe, then rebuilds each frame from those matched patches using a multi-scale pyramid - think of it as guided texture transfer rather than generation. The node's real job is feeding that engine good guides: an edge map (so structure doesn't smear), and RAFT optical flow so the style follows motion instead of just diffusing in place.
Two things the author (FuouM, who also wrote the Ezsynth Python library this pack wraps) fixed over the classic app: flow is computed frame-by-frame with correct time orientation, and "blending" runs a forward pass from one style frame and a reverse pass from the next, then merges them. That blending is what makes transitions between keyframes smooth - and also what makes long clips slow.
The inputs that actually matter
- source_video and style_images - both IMAGE batches. Load your clip with Video Helper Suite (the author built this to interface natively with it), style a few frames, feed both in.
- style_idxes - a string of absolute frame indices, underscore-separated.
0_30_60for three keyframes. This is the field people get wrong first: the count must matchstyle_images, or you get a "Style indices mismatch" error. - edge_method -
Classic(default, the balance),PST(good structure, less detail),PAGE(best detail, slow). Leave it on Classic until you're chasing quality. - flow_model -
sintelorkitti, both RAFT weights that ship with the pack. No download needed. - only_mode -
none(default) does the full forward+reverse blend;forwardorreverseskips half the work when a clip is taking forever. - source_mask (optional) plus do_mask / pre_mask / feather - for limiting the transfer to part of the frame. Keep
pre_maskoff unless you need it; it roughly doubles per-frame time. - The pile of weight floats (
style_weight,edge_weight,warp_weight,pos_weight) and the EbSynth params (uniformity,patch_size,pyramid_levels, …) - honestly, the default settings work for most cases. Tweakstyle_weightfirst.
Outputs: result_video (the styled frames) and error_video (a per-frame error map - genuinely useful for spotting which cuts are giving the engine trouble). Wire result_video into Video Helper Suite's save-video node.
Install
cd ComfyUI/custom_nodes
git clone --recurse-submodules https://github.com/FuouM/ComfyUI-EbSynth.git
pip install -r requirements.txt
The --recurse-submodules matters - Ezsynth is a git submodule and nothing works without it. ComfyUI Manager also has it if you search "ComfyUI-EbSynth". There's no install.py to run. Dependencies are modest: numpy, opencv-python, torch, torchvision, scipy, Pillow, and phycv (the physics-based edge detector). Cupy/cupyx are optional extras that make histogram blending ~100x faster.
Where people get burned
- Linux: the bundled binary is
ebsynth.dll- Windows only. On Linux you must buildebsynth.sofrom the Ezsynth library's build script, or every run dies in the ctypes loader. Windows is plug-and-play; macOS isn't supported at all. - Style index mismatch - the error tells you exactly how many style frames it found vs. the indices you wrote. Fix the string.
- Fast motion = smudging. Classic EbSynth weakness. Add more keyframes near the fast sections or nudge
style_weightup. - Cloned without submodules → import errors. Just re-clone properly.
Inputs (24)
| Name | Type | Default | Description |
|---|---|---|---|
| source_video | IMAGE | — | |
| style_images | IMAGE | — | |
| style_idxes | STRING | 0 | — |
| edge_method | COMBO | Classic | 3 options: PAGE, PST, Classic |
| flow_model | COMBO | sintel | 2 options: sintel, kitti |
| only_mode | COMBO | none | 3 options: forward, reverse, none |
| do_mask | BOOLEAN | false | — |
| pre_mask | BOOLEAN | false | — |
| feather | INT | 5 | — |
| style_weight | FLOAT | 6.00 | — |
| edge_weight | FLOAT | 1.00 | — |
| warp_weight | FLOAT | 0.50 | — |
| pos_weight | FLOAT | 2.00 | — |
| uniformity | FLOAT | 3500.00500–15000 | — |
| patch_size | INT | 5 | — |
| pyramid_levels | INT | 6 | — |
| search_vote_iters | INT | 12 | — |
| patch_match_iters | INT | 6 | — |
| extra_pass_3x3 | BOOLEAN | true | — |
| use_gpu_hist_blend | BOOLEAN | false | — |
| use_lsqr | BOOLEAN | true | — |
| use_poisson_cupy | BOOLEAN | false | — |
| poisson_maxiter | INT | 0 | — |
| source_maskopt | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| result_video | IMAGE | — |
| error_video | IMAGE | — |