Merge pull request #40 from Runware/feature-kling/WanSupport
Feature kling/wan support
This commit is contained in:
@@ -46,6 +46,7 @@ from .modules.referenceVideos import referenceVideos
|
||||
from .modules.videoInferenceInputs import videoInferenceInputs
|
||||
from .modules.lightricksProviderSettings import RunwareLightricksProviderSettings
|
||||
from .modules.minimaxProviderSettings import RunwareMiniMaxProviderSettings
|
||||
from .modules.klingProviderSettings import RunwareKlingProviderSettings
|
||||
from .modules.vectorize import vectorize
|
||||
from .modules.videoBgRemoval import videoBgRemoval
|
||||
from .modules.videoUpscaler import videoUpscaler
|
||||
@@ -112,6 +113,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"Runware Video Inference Inputs": videoInferenceInputs,
|
||||
"Runware Lightricks Provider Settings": RunwareLightricksProviderSettings,
|
||||
"Runware MiniMax Provider Settings": RunwareMiniMaxProviderSettings,
|
||||
"Runware KlingAI Provider Settings": RunwareKlingProviderSettings,
|
||||
"Runware Vectorize": vectorize,
|
||||
"Runware Video Background Removal": videoBgRemoval,
|
||||
"Runware Video Upscaler": videoUpscaler,
|
||||
|
||||
@@ -94,6 +94,7 @@ const RUNWARE_NODE_TYPES = {
|
||||
REFERENCEVIDEOS: "Runware Reference Videos",
|
||||
VIDEOINFERENCEINPUTS: "Runware Video Inference Inputs",
|
||||
LIGHTRICKSPROVIDERSETTINGS: "Runware Lightricks Provider Settings",
|
||||
KLINGPROVIDERSETTINGS: "Runware KlingAI Provider Settings",
|
||||
VECTORIZE: "Runware Vectorize",
|
||||
VIDEOBGREMOVAL: "Runware Video Background Removal",
|
||||
VIDEOUPSCALER: "Runware Video Upscaler",
|
||||
@@ -293,6 +294,10 @@ const RUNWARE_NODE_PROPS = {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
colorModeOnly: true,
|
||||
},
|
||||
[RUNWARE_NODE_TYPES.KLINGPROVIDERSETTINGS]: {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
colorModeOnly: true,
|
||||
},
|
||||
[RUNWARE_NODE_TYPES.VECTORIZE]: {
|
||||
bgColor: DEFAULT_BGCOLOR,
|
||||
},
|
||||
|
||||
@@ -131,6 +131,10 @@ class txt2img:
|
||||
"min": 1,
|
||||
"max": 10,
|
||||
}),
|
||||
"acceleration": (["none", "low", "medium", "high"], {
|
||||
"tooltip": "Applies optimized acceleration presets that automatically configure multiple generation parameters for the best speed and quality balance. This parameter serves as an abstraction layer that intelligently adjusts acceleratorOptions, steps, scheduler, and other underlying settings.\n\nAvailable values:\n- none: No acceleration applied, uses default parameter values.\n- low: Minimal acceleration with optimized settings for lowest quality loss.\n- medium: Balanced acceleration preset with moderate speed improvements.\n- high: Maximum acceleration with caching and aggressive optimizations for fastest generation.",
|
||||
"default": "none",
|
||||
}),
|
||||
},
|
||||
"optional": {
|
||||
"Accelerator": ("RUNWAREACCELERATOR", {
|
||||
@@ -228,6 +232,7 @@ class txt2img:
|
||||
dimensions = kwargs.get("dimensions", "Square (512x512)")
|
||||
outputFormat = kwargs.get("outputFormat", "WEBP")
|
||||
batchSize = kwargs.get("batchSize", 1)
|
||||
acceleration = kwargs.get("acceleration", "none")
|
||||
|
||||
if (maskImage is not None and seedImage is None):
|
||||
raise Exception("Mask Image Requires Seed Image To Be Provided!")
|
||||
@@ -278,6 +283,11 @@ class txt2img:
|
||||
genConfig[0]["promptWeighting"] = "compel"
|
||||
if (runwareAccelerator is not None):
|
||||
genConfig[0]["acceleratorOptions"] = runwareAccelerator
|
||||
|
||||
# Add acceleration if not "none"
|
||||
if acceleration and acceleration != "none":
|
||||
genConfig[0]["acceleration"] = acceleration
|
||||
|
||||
if (runwareLora is not None):
|
||||
if (isinstance(runwareLora, list)):
|
||||
genConfig[0]["lora"] = runwareLora
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Runware KlingAI Provider Settings Node
|
||||
Provides KlingAI-specific settings for video generation
|
||||
"""
|
||||
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class RunwareKlingProviderSettings:
|
||||
"""Runware KlingAI Provider Settings Node"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"soundVolume": ("FLOAT", {
|
||||
"tooltip": "Background sound volume to mix with generated audio (provider key: soundVolume).",
|
||||
"default": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 2.0,
|
||||
"step": 0.1,
|
||||
}),
|
||||
"originalAudioVolume": ("FLOAT", {
|
||||
"tooltip": "Original video volume mix level (provider key: originalAudioVolume). No effect if source has no audio.",
|
||||
"default": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 2.0,
|
||||
"step": 0.1,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",)
|
||||
RETURN_NAMES = ("Provider Settings",)
|
||||
FUNCTION = "create_provider_settings"
|
||||
CATEGORY = "Runware"
|
||||
DESCRIPTION = "Configure KlingAI-specific provider settings for video generation including sound and original audio volume controls."
|
||||
|
||||
def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]:
|
||||
"""Create KlingAI provider settings"""
|
||||
|
||||
sound_volume = kwargs.get("soundVolume", None)
|
||||
original_audio_volume = kwargs.get("originalAudioVolume", None)
|
||||
|
||||
kling_settings: Dict[str, Any] = {}
|
||||
|
||||
if sound_volume is not None:
|
||||
kling_settings["soundVolume"] = float(sound_volume)
|
||||
if original_audio_volume is not None:
|
||||
kling_settings["originalAudioVolume"] = float(original_audio_volume)
|
||||
|
||||
# Remove unset values
|
||||
kling_settings = {k: v for k, v in kling_settings.items() if v is not None}
|
||||
|
||||
return (kling_settings,)
|
||||
|
||||
|
||||
# Node class mappings
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"RunwareKlingProviderSettings": RunwareKlingProviderSettings,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"RunwareKlingProviderSettings": "Runware KlingAI Provider Settings",
|
||||
}
|
||||
|
||||
|
||||
+35
-2
@@ -243,7 +243,24 @@ class RunwareMediaUpload:
|
||||
)
|
||||
|
||||
upload_result = generalRequestWrapper(recaller)
|
||||
upload_result = upload_result.json()
|
||||
|
||||
# Check response status before trying to parse JSON
|
||||
if upload_result.status_code != 200:
|
||||
print(f"[Debug] Upload failed with status {upload_result.status_code}")
|
||||
print(f"[Debug] Response text: {upload_result.text[:500]}")
|
||||
raise Exception(f"Upload failed with status {upload_result.status_code}: {upload_result.text[:200]}")
|
||||
|
||||
# Check if response is empty
|
||||
if not upload_result.text or not upload_result.text.strip():
|
||||
raise Exception("Upload failed: Empty response from server")
|
||||
|
||||
try:
|
||||
upload_result = upload_result.json()
|
||||
except ValueError as e:
|
||||
print(f"[Debug] Failed to parse JSON response: {str(e)}")
|
||||
print(f"[Debug] Response text: {upload_result.text[:500]}")
|
||||
raise Exception(f"Upload failed: Invalid JSON response from server: {str(e)}")
|
||||
|
||||
print(f"[Debug] Upload response: {upload_result}")
|
||||
|
||||
if "errors" in upload_result:
|
||||
@@ -298,7 +315,23 @@ class RunwareMediaUpload:
|
||||
)
|
||||
|
||||
poll_result = generalRequestWrapper(recaller)
|
||||
poll_result = poll_result.json()
|
||||
|
||||
# Check response status
|
||||
if poll_result.status_code != 200:
|
||||
print(f"[Debug] Poll failed with status {poll_result.status_code}")
|
||||
continue
|
||||
|
||||
# Check if response is empty
|
||||
if not poll_result.text or not poll_result.text.strip():
|
||||
print(f"[Debug] Poll returned empty response")
|
||||
continue
|
||||
|
||||
try:
|
||||
poll_result = poll_result.json()
|
||||
except ValueError as e:
|
||||
print(f"[Debug] Failed to parse JSON in poll: {str(e)}")
|
||||
continue
|
||||
|
||||
print(f"[Debug] Poll response: {poll_result}")
|
||||
|
||||
if "errors" in poll_result:
|
||||
|
||||
@@ -92,6 +92,10 @@ class txt2vid:
|
||||
"min": 1,
|
||||
"max": 4,
|
||||
}),
|
||||
"acceleration": (["none", "low", "medium", "high"], {
|
||||
"tooltip": "Applies optimized acceleration presets that automatically configure multiple generation parameters for the best speed and quality balance. This parameter serves as an abstraction layer that intelligently adjusts acceleratorOptions, steps, scheduler, and other underlying settings.\n\nAvailable values:\n- none: No acceleration applied, uses default parameter values.\n- low: Minimal acceleration with optimized settings for lowest quality loss.\n- medium: Balanced acceleration preset with moderate speed improvements.\n- high: Maximum acceleration with caching and aggressive optimizations for fastest generation.",
|
||||
"default": "none",
|
||||
}),
|
||||
},
|
||||
"optional": {
|
||||
"positivePrompt": ("STRING", {
|
||||
@@ -188,6 +192,7 @@ class txt2vid:
|
||||
useSeed = kwargs.get("useSeed", True)
|
||||
steps = kwargs.get("steps", 20)
|
||||
useSteps = kwargs.get("useSteps", False)
|
||||
acceleration = kwargs.get("acceleration", "none")
|
||||
|
||||
# Handle model input - could be dict or string
|
||||
if isinstance(runwareVideoModel, dict):
|
||||
@@ -325,6 +330,10 @@ class txt2vid:
|
||||
# Add accelerator options if provided
|
||||
if runwareAccelerator is not None and isinstance(runwareAccelerator, dict) and len(runwareAccelerator) > 0:
|
||||
genConfig[0]["acceleratorOptions"] = runwareAccelerator
|
||||
|
||||
# Add acceleration if not "none"
|
||||
if acceleration and acceleration != "none":
|
||||
genConfig[0]["acceleration"] = acceleration
|
||||
|
||||
if (multiInferenceMode):
|
||||
return (None, genConfig)
|
||||
|
||||
@@ -12,6 +12,9 @@ class videoInferenceInputs:
|
||||
"Audio": ("STRING", {
|
||||
"tooltip": "Connect the mediaUUID output from Runware Media Upload node with audio file. This audio will be synchronized with the generated video."
|
||||
}),
|
||||
"Video": ("STRING", {
|
||||
"tooltip": "Connect the mediaUUID output from Runware Media Upload node with a reference/input video."
|
||||
}),
|
||||
"Mask": ("IMAGE", {
|
||||
"tooltip": "Mask image to specify a specific subject in the image to speak. Use white/black mask format."
|
||||
}),
|
||||
@@ -24,7 +27,7 @@ class videoInferenceInputs:
|
||||
}
|
||||
}
|
||||
|
||||
DESCRIPTION = "Configure custom inputs for Runware Video Inference with OmniHuman 1.5 support, including image, audio, and mask inputs."
|
||||
DESCRIPTION = "Configure custom inputs for Runware Video Inference with OmniHuman 1.5 support, including image, audio, video, and mask inputs."
|
||||
FUNCTION = "createInputs"
|
||||
RETURN_TYPES = ("RUNWAREVIDEOINFERENCEINPUTS",)
|
||||
RETURN_NAMES = ("Video Inference Inputs",)
|
||||
@@ -33,6 +36,7 @@ class videoInferenceInputs:
|
||||
def createInputs(self, **kwargs):
|
||||
image = kwargs.get("Image", None)
|
||||
audio = kwargs.get("Audio", None)
|
||||
video = kwargs.get("Video", None)
|
||||
mask = kwargs.get("Mask", None)
|
||||
frame = kwargs.get("Frame", None)
|
||||
references = kwargs.get("References", None)
|
||||
@@ -46,6 +50,9 @@ class videoInferenceInputs:
|
||||
if audio is not None and audio.strip() != "":
|
||||
inputs["audio"] = audio.strip()
|
||||
|
||||
if video is not None and video.strip() != "":
|
||||
inputs["video"] = video.strip()
|
||||
|
||||
if mask is not None:
|
||||
mask_uuid = rwUtils.convertTensor2IMG(mask)
|
||||
inputs["mask"] = mask_uuid
|
||||
|
||||
@@ -12,6 +12,7 @@ class videoModelSearch:
|
||||
"klingai:5@1 (KlingAI V2.1 Standard (I2V))",
|
||||
"klingai:5@2 (KlingAI V2.1 Pro (I2V))",
|
||||
"klingai:5@3 (KlingAI V2.0 Master)",
|
||||
"klingai:7@1 (KlingAI Lip-Sync)",
|
||||
],
|
||||
"Veo": [
|
||||
"google:2@0 (Veo 2.0)",
|
||||
@@ -49,6 +50,7 @@ class videoModelSearch:
|
||||
"Wan": [
|
||||
"runware:200@1 (Wan 2.1 1.3B)",
|
||||
"runware:200@2 (Wan 2.1 14B)",
|
||||
"runware:200@6 (Wan 2.2)",
|
||||
],
|
||||
"OpenAI": [
|
||||
"openai:3@1 (OpenAI Sora 3.1)",
|
||||
@@ -76,6 +78,7 @@ class videoModelSearch:
|
||||
"klingai:5@1": {"width": 1280, "height": 720}, # KlingAI V2.1 Standard (I2V)
|
||||
"klingai:5@2": {"width": 1920, "height": 1080}, # KlingAI V2.1 Pro (I2V)
|
||||
"klingai:5@3": {"width": 1920, "height": 1080}, # KlingAI V2.0 Master
|
||||
"klingai:7@1": {"width": 0, "height": 0}, # KlingAI V3.0 Standard
|
||||
|
||||
# Veo Models
|
||||
"google:2@0": {"width": 1280, "height": 720}, # Veo 2.0
|
||||
@@ -113,6 +116,7 @@ class videoModelSearch:
|
||||
# Wan Models
|
||||
"runware:200@1": {"width": 853, "height": 480}, # Wan 2.1 1.3B
|
||||
"runware:200@2": {"width": 853, "height": 480}, # Wan 2.1 14B
|
||||
"runware:200@6": {"width": 1280, "height": 720}, # Wan 2.2
|
||||
|
||||
# OpenAI Models
|
||||
"openai:3@1": {"width": 1280, "height": 720}, # OpenAI Sora 3.1
|
||||
|
||||
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