117 lines
4.8 KiB
Python
117 lines
4.8 KiB
Python
import os
|
|
|
|
class WanVACEBatchContext:
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"input_list": ("STRING", {"forceInput": True}),
|
|
"input_dir": ("STRING", {
|
|
"default": "",
|
|
"tooltip": "Directory containing input videos"
|
|
}),
|
|
"project_name": ("STRING", {
|
|
"default": "",
|
|
"tooltip": "Project name - workflow files will be created under ComfyUI/output/project_name."
|
|
}),
|
|
"index": ("INT", {
|
|
"default": 0,
|
|
"min": 0,
|
|
"tooltip": "Current iteration index (0 based)"
|
|
}),
|
|
"debug": ("BOOLEAN", {
|
|
"default": False,
|
|
"tooltip": "Log some details to the console"
|
|
}),
|
|
"make_loop": ("BOOLEAN", {
|
|
"default": False,
|
|
"tooltip": "Generate an extra loop-closing transition between the last and first video"
|
|
}),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "BOOLEAN", "BOOLEAN", "BOOLEAN")
|
|
RETURN_NAMES = ("work_dir", "workfile_prefix", "video_1_filename", "video_2_filename", "is_first", "is_last", "assemble_video")
|
|
FUNCTION = "setup_context"
|
|
CATEGORY = "video/VACE"
|
|
DESCRIPTION = """
|
|
Establishes iteration context for batch video join processing.
|
|
"""
|
|
INPUT_IS_LIST = True
|
|
|
|
def setup_context(self, **kwargs):
|
|
# INPUT_IS_LIST=True makes ComfyUI deliver every input as a list.
|
|
# The **kwargs signature is required because list-mode inputs can't
|
|
# be declared as positional parameters — ComfyUI wraps each value
|
|
# in a list, including scalars, so we unwrap with [0] here.
|
|
input_dir = kwargs.get('input_dir', [""])[0]
|
|
input_list = kwargs.get('input_list', [])
|
|
project_name = kwargs.get('project_name', [""])[0].strip()
|
|
index = kwargs.get('index', [0])[0]
|
|
debug = kwargs.get('debug', [False])[0]
|
|
make_loop = kwargs.get('make_loop', [False])[0]
|
|
|
|
# Validate input list
|
|
list_length = len(input_list)
|
|
|
|
if list_length < 2:
|
|
raise ValueError(
|
|
f"Need at least 2 videos to create transitions, found {list_length}"
|
|
)
|
|
|
|
# Validate index bounds
|
|
max_index = list_length - 1 if make_loop else list_length - 2
|
|
if index < 0 or index > max_index:
|
|
raise ValueError(
|
|
f"Index {index} out of range (valid: 0-{max_index} for {list_length} videos)"
|
|
)
|
|
|
|
# Construct paths — uses forward slashes intentionally; these are
|
|
# relative paths for ComfyUI's output system, not OS filesystem paths.
|
|
if project_name:
|
|
work_dir = f"{project_name}/vace-work"
|
|
else:
|
|
work_dir = "vace-work"
|
|
padded_index = f"{index:03d}"
|
|
workfile_prefix = f"{work_dir}/index{padded_index}"
|
|
|
|
# Set iteration flags
|
|
if make_loop:
|
|
is_first = False
|
|
is_last = False
|
|
else:
|
|
is_first = (index == 0)
|
|
is_last = (index == max_index)
|
|
|
|
# Extract filenames
|
|
if make_loop and index == list_length - 1:
|
|
# Loop-closing iteration: last video → first video
|
|
v1 = input_list[-1]
|
|
v2 = input_list[0]
|
|
else:
|
|
v1 = input_list[index]
|
|
v2 = input_list[index + 1]
|
|
|
|
video_1_filename = os.path.join(input_dir, v1) if input_dir else v1
|
|
video_2_filename = os.path.join(input_dir, v2) if input_dir else v2
|
|
|
|
assemble_video = (not make_loop and index == list_length - 2) or (make_loop and index == list_length - 1)
|
|
|
|
if make_loop and index == list_length - 2:
|
|
print(f"[VACE Batch Context] Loop enabled: run once more at index {list_length - 1} to generate loop transition.")
|
|
|
|
if debug:
|
|
is_loop_iter = make_loop and index == list_length - 1
|
|
print(f"\n[VACE Batch Context] === Start ===")
|
|
print(f"[VACE Batch Context] Index: {index} (videos {index+1}-{index+2 if not is_loop_iter else 1} of {list_length}){' [LOOP TRANSITION]' if is_loop_iter else ''}")
|
|
if not make_loop:
|
|
print(f"[VACE Batch Context] {'[FIRST]' if is_first else ''} {'[LAST]' if is_last else ''}")
|
|
print(f"[VACE Batch Context] Input directory: {input_dir}")
|
|
print(f"[VACE Batch Context] Video 1: {v1}")
|
|
print(f"[VACE Batch Context] Video 2: {v2}")
|
|
print(f"[VACE Batch Context] Work prefix: {workfile_prefix}")
|
|
print(f"[VACE Batch Context] === End ===")
|
|
|
|
return (work_dir, workfile_prefix, video_1_filename, video_2_filename, is_first, is_last, assemble_video)
|
|
|