In 'mp4 file' mode the join already writes the final MP4 with audio. VHS Video
Combine / Create Video / Save Video fed by its images or comparison output
only encode the finished video again from memory (a 1920 run crashed on the
RAM). The join now logs which active ones do it, and the save_to tooltip and
node description say to bypass them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- BFS Shot H3 Conditioning and its Simple version always pass every picture of the shot: the
use_ref_2 switch is gone (the pictures are chosen in the planner). The published v1.1
character-swap workflow had it off, so only <Picture 1> reached the model. Saved
workflows are upgraded on load: their widget values are put back by name (checked with
the published v1.1 and tutorial workflows).
- 🤖 Auto prompt: Style = H3 official (six sections) or OpenJutsu captions, the short
'Replace the ... in the video with ... from <Picture n>. Keep ...' style of the training
captions (written from the request, the frames and the pictures).
- The writer samples (repetition and presence penalties) instead of greedy decoding, which
looped on long answers; repeated sentences and a cut sentence are removed, missing sound
sections completed; an answer with problems (missing <Subject n> in detailed_description,
a loop, H3 sections in a caption) is written once more, told what was wrong; labels still
missing are tied after [Shot 1]. A subject acts with its own body (hands, not paws).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- With Auto prompt on, the planner's prompt input is the template (e.g. a LoRA's body_swap
prompt) and the panel's text is the request applied to it; the run tells the panel the
template so 🤖 Write uses the same one (shown in the card). Without a VLM the template is the
prompt. The template is part of a written prompt's 'made from'.
- The writer gets the shot's real cut times from the cut detector and at least one key frame
per piece between cuts; a shot without cuts gets no timestamps (the ones the VLM writes from
the frame times are removed), and [Shot 1] never has one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A request that is a whole prompt (H3 sections, e.g. a LoRA's body_swap template) is kept:
same sentences and order, its trigger word first; the writer adds the pictures' features and
the shot's camera, place, light and actions after [Shot 1].
- Writer rules: a timestamp only starts a new [Shot N] at a real cut, never inside a shot; the
replacement is stated (the person of the guide video is replaced by <Subject N>); the summary
names 'the guide video'; {details@Picture n} left in the request is filled by the writer.
- Picture / Subject / Video / Audio N written without brackets get them back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 🤖 Auto prompt (Prompts & refs): the prompt boxes become requests and the VLM writes each
shot's MiniMax H3 prompt in the full-reference format of MiniMax-H3's
VIDEO_PROMPT_WRITING_GUIDE_ref_en (six sections, task types, retention markers, [Shot N],
official camera terms) from key frames of the shot (auto: ~1.5/s, 3-8), the shot's
pictures and their descriptions, the request, Colored Marks, selection and mode, citing
the source as the guide video or <Video 1>. Write all / missing in the panel, per shot
Write again and edit; shots without one are written at run time (before SAM 3) and the
panel stores them; out-of-date prompts are flagged. A written prompt is part of the
stored shot's signature.
- Duet removed from the planner (its split-screen prompt writer, /bfs/shotloop/write) and
from BFS Shot H3 Conditioning (Advanced): duet, panel_*, rope_gap, task, instruction.
The model input stays as a pass-through so workflows that routed the model keep working.
BFS Shot H3 Duet and the Side Panel nodes keep the duet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Colored Mark: every picture has a mark color (12-color palette, editable under each
global picture); a shot's selection and each extra person ("+ Mark another person",
text or points) pick the picture they become ("Picture 3 · red", with its
thumbnail) and are drawn in its color. The prompt gets a model-agnostic mapping
("the person marked in red becomes the character from <Picture 3>"). The
conditioning node checks each marked picture is passed and colors are not shared.
Plans with the old second region open with it as <Picture 2>.
- Points window: fixed size; the frame fits a fixed stage (points are stored relative to
the frame); one point set per marked person.
- BFS Shot Planner outputs refs (every picture the shots use, as a list) and ref_count
where ref_image / ref_image_2 were.
- Saved workflows are upgraded on load: the planner's ref_image / ref_image_2 inputs are
removed, old ref outputs become refs / ref_count, and what fed Repack's ref_image
feeds refs.
- New describe preset "object" (a noun phrase: what it is, shape, materials, colors,
text), written for the prompt sentence like "short".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Describe references is per picture now: one row per picture the plan uses, each with
its own preset (default = the card's; custom with its own instruction) and 🔄 to
describe only that one. {details} = picture 1, {details2} = picture 2,
{details@Picture n} = picture n. Descriptions saved per reference set by older plans
are read as those pictures'. The separate "Describe each picture" section is gone.
- BFS Shot Unpack: refs (every picture of the shot, as a list: the next node runs once
per picture) and ref_count replace ref_image / ref_image_2 in the same output slots.
BFS Shot Repack's refs input takes the list back and splits it per shot; ref_image
links from older workflows still work.
- Prompt chips read PictureN (they insert <Picture N>).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Plans keep a list of pictures (global_refs, per-shot refs) instead of ref / ref2; older
plans are converted on load and ref / ref2 stay in the JSON as pictures 1 and 2. A
shot's empty slot uses the global picture at the same position.
- Panel: the global list starts with one slot and + adds more (several files at once);
drop image files on a slot to replace it or on the box to add them; recent thumbnails
can be dragged onto any slot. Chips under every prompt insert <Picture N> at the cursor
(@PictureN) or {details@Picture N} (📝).
- {details@Picture n}: the description of the shot's n-th picture alone. 📝 Describe each
picture writes one per image (editable, saved as picture_details); without one, the
planner's VLM, then the conditioning node's VLM, describes it at run time.
- The planner's ref_image / ref_image_2 inputs are gone (a workflow saved with them
connected still runs and the log says they are ignored). Conditioning and Duet pass
every picture of the shot (use_ref_2 off: only the first) and log when there are
more than 9.
- Stored shots keep their signature when a shot has at most 2 pictures and no
per-picture descriptions are set.
- A two-picture shot no longer gets the automatic <Subject 2> {details2} line when the
prompt already names <Picture 2> or uses {details@Picture n}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The stored-shot signature now includes what renders the shots: the planner reads the
queued workflow (hidden PROMPT input) and fingerprints every node upstream of BFS Shot
Join's images (loaders, LoRAs and strengths, sampler, seed, conditioning settings).
Changing any of them runs every shot again on the next Run, instead of only
re-assembling the stored ones. The join's own settings (crossfade, comparison) and
display nodes don't count. A seed on "randomize" changes every Run, so fix it to keep
the stored shots.
- BFS Shot Join no longer shows a video preview on the node; the video still goes out
through images and the file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Modes read "<region> (<what stays sharp>)": face / head + hands / person / masked area,
with keep mouth (lips, teeth, tongue) / keep lips + tongue (teeth blurred too) /
mouth too (nothing sharp). The 1.91 values keep working in saved workflows.
- masked area: the shot's own mask (the person being replaced, with its expand), no extra
segmentation; without a mask it blurs the whole person.
- source_blur_segmenter: SAM 3.1 (as before) or Sapiens2 (facebook/sapiens2-seg-0.4b,
body-part classes with lips, teeth and tongue apart from the face, one pass; downloads
to models/sapiens2 the first time, runs in half precision, back to RAM after each shot).
Frames keep their aspect ratio at the trained area instead of being stretched.
- source_blur_effect: blur, or invert colours (shapes and expression stay, skin tone and
colours go).
- On BFS Shot H3 Conditioning (+ Simple), BFS Shot H3 Duet, BFS H3 Duet and BFS H3 Duet
Conditioning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- BFS Video Compare: "save" plays the video once from the start and downloads it as
shown (layout, divider, labels); "rec" records what you do in the player until stop.
Drawn into a canvas and encoded in the browser (MP4 where it can, else WebM).
- Optional "reference" input: up to 4 pictures shown in a corner of the player and in
what save / rec download ("ref" toggles them).
- Side by side no longer grows the player out of the node (the videos stay absolutely
positioned, one per half); save / rec / labels moved to their own row so the top bar
fits in one line.
- The top video follows the bottom one by nudging its speed (it used to seek every
frame: it stuttered, and drew blank into the canvas while seeking).
- BFS Shot Join: turning the comparison on after a run reads the original frames from
the source video, so the guide column is there (before only the target came back).
- Mouse wheel over the Shot Planner panel and the Video Compare player zooms the canvas,
except on something that can still scroll that way; Ctrl / Cmd + wheel always zooms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Every shot stored and up to date: the planner hands out an assemble-only placeholder
(no VLM, SAM 3 or history) and BFS Shot Join assembles the stored shots. Its images
input is lazy, so conditioning, sampler and decode are not executed again (before,
the last shot was generated again just so the join had something to join).
- Run tab: "Unload models before the join" (on by default): once every shot is
rendered, unload the models so the join and the nodes after it get the memory.
Not part of the shot signature, so toggling it keeps the stored shots.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Run tab gets a 'Second pass (upscale)' section: on/off, and the upscaled
size by multiplier, target dimensions or megapixels with an alignment, the
same arithmetic as Minimax H3 Latent Upscaler (3D). The planner outputs
second_pass (BOOLEAN), upscale_width and upscale_height (INT); the graph does
the latent upscale and the second sampling with its own nodes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 15 s limit belongs to the published workflow, not to the node: a plan with
no range works on the whole video again, as before 1.106.2. Choosing a video in
the panel still starts with its first 15 s, as it always did.
This reverts commit d62a721.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plan that never set its range (fresh node, older workflow, plan made outside
the panel) used the whole video, so a long video run through a workflow
nobody adjusted generated every shot of it. Unset now means the first 15 s,
read the same way by the panel and the server; the whole video is the
explicit 'whole video' choice (end frame 0), as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Issue #12: on installs with no ffmpeg on PATH (Windows portable), Shot Join's
mp4 mode - also picked automatically for long videos when the RAM is short -
failed with WinError 2. Video files now go through bfs_video_io: ffmpeg from
PATH, else imageio-ffmpeg's, else PyAV (what ComfyUI's Save Video uses), for
writing and for reading the MP4 back. BFS Video Compare uses the same writer.
Issue #13: a workflow saved with Max shots = 1 silently dropped every shot
after the first, so double-click splits did nothing. A split made by hand now
raises Max shots to keep it, and the Video tab says when detected shots are
left out by the limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BFS Video Compare plays two videos in one player (wipe, overlay or side by
side, any of guide / target / difference on top) and measures a per-pixel
difference map on the real frames, with the difference per frame as a
clickable strip. Shot Join gains a 'guide' output: the original frames under
each output frame (the comparison's original column), so the two connect
straight into the compare node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The colour anchor applies one chroma shift to the whole shot, so with
continuity "head" (whose first frames already continue the previous shot)
it showed as a skin colour jump at every seam. Off by default; turn it on
only for a long take whose colours visibly drift.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The VLM is given the prompt sentence around {details} and sometimes answers
with it ('is the ... shown in', '... is the shown in <Picture 1>'), so the
prompt read 'is the is the ... shown in shown in'. The short preset now drops
those words, and every description (also ones already saved in a plan) is
cleaned when it goes into the prompt. Bump BFSNodes version to 1.105.5.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With save_to = mp4 file (chosen or by the RAM guard) the join writes the
video and comparison itself, without the prompt / workflow tags Save Video
adds, so the files could not be dropped back into ComfyUI. They now carry
the same tags (JSON, use_metadata_tags), passed through an ffmetadata file
so large workflows fit. Bump BFSNodes version to 1.105.4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The box covered every generated frame: the continuity head before the shot
and the frames generated past its end (often another scene after a cut),
both cut by the join. It now holds only the shot's own frames, the same box
the panel's mask preview shows. Bump BFSNodes version to 1.105.3.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
save_to = images stays the default. The memory status now reports the free
RAM, and the Checks warn when the final video as images (with or without
the comparison) would not fit, advising save_to = mp4 file. Bump BFSNodes
version to 1.105.2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With save_to = mp4 file, chosen or forced by the RAM guard, the images and
comparison outputs were blocked, so the result nodes stayed empty and looked
broken. They now carry the video read back from the written files, scaled to
fit the free RAM (the files keep the full size), and the join shows the
files on its node. Bump BFSNodes version to 1.105.1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shots that start on the previous result come out more saturated right after
it, and the next shot inherits that (measured: subject saturation 75 -> 124
over 4 joins, flat inside each shot). The first shot of a take records its
subject's CIELAB a/b statistics; every continuing shot is matched to them
before it is stored (one transform per shot, subject only, soft edge), so the
next head starts from the anchored colours. On the reported video the subject
stays at 69-73. New BFS Shot Join options keep_colors / keep_colors_strength.
Bump BFSNodes version to 1.105.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Before an images join, drop earlier cached outputs (ComfyUI's RAM-pressure
release) and estimate what the video and comparison need; when it does not
fit, write MP4 files instead of letting the OS kill ComfyUI.
- The comparison is built 16 frames at a time, straight into its output or
to ffmpeg: file mode with comparison_height 1024 went from +9.9 GB to +2.1 GB.
- The comparison's original frames are stored as shot_NNNN_orig.mkv instead
of raw inside the .pt (245 MB per shot at full height).
Bump BFSNodes version to 1.104.1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Stored shots move from ComfyUI's temp folder (emptied at every start) to
output/bfs_shotloop (Shot cache = keep; temp still available).
- Each shot is saved as a lossless FFV1 video next to a small .pt (~12x
smaller than raw frames, exact); Smaller / Smallest (H.264 RGB) and Raw
are selectable.
- One run folder per source video; each shot carries a signature of its
settings, so a Queue runs only the shots that changed, plus the ones that
continue from a new take. Redo (with or without cascade) from the panel.
- The final join reads one stored shot at a time into the output (measured
+15.8 GB -> +8.2 GB on 11 shots at 960x544); save to = mp4 file streams
the video and the comparison to ffmpeg (+2.1 GB). New video_path output.
- Combine stored shots: an MP4 of what is stored now, without generating.
- tools/bfs_assemble_shots.py reads the new format; docs updated.
Bump BFSNodes version to 1.104.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BFS Shot Join records every shot it receives (latent tokens = generated
frames x resolution, with the continuity head) and the peak VRAM of its
run, per GPU. The panel compares each planned shot with the biggest one
that already ran on this GPU: a status at the top, a Memory card and a
warning in Checks when a shot is much bigger (possible out of memory).
No fixed GB guess, since ComfyUI offloads weights as needed.
New Run option 'Between shots': keep models loaded (default) or free
memory (unload every model between shots, for low VRAM).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tested on real H3 runs: continuity holds and memory stays as in the other
modes. It needs no open browser tab, unlike the queue loop. Saved plans
keep their own run mode. Bump BFSNodes version to 1.102.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The planner's audio output covers only the shots that run, so with skipped
shots kept as original video the join padded the end with silence and
shifted the sound after a skipped shot. The planner now marks that track
and the join uses the timeline's soundtrack instead; a soundtrack from
elsewhere is still used as given. Bump BFSNodes version to 1.101.1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One Queue renders every shot in order inside the same prompt: after a shot
is stored, BFS Shot Join expands the planner-to-join body (ComfyUI node
expansion) for the next one, so continuity head/history works without the
browser re-queueing. Graph walk adapted from Ethanfel's MiniMax H3
Context Loop. Queue loop and auto loop are unchanged; new plans default to
the recursive run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Continuity head/history needs each shot to read the previous result, which
only exists in the queue loop (the auto loop conditions every shot before
sampling any). New plans start in the queue loop with auto-queue on, and
the Run checks warn when a shot asks for head/history in the auto loop.
Bump BFSNodes version to 1.101.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
H3's VAE encodes 17-frame clips into 5 latent steps and drops the last 3
steps of the whole video, so a 17/34/51-frame history came back as only
its first 5/22/39 frames: a 12-frame hole between the history and the
shot, seen as a jump/drift at every join. History now uses 5/22/39/56
(17k+5); old plans with 17/34/51 read as 22/39/56.
New continuity mode "head" (now the default, 22 frames): the shot is
generated from N frames earlier, the previous shot's result is encoded
into the first latent steps with noise mask 0 (kept, not swapped again),
and BFS Shot Join cuts those frames. Queue loop only; skipped at cuts,
after a skipped shot and off the H3 grid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>