reduce print statemets, update workflow

This commit is contained in:
RyanOnTheInside
2025-05-19 18:43:33 -04:00
parent c10548e88e
commit 4001ca63f9
2 changed files with 234 additions and 270 deletions
@@ -1,8 +1,8 @@
{
"id": "00000000-0000-0000-0000-000000000000",
"revision": 0,
"last_node_id": 92,
"last_link_id": 200,
"last_node_id": 93,
"last_link_id": 203,
"nodes": [
{
"id": 35,
@@ -2090,229 +2090,6 @@
},
"widgets_values": []
},
{
"id": 76,
"type": "VHS_LoadVideo",
"pos": [
-650,
2500
],
"size": [
247.455078125,
452.2566223144531
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "meta_batch",
"shape": 7,
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"shape": 7,
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
199
]
},
{
"name": "frame_count",
"type": "INT",
"links": null
},
{
"name": "audio",
"type": "AUDIO",
"links": null
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": []
}
],
"properties": {
"cnr_id": "comfyui-videohelpersuite",
"ver": "1.6.1",
"Node name for S&R": "VHS_LoadVideo",
"widget_ue_connectable": {}
},
"widgets_values": {
"video": "pinching.mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 100,
"skip_first_frames": 0,
"select_every_nth": 1,
"format": "AnimateDiff",
"choose video to upload": "image",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "pinching.mp4",
"type": "input",
"format": "video/mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 100,
"skip_first_frames": 0,
"select_every_nth": 1
}
}
}
},
{
"id": 84,
"type": "BatchResultCollector",
"pos": [
8981.9296875,
2056.58984375
],
"size": [
390.5999755859375,
174
],
"flags": {},
"order": 49,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 196
},
{
"name": "batch_info",
"type": "BATCH_INFO",
"link": 188
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": null
}
],
"properties": {
"aux_id": "ryanontheinside/ComfyUI_RealtimeNodes",
"ver": "91017f76d80e829738853f366c2f89b7f21f8de8",
"Node name for S&R": "BatchResultCollector",
"widget_ue_connectable": {}
},
"widgets_values": [
true,
"batch_video/batch",
30,
"mp4",
false
]
},
{
"id": 85,
"type": "BatchImageProcessor",
"pos": [
181.67674255371094,
2532.96630859375
],
"size": [
378,
102
],
"flags": {},
"order": 19,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 200
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
195
]
},
{
"name": "batch_info",
"type": "BATCH_INFO",
"links": [
188
]
}
],
"properties": {
"aux_id": "ryanontheinside/ComfyUI_RealtimeNodes",
"ver": "91017f76d80e829738853f366c2f89b7f21f8de8",
"Node name for S&R": "BatchImageProcessor",
"widget_ue_connectable": {}
},
"widgets_values": [
true,
false
]
},
{
"id": 92,
"type": "ImageScale",
"pos": [
-270,
2490
],
"size": [
315,
130
],
"flags": {},
"order": 15,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 199
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
200
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.34",
"widget_ue_connectable": {},
"Node name for S&R": "ImageScale"
},
"widgets_values": [
"lanczos",
512,
512,
"center"
]
},
{
"id": 89,
"type": "ImageScale",
@@ -2368,7 +2145,7 @@
124.8360366821289
],
"flags": {},
"order": 10,
"order": 9,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -2378,6 +2155,229 @@
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 84,
"type": "BatchResultCollector",
"pos": [
8884.26171875,
2620.0791015625
],
"size": [
390.5999755859375,
174
],
"flags": {},
"order": 49,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 196
},
{
"name": "batch_info",
"type": "BATCH_INFO",
"link": 188
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": null
}
],
"properties": {
"aux_id": "ryanontheinside/ComfyUI_RealtimeNodes",
"ver": "91017f76d80e829738853f366c2f89b7f21f8de8",
"Node name for S&R": "BatchResultCollector",
"widget_ue_connectable": {}
},
"widgets_values": [
true,
"batch_video/batch",
30,
"mp4",
false
]
},
{
"id": 76,
"type": "VHS_LoadVideo",
"pos": [
-933.0139770507812,
2530.957275390625
],
"size": [
247.455078125,
452.2566223144531
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "meta_batch",
"shape": 7,
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"shape": 7,
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
202
]
},
{
"name": "frame_count",
"type": "INT",
"links": null
},
{
"name": "audio",
"type": "AUDIO",
"links": null
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": []
}
],
"properties": {
"cnr_id": "comfyui-videohelpersuite",
"ver": "1.6.1",
"Node name for S&R": "VHS_LoadVideo",
"widget_ue_connectable": {}
},
"widgets_values": {
"video": "pinching.mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 60,
"skip_first_frames": 0,
"select_every_nth": 1,
"format": "AnimateDiff",
"choose video to upload": "image",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "pinching.mp4",
"type": "input",
"format": "video/mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 60,
"skip_first_frames": 0,
"select_every_nth": 1
}
}
}
},
{
"id": 93,
"type": "ImageScale",
"pos": [
-484.8045349121094,
2515.98046875
],
"size": [
315,
130
],
"flags": {},
"order": 15,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 202
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
203
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.34",
"widget_ue_connectable": {},
"Node name for S&R": "ImageScale"
},
"widgets_values": [
"nearest-exact",
512,
512,
"center"
]
},
{
"id": 85,
"type": "BatchImageProcessor",
"pos": [
181.67674255371094,
2532.96630859375
],
"size": [
378,
102
],
"flags": {},
"order": 19,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 203
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
195
]
},
{
"name": "batch_info",
"type": "BATCH_INFO",
"links": [
188
]
}
],
"properties": {
"aux_id": "ryanontheinside/ComfyUI_RealtimeNodes",
"ver": "91017f76d80e829738853f366c2f89b7f21f8de8",
"Node name for S&R": "BatchImageProcessor",
"widget_ue_connectable": {}
},
"widgets_values": [
true,
false
]
}
],
"links": [
@@ -2966,16 +2966,16 @@
"IMAGE"
],
[
199,
202,
76,
0,
92,
93,
0,
"IMAGE"
],
[
200,
92,
203,
93,
0,
85,
0,
@@ -3052,10 +3052,10 @@
"config": {},
"extra": {
"ds": {
"scale": 0.12100000000000163,
"scale": 0.12100000000000231,
"offset": [
2342.9131356596554,
2264.162347066301
1583.2325724559685,
1701.4048752808008
]
},
"ue_links": [],
@@ -41,8 +41,6 @@ class BatchImageProcessor(ControlNodeBase):
CATEGORY = "Realtime Nodes/media/batch"
DESCRIPTION = "Feeds images one by one from a batch into the workflow. Must be used in conjunction with BatchResultCollector node."
def update(self, images, reset, always_execute=True, unique_id=None):
print(f"[BatchImageProcessor] Unique ID: {unique_id}")
print(f"[BatchImageProcessor] Input images tensor shape: {images.shape}")
# Use class static variable to persist state
if unique_id not in self.__class__._global_state:
@@ -62,7 +60,6 @@ class BatchImageProcessor(ControlNodeBase):
# Get current image (preserving batch dimension)
current_index = state["current_index"]
current_image = images[current_index:current_index+1]
print(f"[BatchImageProcessor] Current image tensor shape: {current_image.shape}")
# Prepare batch info
is_last_frame = current_index == state["total_frames"] - 1
@@ -75,7 +72,6 @@ class BatchImageProcessor(ControlNodeBase):
# Update index for next run
state["current_index"] = (current_index + 1) % state["total_frames"]
print(f"[BatchImageProcessor] Processing frame {current_index+1}/{state['total_frames']} (is_last_frame: {is_last_frame})")
print(f"[BatchImageProcessor] Next frame index will be: {state['current_index']}")
return (current_image, batch_info)
@@ -105,10 +101,7 @@ class BatchResultCollector(ControlNodeBase):
OUTPUT_NODE = True
DESCRIPTION = "Collects frames from a batch and saves them as a video when the last frame is received. If the last frame is not received, the node will block execution until it is received. Must be used in conjunction with BatchImageProcessor node."
def update(self, image, batch_info, filename_prefix, fps, format, reset, always_execute=True, unique_id=None):
print(f"[BatchResultCollector] Unique ID: {unique_id}")
print(f"[BatchResultCollector] Received frame {batch_info.current_index+1}/{batch_info.total_frames} (is_last_frame: {batch_info.is_last_frame})")
print(f"[BatchResultCollector] Input image tensor shape: {image.shape}")
# Create default state structure
default_state = {
"collected_frames": [],
@@ -147,15 +140,9 @@ class BatchResultCollector(ControlNodeBase):
state["current_index"] = current_index
# Ensure the array is large enough
if len(state["collected_frames"]) <= current_index:
print(f"[BatchResultCollector] Extending collected_frames array from {len(state['collected_frames'])} to {current_index+1}")
state["collected_frames"].extend([None] * (current_index - len(state["collected_frames"]) + 1))
# Make a copy and store the frame
state["collected_frames"][current_index] = image.clone().cpu()
print(f"[BatchResultCollector] Stored frame {current_index+1}/{total_frames}, shape: {state['collected_frames'][current_index].shape}")
# Debug info for collected frames
frame_status = ["✓" if f is not None else "✗" for f in state["collected_frames"]]
print(f"[BatchResultCollector] Frame collection status: {frame_status}")
# Check if all frames collected
collected_count = sum(1 for frame in state["collected_frames"] if frame is not None)
@@ -176,12 +163,6 @@ class BatchResultCollector(ControlNodeBase):
print(f"[BatchResultCollector] Successfully saved video. Stopping auto-queue.")
raise Exception("Processing complete. Disable auto-queue.")
else:
if batch_info.is_last_frame:
print(f"[BatchResultCollector] Last frame received but not all frames collected yet")
if all_frames_collected:
print(f"[BatchResultCollector] All frames collected but not receiving last frame yet")
return (image,)
def _save_frames_as_images(self, frames, filename_prefix, output_dir):
@@ -312,18 +293,12 @@ class BatchResultCollector(ControlNodeBase):
# Generate timestamp for unique filename
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
# Print details of the first frame for debugging
print(f"[BatchResultCollector] First frame type: {type(frames[0])}")
print(f"[BatchResultCollector] First frame tensor shape: {frames[0].shape}")
# Get video dimensions from the first frame
first_frame = frames[0]
if len(first_frame.shape) == 4: # Handle [B,H,W,C] format
height, width = first_frame.shape[1], first_frame.shape[2]
else: # Handle [H,W,C] format
height, width = first_frame.shape[0], first_frame.shape[1]
print(f"[BatchResultCollector] Video dimensions determined: {width}x{height}")
# Get save path
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
@@ -357,27 +332,16 @@ class BatchResultCollector(ControlNodeBase):
if not out.isOpened():
raise Exception(f"Failed to open video writer with any codec for format {format}")
print(f"[BatchResultCollector] Created video writer with dimensions {width}x{height} at {fps} fps")
# Write frames
frames_encoded = 0
for i, frame_tensor in enumerate(frames):
print(f"[BatchResultCollector] Processing frame {i+1}/{len(frames)}")
print(f"[BatchResultCollector] Frame tensor shape: {frame_tensor.shape}")
# Remove batch dimension if present (B,H,W,C) -> (H,W,C)
if len(frame_tensor.shape) == 4:
frame_tensor = frame_tensor.squeeze(0)
print(f"[BatchResultCollector] After removing batch dimension: {frame_tensor.shape}")
# Convert tensor to numpy array with values in [0-255]
frame_np = torch.clamp(frame_tensor * 255, min=0, max=255).to(torch.uint8).cpu().numpy()
print(f"[BatchResultCollector] NumPy array shape: {frame_np.shape}")
# Make sure we have the expected dimensions
if frame_np.shape[0] != height or frame_np.shape[1] != width:
print(f"[BatchResultCollector] Warning: Frame dimensions don't match expected {height}x{width}")
# Convert RGB to BGR for OpenCV
frame_bgr = cv2.cvtColor(frame_np, cv2.COLOR_RGB2BGR)