File size: 6,215 Bytes
e488ce7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | # MAI video tools (alpha)
Three nodes and one widget that remove drudgery around renders without taking
any decision away from you. None of them runs a model.
## MAI Video Out (file + sidecars + draft preview)
Save Video with the record beside it. Frames (+ audio) go through ComfyUI's
own encoder (h264 / av1, CRF), exactly like Create Video + Save Video; the
extras are each off unless wired or toggled:
- `hold_map` -> `<prefix>_00001_.holdmap.json`: the clock that produced these
frames. H3 Load Hold Map and the deck's hold-map staircase read it.
- `write_meta` -> `<prefix>_00001_.meta.json`: seeds, models, LoRAs, steps,
samplers, inject schedule, encode time, your `notes`, all read out of the
graph that ran. The compare viewer's metadata strip and the scorer's labels
come from here instead of from file names.
- `draft_preview` + `latent`: decode the sampled latent through the tiny VAE
in `models/vae_approx` (`taeh3` for H3; any stem) into `<prefix>_draft.mp4`.
The tiny VAE is loaded for that call and released after; with the toggle
off nothing is loaded and nothing runs. Cost measured 2026-08-21: 8 ms per
latent frame at 864x480, 21 ms at 1344x768, 42 ms at 1080p.
## MAI Load Video (path) / MAI Select Every Nth
The two things the graphs still took from VideoHelperSuite: a video by
absolute or input-relative path (as ComfyUI's VIDEO type, frames and fps
alongside), and every n-th frame from an offset. For a smeared clip use H3
Exact Recover instead; it is exact.
## MAI Video Compare (2-6, synchronized)
The player has grown since this page was written: a waveform timeline with
loop brackets, a frame stepper, and a frame-exact export. The README's
MAI Video Compare section is the current reference; this page keeps the
original wiring notes.
A media UI, not a processing stage. The node writes each wired VIDEO once as a
small h264 preview into the temp directory (CPU, no VAE, no tensors kept) and
the widget plays them in the browser with the flipbook's player: one set of
live `<video>` elements, buffered start-together, flip / wipe / side-by-side
for a pair, a grid for more.
- hover a source to hear it, click to lock its audio
- space play/pause all, arrows step all one frame (shift: 12), F flicker A/B
- 1-6 pick the pair (last two pressed), Enter stars the B side
- the star sets the node's `winner` widget; the NEXT queue passes that source
through `winner_video` (and `winner_index`). Pick, then finalize in a second
execution: a graph never waits on a human mid-run.
The flipbook deck (https://matlowai.github.io/flipbook/derope.html) is the
offline twin, same player code.
## MAI Seed Hunter (compare + winner seed)
Video Compare that knows about seeds: wire 2-6 cheap candidates and the seed
each ran on (labels default to the seed), star the keeper, and the NEXT queue
passes the starred candidate's seed out of `winner_seed` for the finalize
pass's RandomNoise (and its video out of `winner_video`). The seed-hunt pass
and the finalize pass are two executions by design.
## MAI Motion Editor additions
Alpha. The editor's rows, modal, undo and run buttons have only been exercised by
an automated browser so far; expect rough edges, and treat anything surprising
as a bug to report rather than a design choice.
Verified headless against a lab instance (2026-08-22, Playwright): run-to-here
renders base + oracle + filmstrip and holds the graph; a drag on the block lane
creates exactly the dragged range (snapped to the token grid); the live envelope
drives the dilated clock, the play loop and the price before any render; the
modal applies as one undo step; run-from-here resumes at the editor with the
whole base chain from ComfyUI's cache (14 nodes cached, editor + downstream
executed); a fresh page load restores the last run's filmstrip from the server.
- **run to here / run from here** on the node: the first is partial execution
(nothing downstream), the second a normal queue where unchanged upstream
nodes come from the cache, so it resumes at this node. Editing a row then
"run from here" is the retry loop.
- **Undo**: the node's undo/redo is the fine-grained one (every row edit, drag,
modal apply). ComfyUI's own ctrl+z jumps back to the graph's last snapshot
(the widget re-hydrates from it and says so); the graph tracker does not see
edits made inside the widget individually, so ctrl+shift+z at graph level
has nothing to redo after that. Use the node's buttons or ctrl+z/ctrl+shift+z
while the editor has focus.
- **hold_until_edited** (default on): with no rows, a run stops after the
filmstrip; lay out rows and run again.
- **Cache reality**: ComfyUI keeps only the previous prompt's outputs, so
running other graphs in between evicts the base pass and the next
run-from-here re-renders it. The other way to lose the cache is a seed that
moves: the frontend's default "control after generate" is randomize on
nodes it builds, so the plain Run button re-renders the base every time
until both RandomNoise nodes are set to fixed. The node's run buttons pin
every seed control to fixed before queueing.
- **Play** (space): the filmstrip plays at fps; in the dilated clock each
frame lingers for its hold, so the slowdown is seen, not inferred.
- **clock: world / dilated**: the timeline's x-axis reads as "when" (frame)
or as "how long it costs" (cumulative holds). The compiled hold curve from
the last run is drawn over the jerk profile in both.
## Paste an API workflow
With the pack installed, Ctrl-V of API-format JSON on the canvas works: the
stock paste handler only takes UI-format workflows, so `web/api_paste.js`
catches API JSON first and routes it through the frontend's own `loadApiJson`
(widgets built from the server schema, never by position). It replaces the
graph, so a non-empty canvas asks first. The deck's "api" links and every
`*_api.json` in `examples/` paste directly now.
## What these replace
Our graphs used VHS_LoadVideoPath and VHS_SelectEveryNthImage; both are
covered. Create Video + Save Video stay valid; MAI Video Out is those plus the
sidecars. The compare node replaces opening three files and scrubbing them to
roughly the same place.
|