From 8adcce50e4021b56eccf3d35de1946c3c156afee Mon Sep 17 00:00:00 2001 From: Sirshendu Ganguly Date: Wed, 3 Jun 2026 18:27:21 +0530 Subject: [PATCH] Fix frame images timestamp input validation and parsing Use FLOAT for timestamp fields, handle invalid strings gracefully, update node description, and reset empty timestamp values in the UI when Use Timestamp is disabled. --- clientlibs/utils.js | 7 +++++++ modules/videoInputsFrame.py | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/clientlibs/utils.js b/clientlibs/utils.js index e2c1406..8ebcf2a 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -5042,6 +5042,13 @@ function videoInputsFrameToggleHandler(frameImagesNode) { function toggleEnabled() { const enabled = useWidget.value === true; + // FLOAT timestamp widgets: avoid '' on disabled slots (ComfyUI validation error) + if (!enabled && paramName && paramName.startsWith("timestamp")) { + if (paramWidget.value === "" || paramWidget.value == null) { + paramWidget.value = 0.0; + } + } + if (paramWidget.inputEl) { paramWidget.inputEl.disabled = !enabled; paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; diff --git a/modules/videoInputsFrame.py b/modules/videoInputsFrame.py index 2c8b10e..60fc4e8 100644 --- a/modules/videoInputsFrame.py +++ b/modules/videoInputsFrame.py @@ -27,8 +27,11 @@ class RunwareVideoInputsFrameImages: "tooltip": "Enable to set a timestamp (seconds) within the input video.", "default": False, }) - optionalInputs[f"timestamp{i}"] = ("STRING", { - "default": "0", + optionalInputs[f"timestamp{i}"] = ("FLOAT", { + "default": 0.0, + "min": 0.0, + "max": 9999.0, + "step": 0.01, "tooltip": "Timestamp in seconds (hundredths supported, e.g. 3.44). Only used when 'Use Timestamp' is enabled.", }) @@ -39,7 +42,7 @@ class RunwareVideoInputsFrameImages: DESCRIPTION = ( "Build inputs.frameImages entries for video inference: " - "{image: base64}, {image: base64, frame: first|last|}, or " + "{image: base64}, {image: base64, frame: first|last}, or " "{image: base64, timestamp: seconds}." ) FUNCTION = "createFrameInputs" @@ -58,7 +61,7 @@ class RunwareVideoInputsFrameImages: use_frame = kwargs.get(f"useFrame{i}", False) frame_position = kwargs.get(f"frame{i} position", "first") use_timestamp = kwargs.get(f"useTimestamp{i}", False) - timestamp = self._parse_timestamp(kwargs.get(f"timestamp{i}", "0")) + timestamp = self._parse_timestamp(kwargs.get(f"timestamp{i}", 0.0)) frameImages.append( self._createFrameEntry( @@ -83,7 +86,10 @@ class RunwareVideoInputsFrameImages: stripped = value.strip() if stripped == "": return default - return max(0.0, float(stripped)) + try: + return max(0.0, float(stripped)) + except ValueError: + return default return default def _createFrameEntry(self, image, use_frame, frame_position, use_timestamp, timestamp):