diff --git a/__init__.py b/__init__.py index 1895171..d08c07c 100644 --- a/__init__.py +++ b/__init__.py @@ -56,6 +56,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.mireloProviderSettings import RunwareMireloProviderSettings from .modules.providerSettings.alibabaProviderSettings import RunwareAlibabaProviderSettings from .modules.providerSettings.googleProviderSettings import RunwareGoogleProviderSettings from .modules.providerSettings.blackForestProviderSettings import RunwareBlackForestProviderSettings @@ -140,6 +141,7 @@ NODE_CLASS_MAPPINGS = { "Runware KlingAI Provider Settings": RunwareKlingProviderSettings, "Runware Runway Provider Settings": RunwareRunwayProviderSettings, "Runware Midjourney Provider Settings": RunwareMidjourneyProviderSettings, + "Runware Mirelo Provider Settings": RunwareMireloProviderSettings, "Runware Alibaba Provider Settings": RunwareAlibabaProviderSettings, "Runware Google Provider Settings": RunwareGoogleProviderSettings, "Runware BlackForest Labs Provider Settings": RunwareBlackForestProviderSettings, diff --git a/clientlibs/main.js b/clientlibs/main.js index 0b98d82..3041139 100644 --- a/clientlibs/main.js +++ b/clientlibs/main.js @@ -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, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler } 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, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; const nodeInitList = []; @@ -73,6 +73,8 @@ app.registerExtension({ pixverseProviderSettingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.ALIBABAPROVIDERSETTINGS) { alibabaProviderSettingsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.MIRELOPROVIDERSETTINGS) { + mireloProviderSettingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.GOOGLEPROVIDERSETTINGS) { googleProviderSettingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.SYNCPROVIDERSETTINGS) { @@ -91,6 +93,8 @@ app.registerExtension({ wanAnimateAdvancedFeatureSettingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.VIDEOADVANCEDFEATUREINPUTS) { videoAdvancedFeatureInputsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.AUDIOINFERENCEINPUTS) { + audioInferenceInputsToggleHandler(node); } if(crNodeProps.colorModeOnly === true) return; diff --git a/clientlibs/types.js b/clientlibs/types.js index ebd9204..5d7d325 100644 --- a/clientlibs/types.js +++ b/clientlibs/types.js @@ -103,6 +103,7 @@ const RUNWARE_NODE_TYPES = { RUNWAYPROVIDERSETTINGS: "Runware Runway Provider Settings", LUMAPROVIDERSETTINGS: "Runware Luma Provider Settings", MIDJOURNEYPROVIDERSETTINGS: "Runware Midjourney Provider Settings", + MIRELOPROVIDERSETTINGS: "Runware Mirelo Provider Settings", ALIBABAPROVIDERSETTINGS: "Runware Alibaba Provider Settings", BLACKFORESTPROVIDERSETTINGS: "Runware BlackForest Labs Provider Settings", GOOGLEPROVIDERSETTINGS: "Runware Google Provider Settings", @@ -346,6 +347,10 @@ const RUNWARE_NODE_PROPS = { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, }, + [RUNWARE_NODE_TYPES.MIRELOPROVIDERSETTINGS]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, [RUNWARE_NODE_TYPES.ALIBABAPROVIDERSETTINGS]: { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, diff --git a/clientlibs/utils.js b/clientlibs/utils.js index c505709..a801518 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -966,6 +966,8 @@ function audioInferenceToggleHandler(audioInferenceNode) { const sampleRateWidget = audioInferenceNode.widgets.find(w => w.name === "sampleRate"); const useBitrateWidget = audioInferenceNode.widgets.find(w => w.name === "useBitrate"); const bitrateWidget = audioInferenceNode.widgets.find(w => w.name === "bitrate"); + const useStepsWidget = audioInferenceNode.widgets.find(w => w.name === "useSteps"); + const stepsWidget = audioInferenceNode.widgets.find(w => w.name === "steps"); // Helper function to toggle widget enabled state (exact same pattern) function toggleWidgetState(useWidget, paramWidget, paramName) { @@ -1024,6 +1026,10 @@ function audioInferenceToggleHandler(audioInferenceNode) { if (useBitrateWidget && bitrateWidget) { toggleWidgetState(useBitrateWidget, bitrateWidget, "bitrate"); } + + if (useStepsWidget && stepsWidget) { + toggleWidgetState(useStepsWidget, stepsWidget, "steps"); + } } function acceleratorOptionsToggleHandler(acceleratorNode) { @@ -1748,6 +1754,10 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "Bria": [ "bria:60@1 (Bria Video Eraser)", ], + "Creatify": [ + "creatify:aurora@fast (Creatify Aurora Avatar Model API (720p))", + "creatify:aurora@0 (Creatify Aurora Avatar Model API (720p))", + ], }; const MODEL_DIMENSIONS = { @@ -1812,6 +1822,8 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "sync:lipsync-2-pro@1": {"width": 0, "height": 0}, "sync:react-1@1": {"width": 0, "height": 0}, "bria:60@1": {"width": 1280, "height": 720}, + "creatify:aurora@fast": {"width": 1280, "height": 720}, + "creatify:aurora@0": {"width": 1280, "height": 720}, }; const MODEL_RESOLUTIONS = { @@ -1876,6 +1888,8 @@ function videoModelSearchFilterHandler(videoModelSearchNode) { "sync:lipsync-2-pro@1": "720p", "sync:react-1@1": "720p", "bria:60@1": "720p", + "creatify:aurora@fast": "720p", + "creatify:aurora@0": "720p", }; const DEFAULT_DIMENSIONS = {"width": 1024, "height": 576}; @@ -2086,6 +2100,9 @@ function audioModelSearchFilterHandler(audioModelSearchNode) { "KlingAI": [ "klingai:8@1 (KlingAI Audio)", ], + "Mirelo": [ + "mirelo:1@1 (Mirelo SFX 1.5)", + ], }; function filterModelList() { @@ -2347,6 +2364,59 @@ function alibabaProviderSettingsToggleHandler(alibabaNode) { } } +function mireloProviderSettingsToggleHandler(mireloNode) { + // Find all "use" parameter widgets for Mirelo Provider Settings + const useStartOffsetWidget = mireloNode.widgets.find(w => w.name === "useStartOffset"); + const startOffsetWidget = mireloNode.widgets.find(w => w.name === "startOffset"); + + // 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 = mireloNode.htmlElements?.widgetsContainer || mireloNode.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"; + } + } + } + } + + mireloNode.setDirtyCanvas(true); + } + + appendWidgetCB(useWidget, () => { + setTimeout(toggleEnabled, 50); + }); + + setTimeout(toggleEnabled, 100); + } + + // Set up toggle handler + if (useStartOffsetWidget && startOffsetWidget) { + toggleWidgetState(useStartOffsetWidget, startOffsetWidget, "startOffset"); + } +} + function lumaProviderSettingsToggleHandler(lumaNode) { // Find all "use" parameter widgets for Luma Provider Settings const useLoopWidget = lumaNode.widgets.find(w => w.name === "useLoop"); @@ -2964,6 +3034,105 @@ function videoAdvancedFeatureInputsToggleHandler(advancedFeatureNode) { } } +function audioInferenceInputsToggleHandler(audioInputsNode) { + // Find widgets + const useVideoWidget = audioInputsNode.widgets.find(w => w.name === "useVideo"); + const videoWidget = audioInputsNode.widgets.find(w => w.name === "Video"); + const useVideosWidget = audioInputsNode.widgets.find(w => w.name === "useVideos"); + + // 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; + + // Fallback: try to find inputs via DOM if inputEl is not available + if (!paramWidget.inputEl && paramName) { + const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.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; + } + } + } + + audioInputsNode.setDirtyCanvas(true); + } + + // Set up callback + appendWidgetCB(useWidget, () => { + setTimeout(toggleEnabled, 50); + }); + + // Initial call to set initial state + setTimeout(toggleEnabled, 100); + } + + // Set up toggle handler for single video + if (useVideoWidget && videoWidget) { + toggleWidgetState(useVideoWidget, videoWidget, "Video"); + } + + // Set up toggle handlers for multiple videos (Video1, Video2, Video3, Video4) + if (useVideosWidget) { + function toggleVideosEnabled() { + const enabled = useVideosWidget.value === true; + + for (let i = 1; i <= 4; i++) { + const videoWidget = audioInputsNode.widgets.find(w => w.name === `Video${i}`); + if (videoWidget) { + if (videoWidget.inputEl) { + videoWidget.inputEl.disabled = !enabled; + videoWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + videoWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + videoWidget.inputEl.readOnly = !enabled; + } + + videoWidget.disabled = !enabled; + + // Fallback: try to find inputs via DOM + if (!videoWidget.inputEl) { + const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.htmlElements; + if (nodeElement) { + const input = nodeElement.querySelector(`input[name="Video${i}"], textarea[name="Video${i}"], select[name="Video${i}"]`); + if (input) { + input.disabled = !enabled; + input.style.opacity = enabled ? "1" : "0.5"; + input.style.cursor = enabled ? "text" : "not-allowed"; + input.readOnly = !enabled; + } + } + } + } + } + + audioInputsNode.setDirtyCanvas(true); + } + + // Set up callback + appendWidgetCB(useVideosWidget, () => { + setTimeout(toggleVideosEnabled, 50); + }); + + // Initial call to set initial state + setTimeout(toggleVideosEnabled, 100); + } +} + export { notifyUser, promptEnhanceHandler, @@ -2991,6 +3160,7 @@ export { briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, + mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, @@ -3000,6 +3170,7 @@ export { briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, + audioInferenceInputsToggleHandler, }; function googleProviderSettingsToggleHandler(googleNode) { diff --git a/modules/audioInference.py b/modules/audioInference.py index a755824..c60633f 100644 --- a/modules/audioInference.py +++ b/modules/audioInference.py @@ -5,6 +5,7 @@ import numpy as np import librosa import tempfile import os +import comfy.model_management from .utils import runwareUtils as rwUtils @@ -72,7 +73,7 @@ class RunwareAudioInference: "default": "URL", "tooltip": "Output type for the generated audio" }), - "outputFormat": (["MP3"], { + "outputFormat": (["MP3", "MP4"], { "default": "MP3", "tooltip": "Format of the output audio" }), @@ -82,6 +83,16 @@ class RunwareAudioInference: "max": 3, "tooltip": "Number of audio files to generate" }), + "useSteps": ("BOOLEAN", { + "tooltip": "Enable to include steps parameter in API request. Disable if your model doesn't support steps.", + "default": False, + }), + "steps": ("INT", { + "tooltip": "Number of inference steps for audio generation. More steps generally result in higher quality but longer generation time.", + "default": 20, + "min": 1, + "max": 100, + }), }, "optional": { "inputs": ("RUNWAREAUDIOINFERENCEINPUTS", { @@ -93,8 +104,8 @@ class RunwareAudioInference: } } - RETURN_TYPES = ("AUDIO",) - RETURN_NAMES = ("audio",) + RETURN_TYPES = ("AUDIO", "VIDEO") + RETURN_NAMES = ("audio", "video") FUNCTION = "generateAudio" CATEGORY = "Runware/Audio" @@ -102,15 +113,102 @@ class RunwareAudioInference: """Main function to generate audio using Runware API""" params = self._extractParameters(kwargs) genConfig = self._buildGenConfig(params) - genResult = rwUtils.inferenecRequest(genConfig) - self._logResponse(genResult) - self._validateResponse(genResult) + try: + # Debug: Print the request being sent + print(f"[DEBUG] Sending Audio Inference Request:") + print(f"[DEBUG] Request Payload: {rwUtils.safe_json_dumps(genConfig, indent=2)}") + + genResult = rwUtils.inferenecRequest(genConfig) + + # Debug: Print the response received + print(f"[DEBUG] Received Audio Inference Response:") + print(f"[DEBUG] Response: {rwUtils.safe_json_dumps(genResult, indent=2)}") + + print(f"[Debugging] Generation config: {rwUtils.safe_json_dumps(genConfig, indent=2)}") + except Exception as e: + # Re-raise the original error without modification + raise e - audioUrl = self._extractAudioUrl(genResult) - audioObj = self._downloadAndProcessAudio(audioUrl, params["sampleRate"]) + # Extract task UUID for polling + taskUUID = genConfig[0]["taskUUID"] - return (audioObj,) + # Poll for audio completion + while True: + # Check for interrupt before each poll + comfy.model_management.throw_exception_if_processing_interrupted() + + # Poll for audio result + pollResult = rwUtils.pollVideoResult(taskUUID) + print(f"[Debugging] Poll result: {rwUtils.safe_json_dumps(pollResult, indent=2) if isinstance(pollResult, (dict, list)) else pollResult}") + + # Check for errors first + if pollResult and "errors" in pollResult and len(pollResult["errors"]) > 0: + error_info = pollResult["errors"][0] + error_message = error_info.get("message", "Unknown error") + + # Extract more detailed error info if available + if "responseContent" in error_info: + response_content = error_info["responseContent"] + # Handle both string and dict response content + if isinstance(response_content, str): + detailed_message = response_content + elif isinstance(response_content, dict): + detailed_message = response_content.get("message", str(response_content)) + else: + detailed_message = str(response_content) + + if detailed_message: + error_message = f"{error_message}\nProvider Error: {detailed_message}" + + # Include taskUUID for debugging + task_uuid = error_info.get("taskUUID", "unknown") + raise Exception(f"Audio generation failed (Task: {task_uuid}): {error_message}") + + if pollResult and "data" in pollResult and len(pollResult["data"]) > 0: + audioData = pollResult["data"][0] + + # Check status directly + if "status" in audioData: + status = audioData["status"] + + if status == "success": + audioUrl = self._extractAudioUrl(pollResult) + hasAudio = audioUrl is not None + hasVideo = bool(audioData.get("videoURL") or audioData.get("videoBase64Data", False)) + + if hasAudio: + audioObj = self._downloadAndProcessAudio(audioUrl, params["sampleRate"]) + print(f"[DEBUG] Audio URL found, returning audio. Audio URL: {audioUrl}") + # Return empty video object when only audio is present (prevents errors in downstream nodes) + emptyVideoObj = rwUtils.VideoObject("", width=0, height=0) + return (audioObj, emptyVideoObj) + + if hasVideo: + videos = rwUtils.convertVideoB64List(pollResult, width=None, height=None) + print(f"[DEBUG] No audio URL in response, but video is present. Returning video.") + # Extract first video object from tuple (ComfyUI expects single VideoObject, not tuple) + if len(videos) > 0: + # Return empty audio object when only video is present (prevents errors in downstream nodes) + emptyAudioObj = { + "waveform": torch.zeros((1, 1, 1)), # [batch, channels, samples] + "sample_rate": params["sampleRate"] + } + return (emptyAudioObj, videos[0]) + else: + raise Exception("No video object found in response") + + raise Exception("No audio or video data received from API") + + # If status is "processing", continue polling + + # Check for interrupt before waiting + comfy.model_management.throw_exception_if_processing_interrupted() + + # Wait before next poll (split into smaller chunks to allow more frequent interrupt checks) + for _ in range(10): # 10 x 0.1 second = 1 second total + comfy.model_management.throw_exception_if_processing_interrupted() + rwUtils.time.sleep(0.1) def _extractParameters(self, kwargs): """Extract and validate parameters from kwargs""" @@ -128,6 +226,8 @@ class RunwareAudioInference: "outputFormat": kwargs.get("outputFormat", "MP3"), "negativePrompt": kwargs.get("negativePrompt", ""), "numberResults": kwargs.get("numberResults", 1), + "steps": kwargs.get("steps", 20), + "useSteps": kwargs.get("useSteps", False), "inputs": kwargs.get("inputs", None), "providerSettings": kwargs.get("providerSettings", None), } @@ -155,7 +255,7 @@ class RunwareAudioInference: "model": params["model"], "outputType": params["outputType"], "outputFormat": params["outputFormat"], - "deliveryMethod": "sync", + "deliveryMethod": "async", "includeCost": True, "numberResults": params["numberResults"], }] @@ -190,6 +290,13 @@ class RunwareAudioInference: else: print(f"[DEBUG] Skipped duration") + # Add steps parameter only if enabled + if params["useSteps"]: + genConfig[0]["steps"] = params["steps"] + print(f"[DEBUG] Added steps: {params['steps']}") + else: + print(f"[DEBUG] Skipped steps") + # Add optional parameters if params["negativePrompt"]: genConfig[0]["negativePrompt"] = params["negativePrompt"] @@ -241,10 +348,18 @@ class RunwareAudioInference: raise Exception(f"Audio generation failed: {errorMessage}") if "data" not in genResult or len(genResult["data"]) == 0: - raise Exception("No audio data received from API") + raise Exception("No data received from API") + + + audioData = genResult["data"][0] + hasAudio = bool(audioData.get("audioURL") or audioData.get("audioDataURI") or audioData.get("audioBase64Data")) + hasVideo = bool(audioData.get("videoURL") or audioData.get("videoBase64Data") or audioData.get("videoUUID")) + + if not hasAudio and not hasVideo: + raise Exception("No audio or video data received from API") def _extractAudioUrl(self, genResult): - """Extract audio URL from API response""" + """Extract audio URL from API response. Returns None if no audio URL is present (e.g., when only video is returned).""" audioData = genResult["data"][0] audioUrl = audioData.get("audioURL", "") @@ -253,10 +368,8 @@ class RunwareAudioInference: if not audioUrl: audioUrl = audioData.get("audioBase64Data", "") - if not audioUrl: - raise Exception("No audio URL received from API") - - return audioUrl + + return audioUrl if audioUrl else None def _downloadAndProcessAudio(self, audioUrl, targetSampleRate): """Download audio file and process it for ComfyUI""" diff --git a/modules/audioInferenceInputs.py b/modules/audioInferenceInputs.py index 5179338..7d670b7 100644 --- a/modules/audioInferenceInputs.py +++ b/modules/audioInferenceInputs.py @@ -1,23 +1,43 @@ from .utils import runwareUtils as rwUtils -from typing import Dict, Any +from typing import Dict, Any, List class audioInferenceInputs: """Audio Inference Inputs node for configuring audio generation inputs""" + MAX_VIDEOS = 4 + @classmethod def INPUT_TYPES(cls): + optionalInputs = { + "useVideo": ("BOOLEAN", { + "tooltip": "Enable to include single video input in API request.", + "default": False, + }), + "Video": ("STRING", { + "tooltip": "Video URL or mediaUUID for audio generation. Can be a direct URL or a mediaUUID from Runware Media Upload node. Only used when 'Use Video' is enabled.", + "default": "", + }), + "useVideos": ("BOOLEAN", { + "tooltip": "Enable to include multiple videos input in API request.", + "default": False, + }), + } + + # Add Video1, Video2, Video3, Video4 inputs + for i in range(1, cls.MAX_VIDEOS + 1): + ordinal = rwUtils.getOrdinal(i) + optionalInputs[f"Video{i}"] = ("STRING", { + "tooltip": f"Video URL or mediaUUID for the {ordinal} video. Only used when 'Use Videos' is enabled.", + "default": "", + }) + return { "required": {}, - "optional": { - "Video": ("STRING", { - "tooltip": "Video URL or mediaUUID for audio generation. Can be a direct URL or a mediaUUID from Runware Media Upload node.", - "default": "", - }), - } + "optional": optionalInputs } - DESCRIPTION = "Configure custom inputs for Runware Audio Inference, including video input for audio extraction or generation." + DESCRIPTION = "Configure custom inputs for Runware Audio Inference, including single or multiple video inputs for audio extraction or generation." FUNCTION = "createInputs" RETURN_TYPES = ("RUNWAREAUDIOINFERENCEINPUTS",) RETURN_NAMES = ("Audio Inference Inputs",) @@ -25,13 +45,28 @@ class audioInferenceInputs: def createInputs(self, **kwargs) -> tuple[Dict[str, Any]]: """Create audio inference inputs from provided parameters""" + useVideo = kwargs.get("useVideo", False) video = kwargs.get("Video", None) + useVideos = kwargs.get("useVideos", False) inputs = {} - if video is not None and video.strip() != "": + # Handle single video (inputs.video) + if useVideo and video is not None and video.strip() != "": inputs["video"] = video.strip() + # Handle multiple videos (inputs.videos as array) + if useVideos: + videoList = [] + for i in range(1, self.MAX_VIDEOS + 1): + videoKey = f"Video{i}" + videoUrl = kwargs.get(videoKey) + if videoUrl and videoUrl.strip() != "": + videoList.append(videoUrl.strip()) + + if len(videoList) > 0: + inputs["videos"] = videoList + return (inputs,) diff --git a/modules/audioModelSearch.py b/modules/audioModelSearch.py index 76bcade..9ef8946 100644 --- a/modules/audioModelSearch.py +++ b/modules/audioModelSearch.py @@ -11,12 +11,16 @@ class RunwareAudioModelSearch: "KlingAI": [ "klingai:8@1 (KlingAI Audio)", ], + "Mirelo": [ + "mirelo:1@1 (Mirelo SFX 1.5)", + ], } MODEL_PROVIDERS = [ "All", "ElevenLabs", "KlingAI", + "Mirelo", ] @classmethod diff --git a/modules/providerSettings/mireloProviderSettings.py b/modules/providerSettings/mireloProviderSettings.py new file mode 100644 index 0000000..ff3074a --- /dev/null +++ b/modules/providerSettings/mireloProviderSettings.py @@ -0,0 +1,67 @@ +""" +Runware Mirelo Provider Settings Node +Provides Mirelo-specific settings for audio generation +""" + +from typing import Optional, Dict, Any + + +class RunwareMireloProviderSettings: + """Runware Mirelo Provider Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useStartOffset": ("BOOLEAN", { + "tooltip": "Enable to include startOffset parameter in provider settings", + "default": False, + }), + "startOffset": ("INT", { + "tooltip": "Start offset in seconds for audio generation. Specifies the starting point in the video (0-10 seconds). Only used when 'Use Start Offset' is enabled.", + "default": 0, + "min": 0, + "max": 10, + }), + } + } + + RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) + RETURN_NAMES = ("Provider Settings",) + FUNCTION = "createProviderSettings" + CATEGORY = "Runware/Provider Settings" + DESCRIPTION = "Configure Mirelo-specific provider settings for audio generation including start offset for video-to-audio conversion." + + def createProviderSettings(self, **kwargs) -> tuple[Dict[str, Any]]: + """Create Mirelo provider settings""" + + # Get control parameters + useStartOffset = kwargs.get("useStartOffset", False) + + # Get value parameters + startOffset = kwargs.get("startOffset", 0) + + # Build settings dictionary - only include what is enabled + mireloSettings: Dict[str, Any] = {} + + # Add startOffset only if useStartOffset is enabled + if useStartOffset: + mireloSettings["startOffset"] = startOffset + + # Clean up None values + mireloSettings = {k: v for k, v in mireloSettings.items() if v is not None} + + # Return flat dictionary - will be wrapped by inference node with provider name + return (mireloSettings,) + + +# Node class mappings +NODE_CLASS_MAPPINGS = { + "RunwareMireloProviderSettings": RunwareMireloProviderSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareMireloProviderSettings": "Runware Mirelo Provider Settings", +} + diff --git a/modules/upscaler.py b/modules/upscaler.py index 93fc3ee..d1a17cf 100644 --- a/modules/upscaler.py +++ b/modules/upscaler.py @@ -18,7 +18,7 @@ class upscaler: }, "optional": { "model": ("STRING", { - "tooltip": "Model AIR ID (runware:500@1, runware:501@1, runware:502@1, runware:503@1, bria:52@1)", + "tooltip": "Model AIR ID (runware:500@1, runware:501@1, runware:502@1, runware:503@1, runware:504@1, bria:52@1)", "default": "", }), # Common parameters toggles diff --git a/modules/utils/runwareUtils.py b/modules/utils/runwareUtils.py index 559d6f4..3be6cd9 100644 --- a/modules/utils/runwareUtils.py +++ b/modules/utils/runwareUtils.py @@ -596,6 +596,11 @@ class VideoObject: def save_to(self, filename, **kwargs): """Save video to file by downloading from URL with retry logic""" + # If video URL is empty, this is a placeholder object (e.g., when only audio is returned) + if not self.video_url or self.video_url.strip() == "": + print(f"[Video Download] Skipping download - empty video URL (placeholder object)") + return False + max_retries = 10 retry_delays = [2, 5, 10, 15, 20] # Longer delays for retries with larger videos diff --git a/modules/videoModelSearch.py b/modules/videoModelSearch.py index 9dd7f48..8c541ef 100644 --- a/modules/videoModelSearch.py +++ b/modules/videoModelSearch.py @@ -90,6 +90,10 @@ class videoModelSearch: "Bria": [ "bria:60@1 (Bria Video Eraser)", ], + "Creatify": [ + "creatify:aurora@fast (Creatify Aurora Avatar Model API (720p))", + "creatify:aurora@0 (Creatify Aurora Avatar Model API (720p))", + ], } # Model dimensions mapping @@ -180,6 +184,10 @@ class videoModelSearch: # Bria Models "bria:60@1": {"width": 0, "height": 0}, + + # Creatify Models + "creatify:aurora@fast": {"width": 1280, "height": 720}, + "creatify:aurora@0": {"width": 1280, "height": 720}, } # Model resolutions mapping @@ -270,6 +278,10 @@ class videoModelSearch: # Bria Models "bria:60@1": "720p", + + # Creatify Models + "creatify:aurora@fast": "720p", + "creatify:aurora@0": "720p", } MODEL_ARCHITECTURES = [ @@ -287,7 +299,8 @@ class videoModelSearch: "Runway", "Luma", "Sync", - "Bria" + "Bria", + "Creatify" ] DEFAULT_DIMENSIONS = {"width": 1024, "height": 576} diff --git a/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_audio.json b/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_audio.json new file mode 100644 index 0000000..7146b96 --- /dev/null +++ b/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_audio.json @@ -0,0 +1 @@ +{"id":"5549ed01-3c63-4157-a500-1c576048515a","revision":0,"last_node_id":34,"last_link_id":38,"nodes":[{"id":18,"type":"Runware Audio Model Search","pos":[323.36553955078125,-158.066650390625],"size":[270,130],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Provider","name":"Model Provider","type":"COMBO","widget":{"name":"Model Provider"},"link":null},{"localized_name":"AudioList","name":"AudioList","type":"COMBO","widget":{"name":"AudioList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"model","name":"model","type":"RUNWAREAUDIOMODEL","links":[33]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"5e5e2b3fac2c984692b057e4e607d778a8c73e40","Node name for S&R":"Runware Audio Model Search"},"widgets_values":["elevenlabs:1@1","Mirelo","mirelo:1@1 (Mirelo SFX 1.5)",false],"bgcolor":"#5345bf"},{"id":16,"type":"SaveAudioMP3","pos":[1111.5191650390625,-186.8231964111328],"size":[270,136],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"audio","name":"audio","type":"AUDIO","link":34},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"quality","name":"quality","type":"COMBO","widget":{"name":"quality"},"link":null},{"localized_name":"audioUI","name":"audioUI","type":"AUDIO_UI","widget":{"name":"audioUI"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveAudioMP3"},"widgets_values":["audio/ComfyUI","V0"]},{"id":34,"type":"SaveVideo","pos":[1108.7330322265625,21.69818878173828],"size":[270,251],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"video","name":"video","type":"VIDEO","link":38},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"codec","name":"codec","type":"COMBO","widget":{"name":"codec"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveVideo"},"widgets_values":["video/ComfyUI","auto","auto"]},{"id":33,"type":"Runware Audio Inference","pos":[642.70654296875,-193.15802001953125],"size":[400,470],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"RUNWAREAUDIOMODEL","link":33},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREAUDIOINFERENCEINPUTS","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":null},{"localized_name":"usePositivePrompt","name":"usePositivePrompt","type":"BOOLEAN","widget":{"name":"usePositivePrompt"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"useDuration","name":"useDuration","type":"BOOLEAN","widget":{"name":"useDuration"},"link":null},{"localized_name":"duration","name":"duration","type":"INT","widget":{"name":"duration"},"link":null},{"localized_name":"useSampleRate","name":"useSampleRate","type":"BOOLEAN","widget":{"name":"useSampleRate"},"link":null},{"localized_name":"sampleRate","name":"sampleRate","type":"INT","widget":{"name":"sampleRate"},"link":null},{"localized_name":"useBitrate","name":"useBitrate","type":"BOOLEAN","widget":{"name":"useBitrate"},"link":null},{"localized_name":"bitrate","name":"bitrate","type":"INT","widget":{"name":"bitrate"},"link":null},{"localized_name":"outputType","name":"outputType","type":"COMBO","widget":{"name":"outputType"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"numberResults","name":"numberResults","type":"INT","widget":{"name":"numberResults"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null}],"outputs":[{"localized_name":"audio","name":"audio","type":"AUDIO","links":[34]},{"localized_name":"video","name":"video","type":"VIDEO","links":[38]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bce6458e31fa6401ddc7e0750920fb300694150f","Node name for S&R":"Runware Audio Inference"},"widgets_values":[true,"Generate immersive sound effects for this video. Include:- Ambient/background sounds matching the environment- Action-specific sounds (footsteps, impacts, movements)- Object interaction sounds- Natural environmental audio (wind, water, traffic, etc.)Ensure all sounds are properly synchronized with the visual timeline and maintain realistic volume levels based on distance and intensity.","",false,10,false,22050,false,32,"URL","MP3",1,true,20],"bgcolor":"#5345bf"}],"links":[[33,18,0,33,0,"RUNWAREAUDIOMODEL"],[34,33,0,16,0,"AUDIO"],[38,33,1,34,0,"VIDEO"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7063044548234175,"offset":[194.53497219183214,336.3936659797324]}},"version":0.4} \ No newline at end of file diff --git a/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_video.json b/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_video.json new file mode 100644 index 0000000..e1b8e2f --- /dev/null +++ b/workflows/Runware_Audio_Inference_Mirelo_Provider_Settings_generate_video.json @@ -0,0 +1 @@ +{"id":"5549ed01-3c63-4157-a500-1c576048515a","revision":0,"last_node_id":34,"last_link_id":38,"nodes":[{"id":18,"type":"Runware Audio Model Search","pos":[323.36553955078125,-158.066650390625],"size":[270,130],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Provider","name":"Model Provider","type":"COMBO","widget":{"name":"Model Provider"},"link":null},{"localized_name":"AudioList","name":"AudioList","type":"COMBO","widget":{"name":"AudioList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"model","name":"model","type":"RUNWAREAUDIOMODEL","links":[33]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"5e5e2b3fac2c984692b057e4e607d778a8c73e40","Node name for S&R":"Runware Audio Model Search"},"widgets_values":["elevenlabs:1@1","Mirelo","mirelo:1@1 (Mirelo SFX 1.5)",false],"bgcolor":"#5345bf"},{"id":29,"type":"Runware Mirelo Provider Settings","pos":[662.1192016601562,341.607177734375],"size":[308.4302673339844,82],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"useStartOffset","name":"useStartOffset","shape":7,"type":"BOOLEAN","widget":{"name":"useStartOffset"},"link":null},{"localized_name":"startOffset","name":"startOffset","shape":7,"type":"INT","widget":{"name":"startOffset"},"link":null}],"outputs":[{"localized_name":"Provider Settings","name":"Provider Settings","type":"RUNWAREPROVIDERSETTINGS","links":[36]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bce6458e31fa6401ddc7e0750920fb300694150f","Node name for S&R":"Runware Mirelo Provider Settings"},"widgets_values":[true,10],"bgcolor":"#5345bf"},{"id":30,"type":"Runware Audio Inference Inputs","pos":[-3.327440023422241,-148.79747009277344],"size":[299.9126892089844,202],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"useVideo","name":"useVideo","shape":7,"type":"BOOLEAN","widget":{"name":"useVideo"},"link":null},{"localized_name":"Video","name":"Video","shape":7,"type":"STRING","widget":{"name":"Video"},"link":null},{"localized_name":"useVideos","name":"useVideos","shape":7,"type":"BOOLEAN","widget":{"name":"useVideos"},"link":null},{"localized_name":"Video1","name":"Video1","shape":7,"type":"STRING","widget":{"name":"Video1"},"link":37},{"localized_name":"Video2","name":"Video2","shape":7,"type":"STRING","widget":{"name":"Video2"},"link":null},{"localized_name":"Video3","name":"Video3","shape":7,"type":"STRING","widget":{"name":"Video3"},"link":null},{"localized_name":"Video4","name":"Video4","shape":7,"type":"STRING","widget":{"name":"Video4"},"link":null}],"outputs":[{"localized_name":"Audio Inference Inputs","name":"Audio Inference Inputs","type":"RUNWAREAUDIOINFERENCEINPUTS","links":[35]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bce6458e31fa6401ddc7e0750920fb300694150f","Node name for S&R":"Runware Audio Inference Inputs"},"widgets_values":[false,"",true,"","","",""],"bgcolor":"#5345bf"},{"id":31,"type":"Runware Media Upload","pos":[344.95306396484375,40.3858642578125],"size":[270,58],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"media","name":"media","shape":7,"type":"VIDEO,AUDIO","link":30},{"localized_name":"mediaUUID","name":"mediaUUID","shape":7,"type":"STRING","widget":{"name":"mediaUUID"},"link":null}],"outputs":[{"localized_name":"mediaUUID","name":"mediaUUID","type":"STRING","links":[37]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bce6458e31fa6401ddc7e0750920fb300694150f","Node name for S&R":"Runware Media Upload"},"widgets_values":["ce46e737-5ff0-4330-b259-c9b77b0ee1b2"],"bgcolor":"#5345bf"},{"id":32,"type":"LoadVideo","pos":[338.8531494140625,167.2510986328125],"size":[274.080078125,348.080078125],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"file","name":"file","type":"COMBO","widget":{"name":"file"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[30]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"LoadVideo"},"widgets_values":["video_5s.mov","image"]},{"id":16,"type":"SaveAudioMP3","pos":[1111.5191650390625,-186.8231964111328],"size":[270,136],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"audio","name":"audio","type":"AUDIO","link":34},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"quality","name":"quality","type":"COMBO","widget":{"name":"quality"},"link":null},{"localized_name":"audioUI","name":"audioUI","type":"AUDIO_UI","widget":{"name":"audioUI"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveAudioMP3"},"widgets_values":["audio/ComfyUI","V0"]},{"id":34,"type":"SaveVideo","pos":[1108.7330322265625,21.69818878173828],"size":[270,251],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"video","name":"video","type":"VIDEO","link":38},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"codec","name":"codec","type":"COMBO","widget":{"name":"codec"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveVideo"},"widgets_values":["video/ComfyUI","auto","auto"]},{"id":33,"type":"Runware Audio Inference","pos":[642.70654296875,-193.15802001953125],"size":[400,470],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"RUNWAREAUDIOMODEL","link":33},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREAUDIOINFERENCEINPUTS","link":35},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":36},{"localized_name":"usePositivePrompt","name":"usePositivePrompt","type":"BOOLEAN","widget":{"name":"usePositivePrompt"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"useDuration","name":"useDuration","type":"BOOLEAN","widget":{"name":"useDuration"},"link":null},{"localized_name":"duration","name":"duration","type":"INT","widget":{"name":"duration"},"link":null},{"localized_name":"useSampleRate","name":"useSampleRate","type":"BOOLEAN","widget":{"name":"useSampleRate"},"link":null},{"localized_name":"sampleRate","name":"sampleRate","type":"INT","widget":{"name":"sampleRate"},"link":null},{"localized_name":"useBitrate","name":"useBitrate","type":"BOOLEAN","widget":{"name":"useBitrate"},"link":null},{"localized_name":"bitrate","name":"bitrate","type":"INT","widget":{"name":"bitrate"},"link":null},{"localized_name":"outputType","name":"outputType","type":"COMBO","widget":{"name":"outputType"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"numberResults","name":"numberResults","type":"INT","widget":{"name":"numberResults"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null}],"outputs":[{"localized_name":"audio","name":"audio","type":"AUDIO","links":[34]},{"localized_name":"video","name":"video","type":"VIDEO","links":[38]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bce6458e31fa6401ddc7e0750920fb300694150f","Node name for S&R":"Runware Audio Inference"},"widgets_values":[true,"add audio to the video","",false,10,false,22050,false,32,"URL","MP4",1,false,20],"bgcolor":"#5345bf"}],"links":[[30,32,0,31,0,"VIDEO,AUDIO"],[33,18,0,33,0,"RUNWAREAUDIOMODEL"],[34,33,0,16,0,"AUDIO"],[35,30,0,33,1,"RUNWAREAUDIOINFERENCEINPUTS"],[36,29,0,33,2,"RUNWAREPROVIDERSETTINGS"],[37,31,0,30,3,"STRING"],[38,33,1,34,0,"VIDEO"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7063044548234175,"offset":[194.53497219183214,336.3936659797324]}},"version":0.4} \ No newline at end of file diff --git a/workflows/Runware_Image_Inference_Wan_2_5.json b/workflows/Runware_Image_Inference_Wan_2_5.json new file mode 100644 index 0000000..0784e96 --- /dev/null +++ b/workflows/Runware_Image_Inference_Wan_2_5.json @@ -0,0 +1 @@ +{"id":"068ae80e-1b2a-49be-a88d-683487b3d845","revision":0,"last_node_id":6,"last_link_id":9,"nodes":[{"id":5,"type":"SaveImage","pos":[608.0076904296875,714.6411743164062],"size":[270,270],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":4},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46"},"widgets_values":["ComfyUI"]},{"id":2,"type":"Runware Model Search","pos":[-239.7601776123047,574.0917358398438],"size":[270,154],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"ModelType","name":"ModelType","type":"COMBO","widget":{"name":"ModelType"},"link":null},{"localized_name":"ModelList","name":"ModelList","type":"COMBO","widget":{"name":"ModelList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"Runware Model","name":"Runware Model","type":"RUNWAREMODEL","links":[1]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"ee85e6a95611621cd2d148097b93a2da84b5fa45","Node name for S&R":"Runware Model Search"},"widgets_values":["runware:201@10","All","Base Model","runware:201@10 (Wan2.5-Preview Image 1.0)",true],"bgcolor":"#5345bf"},{"id":1,"type":"Runware Image Inference","pos":[119.142578125,573.3684692382812],"size":[400,1018],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREMODEL","link":1},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"Lora","name":"Lora","shape":7,"type":"RUNWARELORA","link":null},{"localized_name":"Outpainting","name":"Outpainting","shape":7,"type":"RUNWAREOUTPAINT","link":null},{"localized_name":"IPAdapters","name":"IPAdapters","shape":7,"type":"RUNWAREIPAdapter","link":null},{"localized_name":"ControlNet","name":"ControlNet","shape":7,"type":"RUNWARECONTROLNET","link":null},{"localized_name":"Refiner","name":"Refiner","shape":7,"type":"RUNWAREREFINER","link":null},{"localized_name":"seedImage","name":"seedImage","shape":7,"type":"IMAGE","link":null},{"localized_name":"maskImage","name":"maskImage","shape":7,"type":"MASK","link":null},{"localized_name":"Embeddings","name":"Embeddings","shape":7,"type":"RUNWAREEMBEDDING","link":null},{"localized_name":"VAE","name":"VAE","shape":7,"type":"RUNWAREVAE","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREIMAGEINFERENCEINPUTS","link":3},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":null},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"settings","name":"settings","shape":7,"type":"RUNWARESETTINGS","link":null},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"dimensions","name":"dimensions","type":"COMBO","widget":{"name":"dimensions"},"link":null},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useScheduler","name":"useScheduler","type":"BOOLEAN","widget":{"name":"useScheduler"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useClipSkip","name":"useClipSkip","type":"BOOLEAN","widget":{"name":"useClipSkip"},"link":null},{"localized_name":"clipSkip","name":"clipSkip","type":"INT","widget":{"name":"clipSkip"},"link":null},{"localized_name":"strength","name":"strength","type":"FLOAT","widget":{"name":"strength"},"link":null},{"localized_name":"Mask Margin","name":"Mask Margin","type":"BOOLEAN","widget":{"name":"Mask Margin"},"link":null},{"localized_name":"maskMargin","name":"maskMargin","type":"INT","widget":{"name":"maskMargin"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[4]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"ee85e6a95611621cd2d148097b93a2da84b5fa45","Node name for S&R":"Runware Image Inference"},"widgets_values":["Change the floral dress to a vintage-style lace long dress with exquisite embroidery details on the collar and cuffs.","",false,"Disabled","Square HD (1024x1024)",1024,1024,false,"1k",true,4,false,"Default",false,6.5,true,2045042381,"randomize",true,0,0.8,false,32,"WEBP",1,"none"],"bgcolor":"#5345bf"},{"id":3,"type":"Runware Image Inference Inputs","pos":[-254.8972930908203,821.53564453125],"size":[303.0162048339844,210],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"image","name":"image","shape":7,"type":"IMAGE","link":null},{"localized_name":"Reference Image 1","name":"Reference Image 1","shape":7,"type":"IMAGE","link":9},{"localized_name":"Reference Image 2","name":"Reference Image 2","shape":7,"type":"IMAGE","link":null},{"localized_name":"Reference Image 3","name":"Reference Image 3","shape":7,"type":"IMAGE","link":null},{"localized_name":"Reference Image 4","name":"Reference Image 4","shape":7,"type":"IMAGE","link":null},{"localized_name":"Reference Tag 1","name":"Reference Tag 1","shape":7,"type":"STRING","widget":{"name":"Reference Tag 1"},"link":null},{"localized_name":"Reference Tag 2","name":"Reference Tag 2","shape":7,"type":"STRING","widget":{"name":"Reference Tag 2"},"link":null},{"localized_name":"Reference Tag 3","name":"Reference Tag 3","shape":7,"type":"STRING","widget":{"name":"Reference Tag 3"},"link":null},{"localized_name":"Reference Tag 4","name":"Reference Tag 4","shape":7,"type":"STRING","widget":{"name":"Reference Tag 4"},"link":null}],"outputs":[{"localized_name":"Inference Inputs","name":"Inference Inputs","type":"RUNWAREIMAGEINFERENCEINPUTS","links":[3]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"ee85e6a95611621cd2d148097b93a2da84b5fa45","Node name for S&R":"Runware Image Inference Inputs"},"widgets_values":["","","",""],"bgcolor":"#5345bf"},{"id":6,"type":"LoadImage","pos":[-256.8748474121094,1116.239013671875],"size":[274.080078125,314],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[9]},{"localized_name":"MASK","name":"MASK","type":"MASK","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"LoadImage"},"widgets_values":["woman.webp","image"]}],"links":[[1,2,0,1,0,"RUNWAREMODEL"],[3,3,0,1,12,"RUNWAREIMAGEINFERENCEINPUTS"],[4,1,0,5,0,"IMAGE"],[9,6,0,3,1,"IMAGE"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6600463966995841,"offset":[739.8380828142955,-513.6280604779076]}},"version":0.4} \ No newline at end of file diff --git a/workflows/Runware_Video_Inference_Creatify_Aurora_fast.json b/workflows/Runware_Video_Inference_Creatify_Aurora_fast.json new file mode 100644 index 0000000..dacb763 --- /dev/null +++ b/workflows/Runware_Video_Inference_Creatify_Aurora_fast.json @@ -0,0 +1 @@ +{"id":"020a5070-efe8-4958-9061-6ec3ab1cc023","revision":0,"last_node_id":8,"last_link_id":6,"nodes":[{"id":2,"type":"Runware Video Inference Inputs","pos":[-106.36685180664062,-63.57731246948242],"size":[320.0390625,242],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"Image","name":"Image","shape":7,"type":"IMAGE","link":6},{"localized_name":"Frame Images","name":"Frame Images","shape":7,"type":"RUNWAREVIDEOINPUTSFRAMEIMAGES","link":null},{"localized_name":"Audio Inputs","name":"Audio Inputs","shape":7,"type":"RUNWAREAUDIOINPUT","link":null},{"localized_name":"Speech Inputs","name":"Speech Inputs","shape":7,"type":"RUNWARESPEECHINPUT","link":null},{"localized_name":"Mask","name":"Mask","shape":7,"type":"IMAGE","link":null},{"localized_name":"Frame","name":"Frame","shape":7,"type":"IMAGE","link":null},{"localized_name":"References","name":"References","shape":7,"type":"RUNWAREVIDEOINPUTSREFERENCEIMAGES","link":null},{"localized_name":"Reference Videos","name":"Reference Videos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"Reference Voices","name":"Reference Voices","shape":7,"type":"RUNWAREREFERENCEVOICES","link":null},{"localized_name":"Audio","name":"Audio","shape":7,"type":"STRING","widget":{"name":"Audio"},"link":2},{"localized_name":"Video","name":"Video","shape":7,"type":"STRING","widget":{"name":"Video"},"link":null}],"outputs":[{"localized_name":"Video Inference Inputs","name":"Video Inference Inputs","type":"RUNWAREVIDEOINFERENCEINPUTS","links":[3]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"745acacd2b49bb6487bb0bd854be807ae588eb59","Node name for S&R":"Runware Video Inference Inputs"},"widgets_values":["",""],"bgcolor":"#5345bf"},{"id":3,"type":"Runware Media Upload","pos":[-92.26959991455078,231.8535919189453],"size":[270,58],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"media","name":"media","shape":7,"type":"VIDEO,AUDIO","link":1},{"localized_name":"mediaUUID","name":"mediaUUID","shape":7,"type":"STRING","widget":{"name":"mediaUUID"},"link":null}],"outputs":[{"localized_name":"mediaUUID","name":"mediaUUID","type":"STRING","links":[2]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"745acacd2b49bb6487bb0bd854be807ae588eb59","Node name for S&R":"Runware Media Upload"},"widgets_values":["47a3dea1-213d-4cf8-a72e-cebf3e6698bc"],"bgcolor":"#5345bf"},{"id":8,"type":"LoadImage","pos":[255.5740966796875,229.10475158691406],"size":[274.080078125,314],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"COMBO","widget":{"name":"image"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"IMAGEUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[6]},{"localized_name":"MASK","name":"MASK","type":"MASK","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"LoadImage"},"widgets_values":["0c5b1d6a-84ab-4276-80cc-65ccfb2b54a9.png","image"]},{"id":1,"type":"Runware Video Inference","pos":[566.916259765625,-190.84072875976562],"size":[400,760],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREVIDEOMODEL","link":4},{"localized_name":"frameImages","name":"frameImages","shape":7,"type":"RUNWAREFRAMEIMAGES","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":null},{"localized_name":"inputAudios","name":"inputAudios","shape":7,"type":"RUNWAREINPUTAUDIOS","link":null},{"localized_name":"referenceVideos","name":"referenceVideos","shape":7,"type":"RUNWAREREFERENCEVIDEOS","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREVIDEOINFERENCEINPUTS","link":3},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"videoAdvancedFeatureInputs","name":"videoAdvancedFeatureInputs","shape":7,"type":"RUNWAREVIDEOADVANCEDFEATUREINPUTS","link":null},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"useDuration","name":"useDuration","type":"BOOLEAN","widget":{"name":"useDuration"},"link":null},{"localized_name":"duration","name":"duration","type":"INT","widget":{"name":"duration"},"link":null},{"localized_name":"useFps","name":"useFps","type":"BOOLEAN","widget":{"name":"useFps"},"link":null},{"localized_name":"fps","name":"fps","type":"INT","widget":{"name":"fps"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useBatchSize","name":"useBatchSize","type":"BOOLEAN","widget":{"name":"useBatchSize"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null},{"localized_name":"positivePrompt","name":"positivePrompt","shape":7,"type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","shape":7,"type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"speechVoice","name":"speechVoice","shape":7,"type":"STRING","widget":{"name":"speechVoice"},"link":null},{"localized_name":"speechText","name":"speechText","shape":7,"type":"STRING","widget":{"name":"speechText"},"link":null}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[5]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"745acacd2b49bb6487bb0bd854be807ae588eb59","Node name for S&R":"Runware Video Inference"},"widgets_values":[false,"Disabled",false,5,false,24,"mp4",false,1343322090,"randomize",false,20,false,1,"none","Couple walking fast","","",""],"bgcolor":"#5345bf"},{"id":5,"type":"SaveVideo","pos":[1034.9610595703125,-169.85784912109375],"size":[270,368],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"video","name":"video","type":"VIDEO","link":5},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"codec","name":"codec","type":"COMBO","widget":{"name":"codec"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"SaveVideo"},"widgets_values":["video/ComfyUI","auto","auto"]},{"id":7,"type":"Runware Video Model Search","pos":[237.35098266601562,-195.19326782226562],"size":[287.380859375,290],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"VideoList","name":"VideoList","type":"COMBO","widget":{"name":"VideoList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null},{"localized_name":"useCustomDimensions","name":"useCustomDimensions","type":"COMBO","widget":{"name":"useCustomDimensions"},"link":null},{"localized_name":"Width","name":"Width","type":"INT","widget":{"name":"Width"},"link":null},{"localized_name":"Height","name":"Height","type":"INT","widget":{"name":"Height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null}],"outputs":[{"localized_name":"Runware Video Model","name":"Runware Video Model","type":"RUNWAREVIDEOMODEL","links":[4]},{"localized_name":"Width","name":"Width","type":"INT","links":null},{"localized_name":"Height","name":"Height","type":"INT","links":null}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"745acacd2b49bb6487bb0bd854be807ae588eb59","Node name for S&R":"Runware Video Model Search"},"widgets_values":["creatify:aurora@fast","Creatify","creatify:aurora@fast (Creatify Aurora Avatar Model API (720p))",true,"Disabled",0,0,false,"1080p"],"bgcolor":"#5345bf"},{"id":6,"type":"LoadAudio","pos":[-69.682861328125,382.52764892578125],"size":[274.080078125,136],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"audio","name":"audio","type":"COMBO","widget":{"name":"audio"},"link":null},{"localized_name":"audioUI","name":"audioUI","type":"AUDIO_UI","widget":{"name":"audioUI"},"link":null},{"localized_name":"choose file to upload","name":"upload","type":"AUDIOUPLOAD","widget":{"name":"upload"},"link":null}],"outputs":[{"localized_name":"AUDIO","name":"AUDIO","type":"AUDIO","links":[1]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.46","Node name for S&R":"LoadAudio"},"widgets_values":["test_file.mp3",null,null]}],"links":[[1,6,0,3,0,"VIDEO,AUDIO"],[2,3,0,2,9,"STRING"],[3,2,0,1,6,"RUNWAREVIDEOINFERENCEINPUTS"],[4,7,0,1,0,"RUNWAREVIDEOMODEL"],[5,1,0,5,0,"VIDEO"],[6,8,0,2,0,"IMAGE"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7063044548234175,"offset":[237.1699591926271,299.4551424126926]}},"version":0.4} \ No newline at end of file