Merge pull request #56 from Runware/feature-videoResolution
Add resolution parameter support for video models
This commit is contained in:
@@ -9,9 +9,14 @@ Imagine creating stunning images or videos, refining details, or even removing b
|
||||
This integration adds a suite of custom nodes to ComfyUI, allowing you to:
|
||||
- Perform advanced image inference tasks, including image generation and editing with powerful models.
|
||||
- Utilize PhotoMaker V2 pipelines
|
||||
- Leverage cutting-edge models like **Flux .1 Kontext Pro** and **Flux .1 Kontext Max** for superior image generation and editing.
|
||||
- Leverage cutting-edge image models like **Flux .1 Kontext Pro**, **Flux .1 Kontext Max**, **Nano Banana**, **Seedream**, and more for superior image generation and editing.
|
||||
- Upscale images
|
||||
- Remove backgrounds
|
||||
- Generate videos from text prompts and/or images with video inference
|
||||
- Generate audio from text
|
||||
- Upscale videos
|
||||
- Generate video captions
|
||||
- Remove video backgrounds
|
||||
- Leverage specialized models and LoRAs
|
||||
- Use your custom uploaded models and LoRAs
|
||||
|
||||
@@ -22,15 +27,22 @@ This integration adds a suite of custom nodes to ComfyUI, allowing you to:
|
||||
## 📖 Table of Contents
|
||||
|
||||
1. [Introduction](#-what-is-comfyui-runware)
|
||||
2. [Installation](#-installation)
|
||||
3. [Node Features](#-node-features)
|
||||
4. [Support & Community](#-support--community)
|
||||
2. [Workflows](#-workflows)
|
||||
3. [Installation](#-installation)
|
||||
4. [Node Features](#-node-features)
|
||||
5. [Support & Community](#-support--community)
|
||||
|
||||
---
|
||||
|
||||
Here’s a sneak peek of the ComfyUI-Runware nodes in action:
|
||||
## 🎬 Workflows
|
||||
|
||||

|
||||
Here are some example workflows showcasing the power of ComfyUI-Runware:
|
||||
|
||||
### Image Workflows
|
||||

|
||||
|
||||
### Video Workflows
|
||||

|
||||
|
||||
---
|
||||
|
||||
@@ -126,9 +138,22 @@ Here's a breakdown of the amazing nodes included in this integration:
|
||||
- **Runware Frame Images**: Configure keyframe images with precise positioning control for video generation. 🖼️➡️🎥
|
||||
- **Runware Reference Images**: Provide reference images for overall visual guidance in video generation. 🖼️
|
||||
|
||||
- **Runware Pixverse Provider Settings**: Configure Pixverse-specific settings with effect, style, motion, and sound options. 🎬
|
||||
- **Runware OpenAI Provider Settings**: Configure OpenAI-specific settings with quality, background, and style options. 🤖
|
||||
### Provider Settings
|
||||
|
||||
Configure provider-specific settings for various services:
|
||||
- **Runware Alibaba Provider Settings**: Configure Alibaba-specific settings. ☁️
|
||||
- **Runware BRIA Image Provider Settings**: Configure BRIA Image-specific settings. 🖼️
|
||||
- **Runware ByteDance Provider Settings**: Configure ByteDance-specific settings. 🎬
|
||||
- **Runware ElevenLabs Provider Settings**: Configure ElevenLabs-specific settings for audio generation. 🎤
|
||||
- **Runware Kling Provider Settings**: Configure Kling-specific settings. 🎥
|
||||
- **Runware Lightricks Provider Settings**: Configure Lightricks-specific settings. ✨
|
||||
- **Runware Luma Provider Settings**: Configure Luma-specific settings. 🎬
|
||||
- **Runware Midjourney Provider Settings**: Configure Midjourney-specific settings. 🎨
|
||||
- **Runware MiniMax Provider Settings**: Configure MiniMax-specific settings. 🤖
|
||||
- **Runware OpenAI Provider Settings**: Configure OpenAI-specific settings with quality, background, and style options. 🤖
|
||||
- **Runware Pixverse Provider Settings**: Configure Pixverse-specific settings with effect, style, motion, and sound options. 🎬
|
||||
- **Runware Runway Provider Settings**: Configure Runway-specific settings. 🎥
|
||||
- **Runware Vidu Provider Settings**: Configure Vidu-specific settings. 🎬
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ from .modules.providerSettings.klingProviderSettings import RunwareKlingProvider
|
||||
from .modules.providerSettings.runwayProviderSettings import RunwareRunwayProviderSettings
|
||||
from .modules.providerSettings.lumaProviderSettings import RunwareLumaProviderSettings
|
||||
from .modules.providerSettings.midjourneyProviderSettings import RunwareMidjourneyProviderSettings
|
||||
from .modules.providerSettings.alibabaProviderSettings import RunwareAlibabaProviderSettings
|
||||
from .modules.vectorize import vectorize
|
||||
from .modules.videoBgRemoval import videoBgRemoval
|
||||
from .modules.videoUpscaler import videoUpscaler
|
||||
@@ -121,6 +122,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"Runware KlingAI Provider Settings": RunwareKlingProviderSettings,
|
||||
"Runware Runway Provider Settings": RunwareRunwayProviderSettings,
|
||||
"Runware Midjourney Provider Settings": RunwareMidjourneyProviderSettings,
|
||||
"Runware Alibaba Provider Settings": RunwareAlibabaProviderSettings,
|
||||
"Runware Vectorize": vectorize,
|
||||
"Runware Video Background Removal": videoBgRemoval,
|
||||
"Runware Video Upscaler": videoUpscaler,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1020 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 780 KiB |
+3
-1
@@ -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 } 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 } from "./utils.js";
|
||||
import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js";
|
||||
|
||||
const nodeInitList = [];
|
||||
@@ -71,6 +71,8 @@ app.registerExtension({
|
||||
briaProviderSettingsToggleHandler(node);
|
||||
} else if(nodeClass === RUNWARE_NODE_TYPES.PIXVERSEPROVIDERSETTINGS) {
|
||||
pixverseProviderSettingsToggleHandler(node);
|
||||
} else if(nodeClass === RUNWARE_NODE_TYPES.ALIBABAPROVIDERSETTINGS) {
|
||||
alibabaProviderSettingsToggleHandler(node);
|
||||
}
|
||||
|
||||
if(crNodeProps.colorModeOnly === true) return;
|
||||
|
||||
@@ -99,6 +99,7 @@ const RUNWARE_NODE_TYPES = {
|
||||
RUNWAYPROVIDERSETTINGS: "Runware Runway Provider Settings",
|
||||
LUMAPROVIDERSETTINGS: "Runware Luma Provider Settings",
|
||||
MIDJOURNEYPROVIDERSETTINGS: "Runware Midjourney Provider Settings",
|
||||
ALIBABAPROVIDERSETTINGS: "Runware Alibaba Provider Settings",
|
||||
VECTORIZE: "Runware Vectorize",
|
||||
VIDEOBGREMOVAL: "Runware Video Background Removal",
|
||||
VIDEOUPSCALER: "Runware Video Upscaler",
|
||||
@@ -319,6 +320,10 @@ const RUNWARE_NODE_PROPS = {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
colorModeOnly: true,
|
||||
},
|
||||
[RUNWARE_NODE_TYPES.ALIBABAPROVIDERSETTINGS]: {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
colorModeOnly: true,
|
||||
},
|
||||
[RUNWARE_NODE_TYPES.VECTORIZE]: {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
},
|
||||
|
||||
@@ -1662,6 +1662,8 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
|
||||
const widthWidget = videoModelSearchNode.widgets.find(w => w.name === "Width");
|
||||
const heightWidget = videoModelSearchNode.widgets.find(w => w.name === "Height");
|
||||
const useCustomDimensionsWidget = videoModelSearchNode.widgets.find(w => w.name === "useCustomDimensions");
|
||||
const useResolutionWidget = videoModelSearchNode.widgets.find(w => w.name === "useResolution");
|
||||
const resolutionWidget = videoModelSearchNode.widgets.find(w => w.name === "resolution");
|
||||
|
||||
if (!modelArchWidget || !videoListWidget) return;
|
||||
|
||||
@@ -1776,6 +1778,60 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
|
||||
"lumaai:2@2": {"width": 1080, "height": 720},
|
||||
};
|
||||
|
||||
const MODEL_RESOLUTIONS = {
|
||||
"klingai:1@2": "720p",
|
||||
"klingai:1@1": "720p",
|
||||
"klingai:2@2": "1080p",
|
||||
"klingai:2@1": "720p",
|
||||
"klingai:3@1": "720p",
|
||||
"klingai:3@2": "1080p",
|
||||
"klingai:4@3": "720p",
|
||||
"klingai:5@1": "720p",
|
||||
"klingai:5@2": "1080p",
|
||||
"klingai:5@3": "1080p",
|
||||
"klingai:6@1": "1080p",
|
||||
"klingai:7@1": null, // No resolution support
|
||||
"klingai:kling@o1": null, // No standard resolution
|
||||
"google:2@0": "720p",
|
||||
"google:3@0": "720p",
|
||||
"google:3@1": "720p",
|
||||
"google:3@2": "720p",
|
||||
"google:3@3": "720p",
|
||||
"bytedance:2@1": "480p",
|
||||
"bytedance:1@1": "480p",
|
||||
"bytedance:5@1": null, // No resolution support
|
||||
"bytedance:5@2": null, // No resolution support
|
||||
"minimax:1@1": "768p",
|
||||
"minimax:2@1": "768p",
|
||||
"minimax:2@3": "768p",
|
||||
"minimax:3@1": "768p",
|
||||
"minimax:4@1": "768p",
|
||||
"minimax:4@2": "768p",
|
||||
"pixverse:1@1": "360p",
|
||||
"pixverse:1@2": "360p",
|
||||
"pixverse:1@3": "360p",
|
||||
"pixverse:1@6": "360p",
|
||||
"pixverse:lipsync@1": "360p",
|
||||
"vidu:1@0": "1080p",
|
||||
"vidu:1@1": "1080p",
|
||||
"vidu:1@5": "1080p",
|
||||
"vidu:2@0": "1080p",
|
||||
"runware:200@1": "480p",
|
||||
"runware:200@2": "480p",
|
||||
"runware:200@6": "720p",
|
||||
"openai:3@1": "720p",
|
||||
"openai:3@0": "720p",
|
||||
"lightricks:2@0": "1080p",
|
||||
"lightricks:2@1": "1080p",
|
||||
"lightricks:3@1": null, // No resolution support
|
||||
"runware:190@1": null, // No resolution support
|
||||
"runway:2@1": "720p",
|
||||
"runway:1@1": "720p",
|
||||
"lumaai:1@1": "720p",
|
||||
"lumaai:2@1": "720p",
|
||||
"lumaai:2@2": "720p",
|
||||
};
|
||||
|
||||
const DEFAULT_DIMENSIONS = {"width": 1024, "height": 576};
|
||||
|
||||
function setWidthHeightEnabled(enabled) {
|
||||
@@ -1836,6 +1892,49 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
|
||||
}
|
||||
// For "Custom" mode, don't update - let user set their own values
|
||||
// For "Disabled" mode, already handled above (set to None and disabled)
|
||||
|
||||
// Update resolution based on selected model
|
||||
if (resolutionWidget && useResolutionWidget) {
|
||||
const modelCode = selectedModel.split(" (")[0];
|
||||
const modelResolution = MODEL_RESOLUTIONS[modelCode];
|
||||
|
||||
// If model supports resolution
|
||||
if (modelResolution !== null && modelResolution !== undefined) {
|
||||
// Enable useResolution checkbox
|
||||
if (useResolutionWidget.inputEl) {
|
||||
useResolutionWidget.inputEl.disabled = false;
|
||||
useResolutionWidget.inputEl.style.opacity = "1";
|
||||
}
|
||||
useResolutionWidget.disabled = false;
|
||||
|
||||
// Only update resolution value if useResolution is enabled
|
||||
if (useResolutionWidget.value === true) {
|
||||
// Set resolution value to model's default
|
||||
if (resolutionWidget.callback) resolutionWidget.callback(modelResolution, "customSetOperation");
|
||||
resolutionWidget.value = modelResolution;
|
||||
}
|
||||
} else {
|
||||
// Model doesn't support resolution, disable useResolution checkbox and resolution dropdown
|
||||
if (useResolutionWidget.callback) useResolutionWidget.callback(false, "customSetOperation");
|
||||
useResolutionWidget.value = false;
|
||||
|
||||
// Disable useResolution checkbox
|
||||
if (useResolutionWidget.inputEl) {
|
||||
useResolutionWidget.inputEl.disabled = true;
|
||||
useResolutionWidget.inputEl.style.opacity = "0.5";
|
||||
}
|
||||
useResolutionWidget.disabled = true;
|
||||
|
||||
// Disable resolution dropdown
|
||||
if (resolutionWidget.inputEl) {
|
||||
resolutionWidget.inputEl.disabled = true;
|
||||
resolutionWidget.inputEl.style.opacity = "0.5";
|
||||
resolutionWidget.inputEl.style.cursor = "not-allowed";
|
||||
}
|
||||
resolutionWidget.disabled = true;
|
||||
}
|
||||
videoModelSearchNode.setDirtyCanvas(true);
|
||||
}
|
||||
}
|
||||
|
||||
function filterModelList() {
|
||||
@@ -1870,6 +1969,58 @@ function videoModelSearchFilterHandler(videoModelSearchNode) {
|
||||
updateDimensions();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle useResolution toggle
|
||||
if (useResolutionWidget && resolutionWidget) {
|
||||
function toggleResolutionState() {
|
||||
// Check if current model supports resolution
|
||||
const selectedModel = videoListWidget ? videoListWidget.value : null;
|
||||
if (!selectedModel) return;
|
||||
|
||||
const modelCode = selectedModel.split(" (")[0];
|
||||
const modelResolution = MODEL_RESOLUTIONS[modelCode];
|
||||
|
||||
// Only enable resolution if model supports it and useResolution is enabled
|
||||
const enabled = useResolutionWidget.value === true && modelResolution !== null && modelResolution !== undefined;
|
||||
|
||||
if (resolutionWidget.inputEl) {
|
||||
resolutionWidget.inputEl.disabled = !enabled;
|
||||
resolutionWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
|
||||
resolutionWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
|
||||
}
|
||||
|
||||
resolutionWidget.disabled = !enabled;
|
||||
|
||||
// Fallback: try to find input via DOM if inputEl is not available
|
||||
if (!resolutionWidget.inputEl) {
|
||||
const nodeElement = videoModelSearchNode.htmlElements?.widgetsContainer || videoModelSearchNode.htmlElements;
|
||||
if (nodeElement) {
|
||||
const input = nodeElement.querySelector(`select[name="resolution"]`);
|
||||
if (input) {
|
||||
input.disabled = !enabled;
|
||||
input.style.opacity = enabled ? "1" : "0.5";
|
||||
input.style.pointerEvents = enabled ? "auto" : "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
videoModelSearchNode.setDirtyCanvas(true);
|
||||
}
|
||||
|
||||
appendWidgetCB(useResolutionWidget, () => {
|
||||
setTimeout(toggleResolutionState, 50);
|
||||
});
|
||||
|
||||
// Also update when model changes
|
||||
if (videoListWidget) {
|
||||
appendWidgetCB(videoListWidget, () => {
|
||||
setTimeout(toggleResolutionState, 50);
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(toggleResolutionState, 100);
|
||||
}
|
||||
|
||||
filterModelList();
|
||||
updateDimensions();
|
||||
}
|
||||
@@ -2010,6 +2161,59 @@ function klingProviderSettingsToggleHandler(klingNode) {
|
||||
}
|
||||
}
|
||||
|
||||
function alibabaProviderSettingsToggleHandler(alibabaNode) {
|
||||
// Find all "use" parameter widgets for Alibaba Provider Settings
|
||||
const usePromptEnhancerWidget = alibabaNode.widgets.find(w => w.name === "usePromptEnhancer");
|
||||
const promptEnhancerWidget = alibabaNode.widgets.find(w => w.name === "promptEnhancer");
|
||||
|
||||
// Helper function to toggle widget enabled state
|
||||
function toggleWidgetState(useWidget, paramWidget, paramName) {
|
||||
if (!useWidget || !paramWidget) return;
|
||||
|
||||
function toggleEnabled() {
|
||||
const enabled = useWidget.value === true;
|
||||
|
||||
if (paramWidget.inputEl) {
|
||||
paramWidget.inputEl.disabled = !enabled;
|
||||
paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
|
||||
paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
|
||||
paramWidget.inputEl.readOnly = !enabled;
|
||||
}
|
||||
|
||||
paramWidget.disabled = !enabled;
|
||||
|
||||
if (!paramWidget.inputEl) {
|
||||
const nodeElement = alibabaNode.htmlElements?.widgetsContainer || alibabaNode.htmlElements;
|
||||
if (nodeElement) {
|
||||
const input = nodeElement.querySelector(`input[name="${paramName}"], textarea[name="${paramName}"], select[name="${paramName}"]`);
|
||||
if (input) {
|
||||
input.disabled = !enabled;
|
||||
input.style.opacity = enabled ? "1" : "0.5";
|
||||
input.style.cursor = enabled ? "text" : "not-allowed";
|
||||
input.readOnly = !enabled;
|
||||
if (input.tagName === "SELECT") {
|
||||
input.style.pointerEvents = enabled ? "auto" : "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alibabaNode.setDirtyCanvas(true);
|
||||
}
|
||||
|
||||
appendWidgetCB(useWidget, () => {
|
||||
setTimeout(toggleEnabled, 50);
|
||||
});
|
||||
|
||||
setTimeout(toggleEnabled, 100);
|
||||
}
|
||||
|
||||
// Set up toggle handler
|
||||
if (usePromptEnhancerWidget && promptEnhancerWidget) {
|
||||
toggleWidgetState(usePromptEnhancerWidget, promptEnhancerWidget, "promptEnhancer");
|
||||
}
|
||||
}
|
||||
|
||||
function lumaProviderSettingsToggleHandler(lumaNode) {
|
||||
// Find all "use" parameter widgets for Luma Provider Settings
|
||||
const useLoopWidget = lumaNode.widgets.find(w => w.name === "useLoop");
|
||||
@@ -2241,4 +2445,5 @@ export {
|
||||
lumaProviderSettingsToggleHandler,
|
||||
briaProviderSettingsToggleHandler,
|
||||
pixverseProviderSettingsToggleHandler,
|
||||
alibabaProviderSettingsToggleHandler,
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Runware Alibaba Provider Settings Node
|
||||
Provides Alibaba-specific settings for image/video generation
|
||||
"""
|
||||
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
|
||||
class RunwareAlibabaProviderSettings:
|
||||
"""Runware Alibaba Provider Settings Node"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"usePromptEnhancer": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include promptEnhancer parameter in provider settings",
|
||||
"default": False,
|
||||
}),
|
||||
"promptEnhancer": ("BOOLEAN", {
|
||||
"tooltip": "Enable prompt enhancement for Alibaba generation. Only used when 'Use Prompt Enhancer' is enabled.",
|
||||
"default": False,
|
||||
"label_on": "Enabled",
|
||||
"label_off": "Disabled",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",)
|
||||
RETURN_NAMES = ("Provider Settings",)
|
||||
FUNCTION = "createProviderSettings"
|
||||
CATEGORY = "Runware/Provider Settings"
|
||||
DESCRIPTION = "Configure Alibaba-specific provider settings for image/video generation including prompt enhancement."
|
||||
|
||||
def createProviderSettings(self, **kwargs) -> tuple[Dict[str, Any]]:
|
||||
"""Create Alibaba provider settings"""
|
||||
|
||||
# Get control parameters
|
||||
usePromptEnhancer = kwargs.get("usePromptEnhancer", False)
|
||||
|
||||
# Get value parameters
|
||||
promptEnhancer = kwargs.get("promptEnhancer", False)
|
||||
|
||||
# Build settings dictionary - only include what is enabled
|
||||
alibabaSettings: Dict[str, Any] = {}
|
||||
|
||||
# Add promptEnhancer only if usePromptEnhancer is enabled
|
||||
if usePromptEnhancer:
|
||||
alibabaSettings["promptEnhancer"] = promptEnhancer
|
||||
|
||||
# Clean up None values
|
||||
alibabaSettings = {k: v for k, v in alibabaSettings.items() if v is not None}
|
||||
|
||||
# Return flat dictionary - will be wrapped by inference node with provider name
|
||||
return (alibabaSettings,)
|
||||
|
||||
|
||||
# Node class mappings
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"RunwareAlibabaProviderSettings": RunwareAlibabaProviderSettings,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"RunwareAlibabaProviderSettings": "Runware Alibaba Provider Settings",
|
||||
}
|
||||
|
||||
@@ -175,10 +175,14 @@ class txt2vid:
|
||||
model = runwareVideoModel.get("model", "")
|
||||
width = runwareVideoModel.get("width")
|
||||
height = runwareVideoModel.get("height")
|
||||
useResolution = runwareVideoModel.get("useResolution", False)
|
||||
resolution = runwareVideoModel.get("resolution", None)
|
||||
else:
|
||||
model = runwareVideoModel
|
||||
width = None
|
||||
height = None
|
||||
useResolution = False
|
||||
resolution = None
|
||||
|
||||
genConfig = [
|
||||
{
|
||||
@@ -190,6 +194,12 @@ class txt2vid:
|
||||
"includeCost": True,
|
||||
}
|
||||
]
|
||||
|
||||
# Add resolution if enabled
|
||||
if useResolution and resolution:
|
||||
genConfig[0]["resolution"] = resolution
|
||||
|
||||
# Add width/height if not using resolution (or if resolution is not provided)
|
||||
if (
|
||||
width is not None and height is not None
|
||||
and width > 0 and height > 0
|
||||
|
||||
+101
-2
@@ -158,6 +158,84 @@ class videoModelSearch:
|
||||
"lumaai:2@2": {"width": 1080, "height": 720},
|
||||
}
|
||||
|
||||
# Model resolutions mapping
|
||||
MODEL_RESOLUTIONS = {
|
||||
# KlingAI Models
|
||||
"klingai:1@2": "720p",
|
||||
"klingai:1@1": "720p",
|
||||
"klingai:2@2": "1080p",
|
||||
"klingai:2@1": "720p",
|
||||
"klingai:3@1": "720p",
|
||||
"klingai:3@2": "1080p",
|
||||
"klingai:4@3": "720p",
|
||||
"klingai:5@1": "720p",
|
||||
"klingai:5@2": "1080p",
|
||||
"klingai:5@3": "1080p",
|
||||
"klingai:6@1": "1080p",
|
||||
"klingai:7@1": None, # No resolution support
|
||||
"klingai:kling@o1": None, # No standard resolution (1440x1440)
|
||||
|
||||
# Veo Models
|
||||
"google:2@0": "720p",
|
||||
"google:3@0": "720p",
|
||||
"google:3@1": "720p",
|
||||
"google:3@2": "720p",
|
||||
"google:3@3": "720p",
|
||||
|
||||
# Bytedance Models
|
||||
"bytedance:2@1": "480p",
|
||||
"bytedance:1@1": "480p",
|
||||
"bytedance:5@1": None, # No resolution support (fixed 1024x1024)
|
||||
"bytedance:5@2": None, # No resolution support (fixed 1024x1024)
|
||||
|
||||
# MiniMax Models (support both 768p and 720p, using 768p as primary)
|
||||
"minimax:1@1": "768p",
|
||||
"minimax:2@1": "768p",
|
||||
"minimax:2@3": "768p",
|
||||
"minimax:3@1": "768p",
|
||||
"minimax:4@1": "768p",
|
||||
"minimax:4@2": "768p",
|
||||
|
||||
# PixVerse Models
|
||||
"pixverse:1@1": "360p",
|
||||
"pixverse:1@2": "360p",
|
||||
"pixverse:1@3": "360p",
|
||||
"pixverse:1@6": "360p",
|
||||
"pixverse:lipsync@1": "360p",
|
||||
|
||||
# Vidu Models
|
||||
"vidu:1@0": "1080p",
|
||||
"vidu:1@1": "1080p",
|
||||
"vidu:1@5": "1080p",
|
||||
"vidu:2@0": "1080p",
|
||||
|
||||
# Wan Models
|
||||
"runware:200@1": "480p",
|
||||
"runware:200@2": "480p",
|
||||
"runware:200@6": "720p",
|
||||
|
||||
# OpenAI Models
|
||||
"openai:3@1": "720p",
|
||||
"openai:3@0": "720p",
|
||||
|
||||
# Lightricks Models
|
||||
"lightricks:2@0": "1080p",
|
||||
"lightricks:2@1": "1080p",
|
||||
"lightricks:3@1": None, # No resolution support
|
||||
|
||||
# Ovi Models
|
||||
"runware:190@1": None, # No resolution support
|
||||
|
||||
# Runway Models
|
||||
"runway:2@1": "720p",
|
||||
"runway:1@1": "720p",
|
||||
|
||||
# Luma Models
|
||||
"lumaai:1@1": "720p",
|
||||
"lumaai:2@1": "720p",
|
||||
"lumaai:2@2": "720p",
|
||||
}
|
||||
|
||||
MODEL_ARCHITECTURES = [
|
||||
"All",
|
||||
"KlingAI",
|
||||
@@ -182,6 +260,7 @@ class videoModelSearch:
|
||||
defaultModel = "klingai:5@3 (KlingAI V2.0 Master)"
|
||||
defaultModelCode = defaultModel.split(" (")[0]
|
||||
defaultDims = cls.MODEL_DIMENSIONS.get(defaultModelCode, cls.DEFAULT_DIMENSIONS)
|
||||
defaultResolution = cls.MODEL_RESOLUTIONS.get(defaultModelCode, None)
|
||||
|
||||
return {
|
||||
"required": {
|
||||
@@ -220,6 +299,14 @@ class videoModelSearch:
|
||||
"step": 1,
|
||||
"tooltip": "Custom Height For The Selected Model. Defaults To Model's Recommended Height.",
|
||||
}),
|
||||
"useResolution": ("BOOLEAN", {
|
||||
"tooltip": "Enable to include resolution parameter in API request. Disable if your model doesn't support resolution.",
|
||||
"default": False,
|
||||
}),
|
||||
"resolution": (["360p", "480p", "720p", "768p", "1080p"], {
|
||||
"tooltip": "Select a standard resolution for Video Inference. Only used when 'Use Resolution' is enabled.",
|
||||
"default": defaultResolution if defaultResolution else "720p",
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -248,6 +335,8 @@ class videoModelSearch:
|
||||
customWidth = kwargs.get("Width", 0)
|
||||
customHeight = kwargs.get("Height", 0)
|
||||
useCustomDimensions = kwargs.get("useCustomDimensions", "Model Default")
|
||||
useResolution = kwargs.get("useResolution", False)
|
||||
resolution = kwargs.get("resolution", "720p")
|
||||
|
||||
if enableSearchValue:
|
||||
modelAirCode = searchInput
|
||||
@@ -256,6 +345,7 @@ class videoModelSearch:
|
||||
modelAirCode = currentModel.split(" (")[0]
|
||||
|
||||
dimensions = self.MODEL_DIMENSIONS.get(modelAirCode, self.DEFAULT_DIMENSIONS)
|
||||
modelResolution = self.MODEL_RESOLUTIONS.get(modelAirCode, None)
|
||||
|
||||
if useCustomDimensions == "Custom":
|
||||
# Use custom dimensions from Width/Height widgets
|
||||
@@ -276,9 +366,18 @@ class videoModelSearch:
|
||||
returnWidth = width
|
||||
returnHeight = height
|
||||
|
||||
return ({
|
||||
resultDict = {
|
||||
"model": modelAirCode,
|
||||
"useCustomDimensions": useCustomDimensions,
|
||||
"width": width,
|
||||
"height": height,
|
||||
}, returnWidth, returnHeight)
|
||||
}
|
||||
|
||||
# Add resolution if enabled and model supports it
|
||||
if useResolution and modelResolution is not None:
|
||||
resultDict["resolution"] = resolution
|
||||
resultDict["useResolution"] = True
|
||||
else:
|
||||
resultDict["useResolution"] = False
|
||||
|
||||
return (resultDict, returnWidth, returnHeight)
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user