Added Support for Luma ray 3.2

This commit is contained in:
Sirshendu Ganguly
2026-06-19 22:39:56 +05:30
parent 83113c70ef
commit c42795833e
11 changed files with 369 additions and 17 deletions
+4
View File
@@ -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,
+3 -1
View File
@@ -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) {
+10
View File
@@ -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,
+56
View File
@@ -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,
+24 -13
View File
@@ -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())
+137
View File
@@ -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",
}
@@ -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",
}
+3
View File
@@ -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",
+56 -2
View File
@@ -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,)
+1 -1
View File
@@ -3,4 +3,4 @@ brotli
zstd
librosa
imageio
websocket-client
websockets
File diff suppressed because one or more lines are too long