Expose per-beat H3 clip outputs

This commit is contained in:
2026-08-27 06:21:26 +00:00
parent f0d51cf6da
commit a6afdeab38
2 changed files with 26 additions and 12 deletions
+7 -4
View File
@@ -5459,10 +5459,12 @@ class H3LongVideos:
# APPEND to these, never insert. A workflow stores an output link by SLOT INDEX,
# so a new type in the middle silently re-points every link after it.
RETURN_TYPES = ("IMAGE", "AUDIO", "STRING", "STRING", "INT", "INT", "INT", "FLOAT", "FLOAT", "INT",
"LATENT", "STRING")
"LATENT", "STRING", "IMAGE", "AUDIO")
RETURN_NAMES = ("images", "audio", "info", "script", "frames_per_shot", "total_frames",
"shots", "video_seconds", "fps", "fps_int",
"latent", "soundscape")
"latent", "soundscape", "beat_images", "beat_audio")
OUTPUT_IS_LIST = (False, False, False, False, False, False, False, False, False, False,
False, False, True, True)
@classmethod
def IS_CHANGED(cls, plan_only=False, **kwargs):
@@ -6415,7 +6417,7 @@ class H3LongVideos:
# a real run.
return (ph_img, ph_audio, plan, "\n---\n".join(gens), max(plan_lens),
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, [], [])
spk = speech_flags(beats) # which shots have real (quoted) dialogue
vram_trace = [] # free VRAM after each shot
@@ -6843,7 +6845,8 @@ class H3LongVideos:
# generated, and feed it straight back into the widget-input to pin it.
return (all_frames, {"waveform": all_audio, "sample_rate": sr}, info, script,
max(shot_lens), all_frames.shape[0], len(gens), round(actual, 2),
float(fps), int(fps), latent_out, global_soundscape)
float(fps), int(fps), latent_out, global_soundscape,
video_chunks, [{"waveform": chunk, "sample_rate": sr} for chunk in audio_chunks])
# The old FL2VA / REF2VA aliases were only alternate menu entries for the same class.
+11
View File
@@ -276,6 +276,16 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
for index in range(1, 10):
self.assertIn(f"ref_{index}", optional)
def test_node_appends_per_beat_list_outputs_without_reordering_existing_slots(self):
self.assertEqual(
self.module.H3LongVideos.RETURN_NAMES[-2:],
("beat_images", "beat_audio"),
)
self.assertEqual(
self.module.H3LongVideos.OUTPUT_IS_LIST[-2:],
(True, True),
)
def test_reference_context_matches_character_names_and_location_tags(self):
refs = [
{"kind": "character", "image": "img1", "name": "Mara", "description": "silver hair", "wardrobe": "red jacket"},
@@ -456,6 +466,7 @@ class DumasH3LongVideosHelperTests(unittest.TestCase):
)
self.assertIn("2 beat(s)", result[2])
self.assertIn("2 shot(s)", result[2])
self.assertEqual(result[-2:], ([], []))
finally:
module.torch = original_torch
module.vram_gb = original_vram_gb