Report chain sampler step progress in Movie Editor UI

Wire ProgressBar callbacks through scene-chain _sample_chunk so denoise
steps update the global progress hook the frontend polls. Reset progress
when a new generation is queued; label the readout as sampling N/M.
This commit is contained in:
digital-garbage
2026-06-10 14:30:46 +03:00
parent 7dc6b22d65
commit ebc8a121a8
4 changed files with 35 additions and 3 deletions
+6
View File
@@ -315,6 +315,12 @@ def _install_progress_hook():
pass
def reset_progress() -> None:
_progress["value"] = 0
_progress["max"] = 0
_progress["ts"] = 0.0
def current_progress() -> dict:
_install_progress_hook()
return {"value": _progress["value"], "max": _progress["max"]}
+9 -2
View File
@@ -459,7 +459,14 @@
if (_interrupted) return;
try {
const pr = await API.progress();
if (pr && pr.max > 0) updateGenProgress({ step: pr.value, maxStep: pr.max });
if (pr && pr.max > 0) {
const head = (state.gen.msg || prefix).replace(/\s*·\s*sampling \d+\/\d+$/, "");
updateGenProgress({
step: pr.value,
maxStep: pr.max,
msg: `${head} · sampling ${pr.value}/${pr.max}`,
});
}
} catch (_) {}
}, 700);
pollTimer = setInterval(async () => {
@@ -491,7 +498,7 @@
resolve(false);
return;
}
const step = (state.gen.maxStep > 0) ? ` · step ${state.gen.step}/${state.gen.maxStep}` : "";
const step = (state.gen.maxStep > 0) ? ` · sampling ${state.gen.step}/${state.gen.maxStep}` : "";
updateGenProgress({ state: s.state, msg: `${prefix} ${_elapsed()}${step}` });
}
} catch (e) {
+1
View File
@@ -567,6 +567,7 @@ if web is not None and PromptServer is not None:
oi = await bridge.object_info()
except Exception as e: # noqa: BLE001
return web.json_response({"detail": f"Node registry unavailable: {e}"}, status=502)
bridge.reset_progress()
bridge.current_progress() # ensure the sampler step-progress hook is installed
active_scenes = [s for s in target.scenes if not s.excluded]
active_scene_count = len(active_scenes)
+19 -1
View File
@@ -2448,7 +2448,8 @@ class FunPackLTXAVSceneChainSampler:
result.pop("noise_mask", None)
return result
def _sample_chunk(self, model, sampler, sigmas, seed, cfg, positive, negative, latent):
def _sample_chunk(self, model, sampler, sigmas, seed, cfg, positive, negative, latent,
pbar=None, step_offset=0):
if sampler is None:
raise ValueError("sampler input is required.")
if not isinstance(sigmas, torch.Tensor):
@@ -2456,9 +2457,15 @@ class FunPackLTXAVSceneChainSampler:
latent = self._clone_latent(latent)
samples = latent["samples"]
noise = comfy.sample.prepare_noise(samples, int(seed))
def _progress_cb(step, _denoised, _x, _total_steps):
if pbar is not None:
pbar.update_absolute(step_offset + int(step) + 1)
sampled = comfy.sample.sample_custom(
model, noise, float(cfg), sampler, sigmas, positive, negative, samples,
noise_mask=latent.get("noise_mask"), seed=int(seed),
callback=_progress_cb if pbar is not None else None,
)
latent["samples"] = sampled
latent.pop("noise_mask", None)
@@ -2845,6 +2852,16 @@ class FunPackLTXAVSceneChainSampler:
first_scene_seed = self._scene_seed(scene_conditionings[0])
if first_scene_seed is None:
first_scene_seed = int(seed)
steps_per_scene = max(1, int(len(sigmas)) - 1)
total_sampling_steps = scene_count * steps_per_scene
pbar = None
try:
pbar = comfy.utils.ProgressBar(total_sampling_steps)
pbar.update_absolute(0)
except Exception:
pass
for scene_index, scene_cond in enumerate(scene_conditionings):
scene_positive = [scene_cond]
scene_negative = negative
@@ -2910,6 +2927,7 @@ class FunPackLTXAVSceneChainSampler:
_temporal_applied = True
sampled = self._sample_chunk(
model, sampler, sigmas, scene_seed, cfg, scene_positive, scene_negative, chunk,
pbar=pbar, step_offset=scene_index * steps_per_scene,
)
if _temporal_applied:
if _temporal_prev_wrapper is not None: