diff --git a/__init__.py b/__init__.py index f68fb7e..c3aa692 100644 --- a/__init__.py +++ b/__init__.py @@ -40,6 +40,8 @@ from .modules.videoInferenceSettingsTts import RunwareVideoInferenceSettingsTts from .modules.videoInferenceSettingsActiveSpeakerDetection import RunwareVideoInferenceSettingsActiveSpeakerDetection from .modules.videoInferenceSettingsActiveSpeakerBoundingBoxes import RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes from .modules.videoInferenceSettingsSegments import RunwareVideoInferenceSettingsSegments +from .modules.videoInferenceSettingsControl import RunwareVideoInferenceSettingsControl +from .modules.videoInferenceSettingsSourcePosition import RunwareVideoInferenceSettingsSourcePosition from .modules.frameImages import RunwareFrameImages from .modules.providerSettings.pixverseProviderSettings import RunwarePixverseProviderSettings from .modules.providerSettings.openaiProviderSettings import RunwareOpenAIProviderSettings @@ -232,6 +234,8 @@ NODE_CLASS_MAPPINGS = { "Runware Video Inference Settings Active Speaker Detection": RunwareVideoInferenceSettingsActiveSpeakerDetection, "Runware Video Inference Settings Active Speaker Bounding Boxes": RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes, "Runware Video Inference Settings Segments": RunwareVideoInferenceSettingsSegments, + "Runware Video Inference Settings Edit": RunwareVideoInferenceSettingsControl, + "Runware Video Inference Settings Source Position": RunwareVideoInferenceSettingsSourcePosition, "Runware Lightricks Provider Settings": RunwareLightricksProviderSettings, "Runware MiniMax Provider Settings": RunwareMiniMaxProviderSettings, "Runware Luma Provider Settings": RunwareLumaProviderSettings, diff --git a/clientlibs/main.js b/clientlibs/main.js index a7681ca..1abdb5d 100644 --- a/clientlibs/main.js +++ b/clientlibs/main.js @@ -1,6 +1,6 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; -import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, saveTextHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, threeDModelSearchFilterHandler, audioModelSearchFilterHandler, textModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, imageInferenceAdvancedFeaturesToggleHandler, watermarkAdvancedFeatureToggleHandler, videoInferenceSpeechInputToggleHandler, regionalPromptingRegionsToggleHandler, upscalerToggleHandler, imageUpscalerSettingsToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, textInferenceSettingsToggleHandler, videoSettingsToggleHandler, videoInferenceSettingsTtsToggleHandler, videoInferenceSettingsActiveSpeakerDetectionToggleHandler, videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler, videoInferenceSettingsSegmentsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, threeDInferenceSettingsMeshClusterToggleHandler, threeDInferenceSettingsDracoCompressionToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, outpaintSettingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, imageInferenceSettingsMoodboardsToggleHandler, imageInferenceSettingsStructuredPromptToggleHandler, imageInferenceSettingsPromptEnhanceToggleHandler, imageInferenceSettingsScoringRubricToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler, audioInferenceReferenceVoiceToggleHandler, audioInferenceSpeechVoicesToggleHandler, videoInputsFrameToggleHandler, referenceVideosToggleHandler } from "./utils.js"; +import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, saveTextHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, threeDModelSearchFilterHandler, audioModelSearchFilterHandler, textModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, imageInferenceAdvancedFeaturesToggleHandler, watermarkAdvancedFeatureToggleHandler, videoInferenceSpeechInputToggleHandler, regionalPromptingRegionsToggleHandler, upscalerToggleHandler, imageUpscalerSettingsToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, textInferenceSettingsToggleHandler, videoSettingsToggleHandler, videoInferenceSettingsTtsToggleHandler, videoInferenceSettingsActiveSpeakerDetectionToggleHandler, videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler, videoInferenceSettingsSegmentsToggleHandler, videoInferenceSettingsControlToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, threeDInferenceSettingsMeshClusterToggleHandler, threeDInferenceSettingsDracoCompressionToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, outpaintSettingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, imageInferenceSettingsMoodboardsToggleHandler, imageInferenceSettingsStructuredPromptToggleHandler, imageInferenceSettingsPromptEnhanceToggleHandler, imageInferenceSettingsScoringRubricToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler, audioInferenceReferenceVoiceToggleHandler, audioInferenceSpeechVoicesToggleHandler, videoInputsFrameToggleHandler, referenceVideosToggleHandler } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; const nodeInitList = []; @@ -107,6 +107,8 @@ app.registerExtension({ videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSSEGMENTS) { videoInferenceSettingsSegmentsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSEDIT) { + videoInferenceSettingsControlToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.ACCELERATOROPTIONS) { acceleratorOptionsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.BYTEDANCEPROVIDERSETTINGS) { diff --git a/clientlibs/types.js b/clientlibs/types.js index b31d5fa..8ac8930 100644 --- a/clientlibs/types.js +++ b/clientlibs/types.js @@ -130,6 +130,8 @@ const RUNWARE_NODE_TYPES = { VIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION: "Runware Video Inference Settings Active Speaker Detection", VIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES: "Runware Video Inference Settings Active Speaker Bounding Boxes", VIDEOINFERENCESETTINGSSEGMENTS: "Runware Video Inference Settings Segments", + VIDEOINFERENCESETTINGSEDIT: "Runware Video Inference Settings Edit", + VIDEOINFERENCESETTINGSSOURCEPOSITION: "Runware Video Inference Settings Source Position", LIGHTRICKSPROVIDERSETTINGS: "Runware Lightricks Provider Settings", KLINGPROVIDERSETTINGS: "Runware KlingAI Provider Settings", KLINGMULTIPROMPTSEGMENT: "Runware Kling MultiPrompt Segment", @@ -620,6 +622,14 @@ const RUNWARE_NODE_PROPS = { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, }, + [RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSEDIT]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, + [RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSSOURCEPOSITION]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, [RUNWARE_NODE_TYPES.ACCELERATOROPTIONS]: { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 681c3c0..824e7ba 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -1432,6 +1432,12 @@ function videoSettingsToggleHandler(settingsNode) { const sourceAudioSyncWidget = settingsNode.widgets.find(w => w && w.name === "sourceAudioSync"); const useTurboWidget = settingsNode.widgets.find(w => w && w.name === "useTurbo"); const turboWidget = settingsNode.widgets.find(w => w && w.name === "turbo"); + const useLoopWidget = settingsNode.widgets.find(w => w && w.name === "useLoop"); + const loopWidget = settingsNode.widgets.find(w => w && w.name === "loop"); + const useHdrWidget = settingsNode.widgets.find(w => w && w.name === "useHdr"); + const hdrWidget = settingsNode.widgets.find(w => w && w.name === "hdr"); + const useExrExportWidget = settingsNode.widgets.find(w => w && w.name === "useExrExport"); + const exrExportWidget = settingsNode.widgets.find(w => w && w.name === "exrExport"); const useVoicePromptWidget = settingsNode.widgets.find(w => w && w.name === "useVoicePrompt"); const voicePromptWidget = settingsNode.widgets.find(w => w && w.name === "voicePrompt"); const useSafetyFilterWidget = settingsNode.widgets.find(w => w && w.name === "useSafetyFilter"); @@ -1494,6 +1500,9 @@ function videoSettingsToggleHandler(settingsNode) { if (usePreserveAudioWidget && preserveAudioWidget) toggleWidgetState(usePreserveAudioWidget, preserveAudioWidget, "preserveAudio"); if (useSourceAudioSyncWidget && sourceAudioSyncWidget) toggleWidgetState(useSourceAudioSyncWidget, sourceAudioSyncWidget, "sourceAudioSync"); if (useTurboWidget && turboWidget) toggleWidgetState(useTurboWidget, turboWidget, "turbo"); + if (useLoopWidget && loopWidget) toggleWidgetState(useLoopWidget, loopWidget, "loop"); + if (useHdrWidget && hdrWidget) toggleWidgetState(useHdrWidget, hdrWidget, "hdr"); + if (useExrExportWidget && exrExportWidget) toggleWidgetState(useExrExportWidget, exrExportWidget, "exrExport"); if (useVoicePromptWidget && voicePromptWidget) toggleWidgetState(useVoicePromptWidget, voicePromptWidget, "voicePrompt"); if (useSafetyFilterWidget && safetyFilterWidget) toggleWidgetState(useSafetyFilterWidget, safetyFilterWidget, "safetyFilter"); if (usePromptUpsamplingWidget && promptUpsamplingWidget) toggleWidgetState(usePromptUpsamplingWidget, promptUpsamplingWidget, "promptUpsampling"); @@ -1674,6 +1683,49 @@ function videoInferenceSettingsSegmentsToggleHandler(node) { wireSegment(4); } +function videoInferenceSettingsControlToggleHandler(node) { + if (!node?.widgets) return; + + const useAutoControlsWidget = node.widgets.find(w => w && w.name === "useAutoControls"); + const autoControlsWidget = node.widgets.find(w => w && w.name === "autoControls"); + const useStrengthWidget = node.widgets.find(w => w && w.name === "useStrength"); + const strengthWidget = node.widgets.find(w => w && w.name === "strength"); + const useDepthBlurWidget = node.widgets.find(w => w && w.name === "useDepthBlur"); + const depthBlurWidget = node.widgets.find(w => w && w.name === "depthBlur"); + const useFaceWidget = node.widgets.find(w => w && w.name === "useFace"); + const faceWidget = node.widgets.find(w => w && w.name === "face"); + const useNormalsAugmentationWidget = node.widgets.find(w => w && w.name === "useNormalsAugmentation"); + const normalsAugmentationWidget = node.widgets.find(w => w && w.name === "normalsAugmentation"); + const usePoseStrengthWidget = node.widgets.find(w => w && w.name === "usePoseStrength"); + const poseStrengthWidget = node.widgets.find(w => w && w.name === "poseStrength"); + const useTrajectorySparsityWidget = node.widgets.find(w => w && w.name === "useTrajectorySparsity"); + const trajectorySparsityWidget = node.widgets.find(w => w && w.name === "trajectorySparsity"); + + function toggleWidgetState(useWidget, paramWidget, paramName) { + if (!useWidget || !paramWidget) return; + function applyState() { + const enabled = useWidget.value === true; + toggleWidgetEnabled(paramWidget, enabled, node); + if (paramWidget.options && paramWidget.options.element) { + paramWidget.options.element.disabled = !enabled; + paramWidget.options.element.style.opacity = enabled ? "1" : "0.5"; + paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none"; + } + node.setDirtyCanvas(true); + } + setTimeout(applyState, 100); + appendWidgetCB(useWidget, () => setTimeout(applyState, 50)); + } + + if (useAutoControlsWidget && autoControlsWidget) toggleWidgetState(useAutoControlsWidget, autoControlsWidget, "autoControls"); + if (useStrengthWidget && strengthWidget) toggleWidgetState(useStrengthWidget, strengthWidget, "strength"); + if (useDepthBlurWidget && depthBlurWidget) toggleWidgetState(useDepthBlurWidget, depthBlurWidget, "depthBlur"); + if (useFaceWidget && faceWidget) toggleWidgetState(useFaceWidget, faceWidget, "face"); + if (useNormalsAugmentationWidget && normalsAugmentationWidget) toggleWidgetState(useNormalsAugmentationWidget, normalsAugmentationWidget, "normalsAugmentation"); + if (usePoseStrengthWidget && poseStrengthWidget) toggleWidgetState(usePoseStrengthWidget, poseStrengthWidget, "poseStrength"); + if (useTrajectorySparsityWidget && trajectorySparsityWidget) toggleWidgetState(useTrajectorySparsityWidget, trajectorySparsityWidget, "trajectorySparsity"); +} + function audioInferenceSpeechToggleHandler(speechNode) { if (!speechNode?.widgets) return; @@ -2937,6 +2989,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "lumaai:1@1 (Luma Ray 1.6)", "lumaai:2@1 (Luma Ray 2)", "lumaai:2@2 (Luma Ray 2 Flash)", + "luma:ray@3.2 (Luma Ray 3.2)", ], "Sync": [ "sync:lipsync-2@1 (Sync LipSync 2)", @@ -3063,6 +3116,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "lumaai:1@1": {"width": 1080, "height": 720}, "lumaai:2@1": {"width": 1080, "height": 720}, "lumaai:2@2": {"width": 1080, "height": 720}, + "luma:ray@3.2": {"width": 1280, "height": 720}, "sync:lipsync-2@1": {"width": 0, "height": 0}, "sync:lipsync-2-pro@1": {"width": 0, "height": 0}, "sync:react-1@1": {"width": 0, "height": 0}, @@ -3168,6 +3222,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "lumaai:1@1": "720p", "lumaai:2@1": "720p", "lumaai:2@2": "720p", + "luma:ray@3.2": "720p", "sync:lipsync-2@1": "720p", "sync:lipsync-2-pro@1": "720p", "sync:react-1@1": "720p", @@ -5314,6 +5369,7 @@ export { videoInferenceSettingsActiveSpeakerDetectionToggleHandler, videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler, videoInferenceSettingsSegmentsToggleHandler, + videoInferenceSettingsControlToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, diff --git a/modules/utils/runwareUtils.py b/modules/utils/runwareUtils.py index 18d0914..4d2ad0b 100644 --- a/modules/utils/runwareUtils.py +++ b/modules/utils/runwareUtils.py @@ -20,7 +20,8 @@ import io import threading import re -import websocket +from websockets.sync.client import connect as ws_connect +from websockets.exceptions import ConnectionClosed, WebSocketException from ..version import __version__ @@ -191,6 +192,13 @@ def getRunwareWsHeaders(): f"X-SDK-Version: {__version__}", ] +def getRunwareWsHeadersDict(): + headers = {} + for header in getRunwareWsHeaders(): + key, value = header.split(": ", 1) + headers[key] = value + return headers + WS_CONNECT_TIMEOUT = 10 WS_READ_TIMEOUT = 1 @@ -333,12 +341,12 @@ class RunwareWebSocketClient: self._reader_thread.join(timeout=2) self._stop_reader.clear() - self._ws = websocket.create_connection( + self._ws = ws_connect( url, - timeout=WS_CONNECT_TIMEOUT, - header=getRunwareWsHeaders(), + max_size=None, + additional_headers=getRunwareWsHeadersDict(), + open_timeout=WS_CONNECT_TIMEOUT, ) - self._ws.settimeout(WS_READ_TIMEOUT) self._reader_thread = threading.Thread( target=self._reader_loop, name="RunwareWebSocketReader", @@ -381,12 +389,12 @@ class RunwareWebSocketClient: def _reader_loop(self): while not self._stop_reader.is_set() and self._ws is not None: try: - raw = self._ws.recv() - except websocket.WebSocketTimeoutException: + raw = self._ws.recv(timeout=WS_READ_TIMEOUT) + except TimeoutError: continue - except websocket.WebSocketConnectionClosedException: + except ConnectionClosed: break - except Exception as e: + except WebSocketException as e: if not self._stop_reader.is_set(): print(f"[Runware] WebSocket reader error: {e}") break @@ -533,9 +541,11 @@ def wsRequestWrapper(recaller): try: return recaller() except ( - websocket.WebSocketException, + WebSocketException, + ConnectionClosed, ConnectionError, OSError, + TimeoutError, ): if attempt == MAX_RETRIES: raise @@ -554,10 +564,11 @@ def checkAPIKeyWithWebSocket(apiKey): url = getCustomEndpoint() ws = None try: - ws = websocket.create_connection( + ws = ws_connect( url, - timeout=WS_CONNECT_TIMEOUT, - header=getRunwareWsHeaders(), + max_size=None, + additional_headers=getRunwareWsHeadersDict(), + open_timeout=WS_CONNECT_TIMEOUT, ) ws.send(json.dumps([{"taskType": "authentication", "apiKey": apiKey}])) response = json.loads(ws.recv()) diff --git a/modules/videoInferenceSettingsControl.py b/modules/videoInferenceSettingsControl.py new file mode 100644 index 0000000..89c2c8c --- /dev/null +++ b/modules/videoInferenceSettingsControl.py @@ -0,0 +1,137 @@ +""" +Runware Video Inference Settings Edit +Exposes settings.edit (autoControls, strength, controls) for video editing models. +Connect the output to Runware Video Inference Settings → edit. +""" + +from typing import Dict, Any + +_STRENGTH_PRESETS = [ + "adhere_1", "adhere_2", "adhere_3", + "flex_1", "flex_2", "flex_3", + "reimagine_1", "reimagine_2", "reimagine_3", +] + + +class RunwareVideoInferenceSettingsControl: + """Optional settings.edit block for video inference (e.g. Luma Ray 3.2).""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useAutoControls": ("BOOLEAN", { + "tooltip": "Enable to include autoControls in settings.edit.", + "default": False, + }), + "autoControls": ("BOOLEAN", { + "tooltip": "Derives the full conditioning schedule from the source video. Cannot be combined with settings.edit.strength or settings.edit.controls. Only used when 'Use Auto Controls' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useStrength": ("BOOLEAN", { + "tooltip": "Enable to include strength in settings.edit.", + "default": False, + }), + "strength": (_STRENGTH_PRESETS, { + "tooltip": "Preservation preset: adhere (stay close to source), flex (moderate changes), or reimagine (loose guidance). Cannot be combined with autoControls. Only used when 'Use Strength' is enabled.", + "default": "flex_2", + }), + "useDepthBlur": ("BOOLEAN", { + "tooltip": "Enable to include depthBlur in settings.edit.controls.", + "default": False, + }), + "depthBlur": ("FLOAT", { + "tooltip": "Scene-geometry depth blur (0–1). Higher values allow more freedom. Only used when 'Use Depth Blur' is enabled.", + "default": 0.0, + "min": 0.0, + "max": 1.0, + "step": 0.01, + }), + "useFace": ("BOOLEAN", { + "tooltip": "Enable to include face in settings.edit.controls.", + "default": False, + }), + "face": ("BOOLEAN", { + "tooltip": "Enable face-identity conditioning. Only used when 'Use Face' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useNormalsAugmentation": ("BOOLEAN", { + "tooltip": "Enable to include normalsAugmentation in settings.edit.controls.", + "default": False, + }), + "normalsAugmentation": ("FLOAT", { + "tooltip": "Surface-geometry normals augmentation (0–1). Higher values allow more reinterpretation. Only used when 'Use Normals Augmentation' is enabled.", + "default": 0.0, + "min": 0.0, + "max": 1.0, + "step": 0.01, + }), + "usePoseStrength": ("BOOLEAN", { + "tooltip": "Enable to include poseStrength in settings.edit.controls.", + "default": False, + }), + "poseStrength": (["precise", "coarse"], { + "tooltip": "Skeleton conditioning strength. Only used when 'Use Pose Strength' is enabled.", + "default": "precise", + }), + "useTrajectorySparsity": ("BOOLEAN", { + "tooltip": "Enable to include trajectorySparsity in settings.edit.controls.", + "default": False, + }), + "trajectorySparsity": ("FLOAT", { + "tooltip": "Motion-anchoring sparsity (0–1). Higher values use fewer anchors. Only used when 'Use Trajectory Sparsity' is enabled.", + "default": 0.0, + "min": 0.0, + "max": 1.0, + "step": 0.01, + }), + }, + } + + RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSEDIT",) + RETURN_NAMES = ("edit",) + FUNCTION = "create" + CATEGORY = "Runware" + DESCRIPTION = ( + "Configure settings.edit (autoControls, strength, controls) for Runware Video Inference. " + "Connect to Runware Video Inference Settings → edit." + ) + + def create(self, **kwargs) -> tuple[Dict[str, Any]]: + edit: Dict[str, Any] = {} + + if kwargs.get("useAutoControls", False): + edit["autoControls"] = bool(kwargs.get("autoControls", False)) + if kwargs.get("useStrength", False): + edit["strength"] = str(kwargs.get("strength", "flex_2")) + + controls: Dict[str, Any] = {} + if kwargs.get("useDepthBlur", False): + controls["depthBlur"] = float(kwargs.get("depthBlur", 0.0)) + if kwargs.get("useFace", False): + controls["face"] = bool(kwargs.get("face", False)) + if kwargs.get("useNormalsAugmentation", False): + controls["normalsAugmentation"] = float(kwargs.get("normalsAugmentation", 0.0)) + if kwargs.get("usePoseStrength", False): + controls["poseStrength"] = str(kwargs.get("poseStrength", "precise")) + if kwargs.get("useTrajectorySparsity", False): + controls["trajectorySparsity"] = float(kwargs.get("trajectorySparsity", 0.0)) + + if len(controls) > 0: + edit["controls"] = controls + + return (edit,) + + +NODE_CLASS_MAPPINGS = { + "RunwareVideoInferenceSettingsControl": RunwareVideoInferenceSettingsControl, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareVideoInferenceSettingsControl": "Runware Video Inference Settings Edit", +} diff --git a/modules/videoInferenceSettingsSourcePosition.py b/modules/videoInferenceSettingsSourcePosition.py new file mode 100644 index 0000000..7b97eb2 --- /dev/null +++ b/modules/videoInferenceSettingsSourcePosition.py @@ -0,0 +1,74 @@ +""" +Runware Video Inference Settings Source Position +Exposes settings.sourcePosition for placing source video within the output canvas. +Connect the output to Runware Video Inference Settings → sourcePosition. +""" + +from typing import Dict, Any + + +class RunwareVideoInferenceSettingsSourcePosition: + """Optional settings.sourcePosition block for video inference.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "width": ("FLOAT", { + "tooltip": "Width of the source video, as a fraction of the canvas width (max 2). Paired with height. Requires inputs.video and output width/height on the inference request.", + "default": 1.0, + "min": 0.0, + "max": 2.0, + "step": 0.01, + }), + "height": ("FLOAT", { + "tooltip": "Height of the source video, as a fraction of the canvas height (max 2). Paired with width.", + "default": 1.0, + "min": 0.0, + "max": 2.0, + "step": 0.01, + }), + "x": ("FLOAT", { + "tooltip": "Horizontal position of the source video, as a fraction of the canvas width (-2 to 2).", + "default": 0.0, + "min": -2.0, + "max": 2.0, + "step": 0.01, + }), + "y": ("FLOAT", { + "tooltip": "Vertical position of the source video, as a fraction of the canvas height (-2 to 2).", + "default": 0.0, + "min": -2.0, + "max": 2.0, + "step": 0.01, + }), + }, + } + + RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSSOURCEPOSITION",) + RETURN_NAMES = ("sourcePosition",) + FUNCTION = "create" + CATEGORY = "Runware" + DESCRIPTION = ( + "Configure settings.sourcePosition (width, height, x, y) for Runware Video Inference. " + "Connect to Runware Video Inference Settings → sourcePosition." + ) + + def create(self, **kwargs) -> tuple[Dict[str, Any]]: + source_position = { + "width": float(kwargs.get("width", 1.0)), + "height": float(kwargs.get("height", 1.0)), + "x": float(kwargs.get("x", 0.0)), + "y": float(kwargs.get("y", 0.0)), + } + return (source_position,) + + +NODE_CLASS_MAPPINGS = { + "RunwareVideoInferenceSettingsSourcePosition": RunwareVideoInferenceSettingsSourcePosition, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareVideoInferenceSettingsSourcePosition": "Runware Video Inference Settings Source Position", +} diff --git a/modules/videoModelSearch.py b/modules/videoModelSearch.py index 3625f69..af02c7a 100644 --- a/modules/videoModelSearch.py +++ b/modules/videoModelSearch.py @@ -108,6 +108,7 @@ class videoModelSearch: "lumaai:1@1 (Luma Ray 1.6)", "lumaai:2@1 (Luma Ray 2)", "lumaai:2@2 (Luma Ray 2 Flash)", + "luma:ray@3.2 (Luma Ray 3.2)", ], "Sync": [ "sync:lipsync-2@1 (Sync LipSync 2)", @@ -258,6 +259,7 @@ class videoModelSearch: "lumaai:1@1": {"width": 1080, "height": 720}, "lumaai:2@1": {"width": 1080, "height": 720}, "lumaai:2@2": {"width": 1080, "height": 720}, + "luma:ray@3.2": {"width": 1280, "height": 720}, # Sync Models "sync:lipsync-2@1": {"width": 0, "height": 0}, @@ -407,6 +409,7 @@ class videoModelSearch: "lumaai:1@1": "720p", "lumaai:2@1": "720p", "lumaai:2@2": "720p", + "luma:ray@3.2": "720p", # Sync Models "sync:lipsync-2@1": "720p", diff --git a/modules/videoSettings.py b/modules/videoSettings.py index c11013e..90c435b 100644 --- a/modules/videoSettings.py +++ b/modules/videoSettings.py @@ -1,6 +1,6 @@ """ Runware Video Inference Settings Node -Provides settings (draft, audio, voicePrompt, safetyFilter, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, fit, caption, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference. +Provides settings (draft, audio, voicePrompt, safetyFilter, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, fit, caption, loop, hdr, exrExport, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference. """ from typing import Dict, Any @@ -188,6 +188,12 @@ class RunwareVideoSettings: "segments": ("RUNWAREVIDEOINFERENCESETTINGSSEGMENTS", { "tooltip": "Connect Runware Video Inference Settings Segments for settings.segments[] (startTime, endTime, audio, audioStartTime, audioEndTime).", }), + "edit": ("RUNWAREVIDEOINFERENCESETTINGSEDIT", { + "tooltip": "Connect Runware Video Inference Settings Edit for settings.edit (autoControls, strength, controls).", + }), + "sourcePosition": ("RUNWAREVIDEOINFERENCESETTINGSSOURCEPOSITION", { + "tooltip": "Connect Runware Video Inference Settings Source Position for settings.sourcePosition (width, height, x, y). Requires inputs.video and output width/height.", + }), "useVoicePrompt": ("BOOLEAN", { "tooltip": "Enable to include voicePrompt (delivery style instructions) in video inference settings.", "default": False, @@ -255,6 +261,36 @@ class RunwareVideoSettings: "label_on": "Enabled", "label_off": "Disabled", }), + "useLoop": ("BOOLEAN", { + "tooltip": "Enable to include loop in video inference settings.", + "default": False, + }), + "loop": ("BOOLEAN", { + "tooltip": "Loop the video. Type video only; rejected with 10s, hdr, end_frame, or keyframes. Only used when 'Use Loop' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useHdr": ("BOOLEAN", { + "tooltip": "Enable to include hdr in video inference settings.", + "default": False, + }), + "hdr": ("BOOLEAN", { + "tooltip": "HDR output. Requires 720p/1080p; incompatible with 10s or loop. Bills at a higher rate. Only used when 'Use HDR' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), + "useExrExport": ("BOOLEAN", { + "tooltip": "Enable to include exrExport in video inference settings.", + "default": False, + }), + "exrExport": ("BOOLEAN", { + "tooltip": "Export EXR. Requires hdr to be true. Only used when 'Use EXR Export' is enabled.", + "default": False, + "label_on": "Enabled", + "label_off": "Disabled", + }), } } @@ -263,7 +299,7 @@ class RunwareVideoSettings: FUNCTION = "createSettings" CATEGORY = "Runware" DESCRIPTION = ( - "Configure video inference settings (draft, audio, voicePrompt, safetyFilter, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, fit, caption, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference. " + "Configure video inference settings (draft, audio, voicePrompt, safetyFilter, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, fit, caption, loop, hdr, exrExport, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference. " "Connect to Runware Video Inference node." ) @@ -279,6 +315,12 @@ class RunwareVideoSettings: source_audio_sync = kwargs.get("sourceAudioSync", True) use_turbo = kwargs.get("useTurbo", False) turbo = kwargs.get("turbo", False) + use_loop = kwargs.get("useLoop", False) + loop = kwargs.get("loop", False) + use_hdr = kwargs.get("useHdr", False) + hdr = kwargs.get("hdr", False) + use_exr_export = kwargs.get("useExrExport", False) + exr_export = kwargs.get("exrExport", False) use_voice_prompt = kwargs.get("useVoicePrompt", False) voice_prompt = (kwargs.get("voicePrompt") or "").strip() use_safety_filter = kwargs.get("useSafetyFilter", False) @@ -322,6 +364,8 @@ class RunwareVideoSettings: use_keyframe_id = kwargs.get("useKeyframeId", False) keyframe_id = kwargs.get("keyframeId", 0) segments_cfg = kwargs.get("segments", None) + edit_cfg = kwargs.get("edit", None) + source_position_cfg = kwargs.get("sourcePosition", None) settings: Dict[str, Any] = {} @@ -335,6 +379,12 @@ class RunwareVideoSettings: settings["sourceAudioSync"] = bool(source_audio_sync) if use_turbo: settings["turbo"] = bool(turbo) + if use_loop: + settings["loop"] = bool(loop) + if use_hdr: + settings["hdr"] = bool(hdr) + if use_exr_export: + settings["exrExport"] = bool(exr_export) if use_voice_prompt and voice_prompt: settings["voicePrompt"] = voice_prompt if use_safety_filter: @@ -382,6 +432,10 @@ class RunwareVideoSettings: settings["activeSpeakerDetection"] = active_speaker_cfg if segments_cfg is not None and isinstance(segments_cfg, list) and len(segments_cfg) > 0: settings["segments"] = segments_cfg + if edit_cfg is not None and isinstance(edit_cfg, dict) and len(edit_cfg) > 0: + settings["edit"] = edit_cfg + if source_position_cfg is not None and isinstance(source_position_cfg, dict) and len(source_position_cfg) > 0: + settings["sourcePosition"] = source_position_cfg return (settings,) diff --git a/requirements.txt b/requirements.txt index 1d35d46..ed85cfa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ brotli zstd librosa imageio -websocket-client \ No newline at end of file +websockets \ No newline at end of file diff --git a/workflows/Runware_Video_Inference_Luma_3_2.json b/workflows/Runware_Video_Inference_Luma_3_2.json new file mode 100644 index 0000000..75a4163 --- /dev/null +++ b/workflows/Runware_Video_Inference_Luma_3_2.json @@ -0,0 +1 @@ +{"id":"38d6f864-bd3f-4ef3-bc55-486e47c48fad","revision":0,"last_node_id":9,"last_link_id":7,"nodes":[{"id":3,"type":"Runware Video Inference Inputs","pos":[-408.999957256969,397.41108647783756],"size":[341.783203125,374],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"Image","name":"Image","shape":7,"type":"IMAGE","link":null},{"localized_name":"Frame Images","name":"Frame Images","shape":7,"type":"RUNWAREVIDEOINPUTSFRAMEIMAGES","link":null},{"localized_name":"Audio Inputs","name":"Audio Inputs","shape":7,"type":"RUNWAREAUDIOINPUT","link":null},{"localized_name":"Speech Inputs","name":"Speech Inputs","shape":7,"type":"RUNWARESPEECHINPUT","link":null},{"localized_name":"Mask","name":"Mask","shape":7,"type":"IMAGE","link":null},{"localized_name":"Frame","name":"Frame","shape":7,"type":"IMAGE","link":null},{"localized_name":"Background","name":"Background","shape":7,"type":"IMAGE","link":null},{"localized_name":"References Images","name":"References Images","shape":7,"type":"RUNWAREVIDEOINPUTSREFERENCEIMAGES","link":null},{"localized_name":"Reference Videos","name":"Reference Videos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"Reference Voices","name":"Reference Voices","shape":7,"type":"RUNWAREREFERENCEVOICES","link":null},{"localized_name":"Elements","name":"Elements","shape":7,"type":"RUNWAREVIDEOINFERENCEELEMENTS","link":null},{"localized_name":"Reference Audios","name":"Reference Audios","shape":7,"type":"RUNWAREINPUTAUDIOS","link":null},{"localized_name":"Avatar","name":"Avatar","shape":7,"type":"STRING","widget":{"name":"Avatar"},"link":null},{"localized_name":"Audio","name":"Audio","shape":7,"type":"STRING","widget":{"name":"Audio"},"link":null},{"localized_name":"Video","name":"Video","shape":7,"type":"STRING","widget":{"name":"Video"},"link":3},{"localized_name":"draftId","name":"draftId","shape":7,"type":"STRING","widget":{"name":"draftId"},"link":null},{"localized_name":"videoId","name":"videoId","shape":7,"type":"STRING","widget":{"name":"videoId"},"link":null}],"outputs":[{"localized_name":"Video Inference Inputs","name":"Video Inference Inputs","type":"RUNWAREVIDEOINFERENCEINPUTS","links":[2]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Video Inference Inputs"},"widgets_values":["","","","",""],"bgcolor":"#5345bf"},{"id":4,"type":"Runware Media Upload","pos":[-360.2737265757989,853.7783534120683],"size":[270,58],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"media","name":"media","shape":7,"type":"VIDEO,AUDIO","link":4},{"localized_name":"mediaUUID","name":"mediaUUID","shape":7,"type":"STRING","widget":{"name":"mediaUUID"},"link":null}],"outputs":[{"localized_name":"mediaUUID","name":"mediaUUID","type":"STRING","links":[3]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Media Upload"},"widgets_values":["ccff040e-3df7-4af3-8b49-d806e7d158cb"],"bgcolor":"#5345bf"},{"id":6,"type":"Runware Video Inference Settings","pos":[468.985432083307,-32.73057465942436],"size":[400,1498],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"tts","name":"tts","shape":7,"type":"RUNWAREVIDEOINFERENCESETTINGSTTS","link":null},{"localized_name":"activeSpeakerDetection","name":"activeSpeakerDetection","shape":7,"type":"RUNWAREVIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION","link":null},{"localized_name":"segments","name":"segments","shape":7,"type":"RUNWAREVIDEOINFERENCESETTINGSSEGMENTS","link":null},{"localized_name":"edit","name":"edit","shape":7,"type":"RUNWAREVIDEOINFERENCESETTINGSEDIT","link":7},{"localized_name":"useDraft","name":"useDraft","shape":7,"type":"BOOLEAN","widget":{"name":"useDraft"},"link":null},{"localized_name":"draft","name":"draft","shape":7,"type":"BOOLEAN","widget":{"name":"draft"},"link":null},{"localized_name":"useAudio","name":"useAudio","shape":7,"type":"BOOLEAN","widget":{"name":"useAudio"},"link":null},{"localized_name":"audio","name":"audio","shape":7,"type":"BOOLEAN","widget":{"name":"audio"},"link":null},{"localized_name":"usePromptUpsampling","name":"usePromptUpsampling","shape":7,"type":"BOOLEAN","widget":{"name":"usePromptUpsampling"},"link":null},{"localized_name":"promptUpsampling","name":"promptUpsampling","shape":7,"type":"BOOLEAN","widget":{"name":"promptUpsampling"},"link":null},{"localized_name":"useBackgroundColor","name":"useBackgroundColor","shape":7,"type":"BOOLEAN","widget":{"name":"useBackgroundColor"},"link":null},{"localized_name":"backgroundColor","name":"backgroundColor","shape":7,"type":"STRING","widget":{"name":"backgroundColor"},"link":null},{"localized_name":"useRemoveBackground","name":"useRemoveBackground","shape":7,"type":"BOOLEAN","widget":{"name":"useRemoveBackground"},"link":null},{"localized_name":"removeBackground","name":"removeBackground","shape":7,"type":"BOOLEAN","widget":{"name":"removeBackground"},"link":null},{"localized_name":"useExpressiveness","name":"useExpressiveness","shape":7,"type":"BOOLEAN","widget":{"name":"useExpressiveness"},"link":null},{"localized_name":"expressiveness","name":"expressiveness","shape":7,"type":"COMBO","widget":{"name":"expressiveness"},"link":null},{"localized_name":"useVoiceDescription","name":"useVoiceDescription","shape":7,"type":"BOOLEAN","widget":{"name":"useVoiceDescription"},"link":null},{"localized_name":"voiceDescription","name":"voiceDescription","shape":7,"type":"STRING","widget":{"name":"voiceDescription"},"link":null},{"localized_name":"useStyle","name":"useStyle","shape":7,"type":"BOOLEAN","widget":{"name":"useStyle"},"link":null},{"localized_name":"style","name":"style","shape":7,"type":"COMBO","widget":{"name":"style"},"link":null},{"localized_name":"useThinking","name":"useThinking","shape":7,"type":"BOOLEAN","widget":{"name":"useThinking"},"link":null},{"localized_name":"thinking","name":"thinking","shape":7,"type":"COMBO","widget":{"name":"thinking"},"link":null},{"localized_name":"useMultiClip","name":"useMultiClip","shape":7,"type":"BOOLEAN","widget":{"name":"useMultiClip"},"link":null},{"localized_name":"multiClip","name":"multiClip","shape":7,"type":"BOOLEAN","widget":{"name":"multiClip"},"link":null},{"localized_name":"useShotType","name":"useShotType","shape":7,"type":"BOOLEAN","widget":{"name":"useShotType"},"link":null},{"localized_name":"shotType","name":"shotType","shape":7,"type":"COMBO","widget":{"name":"shotType"},"link":null},{"localized_name":"usePromptExtend","name":"usePromptExtend","shape":7,"type":"BOOLEAN","widget":{"name":"usePromptExtend"},"link":null},{"localized_name":"promptExtend","name":"promptExtend","shape":7,"type":"BOOLEAN","widget":{"name":"promptExtend"},"link":null},{"localized_name":"useSyncMode","name":"useSyncMode","shape":7,"type":"BOOLEAN","widget":{"name":"useSyncMode"},"link":null},{"localized_name":"syncMode","name":"syncMode","shape":7,"type":"COMBO","widget":{"name":"syncMode"},"link":null},{"localized_name":"useMode","name":"useMode","shape":7,"type":"BOOLEAN","widget":{"name":"useMode"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"useEmotion","name":"useEmotion","shape":7,"type":"BOOLEAN","widget":{"name":"useEmotion"},"link":null},{"localized_name":"emotion","name":"emotion","shape":7,"type":"COMBO","widget":{"name":"emotion"},"link":null},{"localized_name":"useTemperature","name":"useTemperature","shape":7,"type":"BOOLEAN","widget":{"name":"useTemperature"},"link":null},{"localized_name":"temperature","name":"temperature","shape":7,"type":"FLOAT","widget":{"name":"temperature"},"link":null},{"localized_name":"useOcclusionDetection","name":"useOcclusionDetection","shape":7,"type":"BOOLEAN","widget":{"name":"useOcclusionDetection"},"link":null},{"localized_name":"occlusionDetection","name":"occlusionDetection","shape":7,"type":"BOOLEAN","widget":{"name":"occlusionDetection"},"link":null},{"localized_name":"useKeyframeId","name":"useKeyframeId","shape":7,"type":"BOOLEAN","widget":{"name":"useKeyframeId"},"link":null},{"localized_name":"keyframeId","name":"keyframeId","shape":7,"type":"INT","widget":{"name":"keyframeId"},"link":null},{"localized_name":"useVoicePrompt","name":"useVoicePrompt","shape":7,"type":"BOOLEAN","widget":{"name":"useVoicePrompt"},"link":null},{"localized_name":"voicePrompt","name":"voicePrompt","shape":7,"type":"STRING","widget":{"name":"voicePrompt"},"link":null},{"localized_name":"useSafetyFilter","name":"useSafetyFilter","shape":7,"type":"BOOLEAN","widget":{"name":"useSafetyFilter"},"link":null},{"localized_name":"safetyFilter","name":"safetyFilter","shape":7,"type":"BOOLEAN","widget":{"name":"safetyFilter"},"link":null},{"localized_name":"useFit","name":"useFit","shape":7,"type":"BOOLEAN","widget":{"name":"useFit"},"link":null},{"localized_name":"fit","name":"fit","shape":7,"type":"COMBO","widget":{"name":"fit"},"link":null},{"localized_name":"useCaption","name":"useCaption","shape":7,"type":"BOOLEAN","widget":{"name":"useCaption"},"link":null},{"localized_name":"caption","name":"caption","shape":7,"type":"BOOLEAN","widget":{"name":"caption"},"link":null},{"localized_name":"usePreserveAudio","name":"usePreserveAudio","shape":7,"type":"BOOLEAN","widget":{"name":"usePreserveAudio"},"link":null},{"localized_name":"preserveAudio","name":"preserveAudio","shape":7,"type":"BOOLEAN","widget":{"name":"preserveAudio"},"link":null},{"localized_name":"useSourceAudioSync","name":"useSourceAudioSync","shape":7,"type":"BOOLEAN","widget":{"name":"useSourceAudioSync"},"link":null},{"localized_name":"sourceAudioSync","name":"sourceAudioSync","shape":7,"type":"BOOLEAN","widget":{"name":"sourceAudioSync"},"link":null},{"localized_name":"useTurbo","name":"useTurbo","shape":7,"type":"BOOLEAN","widget":{"name":"useTurbo"},"link":null},{"localized_name":"turbo","name":"turbo","shape":7,"type":"BOOLEAN","widget":{"name":"turbo"},"link":null},{"localized_name":"useLoop","name":"useLoop","shape":7,"type":"BOOLEAN","widget":{"name":"useLoop"},"link":null},{"localized_name":"loop","name":"loop","shape":7,"type":"BOOLEAN","widget":{"name":"loop"},"link":null},{"localized_name":"useHdr","name":"useHdr","shape":7,"type":"BOOLEAN","widget":{"name":"useHdr"},"link":null},{"localized_name":"hdr","name":"hdr","shape":7,"type":"BOOLEAN","widget":{"name":"hdr"},"link":null},{"localized_name":"useExrExport","name":"useExrExport","shape":7,"type":"BOOLEAN","widget":{"name":"useExrExport"},"link":null},{"localized_name":"exrExport","name":"exrExport","shape":7,"type":"BOOLEAN","widget":{"name":"exrExport"},"link":null}],"outputs":[{"localized_name":"settings","name":"settings","type":"RUNWAREVIDEOSETTINGS","links":[5]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Video Inference Settings"},"widgets_values":[false,false,false,false,false,false,false,"",false,false,false,"low",false,"",false,"anime",false,"auto",false,false,false,"single",false,false,false,"cut_off",false,"lips",false,"neutral",false,0.7,false,false,false,0,false,"Say the following.",false,false,false,"auto",false,false,false,true,false,true,false,false,false,false,false,false,false,false],"bgcolor":"#5345bf"},{"id":1,"type":"Runware Video Inference","pos":[0.37079178779292754,13.87126050896678],"size":[400,838],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREVIDEOMODEL","link":1},{"localized_name":"frameImages","name":"frameImages","shape":7,"type":"RUNWAREFRAMEIMAGES","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":null},{"localized_name":"inputAudios","name":"inputAudios","shape":7,"type":"RUNWAREINPUTAUDIOS","link":null},{"localized_name":"referenceVideos","name":"referenceVideos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"speech","name":"speech","shape":7,"type":"RUNWAREVIDEOINFERENCESPEECHINPUT","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREVIDEOINFERENCEINPUTS","link":2},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"videoAdvancedFeatureInputs","name":"videoAdvancedFeatureInputs","shape":7,"type":"RUNWAREVIDEOADVANCEDFEATUREINPUTS","link":null},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"settings","name":"settings","shape":7,"type":"RUNWAREVIDEOSETTINGS","link":5},{"localized_name":"lora","name":"lora","shape":7,"type":"RUNWAREVIDEOINFERENCELORA","link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"useDuration","name":"useDuration","type":"BOOLEAN","widget":{"name":"useDuration"},"link":null},{"localized_name":"duration","name":"duration","type":"INT","widget":{"name":"duration"},"link":null},{"localized_name":"useFps","name":"useFps","type":"BOOLEAN","widget":{"name":"useFps"},"link":null},{"localized_name":"fps","name":"fps","type":"INT","widget":{"name":"fps"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useBatchSize","name":"useBatchSize","type":"BOOLEAN","widget":{"name":"useBatchSize"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"useSchedulers","name":"useSchedulers","type":"BOOLEAN","widget":{"name":"useSchedulers"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","shape":7,"type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","shape":7,"type":"STRING","widget":{"name":"negativePrompt"},"link":null}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[6]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null},{"localized_name":"OUTPUT","name":"OUTPUT","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Video Inference"},"widgets_values":[false,"Disabled",false,5,false,24,"mp4",false,147873628,"randomize",false,20,false,1,false,"euler",false,5,"none","restyle as an oil painting",""],"bgcolor":"#5345bf"},{"id":5,"type":"LoadVideo","pos":[-778.9266823235918,487.42348539619053],"size":[282.798828125,576.7534722222222],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file","name":"file","type":"COMBO","widget":{"name":"file"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[4]}],"properties":{"cnr_id":"comfy-core","ver":"0.22.0","Node name for S&R":"LoadVideo"},"widgets_values":["ec4d9e23-c857-42fe-aab0-f96ce8a42201.mp4","image"]},{"id":2,"type":"Runware Video Model Search","pos":[-672.5574024668681,40.75366550827581],"size":[294.16015625,250],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"VideoList","name":"VideoList","type":"COMBO","widget":{"name":"VideoList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null},{"localized_name":"useCustomDimensions","name":"useCustomDimensions","type":"COMBO","widget":{"name":"useCustomDimensions"},"link":null},{"localized_name":"Width","name":"Width","type":"INT","widget":{"name":"Width"},"link":null},{"localized_name":"Height","name":"Height","type":"INT","widget":{"name":"Height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null}],"outputs":[{"localized_name":"Runware Video Model","name":"Runware Video Model","type":"RUNWAREVIDEOMODEL","links":[1]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Video Model Search"},"widgets_values":["","Luma","luma:ray@3.2 (Luma Ray 3.2)",false,"Disabled",0,0,false,"1080p"],"bgcolor":"#5345bf"},{"id":8,"type":"SaveVideo","pos":[928.6985715413998,46.27077880793269],"size":[270,578],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"video","name":"video","type":"VIDEO","link":6},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"codec","name":"codec","type":"COMBO","widget":{"name":"codec"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.22.0"},"widgets_values":["video/ComfyUI","auto","auto"]},{"id":9,"type":"Runware Video Inference Settings Edit","pos":[1255.975592421862,165.02780164046493],"size":[353.40390625,370],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"useAutoControls","name":"useAutoControls","shape":7,"type":"BOOLEAN","widget":{"name":"useAutoControls"},"link":null},{"localized_name":"autoControls","name":"autoControls","shape":7,"type":"BOOLEAN","widget":{"name":"autoControls"},"link":null},{"localized_name":"useStrength","name":"useStrength","shape":7,"type":"BOOLEAN","widget":{"name":"useStrength"},"link":null},{"localized_name":"strength","name":"strength","shape":7,"type":"COMBO","widget":{"name":"strength"},"link":null},{"localized_name":"useDepthBlur","name":"useDepthBlur","shape":7,"type":"BOOLEAN","widget":{"name":"useDepthBlur"},"link":null},{"localized_name":"depthBlur","name":"depthBlur","shape":7,"type":"FLOAT","widget":{"name":"depthBlur"},"link":null},{"localized_name":"useFace","name":"useFace","shape":7,"type":"BOOLEAN","widget":{"name":"useFace"},"link":null},{"localized_name":"face","name":"face","shape":7,"type":"BOOLEAN","widget":{"name":"face"},"link":null},{"localized_name":"useNormalsAugmentation","name":"useNormalsAugmentation","shape":7,"type":"BOOLEAN","widget":{"name":"useNormalsAugmentation"},"link":null},{"localized_name":"normalsAugmentation","name":"normalsAugmentation","shape":7,"type":"FLOAT","widget":{"name":"normalsAugmentation"},"link":null},{"localized_name":"usePoseStrength","name":"usePoseStrength","shape":7,"type":"BOOLEAN","widget":{"name":"usePoseStrength"},"link":null},{"localized_name":"poseStrength","name":"poseStrength","shape":7,"type":"COMBO","widget":{"name":"poseStrength"},"link":null},{"localized_name":"useTrajectorySparsity","name":"useTrajectorySparsity","shape":7,"type":"BOOLEAN","widget":{"name":"useTrajectorySparsity"},"link":null},{"localized_name":"trajectorySparsity","name":"trajectorySparsity","shape":7,"type":"FLOAT","widget":{"name":"trajectorySparsity"},"link":null}],"outputs":[{"localized_name":"edit","name":"edit","type":"RUNWAREVIDEOINFERENCESETTINGSEDIT","links":[7]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"83113c70ef6d442e02c2bd45e93e56587fe717c9","Node name for S&R":"Runware Video Inference Settings Edit"},"widgets_values":[false,false,false,"flex_2",false,0,false,false,false,0,false,"precise",true,0.5],"bgcolor":"#5345bf"}],"links":[[1,2,0,1,0,"RUNWAREVIDEOMODEL"],[2,3,0,1,7,"RUNWAREVIDEOINFERENCEINPUTS"],[3,4,0,3,14,"STRING"],[4,5,0,4,0,"VIDEO"],[5,6,0,1,11,"RUNWAREVIDEOSETTINGS"],[6,1,0,8,0,"VIDEO"],[7,9,0,6,3,"RUNWAREVIDEOINFERENCESETTINGSEDIT"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.505529313703492,"offset":[1154.9644977338503,227.85522512606556]}},"version":0.4} \ No newline at end of file