From 02dfc5ee26ceaaabd4c4dbff53e2075e258a626f Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Mon, 24 Aug 2026 21:27:50 -0700 Subject: [PATCH] Move unbatch to matchtype VHS is v3 now? --- videohelpersuite/nodes.py | 36 +++++++++++++++++------------ web/js/VHS.core.js | 48 --------------------------------------- 2 files changed, 21 insertions(+), 63 deletions(-) diff --git a/videohelpersuite/nodes.py b/videohelpersuite/nodes.py index 4389f5d..496bf94 100755 --- a/videohelpersuite/nodes.py +++ b/videohelpersuite/nodes.py @@ -25,6 +25,7 @@ from .utils import ffmpeg_path, get_audio, hash_path, validate_path, requeue_wor imageOrLatent, BIGMAX, merge_filter_args, ENCODE_ARGS, floatOrInt, cached, \ ContainsAll from comfy.utils import ProgressBar +from comfy_api.v0_0_2 import IO if 'VHS_video_formats' not in folder_paths.folder_names_and_paths: folder_paths.folder_names_and_paths["VHS_video_formats"] = ((),{".json"}) @@ -989,19 +990,26 @@ class SelectFilename: def select_filename(self, filenames, index): return (filenames[1][index],) -class Unbatch: - class Any(str): - def __ne__(self, other): - return False + +class Unbatch(IO.ComfyNode): @classmethod - def INPUT_TYPES(s): - return {"required": {"batched": ("*",)}} - RETURN_TYPES = (Any('*'),) - INPUT_IS_LIST = True - RETURN_NAMES =("unbatched",) - CATEGORY = "Video Helper Suite 🎥🅥🅗🅢" - FUNCTION = "unbatch" - def unbatch(self, batched): + def define_schema(cls): + template = IO.MatchType.Template("type") + return IO.Schema( + node_id="VHS_Unbatch", + display_name="Unbatch 🎥🅥🅗🅢", + category = "Video Helper Suite 🎥🅥🅗🅢", + is_input_list = True, + inputs=[ + IO.MatchType.Input("batched", template=template), + ], + outputs=[ + IO.MatchType.Output(template=template, display_name="unbatched"), + ], + ) + + @classmethod + async def execute(cls, batched): if isinstance(batched[0], torch.Tensor): return (torch.cat(batched),) if isinstance(batched[0], dict): @@ -1013,9 +1021,7 @@ class Unbatch: out.pop('batch_index', None) return (out,) return (functools.reduce(lambda x,y: x+y, batched),) - @classmethod - def VALIDATE_INPUTS(cls, input_types): - return True + class SelectLatest: @classmethod def INPUT_TYPES(s): diff --git a/web/js/VHS.core.js b/web/js/VHS.core.js index fcbf03f..a4d3e4f 100755 --- a/web/js/VHS.core.js +++ b/web/js/VHS.core.js @@ -579,52 +579,6 @@ function addVAEInputToggle(nodeType, nodeData) { } }); } -function cloneType(nodeType, nodeData) { - chainCallback(nodeType.prototype, "onNodeCreated", function() { - this.changeOutputType = function (new_type) { - this.linkTimeout = setTimeout(() => { - this.linkTimeout = false - if (this.outputs[0].type != new_type) { - this.outputs[0].type = new_type - //check and potentially remove links - if (!this.outputs[0].links) { - return - } - let removed_links = [] - for (let link_id of this.outputs[0].links) { - let link = app.graph.links[link_id] - if (!link) - debugger - let target_node = app.graph.getNodeById(link.target_id) - let target_input = target_node.inputs[link.target_slot] - let keep = LiteGraph.isValidConnection(new_type, target_input.type) - if (!keep) { - link.disconnect(app.graph, 'input') - removed_links.push(link_id) - } - target_node.onConnectionsChange?.(LiteGraph.INPUT, - link.target_slot, keep, link, target_input) - } - this.outputs[0].links = this.outputs[0].links - .filter((v) => !removed_links.includes(v)) - } - }, 50) - } - this.changeOutputType("VHS_DUMMY_NONE") - }); - chainCallback(nodeType.prototype, "onConnectionsChange", function(contype, slot, iscon, linf) { - if (contype == LiteGraph.INPUT && slot == 0) { - let new_type = "VHS_DUMMY_NONE" - if (iscon && linf) { - new_type = app.graph.getNodeById(linf.origin_id).outputs[linf.origin_slot].type - } - if (this.linkTimeout) { - clearTimeout(this.linkTimeout) - } - this.changeOutputType(new_type) - } - }); -} function addDateFormatting(nodeType, field, timestamp_widget = false) { chainCallback(nodeType.prototype, "onNodeCreated", function() { @@ -2075,8 +2029,6 @@ app.registerExtension({ computeSize: () => {return [0,-4]}, afterQueued: function() {this.value++;}}); }); - } else if (nodeData?.name == "VHS_Unbatch") { - cloneType(nodeType, nodeData) } else if (nodeData?.name == "VHS_SelectLatest") { chainCallback(nodeType.prototype, "onNodeCreated", function() { this.isVirtualNode = true