Added new settings params support

This commit is contained in:
Sirshendu Ganguly
2026-04-14 14:56:29 +05:30
parent ae704f0664
commit e6ac074f91
12 changed files with 630 additions and 4 deletions
+8
View File
@@ -34,6 +34,10 @@ from .modules.videoInference import txt2vid
from .modules.videoInferenceSpeechInput import RunwareVideoInferenceSpeechInput
from .modules.videoModelSearch import videoModelSearch
from .modules.videoSettings import RunwareVideoSettings
from .modules.videoInferenceSettingsTts import RunwareVideoInferenceSettingsTts
from .modules.videoInferenceSettingsActiveSpeakerDetection import RunwareVideoInferenceSettingsActiveSpeakerDetection
from .modules.videoInferenceSettingsActiveSpeakerBoundingBoxes import RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes
from .modules.videoInferenceSettingsSegments import RunwareVideoInferenceSettingsSegments
from .modules.frameImages import RunwareFrameImages
from .modules.providerSettings.pixverseProviderSettings import RunwarePixverseProviderSettings
from .modules.providerSettings.openaiProviderSettings import RunwareOpenAIProviderSettings
@@ -189,6 +193,10 @@ NODE_CLASS_MAPPINGS = {
"Runware Video Inference Elements Combine": RunwareVideoInferenceElementsCombine,
"Runware Video Inference Speech Input": RunwareVideoInferenceSpeechInput,
"Runware Video Inference Settings": RunwareVideoSettings,
"Runware Video Inference Settings TTS": RunwareVideoInferenceSettingsTts,
"Runware Video Inference Settings Active Speaker Detection": RunwareVideoInferenceSettingsActiveSpeakerDetection,
"Runware Video Inference Settings Active Speaker Bounding Boxes": RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes,
"Runware Video Inference Settings Segments": RunwareVideoInferenceSettingsSegments,
"Runware Lightricks Provider Settings": RunwareLightricksProviderSettings,
"Runware MiniMax Provider Settings": RunwareMiniMaxProviderSettings,
"Runware Luma Provider Settings": RunwareLumaProviderSettings,
+9 -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, audioModelSearchFilterHandler, textModelSearchFilterHandler, vectorizeModelSearchFilterHandler, vectorizeToggleHandler, useParameterToggleHandler, imageInferenceToggleHandler, imageInferenceAdvancedFeaturesToggleHandler, watermarkAdvancedFeatureToggleHandler, videoInferenceSpeechInputToggleHandler, regionalPromptingRegionsToggleHandler, upscalerToggleHandler, imageUpscalerSettingsToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, audioInferenceSpeechToggleHandler, audioSettingsToggleHandler, textInferenceSettingsToggleHandler, videoSettingsToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, threeDInferenceToggleHandler, threeDInferenceSettingsToggleHandler, threeDInferenceSettingsLatToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js";
import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, saveTextHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, 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, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, safetyInputsToggleHandler, imageInferenceSettingsColorPaletteToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js";
import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js";
const nodeInitList = [];
@@ -97,6 +97,14 @@ app.registerExtension({
textInferenceSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOSETTINGS) {
videoSettingsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSTTS) {
videoInferenceSettingsTtsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION) {
videoInferenceSettingsActiveSpeakerDetectionToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES) {
videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSSEGMENTS) {
videoInferenceSettingsSegmentsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.ACCELERATOROPTIONS) {
acceleratorOptionsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.BYTEDANCEPROVIDERSETTINGS) {
+20
View File
@@ -112,6 +112,10 @@ const RUNWARE_NODE_TYPES = {
VIDEOINFERENCEELEMENTSCOMBINE: "Runware Video Inference Elements Combine",
VIDEOINFERENCESPEECHINPUT: "Runware Video Inference Speech Input",
VIDEOSETTINGS: "Runware Video Inference Settings",
VIDEOINFERENCESETTINGSTTS: "Runware Video Inference Settings TTS",
VIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION: "Runware Video Inference Settings Active Speaker Detection",
VIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES: "Runware Video Inference Settings Active Speaker Bounding Boxes",
VIDEOINFERENCESETTINGSSEGMENTS: "Runware Video Inference Settings Segments",
LIGHTRICKSPROVIDERSETTINGS: "Runware Lightricks Provider Settings",
KLINGPROVIDERSETTINGS: "Runware KlingAI Provider Settings",
KLINGMULTIPROMPTSEGMENT: "Runware Kling MultiPrompt Segment",
@@ -522,6 +526,22 @@ const RUNWARE_NODE_PROPS = {
[RUNWARE_NODE_TYPES.VIDEOSETTINGS]: {
bgColor: DEFAULT_BGCOLOR,
},
[RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSTTS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.VIDEOINFERENCESETTINGSSEGMENTS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.ACCELERATOROPTIONS]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
+163
View File
@@ -1397,6 +1397,16 @@ function videoSettingsToggleHandler(settingsNode) {
const shotTypeWidget = settingsNode.widgets.find(w => w && w.name === "shotType");
const usePromptExtendWidget = settingsNode.widgets.find(w => w && w.name === "usePromptExtend");
const promptExtendWidget = settingsNode.widgets.find(w => w && w.name === "promptExtend");
const useSyncModeWidget = settingsNode.widgets.find(w => w && w.name === "useSyncMode");
const syncModeWidget = settingsNode.widgets.find(w => w && w.name === "syncMode");
const useModeWidget = settingsNode.widgets.find(w => w && w.name === "useMode");
const modeWidget = settingsNode.widgets.find(w => w && w.name === "mode");
const useEmotionWidget = settingsNode.widgets.find(w => w && w.name === "useEmotion");
const emotionWidget = settingsNode.widgets.find(w => w && w.name === "emotion");
const useTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w && w.name === "temperature");
const useOcclusionDetectionWidget = settingsNode.widgets.find(w => w && w.name === "useOcclusionDetection");
const occlusionDetectionWidget = settingsNode.widgets.find(w => w && w.name === "occlusionDetection");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
@@ -1426,6 +1436,152 @@ function videoSettingsToggleHandler(settingsNode) {
if (useMultiClipWidget && multiClipWidget) toggleWidgetState(useMultiClipWidget, multiClipWidget, "multiClip");
if (useShotTypeWidget && shotTypeWidget) toggleWidgetState(useShotTypeWidget, shotTypeWidget, "shotType");
if (usePromptExtendWidget && promptExtendWidget) toggleWidgetState(usePromptExtendWidget, promptExtendWidget, "promptExtend");
if (useSyncModeWidget && syncModeWidget) toggleWidgetState(useSyncModeWidget, syncModeWidget, "syncMode");
if (useModeWidget && modeWidget) toggleWidgetState(useModeWidget, modeWidget, "mode");
if (useEmotionWidget && emotionWidget) toggleWidgetState(useEmotionWidget, emotionWidget, "emotion");
if (useTemperatureWidget && temperatureWidget) toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
if (useOcclusionDetectionWidget && occlusionDetectionWidget) toggleWidgetState(useOcclusionDetectionWidget, occlusionDetectionWidget, "occlusionDetection");
}
function videoInferenceSettingsTtsToggleHandler(node) {
if (!node?.widgets) return;
const useStabilityWidget = node.widgets.find(w => w && w.name === "useStability");
const stabilityWidget = node.widgets.find(w => w && w.name === "stability");
const useSimilarityBoostWidget = node.widgets.find(w => w && w.name === "useSimilarityBoost");
const similarityBoostWidget = node.widgets.find(w => w && w.name === "similarityBoost");
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 (useStabilityWidget && stabilityWidget) toggleWidgetState(useStabilityWidget, stabilityWidget, "stability");
if (useSimilarityBoostWidget && similarityBoostWidget) toggleWidgetState(useSimilarityBoostWidget, similarityBoostWidget, "similarityBoost");
}
function videoInferenceSettingsActiveSpeakerDetectionToggleHandler(node) {
if (!node?.widgets) return;
const useAutoDetectWidget = node.widgets.find(w => w && w.name === "useAutoDetect");
const autoDetectWidget = node.widgets.find(w => w && w.name === "autoDetect");
const useFrameNumberWidget = node.widgets.find(w => w && w.name === "useFrameNumber");
const frameNumberWidget = node.widgets.find(w => w && w.name === "frameNumber");
const useCoordinatesWidget = node.widgets.find(w => w && w.name === "useCoordinates");
const coordinateXWidget = node.widgets.find(w => w && w.name === "coordinateX");
const coordinateYWidget = node.widgets.find(w => w && w.name === "coordinateY");
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 (useAutoDetectWidget && autoDetectWidget) toggleWidgetState(useAutoDetectWidget, autoDetectWidget, "autoDetect");
if (useFrameNumberWidget && frameNumberWidget) toggleWidgetState(useFrameNumberWidget, frameNumberWidget, "frameNumber");
if (useCoordinatesWidget && coordinateXWidget) toggleWidgetState(useCoordinatesWidget, coordinateXWidget, "coordinateX");
if (useCoordinatesWidget && coordinateYWidget) toggleWidgetState(useCoordinatesWidget, coordinateYWidget, "coordinateY");
}
function videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler(node) {
if (!node?.widgets) return;
const useBox1Widget = node.widgets.find(w => w && w.name === "useBox1");
const box1Widget = node.widgets.find(w => w && w.name === "box1");
const useBox2Widget = node.widgets.find(w => w && w.name === "useBox2");
const box2Widget = node.widgets.find(w => w && w.name === "box2");
const useBox3Widget = node.widgets.find(w => w && w.name === "useBox3");
const box3Widget = node.widgets.find(w => w && w.name === "box3");
const useBox4Widget = node.widgets.find(w => w && w.name === "useBox4");
const box4Widget = node.widgets.find(w => w && w.name === "box4");
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 (useBox1Widget && box1Widget) toggleWidgetState(useBox1Widget, box1Widget, "box1");
if (useBox2Widget && box2Widget) toggleWidgetState(useBox2Widget, box2Widget, "box2");
if (useBox3Widget && box3Widget) toggleWidgetState(useBox3Widget, box3Widget, "box3");
if (useBox4Widget && box4Widget) toggleWidgetState(useBox4Widget, box4Widget, "box4");
}
function videoInferenceSettingsSegmentsToggleHandler(node) {
if (!node?.widgets) return;
function byName(name) {
return node.widgets.find(w => w && w.name === name);
}
function togglePair(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));
}
function wireSegment(idx) {
const useSegment = byName(`useSegment${idx}`);
const start = byName(`segment${idx}StartTime`);
const end = byName(`segment${idx}EndTime`);
const audio = byName(`segment${idx}Audio`);
const useCrop = byName(`useSegment${idx}AudioCrop`);
const cropStart = byName(`segment${idx}AudioStartTime`);
const cropEnd = byName(`segment${idx}AudioEndTime`);
if (useSegment && start) togglePair(useSegment, start, `segment${idx}StartTime`);
if (useSegment && end) togglePair(useSegment, end, `segment${idx}EndTime`);
if (useSegment && audio) togglePair(useSegment, audio, `segment${idx}Audio`);
if (useSegment && useCrop) togglePair(useSegment, useCrop, `useSegment${idx}AudioCrop`);
if (useCrop && cropStart) togglePair(useCrop, cropStart, `segment${idx}AudioStartTime`);
if (useCrop && cropEnd) togglePair(useCrop, cropEnd, `segment${idx}AudioEndTime`);
}
wireSegment(1);
wireSegment(2);
wireSegment(3);
wireSegment(4);
}
function audioInferenceSpeechToggleHandler(speechNode) {
@@ -2620,6 +2776,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
"sync:lipsync-2@1 (Sync LipSync 2)",
"sync:lipsync-2-pro@1 (Sync LipSync 2 Pro)",
"sync:react-1@1 (Sync React-1)",
"sync:3@0 (sync-3)",
],
"Bria": [
"bria:60@1 (Bria Video Eraser)",
@@ -2726,6 +2883,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
"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},
"sync:3@0": {"width": 1280, "height": 720},
"bria:60@1": {"width": 1280, "height": 720},
"creatify:aurora@fast": {"width": 1280, "height": 720},
"creatify:aurora@0": {"width": 1280, "height": 720},
@@ -2815,6 +2973,7 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
"sync:lipsync-2@1": "720p",
"sync:lipsync-2-pro@1": "720p",
"sync:react-1@1": "720p",
"sync:3@0": "720p",
"bria:60@1": "720p",
"creatify:aurora@fast": "720p",
"creatify:aurora@0": "720p",
@@ -4623,6 +4782,10 @@ export {
audioSettingsToggleHandler,
textInferenceSettingsToggleHandler,
videoSettingsToggleHandler,
videoInferenceSettingsTtsToggleHandler,
videoInferenceSettingsActiveSpeakerDetectionToggleHandler,
videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler,
videoInferenceSettingsSegmentsToggleHandler,
acceleratorOptionsToggleHandler,
bytedanceProviderSettingsToggleHandler,
xaiProviderSettingsToggleHandler,
+1 -1
View File
@@ -141,7 +141,7 @@ class txt2vid:
"tooltip": "Connect a Runware Accelerator Options Node to configure caching and acceleration settings.",
}),
"settings": ("RUNWAREVIDEOSETTINGS", {
"tooltip": "Connect a Runware Video Inference Settings node to configure draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, etc.",
"tooltip": "Connect a Runware Video Inference Settings node to configure draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, tts, activeSpeakerDetection, segments, etc.",
}),
}
}
@@ -0,0 +1,74 @@
"""
Runware Video Inference Settings Active Speaker Bounding Boxes
Builds settings.activeSpeakerDetection.boundingBoxes for Sync models.
Each element is [x1, y1, x2, y2] or null. Up to 4 elements.
"""
from typing import Dict, Any
def _parse_box(raw: str, label: str):
value = (raw or "").strip()
if value == "" or value.lower() == "null":
return None
parts = [p.strip() for p in value.split(",")]
if len(parts) != 4:
raise ValueError(f"{label} must be 'x1,y1,x2,y2' or null.")
try:
return [float(parts[0]), float(parts[1]), float(parts[2]), float(parts[3])]
except ValueError as exc:
raise ValueError(f"{label} values must be numbers.") from exc
class RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes:
"""Optional settings.activeSpeakerDetection.boundingBoxes block for Sync."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useBox1": ("BOOLEAN", {"tooltip": "Enable bounding box element 1.", "default": False}),
"box1": ("STRING", {"tooltip": "Element 1 as 'x1,y1,x2,y2' or null.", "default": ""}),
"useBox2": ("BOOLEAN", {"tooltip": "Enable bounding box element 2.", "default": False}),
"box2": ("STRING", {"tooltip": "Element 2 as 'x1,y1,x2,y2' or null.", "default": ""}),
"useBox3": ("BOOLEAN", {"tooltip": "Enable bounding box element 3.", "default": False}),
"box3": ("STRING", {"tooltip": "Element 3 as 'x1,y1,x2,y2' or null.", "default": ""}),
"useBox4": ("BOOLEAN", {"tooltip": "Enable bounding box element 4.", "default": False}),
"box4": ("STRING", {"tooltip": "Element 4 as 'x1,y1,x2,y2' or null.", "default": ""}),
},
}
RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES",)
RETURN_NAMES = ("boundingBoxes",)
FUNCTION = "create"
CATEGORY = "Runware"
DESCRIPTION = (
"Configure settings.activeSpeakerDetection.boundingBoxes for Runware Video Inference. "
"Supports up to 4 elements, each [x1, y1, x2, y2] or null."
)
def create(self, **kwargs) -> tuple[list]:
boxes = []
if kwargs.get("useBox1", False):
boxes.append(_parse_box(kwargs.get("box1", ""), "box1"))
if kwargs.get("useBox2", False):
boxes.append(_parse_box(kwargs.get("box2", ""), "box2"))
if kwargs.get("useBox3", False):
boxes.append(_parse_box(kwargs.get("box3", ""), "box3"))
if kwargs.get("useBox4", False):
boxes.append(_parse_box(kwargs.get("box4", ""), "box4"))
return (boxes[:4],)
NODE_CLASS_MAPPINGS = {
"RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes": RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoInferenceSettingsActiveSpeakerBoundingBoxes": "Runware Video Inference Settings Active Speaker Bounding Boxes",
}
@@ -0,0 +1,97 @@
"""
Runware Video Inference Settings Active Speaker Detection
Exposes settings.activeSpeakerDetection fields for Sync models.
Connect optional boundingBoxes from the dedicated bounding-boxes node.
Connect the output to Runware Video Inference Settings -> activeSpeakerDetection.
"""
from typing import Dict, Any
class RunwareVideoInferenceSettingsActiveSpeakerDetection:
"""Optional settings.activeSpeakerDetection block for video inference (Sync)."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useAutoDetect": ("BOOLEAN", {
"tooltip": "Enable to include autoDetect in settings.activeSpeakerDetection.",
"default": False,
}),
"autoDetect": ("BOOLEAN", {
"tooltip": "Let Sync choose the active speaker automatically. Only used when 'Use Auto Detect' is enabled.",
"default": True,
"label_on": "true",
"label_off": "false",
}),
"useFrameNumber": ("BOOLEAN", {
"tooltip": "Enable to include frameNumber in settings.activeSpeakerDetection.",
"default": False,
}),
"frameNumber": ("INT", {
"tooltip": "Frame index corresponding to the provided face coordinates. Only used when 'Use Frame Number' is enabled.",
"default": 0,
"min": 0,
"max": 1000000,
"step": 1,
}),
"useCoordinates": ("BOOLEAN", {
"tooltip": "Enable to include coordinates ([x, y]) in settings.activeSpeakerDetection.",
"default": False,
}),
"coordinateX": ("FLOAT", {
"tooltip": "X point on the target speaker face for the selected frame. Must be an integer in range 1-4096. Only used when 'Use Coordinates' is enabled.",
"default": 512.0,
"min": 1.0,
"max": 4096.0,
"step": 1.0,
}),
"coordinateY": ("FLOAT", {
"tooltip": "Y point on the target speaker face for the selected frame. Must be an integer in range 1-4096. Only used when 'Use Coordinates' is enabled.",
"default": 512.0,
"min": 1.0,
"max": 4096.0,
"step": 1.0,
}),
"boundingBoxes": ("RUNWAREVIDEOINFERENCESETTINGSACTIVESPEAKERBOUNDINGBOXES", {
"tooltip": "Connect Runware Video Inference Settings Active Speaker Bounding Boxes (up to 4 elements).",
}),
},
}
RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION",)
RETURN_NAMES = ("activeSpeakerDetection",)
FUNCTION = "create"
CATEGORY = "Runware"
DESCRIPTION = (
"Configure settings.activeSpeakerDetection (autoDetect, frameNumber, coordinates, boundingBoxes) "
"for Runware Video Inference. Connect to Runware Video Inference Settings -> activeSpeakerDetection (Sync)."
)
def create(self, **kwargs) -> tuple[Dict[str, Any]]:
active_speaker: Dict[str, Any] = {}
if kwargs.get("useAutoDetect", False):
active_speaker["autoDetect"] = bool(kwargs.get("autoDetect", True))
if kwargs.get("useFrameNumber", False):
active_speaker["frameNumber"] = int(kwargs.get("frameNumber", 0))
if kwargs.get("useCoordinates", False):
x = int(round(float(kwargs.get("coordinateX", 512.0))))
y = int(round(float(kwargs.get("coordinateY", 512.0))))
x = max(1, min(4096, x))
y = max(1, min(4096, y))
active_speaker["coordinates"] = [x, y]
bounding_boxes = kwargs.get("boundingBoxes", None)
if isinstance(bounding_boxes, list) and len(bounding_boxes) > 0:
active_speaker["boundingBoxes"] = bounding_boxes[:4]
return (active_speaker,)
NODE_CLASS_MAPPINGS = {
"RunwareVideoInferenceSettingsActiveSpeakerDetection": RunwareVideoInferenceSettingsActiveSpeakerDetection,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoInferenceSettingsActiveSpeakerDetection": "Runware Video Inference Settings Active Speaker Detection",
}
+101
View File
@@ -0,0 +1,101 @@
"""
Runware Video Inference Settings Segments
Builds settings.segments[] for Sync models.
Each segment can include startTime, endTime, audio, and optional audio crop range.
"""
from typing import Any
class RunwareVideoInferenceSettingsSegments:
"""Optional settings.segments[] block for video inference (Sync)."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useSegment1": ("BOOLEAN", {"default": False, "tooltip": "Enable segment 1."}),
"segment1StartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 1 start time in seconds."}),
"segment1EndTime": ("FLOAT", {"default": 1.0, "step": 0.01, "tooltip": "Segment 1 end time in seconds."}),
"segment1Audio": ("STRING", {"default": "", "tooltip": "Segment 1 audio mediaUUID. Connect from Runware Media Upload output."}),
"useSegment1AudioCrop": ("BOOLEAN", {"default": False, "tooltip": "Enable audioStartTime/audioEndTime for segment 1."}),
"segment1AudioStartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 1 audio crop start time in seconds."}),
"segment1AudioEndTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 1 audio crop end time in seconds."}),
"useSegment2": ("BOOLEAN", {"default": False, "tooltip": "Enable segment 2."}),
"segment2StartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 2 start time in seconds."}),
"segment2EndTime": ("FLOAT", {"default": 1.0, "step": 0.01, "tooltip": "Segment 2 end time in seconds."}),
"segment2Audio": ("STRING", {"default": "", "tooltip": "Segment 2 audio mediaUUID. Connect from Runware Media Upload output."}),
"useSegment2AudioCrop": ("BOOLEAN", {"default": False, "tooltip": "Enable audioStartTime/audioEndTime for segment 2."}),
"segment2AudioStartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 2 audio crop start time in seconds."}),
"segment2AudioEndTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 2 audio crop end time in seconds."}),
"useSegment3": ("BOOLEAN", {"default": False, "tooltip": "Enable segment 3."}),
"segment3StartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 3 start time in seconds."}),
"segment3EndTime": ("FLOAT", {"default": 1.0, "step": 0.01, "tooltip": "Segment 3 end time in seconds."}),
"segment3Audio": ("STRING", {"default": "", "tooltip": "Segment 3 audio mediaUUID. Connect from Runware Media Upload output."}),
"useSegment3AudioCrop": ("BOOLEAN", {"default": False, "tooltip": "Enable audioStartTime/audioEndTime for segment 3."}),
"segment3AudioStartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 3 audio crop start time in seconds."}),
"segment3AudioEndTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 3 audio crop end time in seconds."}),
"useSegment4": ("BOOLEAN", {"default": False, "tooltip": "Enable segment 4."}),
"segment4StartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 4 start time in seconds."}),
"segment4EndTime": ("FLOAT", {"default": 1.0, "step": 0.01, "tooltip": "Segment 4 end time in seconds."}),
"segment4Audio": ("STRING", {"default": "", "tooltip": "Segment 4 audio mediaUUID. Connect from Runware Media Upload output."}),
"useSegment4AudioCrop": ("BOOLEAN", {"default": False, "tooltip": "Enable audioStartTime/audioEndTime for segment 4."}),
"segment4AudioStartTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 4 audio crop start time in seconds."}),
"segment4AudioEndTime": ("FLOAT", {"default": 0.0, "step": 0.01, "tooltip": "Segment 4 audio crop end time in seconds."}),
},
}
RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSSEGMENTS",)
RETURN_NAMES = ("segments",)
FUNCTION = "create"
CATEGORY = "Runware"
DESCRIPTION = (
"Configure settings.segments[] for Runware Video Inference (Sync). "
"Each enabled segment includes startTime, endTime, audio and optional audioStartTime/audioEndTime."
)
def _build_segment(self, kwargs: dict[str, Any], idx: int) -> dict[str, Any]:
start = float(kwargs.get(f"segment{idx}StartTime", 0.0))
end = float(kwargs.get(f"segment{idx}EndTime", 1.0))
audio = (kwargs.get(f"segment{idx}Audio", "") or "").strip()
if audio == "":
raise ValueError(f"segment{idx}Audio is required when segment {idx} is enabled.")
if end < start:
raise ValueError(f"segment{idx}EndTime must be >= segment{idx}StartTime.")
segment: dict[str, Any] = {
"startTime": start,
"endTime": end,
"audio": audio,
}
if kwargs.get(f"useSegment{idx}AudioCrop", False):
astart = float(kwargs.get(f"segment{idx}AudioStartTime", 0.0))
aend = float(kwargs.get(f"segment{idx}AudioEndTime", 0.0))
if aend < astart:
raise ValueError(f"segment{idx}AudioEndTime must be >= segment{idx}AudioStartTime.")
segment["audioStartTime"] = astart
segment["audioEndTime"] = aend
return segment
def create(self, **kwargs) -> tuple[list]:
segments: list[dict[str, Any]] = []
for idx in (1, 2, 3, 4):
if kwargs.get(f"useSegment{idx}", False):
segments.append(self._build_segment(kwargs, idx))
return (segments,)
NODE_CLASS_MAPPINGS = {
"RunwareVideoInferenceSettingsSegments": RunwareVideoInferenceSettingsSegments,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoInferenceSettingsSegments": "Runware Video Inference Settings Segments",
}
+67
View File
@@ -0,0 +1,67 @@
"""
Runware Video Inference Settings TTS
Exposes settings.tts fields (stability, similarityBoost) for Sync / ElevenLabs-style tuning.
Connect the output to Runware Video Inference Settings → tts.
"""
from typing import Dict, Any
class RunwareVideoInferenceSettingsTts:
"""Optional settings.tts block for video inference (Sync)."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useStability": ("BOOLEAN", {
"tooltip": "Enable to include stability in settings.tts.",
"default": False,
}),
"stability": ("FLOAT", {
"tooltip": "TTS stability (0–1). Optional Sync / ElevenLabs-style tuning. Only used when 'Use Stability' is enabled.",
"default": 0.5,
"min": 0.0,
"max": 1.0,
"step": 0.01,
}),
"useSimilarityBoost": ("BOOLEAN", {
"tooltip": "Enable to include similarityBoost in settings.tts.",
"default": False,
}),
"similarityBoost": ("FLOAT", {
"tooltip": "TTS similarity boost (0–1). Optional Sync / ElevenLabs-style tuning. Only used when 'Use Similarity Boost' is enabled.",
"default": 0.75,
"min": 0.0,
"max": 1.0,
"step": 0.01,
}),
},
}
RETURN_TYPES = ("RUNWAREVIDEOINFERENCESETTINGSTTS",)
RETURN_NAMES = ("tts",)
FUNCTION = "create"
CATEGORY = "Runware"
DESCRIPTION = (
"Configure settings.tts (stability, similarityBoost) for Runware Video Inference. "
"Connect to Runware Video Inference Settings → tts (Sync)."
)
def create(self, **kwargs) -> tuple[Dict[str, Any]]:
tts: Dict[str, Any] = {}
if kwargs.get("useStability", False):
tts["stability"] = float(kwargs.get("stability", 0.5))
if kwargs.get("useSimilarityBoost", False):
tts["similarityBoost"] = float(kwargs.get("similarityBoost", 0.75))
return (tts,)
NODE_CLASS_MAPPINGS = {
"RunwareVideoInferenceSettingsTts": RunwareVideoInferenceSettingsTts,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareVideoInferenceSettingsTts": "Runware Video Inference Settings TTS",
}
+3
View File
@@ -104,6 +104,7 @@ class videoModelSearch:
"sync:lipsync-2@1 (Sync LipSync 2)",
"sync:lipsync-2-pro@1 (Sync LipSync 2 Pro)",
"sync:react-1@1 (Sync React-1)",
"sync:3@0 (sync-3)",
],
"Bria": [
"bria:60@1 (Bria Video Eraser)",
@@ -236,6 +237,7 @@ class videoModelSearch:
"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},
"sync:3@0": {"width": 1280, "height": 720},
# Bria Models
"bria:60@1": {"width": 0, "height": 0},
@@ -367,6 +369,7 @@ class videoModelSearch:
"sync:lipsync-2@1": "720p",
"sync:lipsync-2-pro@1": "720p",
"sync:react-1@1": "720p",
"sync:3@0": "720p",
# Bria Models
"bria:60@1": "720p",
+86 -2
View File
@@ -1,6 +1,6 @@
"""
Runware Video Inference Settings Node
Provides settings (draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, etc.) for Runware Video Inference.
Provides settings (draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference.
"""
from typing import Dict, Any
@@ -123,6 +123,60 @@ class RunwareVideoSettings:
"label_on": "Enabled",
"label_off": "Disabled",
}),
"useSyncMode": ("BOOLEAN", {
"tooltip": "Enable to include syncMode in video inference settings.",
"default": False,
}),
"syncMode": (["bounce", "cut_off", "silence", "remap"], {
"tooltip": "Controls how mismatched audio/video lengths are handled. Default provider behavior is usually cropping to shorter duration. Only used when 'Use Sync Mode' is enabled.",
"default": "cut_off",
}),
"tts": ("RUNWAREVIDEOINFERENCESETTINGSTTS", {
"tooltip": "Connect Runware Video Inference Settings TTS for settings.tts (stability, similarityBoost). Sync / ElevenLabs-style optional tuning.",
}),
"activeSpeakerDetection": ("RUNWAREVIDEOINFERENCESETTINGSACTIVESPEAKERDETECTION", {
"tooltip": "Connect Runware Video Inference Settings Active Speaker Detection for settings.activeSpeakerDetection (autoDetect, frameNumber, coordinates).",
}),
"useMode": ("BOOLEAN", {
"tooltip": "Enable to include mode in video inference settings.",
"default": False,
}),
"mode": (["lips", "face", "head"], {
"tooltip": "Sync processing mode. Only used when 'Use Mode' is enabled.",
"default": "lips",
}),
"useEmotion": ("BOOLEAN", {
"tooltip": "Enable to include emotion in video inference settings.",
"default": False,
}),
"emotion": (["happy", "sad", "angry", "disgusted", "surprised", "neutral"], {
"tooltip": "Target emotion for generation. Only used when 'Use Emotion' is enabled.",
"default": "neutral",
}),
"useTemperature": ("BOOLEAN", {
"tooltip": "Enable to include temperature in video inference settings.",
"default": False,
}),
"temperature": ("FLOAT", {
"tooltip": "Sampling temperature. Only used when 'Use Temperature' is enabled.",
"default": 0.7,
"min": 0.0,
"max": 5.0,
"step": 0.01,
}),
"useOcclusionDetection": ("BOOLEAN", {
"tooltip": "Enable to include occlusionDetection in video inference settings.",
"default": False,
}),
"occlusionDetection": ("BOOLEAN", {
"tooltip": "Enable occlusion detection. Only used when 'Use Occlusion Detection' is enabled.",
"default": False,
"label_on": "true",
"label_off": "false",
}),
"segments": ("RUNWAREVIDEOINFERENCESETTINGSSEGMENTS", {
"tooltip": "Connect Runware Video Inference Settings Segments for settings.segments[] (startTime, endTime, audio, audioStartTime, audioEndTime).",
}),
}
}
@@ -131,7 +185,7 @@ class RunwareVideoSettings:
FUNCTION = "createSettings"
CATEGORY = "Runware"
DESCRIPTION = (
"Configure video inference settings (draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, etc.) for Runware Video Inference. "
"Configure video inference settings (draft, audio, promptUpsampling, voiceDescription, style, thinking, multiClip, shotType, promptExtend, syncMode, mode, emotion, temperature, occlusionDetection, tts, activeSpeakerDetection, segments, etc.) for Runware Video Inference. "
"Connect to Runware Video Inference node."
)
@@ -161,6 +215,19 @@ class RunwareVideoSettings:
shot_type = kwargs.get("shotType", "single")
use_prompt_extend = kwargs.get("usePromptExtend", False)
prompt_extend = kwargs.get("promptExtend", False)
use_sync_mode = kwargs.get("useSyncMode", False)
sync_mode = kwargs.get("syncMode", "cut_off")
tts_cfg = kwargs.get("tts", None)
active_speaker_cfg = kwargs.get("activeSpeakerDetection", None)
use_mode = kwargs.get("useMode", False)
mode = kwargs.get("mode", "lips")
use_emotion = kwargs.get("useEmotion", False)
emotion = kwargs.get("emotion", "neutral")
use_temperature = kwargs.get("useTemperature", False)
temperature = kwargs.get("temperature", 0.7)
use_occlusion_detection = kwargs.get("useOcclusionDetection", False)
occlusion_detection = kwargs.get("occlusionDetection", False)
segments_cfg = kwargs.get("segments", None)
settings: Dict[str, Any] = {}
@@ -188,6 +255,23 @@ class RunwareVideoSettings:
settings["shotType"] = shot_type
if use_prompt_extend:
settings["promptExtend"] = bool(prompt_extend)
if use_sync_mode:
settings["syncMode"] = sync_mode
if use_mode:
settings["mode"] = mode
if use_emotion:
settings["emotion"] = emotion
if use_temperature:
settings["temperature"] = float(temperature)
if use_occlusion_detection:
settings["occlusionDetection"] = bool(occlusion_detection)
if tts_cfg is not None and isinstance(tts_cfg, dict) and len(tts_cfg) > 0:
settings["tts"] = tts_cfg
if active_speaker_cfg is not None and isinstance(active_speaker_cfg, dict) and len(active_speaker_cfg) > 0:
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
return (settings,)
File diff suppressed because one or more lines are too long