Show anatomy guard in H3 script output
This commit is contained in:
+28
-7
@@ -3225,7 +3225,7 @@ def continuity_warnings(gens):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def dialogue_filler_warnings(beats, seconds_per_shot):
|
def dialogue_filler_warnings(beats, seconds_per_shot):
|
||||||
"""Dialogue shots with far more time than their line, which H3 fills with speech.
|
"""Dialogue shots with far more time than their line, which H3 fills with speech.
|
||||||
|
|
||||||
dialogue_fit_warnings covers the opposite error -- a line too long for its shot,
|
dialogue_fit_warnings covers the opposite error -- a line too long for its shot,
|
||||||
@@ -3249,10 +3249,31 @@ def dialogue_filler_warnings(beats, seconds_per_shot):
|
|||||||
if gap >= 3.0 and sec > spoken * 2:
|
if gap >= 3.0 and sec > spoken * 2:
|
||||||
out.append(f"shot {i}: {spoken:.1f}s of dialogue in a {sec:.1f}s shot -- {gap:.1f}s of "
|
out.append(f"shot {i}: {spoken:.1f}s of dialogue in a {sec:.1f}s shot -- {gap:.1f}s of "
|
||||||
f"unscripted audio the model will fill with more speech")
|
f"unscripted audio the model will fill with more speech")
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def speech_flags(beats):
|
def annotate_script_guards(gens, anatomy_shots, anatomy_mode):
|
||||||
|
"""Human-readable guard report prepended to the script socket.
|
||||||
|
|
||||||
|
The `script` output is for inspection, not for feeding back into the node, so
|
||||||
|
a compact report there is the quickest way to see whether a guard actually made
|
||||||
|
it into each shot's prompt text.
|
||||||
|
"""
|
||||||
|
lines = []
|
||||||
|
if anatomy_mode == "off":
|
||||||
|
lines.append("# anatomy_guard: off")
|
||||||
|
elif anatomy_shots:
|
||||||
|
lines.append(
|
||||||
|
"# anatomy_guard: injected on shot(s) "
|
||||||
|
+ ",".join(str(n) for n in anatomy_shots)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
lines.append("# anatomy_guard: no shots matched the auto gate")
|
||||||
|
body = "\n---\n".join(gens)
|
||||||
|
return "\n".join(lines + ["", body]) if body else "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def speech_flags(beats):
|
||||||
"""Per-beat: does it contain scripted (quoted) dialogue? Same rule the prompt
|
"""Per-beat: does it contain scripted (quoted) dialogue? Same rule the prompt
|
||||||
builder uses to decide silencing, exposed so the renderer can also MUTE the
|
builder uses to decide silencing, exposed so the renderer can also MUTE the
|
||||||
audio of non-speech shots -- a deterministic fix when H3 vocalizes anyway."""
|
audio of non-speech shots -- a deterministic fix when H3 vocalizes anyway."""
|
||||||
@@ -6433,7 +6454,7 @@ class H3LongVideos:
|
|||||||
# correctly-SHAPED empty one rather than None: a downstream LATENT input
|
# correctly-SHAPED empty one rather than None: a downstream LATENT input
|
||||||
# would choke on None, and this keeps the preview wireable exactly like
|
# would choke on None, and this keeps the preview wireable exactly like
|
||||||
# a real run.
|
# a real run.
|
||||||
return (ph_img, ph_audio, plan, "\n---\n".join(gens), max(plan_lens),
|
return (ph_img, ph_audio, plan, annotate_script_guards(gens, anatomy_shots, anatomy_mode), max(plan_lens),
|
||||||
sum(plan_lens), shots, total, float(fps), int(fps),
|
sum(plan_lens), shots, total, float(fps), int(fps),
|
||||||
_empty_av_latent(w, h, 5, fps)[0], global_soundscape, [], [])
|
_empty_av_latent(w, h, 5, fps)[0], global_soundscape, [], [])
|
||||||
|
|
||||||
@@ -6740,7 +6761,7 @@ class H3LongVideos:
|
|||||||
watermark_opacity, watermark_margin, intro_text, intro_seconds,
|
watermark_opacity, watermark_margin, intro_text, intro_seconds,
|
||||||
intro_fade, intro_size, intro_position, overlay_font, overlay_stroke)
|
intro_fade, intro_size, intro_position, overlay_font, overlay_stroke)
|
||||||
|
|
||||||
script = "\n---\n".join(gens)
|
script = annotate_script_guards(gens, anatomy_shots, anatomy_mode)
|
||||||
actual = all_frames.shape[0] / fps
|
actual = all_frames.shape[0] / fps
|
||||||
uniform_len = len(set(shot_lens)) == 1
|
uniform_len = len(set(shot_lens)) == 1
|
||||||
shape_str = (f"{len(gens)} shot(s) x {shot_lens[0]}f (~{shot_lens[0] / fps:.1f}s each) "
|
shape_str = (f"{len(gens)} shot(s) x {shot_lens[0]}f (~{shot_lens[0] / fps:.1f}s each) "
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
|
|||||||
plan_only=True,
|
plan_only=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.assertIn("# anatomy_guard: injected on shot(s) 2", result[3])
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"[Generation 1] editorial room, soft practical lighting. Francine stands alone.",
|
"[Generation 1] editorial room, soft practical lighting. Francine stands alone.",
|
||||||
result[3],
|
result[3],
|
||||||
|
|||||||
Reference in New Issue
Block a user