Movie Editor: add 'carry i2v guide' scene source mode

A 4th scene source: the scene has no anchor of its own and continues from the
previous scene's i2v guide with overlap (chain-sampler carry behaviour). UI +
data model only; per-scene carry/reset in the sampler is the V2 work to follow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-06-07 09:05:20 +03:00
co-authored by Claude Opus 4.8
parent b313bb69ea
commit ff2f3c65d8
3 changed files with 14 additions and 3 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ def _new_id() -> str:
class SceneSource:
"""How a scene's latent is born. V1 ignores this (uniform chain); Phase 2 maps
it onto EmptyLTXVLatent (empty/t2v) or LTXV Image to Video (image/i2v)."""
type: str = "empty" # "empty" | "image" | "generated_frame"
type: str = "empty" # "empty" | "image" | "generated_frame" | "carry"
media_ref: Optional[str] = None # asset id, for type == "image"
frame_ref: Optional[dict[str, Any]] = None # {scene_id, frame_idx}, for "generated_frame"
target: Optional[str] = None # wire dest for the image: "port:<id>" | "node:<slotId>:<input>"
+12 -1
View File
@@ -5,7 +5,12 @@
const body = document.getElementById("inspector-body");
const title = document.getElementById("inspector-title");
const SRC = [["empty", "Empty · text-to-video"], ["image", "Image · i2v anchor"], ["generated_frame", "From generated frame"]];
const SRC = [
["empty", "Empty · text-to-video"],
["image", "Image · i2v anchor"],
["generated_frame", "From generated frame"],
["carry", "Carry i2v guide · continue previous"],
];
function transitionSelect(value, onChange) {
const sel = el("select");
@@ -157,6 +162,12 @@
if ((scene.source?.type) === "image") renderImageSource(st, scene);
if ((scene.source?.type) === "generated_frame") renderGeneratedFrameSource(st, scene);
if ((scene.source?.type) === "carry") {
const hint = el("div", "insp-block");
hint.append(el("div", "insp-hint",
"No start frame of its own — this scene continues from the previous scene's i2v guide and overlaps with it (chain-sampler carry behaviour). Use this for a continuous shot; use an Image / generated frame to hard-cut to a new anchor."));
body.append(hint);
}
body.append(field("Transition to next scene", transitionSelect(scene.transition_to_next || "",
(v) => S.patchScene(scene.id, { transition_to_next: v }))));
+1 -1
View File
@@ -7,7 +7,7 @@
const body = document.getElementById("timeline-body");
const meta = document.getElementById("timeline-meta");
const SRC_ICON = { empty: "▦", image: "◐", generated_frame: "⛶" };
const SRC_ICON = { empty: "▦", image: "◐", generated_frame: "⛶", carry: "⇥" };
const ZOOM_KEY = "funpack_tl_zoom";
let pxPerSec = parseFloat(localStorage.getItem(ZOOM_KEY)) || 80; // zoom
let scrollLeft = 0;