Files
Runware-ComfyUI-Runware/modules/audioInferenceInputs.py
T

172 lines
7.0 KiB
Python

from .utils import runwareUtils as rwUtils
from typing import Dict, Any
class audioInferenceInputs:
"""Audio Inference Inputs node for configuring audio generation inputs"""
MAX_VIDEOS = 4
MAX_AUDIOS = 4
MAX_REFERENCE_IMAGES = 4
MAX_REFERENCE_AUDIOS = 4
@classmethod
def INPUT_TYPES(cls):
optionalInputs = {
"useAudio": ("BOOLEAN", {
"tooltip": "Enable to include single audio input in API request.",
"default": False,
}),
"Audio": ("STRING", {
"tooltip": "Audio URL or mediaUUID for audio generation. Can be a direct URL or a mediaUUID from Runware Media Upload node. Only used when 'Use Audio' is enabled.",
"default": "",
}),
"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": "",
})
# Multiple audios last so the UI groups useAudios with Audio1…Audio4 (ComfyUI order = dict insertion order)
optionalInputs["useAudios"] = ("BOOLEAN", {
"tooltip": "Enable to include multiple audio inputs in API request (inputs.audios array).",
"default": False,
})
for i in range(1, cls.MAX_AUDIOS + 1):
ordinal = rwUtils.getOrdinal(i)
optionalInputs[f"Audio{i}"] = ("STRING", {
"tooltip": f"Audio URL or mediaUUID for the {ordinal} audio. Only used when 'Use Audios' is enabled.",
"default": "",
})
for i in range(1, cls.MAX_REFERENCE_IMAGES + 1):
ordinal = rwUtils.getOrdinal(i)
optionalInputs[f"Reference Image {i}"] = ("IMAGE", {
"tooltip": f"Optional {ordinal} reference image for audio inference (inputs.referenceImages).",
})
optionalInputs["useReferenceAudios"] = ("BOOLEAN", {
"tooltip": "Enable to include reference audios in API request (inputs.referenceAudios array).",
"default": False,
})
for i in range(1, cls.MAX_REFERENCE_AUDIOS + 1):
ordinal = rwUtils.getOrdinal(i)
optionalInputs[f"Reference Audio {i}"] = ("STRING", {
"tooltip": f"Audio URL or mediaUUID for the {ordinal} reference audio (inputs.referenceAudios).",
"default": "",
})
optionalInputs["Reference Voice"] = ("RUNWAREAUDIOINFERENCEREFERENCEVOICES", {
"tooltip": "Connect Runware Audio Inference Inputs Reference Audio for zero-shot voice cloning (inputs.referenceVoices).",
})
return {
"required": {},
"optional": optionalInputs
}
DESCRIPTION = (
"Configure custom inputs for Runware Audio Inference, including optional single or multiple audio URL/mediaUUID "
"(inputs.audio or inputs.audios), reference voice for cloning (inputs.referenceVoices), "
"single or multiple video inputs for audio extraction or generation, up to 4 reference images "
"(inputs.referenceImages), and up to 4 reference audios (inputs.referenceAudios)."
)
FUNCTION = "createInputs"
RETURN_TYPES = ("RUNWAREAUDIOINFERENCEINPUTS",)
RETURN_NAMES = ("Audio Inference Inputs",)
CATEGORY = "Runware"
def createInputs(self, **kwargs) -> tuple[Dict[str, Any]]:
"""Create audio inference inputs from provided parameters"""
useAudio = kwargs.get("useAudio", False)
audio = kwargs.get("Audio", None)
useAudios = kwargs.get("useAudios", False)
useVideo = kwargs.get("useVideo", False)
video = kwargs.get("Video", None)
useVideos = kwargs.get("useVideos", False)
useReferenceAudios = kwargs.get("useReferenceAudios", False)
referenceVoices = kwargs.get("Reference Voice", None)
inputs = {}
# Handle single audio (inputs.audio)
if useAudio and audio is not None and audio.strip() != "":
inputs["audio"] = audio.strip()
# Handle multiple audios (inputs.audios as array)
if useAudios:
audioList = []
for i in range(1, self.MAX_AUDIOS + 1):
audioKey = f"Audio{i}"
audioUrl = kwargs.get(audioKey)
if audioUrl and audioUrl.strip() != "":
audioList.append(audioUrl.strip())
if len(audioList) > 0:
inputs["audios"] = audioList
# 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
referenceImages = []
for i in range(1, self.MAX_REFERENCE_IMAGES + 1):
image = kwargs.get(f"Reference Image {i}", None)
if image is not None:
referenceImages.append(rwUtils.convertTensor2IMG(image))
if len(referenceImages) > 0:
inputs["referenceImages"] = referenceImages
if useReferenceAudios:
referenceAudios = []
for i in range(1, self.MAX_REFERENCE_AUDIOS + 1):
audioUrl = kwargs.get(f"Reference Audio {i}", None)
if audioUrl and isinstance(audioUrl, str) and audioUrl.strip() != "":
referenceAudios.append(audioUrl.strip())
if len(referenceAudios) > 0:
inputs["referenceAudios"] = referenceAudios
if referenceVoices is not None and isinstance(referenceVoices, list) and len(referenceVoices) > 0:
inputs["referenceVoices"] = referenceVoices
return (inputs,)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"RunwareAudioInferenceInputs": audioInferenceInputs,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RunwareAudioInferenceInputs": "Runware Audio Inference Inputs",
}