Rename Bria Provider Key Points to Bria Provider Mask and move all mask params; Add Bria Video Eraser model to video search

This commit is contained in:
Sirshendu Ganguly
2025-12-22 16:42:17 -05:00
parent 98ad05f11b
commit 785d5b4561
7 changed files with 165 additions and 49 deletions
+2 -2
View File
@@ -32,7 +32,7 @@ from .modules.providerSettings.pixverseProviderSettings import RunwarePixversePr
from .modules.providerSettings.openaiProviderSettings import RunwareOpenAIProviderSettings
from .modules.providerSettings.bytedanceImageProviderSettings import RunwareBytedanceProviderSettings
from .modules.providerSettings.briaImageProviderSettings import RunwareBriaProviderSettings
from .modules.providerSettings.briaProviderKeyPoints import RunwareBriaProviderKeyPoints
from .modules.providerSettings.briaProviderMask import RunwareBriaProviderMask
from .modules.audioInference import RunwareAudioInference
from .modules.audioModelSearch import RunwareAudioModelSearch
from .modules.audioSections import RunwareAudioSections
@@ -114,7 +114,7 @@ NODE_CLASS_MAPPINGS = {
"Runware OpenAI Provider Settings": RunwareOpenAIProviderSettings,
"Runware Bytedance Provider Settings": RunwareBytedanceProviderSettings,
"Runware Bria Provider Settings": RunwareBriaProviderSettings,
"Runware Bria Provider Key Points": RunwareBriaProviderKeyPoints,
"Runware Bria Provider Mask": RunwareBriaProviderMask,
"Runware Audio Inference": RunwareAudioInference,
"Runware Audio Model Search": RunwareAudioModelSearch,
"Runware Audio Sections": RunwareAudioSections,
+3 -3
View File
@@ -1,6 +1,6 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, videoTranscriptionHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderKeyPointsToggleHandler } from "./utils.js";
import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, videoTranscriptionHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler } from "./utils.js";
import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js";
const nodeInitList = [];
@@ -85,8 +85,8 @@ app.registerExtension({
audioInputToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.SPEECHINPUT) {
speechInputToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.BRIAPROVIDERKEYPOINTS) {
briaProviderKeyPointsToggleHandler(node);
} else if(nodeClass === RUNWARE_NODE_TYPES.BRIAPROVIDERMASK) {
briaProviderMaskToggleHandler(node);
}
if(crNodeProps.colorModeOnly === true) return;
+2 -2
View File
@@ -86,7 +86,7 @@ const RUNWARE_NODE_TYPES = {
OPENAIPROVIDERSETTINGS: "Runware OpenAI Provider Settings",
BYTEDANCEPROVIDERSETTINGS: "Runware Bytedance Provider Settings",
BRIAPROVIDERSETTINGS: "Runware Bria Provider Settings",
BRIAPROVIDERKEYPOINTS: "Runware Bria Provider Key Points",
BRIAPROVIDERMASK: "Runware Bria Provider Mask",
ELEVENLABSPROVIDERSETTINGS: "Runware ElevenLabs Provider Settings",
ELEVENLABSPROVIDERSETTINGSSECTIONS: "Runware ElevenLabs Provider Settings Sections",
VIDUPROVIDERSETTINGS: "Runware Vidu Provider Settings",
@@ -276,7 +276,7 @@ const RUNWARE_NODE_PROPS = {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
[RUNWARE_NODE_TYPES.BRIAPROVIDERKEYPOINTS]: {
[RUNWARE_NODE_TYPES.BRIAPROVIDERMASK]: {
bgColor: DEFAULT_BGCOLOR,
colorModeOnly: true,
},
+31 -24
View File
@@ -2425,12 +2425,8 @@ function briaProviderSettingsToggleHandler(briaNode) {
const forceBackgroundDetectionWidget = briaNode.widgets.find(w => w.name === "forceBackgroundDetection");
const useAutoTrimWidget = briaNode.widgets.find(w => w.name === "useAutoTrim");
const autoTrimWidget = briaNode.widgets.find(w => w.name === "autoTrim");
const useMaskForegroundWidget = briaNode.widgets.find(w => w.name === "useMaskForeground");
const maskForegroundWidget = briaNode.widgets.find(w => w.name === "maskForeground");
const useMaskPromptWidget = briaNode.widgets.find(w => w.name === "useMaskPrompt");
const maskPromptWidget = briaNode.widgets.find(w => w.name === "maskPrompt");
const useMaskFrameIndexWidget = briaNode.widgets.find(w => w.name === "useMaskFrameIndex");
const maskFrameIndexWidget = briaNode.widgets.find(w => w.name === "maskFrameIndex");
const usePreserveAudioWidget = briaNode.widgets.find(w => w.name === "usePreserveAudio");
const preserveAudioWidget = briaNode.widgets.find(w => w.name === "preserveAudio");
// Helper function to toggle widget enabled state (exact same pattern)
function toggleWidgetState(useWidget, paramWidget, paramName) {
@@ -2539,16 +2535,8 @@ function briaProviderSettingsToggleHandler(briaNode) {
toggleWidgetState(useAutoTrimWidget, autoTrimWidget, "autoTrim");
}
if (useMaskForegroundWidget && maskForegroundWidget) {
toggleWidgetState(useMaskForegroundWidget, maskForegroundWidget, "maskForeground");
}
if (useMaskPromptWidget && maskPromptWidget) {
toggleWidgetState(useMaskPromptWidget, maskPromptWidget, "maskPrompt");
}
if (useMaskFrameIndexWidget && maskFrameIndexWidget) {
toggleWidgetState(useMaskFrameIndexWidget, maskFrameIndexWidget, "maskFrameIndex");
if (usePreserveAudioWidget && preserveAudioWidget) {
toggleWidgetState(usePreserveAudioWidget, preserveAudioWidget, "preserveAudio");
}
}
@@ -2666,7 +2654,7 @@ function speechInputToggleHandler(speechInputNode) {
}
}
function briaProviderKeyPointsToggleHandler(keyPointsNode) {
function briaProviderMaskToggleHandler(maskNode) {
// Helper function to toggle widget enabled state for multiple widgets
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget || !paramWidgets || paramWidgets.length === 0) return;
@@ -2695,7 +2683,7 @@ function briaProviderKeyPointsToggleHandler(keyPointsNode) {
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl && paramNames[idx]) {
const nodeElement = keyPointsNode.htmlElements?.widgetsContainer || keyPointsNode.htmlElements;
const nodeElement = maskNode.htmlElements?.widgetsContainer || maskNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramNames[idx]}"], textarea[name="${paramNames[idx]}"], select[name="${paramNames[idx]}"]`);
if (input) {
@@ -2711,7 +2699,7 @@ function briaProviderKeyPointsToggleHandler(keyPointsNode) {
}
});
keyPointsNode.setDirtyCanvas(true);
maskNode.setDirtyCanvas(true);
}
// Set up callback
@@ -2723,12 +2711,31 @@ function briaProviderKeyPointsToggleHandler(keyPointsNode) {
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers for foreground, prompt, frameIndex
const useForegroundWidget = maskNode.widgets.find(w => w.name === "useForeground");
const foregroundWidget = maskNode.widgets.find(w => w.name === "foreground");
if (useForegroundWidget && foregroundWidget) {
toggleWidgetState(useForegroundWidget, [foregroundWidget], ["foreground"]);
}
const usePromptWidget = maskNode.widgets.find(w => w.name === "usePrompt");
const promptWidget = maskNode.widgets.find(w => w.name === "prompt");
if (usePromptWidget && promptWidget) {
toggleWidgetState(usePromptWidget, [promptWidget], ["prompt"]);
}
const useFrameIndexWidget = maskNode.widgets.find(w => w.name === "useFrameIndex");
const frameIndexWidget = maskNode.widgets.find(w => w.name === "frameIndex");
if (useFrameIndexWidget && frameIndexWidget) {
toggleWidgetState(useFrameIndexWidget, [frameIndexWidget], ["frameIndex"]);
}
// Set up toggle handlers for all 6 key points
for (let i = 1; i <= 6; i++) {
const useWidget = keyPointsNode.widgets.find(w => w.name === `use_${i}`);
const xWidget = keyPointsNode.widgets.find(w => w.name === `X${i}`);
const yWidget = keyPointsNode.widgets.find(w => w.name === `Y${i}`);
const typeWidget = keyPointsNode.widgets.find(w => w.name === `Type${i}`);
const useWidget = maskNode.widgets.find(w => w.name === `use_${i}`);
const xWidget = maskNode.widgets.find(w => w.name === `X${i}`);
const yWidget = maskNode.widgets.find(w => w.name === `Y${i}`);
const typeWidget = maskNode.widgets.find(w => w.name === `Type${i}`);
if (useWidget && xWidget && yWidget && typeWidget) {
toggleWidgetState(useWidget, [xWidget, yWidget, typeWidget], [`X${i}`, `Y${i}`, `Type${i}`]);
@@ -2769,7 +2776,7 @@ export {
settingsToggleHandler,
audioInputToggleHandler,
speechInputToggleHandler,
briaProviderKeyPointsToggleHandler,
briaProviderMaskToggleHandler,
};
function googleProviderSettingsToggleHandler(googleNode) {
@@ -130,6 +130,29 @@ class RunwareBriaProviderSettings:
"label_on": "Enabled",
"label_off": "Disabled",
}),
"usePreserveAudio": ("BOOLEAN", {
"tooltip": "Enable to include preserveAudio parameter in API request.",
"default": False,
}),
"preserveAudio": ("BOOLEAN", {
"tooltip": "Whether to keep the original audio track. Only used when 'Use Preserve Audio' is enabled.",
"default": True,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"useAutoTrim": ("BOOLEAN", {
"tooltip": "Enable to include autoTrim parameter in API request.",
"default": False,
}),
"autoTrim": ("BOOLEAN", {
"tooltip": "If true, videos longer than 5 seconds are trimmed to the first 5 seconds. If false, videos longer than 5 seconds are rejected. Only used when 'Use Auto Trim' is enabled.",
"default": False,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"Bria Provider Setting Mask": ("RUNWAREBRIAPROVIDERMASK", {
"tooltip": "Connect Runware Bria Provider Mask node to provide mask configuration for video eraser operations.",
}),
}
}
@@ -155,6 +178,8 @@ class RunwareBriaProviderSettings:
useRefinePrompt = kwargs.get("useRefinePrompt", False)
useOriginalQuality = kwargs.get("useOriginalQuality", False)
useForceBackgroundDetection = kwargs.get("useForceBackgroundDetection", False)
usePreserveAudio = kwargs.get("usePreserveAudio", False)
useAutoTrim = kwargs.get("useAutoTrim", False)
# Get actual parameters
medium = kwargs.get("medium", "photography")
@@ -169,6 +194,9 @@ class RunwareBriaProviderSettings:
refinePrompt = kwargs.get("refinePrompt", True)
originalQuality = kwargs.get("originalQuality", True)
forceBackgroundDetection = kwargs.get("forceBackgroundDetection", False)
preserveAudio = kwargs.get("preserveAudio", True)
autoTrim = kwargs.get("autoTrim", False)
mask = kwargs.get("Bria Provider Setting Mask", None)
# Build settings dictionary
settings = {}
@@ -221,6 +249,18 @@ class RunwareBriaProviderSettings:
if useForceBackgroundDetection:
settings["forceBackgroundDetection"] = forceBackgroundDetection
# Add preserveAudio only if usePreserveAudio is enabled
if usePreserveAudio:
settings["preserveAudio"] = preserveAudio
# Add autoTrim only if useAutoTrim is enabled
if useAutoTrim:
settings["autoTrim"] = autoTrim
# Add mask if provided from Mask node
if mask is not None and isinstance(mask, dict) and len(mask) > 0:
settings["mask"] = mask
# Clean up None values
settings = {k: v for k, v in settings.items() if v is not None}
@@ -1,19 +1,47 @@
"""
Runware Bria Provider Key Points Node
Creates key points configuration for Bria mask settings
Runware Bria Provider Mask Node
Creates mask configuration for Bria video eraser settings
"""
from typing import Optional, Dict, Any, List
class RunwareBriaProviderKeyPoints:
"""Runware Bria Provider Key Points Node"""
class RunwareBriaProviderMask:
"""Runware Bria Provider Mask Node"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": {
"useForeground": ("BOOLEAN", {
"tooltip": "Enable to include mask.foreground parameter in API request.",
"default": False,
}),
"foreground": ("BOOLEAN", {
"tooltip": "Triggers the foreground mask endpoint. Only used when 'Use Foreground' is enabled.",
"default": True,
"label_on": "Enabled",
"label_off": "Disabled",
}),
"usePrompt": ("BOOLEAN", {
"tooltip": "Enable to include mask.prompt parameter in API request.",
"default": False,
}),
"prompt": ("STRING", {
"tooltip": "Text instruction describing the object to be masked. Only used when 'Use Prompt' is enabled.",
"default": "",
"multiline": True,
}),
"useFrameIndex": ("BOOLEAN", {
"tooltip": "Enable to include mask.frameIndex parameter in API request.",
"default": False,
}),
"frameIndex": ("INT", {
"tooltip": "The frame number to apply key points to. Specifies which frame in the video to use for masking. Only used when 'Use Frame Index' is enabled.",
"default": 0,
"min": 0,
}),
"use_1": ("BOOLEAN", {
"tooltip": "Enable to include the first key point in the mask configuration.",
"default": False,
@@ -125,18 +153,42 @@ class RunwareBriaProviderKeyPoints:
}
}
RETURN_TYPES = ("RUNWAREBRIAPROVIDERKEYPOINTS",)
RETURN_NAMES = ("Key Points",)
FUNCTION = "createKeyPoints"
RETURN_TYPES = ("RUNWAREBRIAPROVIDERMASK",)
RETURN_NAMES = ("Bria Provider Setting Mask",)
FUNCTION = "createMask"
CATEGORY = "Runware/Provider Settings"
DESCRIPTION = "Create key points configuration for Bria mask settings. Each key point defines a coordinate (x, y) and type (positive/negative) to guide mask generation."
DESCRIPTION = "Create mask configuration for Bria video eraser settings. Supports foreground mask, text-based masking, and coordinate-based key points for precise object removal."
def createKeyPoints(self, **kwargs) -> tuple[List[Dict[str, Any]]]:
"""Create key points array from provided parameters"""
def createMask(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create mask configuration from provided parameters"""
mask: Dict[str, Any] = {}
maskEnabled = False
# Handle foreground
useForeground = kwargs.get("useForeground", False)
if useForeground:
foreground = kwargs.get("foreground", True)
mask["foreground"] = foreground
maskEnabled = True
# Handle prompt
usePrompt = kwargs.get("usePrompt", False)
if usePrompt:
prompt = kwargs.get("prompt", "").strip()
if prompt:
mask["prompt"] = prompt
maskEnabled = True
# Handle frameIndex
useFrameIndex = kwargs.get("useFrameIndex", False)
if useFrameIndex:
frameIndex = kwargs.get("frameIndex", 0)
mask["frameIndex"] = frameIndex
maskEnabled = True
# Process key points
keyPoints: List[Dict[str, Any]] = []
# Process up to 6 key points
for i in range(1, 7):
use_key = kwargs.get(f"use_{i}", False)
@@ -147,7 +199,6 @@ class RunwareBriaProviderKeyPoints:
point_type = kwargs.get(f"Type{i}", "positive")
# Only add key point if both x and y are provided and at least one is non-zero
# This allows users to leave unused key points at 0,0
if x > 0 or y > 0:
keyPoints.append({
"x": x,
@@ -155,15 +206,23 @@ class RunwareBriaProviderKeyPoints:
"type": point_type
})
return (keyPoints,)
# Add keyPoints if any were provided
if len(keyPoints) > 0:
mask["keyPoints"] = keyPoints
maskEnabled = True
# Only return mask if it has at least one property
if maskEnabled:
return (mask,)
else:
return ({},)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareBriaProviderKeyPoints": RunwareBriaProviderKeyPoints,
"RunwareBriaProviderMask": RunwareBriaProviderMask,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareBriaProviderKeyPoints": "Runware Bria Provider Key Points",
"RunwareBriaProviderMask": "Runware Bria Provider Mask",
}
+11 -1
View File
@@ -85,6 +85,9 @@ class videoModelSearch:
"sync:lipsync-2-pro@1 (Sync LipSync 2 Pro)",
"sync:react-1@1 (Sync React-1)",
],
"Bria": [
"bria:60@1 (Bria Video Eraser)",
],
}
# Model dimensions mapping
@@ -170,6 +173,9 @@ 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},
# Bria Models
"bria:60@1": {"width": 0, "height": 0},
}
# Model resolutions mapping
@@ -255,6 +261,9 @@ class videoModelSearch:
"sync:lipsync-2@1": "720p",
"sync:lipsync-2-pro@1": "720p",
"sync:react-1@1": "720p",
# Bria Models
"bria:60@1": "720p",
}
MODEL_ARCHITECTURES = [
@@ -271,7 +280,8 @@ class videoModelSearch:
"Ovi",
"Runway",
"Luma",
"Sync"
"Sync",
"Bria"
]
DEFAULT_DIMENSIONS = {"width": 1024, "height": 576}