Establish the immutable mediahub-cloud identity, public documentation, branding, contribution contract, CI, guarded publishing workflow, and a live-smoke regression fix before the first public release. Constraint: Registry versions and node IDs are immutable after publication Rejected: Automatic publish on pyproject.toml changes | too easy to publish an unverified immutable version Confidence: high Scope-risk: moderate Directive: Run paid provider-family live verification before triggering the manual Registry workflow Tested: 221 pytest tests; JavaScript syntax; Python compilation; workflow JSON validation; restarted ComfyUI smoke; clean editable install; comfy node validate; comfy node pack inspection Not-tested: Paid live API calls for every advertised provider family
554 lines
23 KiB
Python
554 lines
23 KiB
Python
import json
|
|
|
|
import torch
|
|
|
|
if __package__:
|
|
from .mediahub.core.contracts import MediaRequest
|
|
from .mediahub.core.registry import registry
|
|
from .mediahub.core.services import generate_image, resolve_video, submit_video
|
|
from .mediahub.images import image_sources_to_tensor_batch, image_tensor_to_base64_data_url
|
|
from .mediahub import providers as _providers
|
|
else:
|
|
from mediahub.core.contracts import MediaRequest
|
|
from mediahub.core.registry import registry
|
|
from mediahub.core.services import generate_image, resolve_video, submit_video
|
|
from mediahub.images import image_sources_to_tensor_batch, image_tensor_to_base64_data_url
|
|
from mediahub import providers as _providers
|
|
|
|
|
|
KEY_INPUT = ("STRING", {"forceInput": True})
|
|
PROMPT_INPUT = ("STRING", {"forceInput": True})
|
|
IMAGE_INPUT = ("IMAGE", {"forceInput": True})
|
|
SEED_INPUT = ("INT", {"default": 0, "min": 0, "max": 9223372036854775807, "control_after_generate": False})
|
|
RATIOS = ["1:1", "16:9", "4:3", "3:2", "2:3", "3:4", "9:16", "21:9"]
|
|
|
|
|
|
def _request(provider, operation, payload):
|
|
return (MediaRequest(provider, operation, payload),)
|
|
|
|
|
|
def _minimax_image_inputs(i2i=False):
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["image-01", "image-01-live"],),
|
|
"aspect_ratio": (RATIOS,),
|
|
"use_seed": ("BOOLEAN", {"default": False}),
|
|
"seed": SEED_INPUT,
|
|
"n": ("INT", {"default": 1, "min": 1, "max": 9}),
|
|
"response_format": (["url", "base64"],),
|
|
"prompt_optimizer": ("BOOLEAN", {"default": False}),
|
|
"aigc_watermark": ("BOOLEAN", {"default": False}),
|
|
"use_style": ("BOOLEAN", {"default": False}),
|
|
"style_type": (["漫画", "元气", "中世纪", "水彩"],),
|
|
"style_weight": ("FLOAT", {"default": 0.8, "min": 0.01, "max": 1.0, "step": 0.01}),
|
|
}
|
|
if i2i:
|
|
required["subject_image"] = IMAGE_INPUT
|
|
else:
|
|
required = {
|
|
**required,
|
|
"size_mode": (["aspect_ratio", "custom"],),
|
|
"width": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 8}),
|
|
"height": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 8}),
|
|
}
|
|
return {"required": required}
|
|
|
|
|
|
class MiniMaxCNT2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _minimax_image_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/MiniMax CN/Image"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("MiniMax CN", "image.t2i.build", **kwargs)
|
|
return _request("MiniMax CN", "image.generate", payload)
|
|
|
|
|
|
class MiniMaxCNI2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _minimax_image_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/MiniMax CN/Image"
|
|
|
|
def build(self, subject_image: torch.Tensor, **kwargs):
|
|
refs = [{"type": "character", "image_file": value} for value in image_tensor_to_base64_data_url(subject_image)]
|
|
payload = registry.call("MiniMax CN", "image.i2i.build", subject_reference=refs, **kwargs)
|
|
return _request("MiniMax CN", "image.generate", payload)
|
|
|
|
|
|
def _agnes_image_inputs(i2i=False):
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"width": ("INT", {"default": 1024, "min": 64, "max": 4096, "step": 8}),
|
|
"height": ("INT", {"default": 768, "min": 64, "max": 4096, "step": 8}),
|
|
"response_format": (["url", "base64"],),
|
|
}
|
|
if i2i:
|
|
required["image"] = IMAGE_INPUT
|
|
return {"required": required}
|
|
|
|
|
|
class AgnesImage21T2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _agnes_image_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Agnes/Image"
|
|
|
|
def build(self, prompt, width, height, response_format):
|
|
payload = registry.call("Agnes", "image.t2i.build", prompt=prompt, width=width, height=height, response_format=response_format)
|
|
return _request("Agnes", "image.generate", payload)
|
|
|
|
|
|
class AgnesImage21I2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _agnes_image_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Agnes/Image"
|
|
|
|
def build(self, prompt, width, height, response_format, image):
|
|
images = image_tensor_to_base64_data_url(image)
|
|
payload = registry.call("Agnes", "image.i2i.build", prompt=prompt, width=width, height=height, images=images, response_format=response_format)
|
|
return _request("Agnes", "image.generate", payload)
|
|
|
|
|
|
def _seed_image_inputs(i2i=False):
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["doubao-seedream-5-0-260128", "doubao-seedream-4-5-251128", "doubao-seedream-4-0-250828"],),
|
|
"size": (["1K", "2K", "3K", "4K"],),
|
|
"response_format": (["url", "base64"],),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
|
|
}
|
|
if i2i:
|
|
required["image"] = IMAGE_INPUT
|
|
return {"required": required}
|
|
|
|
|
|
class SeedVolcengineT2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _seed_image_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Seed Volcengine/Image"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("Seed Volcengine", "image.t2i.build", **kwargs)
|
|
return _request("Seed Volcengine", "image.generate", payload)
|
|
|
|
|
|
class SeedVolcengineI2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _seed_image_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Seed Volcengine/Image"
|
|
|
|
def build(self, image, **kwargs):
|
|
images = image_tensor_to_base64_data_url(image)
|
|
payload = registry.call("Seed Volcengine", "image.i2i.build", images=images, **kwargs)
|
|
return _request("Seed Volcengine", "image.generate", payload)
|
|
|
|
|
|
def _seed_video_inputs(with_image=False):
|
|
models = ["doubao-seedance-2-0-260128", "doubao-seedance-2-0-fast-260128", "doubao-seedance-1-5-pro-251215", "doubao-seedance-1-0-pro-250528", "doubao-seedance-1-0-pro-fast-251015"]
|
|
if with_image:
|
|
required = {
|
|
"mode": (["first_frame", "first_last_frame"],),
|
|
"prompt": PROMPT_INPUT,
|
|
"first_frame_image": IMAGE_INPUT,
|
|
"model": (models,),
|
|
"resolution": (["480p", "720p", "1080p"],),
|
|
"ratio": (["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],),
|
|
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"generate_audio": ("BOOLEAN", {"default": True}),
|
|
}
|
|
return {"required": required, "optional": {"last_frame_image": IMAGE_INPUT}}
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (models,),
|
|
"resolution": (["480p", "720p", "1080p"],),
|
|
"ratio": (["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],),
|
|
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"generate_audio": ("BOOLEAN", {"default": True}),
|
|
}
|
|
return {"required": required}
|
|
|
|
|
|
class SeedVolcengineT2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _seed_video_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Seed Volcengine/Video"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("Seed Volcengine", "video.t2v.build", **kwargs)
|
|
return _request("Seed Volcengine", "video.submit", payload)
|
|
|
|
|
|
class SeedVolcengineI2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _seed_video_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Seed Volcengine/Video"
|
|
|
|
def build(self, mode, first_frame_image, last_frame_image=None, **kwargs):
|
|
images = image_tensor_to_base64_data_url(first_frame_image)
|
|
if mode == "first_last_frame":
|
|
if last_frame_image is None:
|
|
raise ValueError("Last frame image is required for first_last_frame mode")
|
|
images.extend(image_tensor_to_base64_data_url(last_frame_image))
|
|
payload = registry.call("Seed Volcengine", "video.i2v.build", images=images, mode=mode, **kwargs)
|
|
return _request("Seed Volcengine", "video.submit", payload)
|
|
|
|
|
|
def _wan_image_inputs(i2i=False):
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["wan2.7-image-pro", "wan2.7-image"],),
|
|
"size": (["1K", "2K", "4K"],),
|
|
"n": ("INT", {"default": 1, "min": 1, "max": 4}),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
}
|
|
if i2i:
|
|
required["image"] = IMAGE_INPUT
|
|
return {"required": required}
|
|
|
|
|
|
class WanBailianCNT2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _wan_image_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Image"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("Wan Bailian CN", "image.t2i.build", **kwargs)
|
|
return _request("Wan Bailian CN", "image.generate", payload)
|
|
|
|
|
|
class WanBailianCNI2IConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _wan_image_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Image"
|
|
|
|
def build(self, image, **kwargs):
|
|
images = image_tensor_to_base64_data_url(image)
|
|
payload = registry.call("Wan Bailian CN", "image.i2i.build", images=images, **kwargs)
|
|
return _request("Wan Bailian CN", "image.generate", payload)
|
|
|
|
|
|
def _wan_t2v_inputs():
|
|
return {"required": {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["wan2.7-t2v"],),
|
|
"resolution": (["720P", "1080P"],),
|
|
"ratio": (["16:9", "9:16", "1:1", "4:3", "3:4"],),
|
|
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
"prompt_extend": ("BOOLEAN", {"default": True}),
|
|
"negative_prompt": ("STRING", {"default": "", "multiline": True}),
|
|
"audio_url": ("STRING", {"default": ""}),
|
|
}}
|
|
|
|
|
|
class WanBailianCNT2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _wan_t2v_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Video"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("Wan Bailian CN", "video.t2v.build", **kwargs)
|
|
return _request("Wan Bailian CN", "video.submit", payload)
|
|
|
|
|
|
def _wan_i2v_inputs():
|
|
return {"required": {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["wan2.7-i2v-2026-04-25"],),
|
|
"resolution": (["720P", "1080P"],),
|
|
"duration": ("INT", {"default": 5, "min": 2, "max": 15}),
|
|
"watermark": ("BOOLEAN", {"default": False}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
"prompt_extend": ("BOOLEAN", {"default": True}),
|
|
"mode": (["first_frame", "first_last_frame"],),
|
|
"first_frame_image": IMAGE_INPUT,
|
|
}, "optional": {"last_frame_image": IMAGE_INPUT, "audio_url": ("STRING", {"default": ""})}}
|
|
|
|
|
|
class WanBailianCNI2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _wan_i2v_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Video"
|
|
|
|
def build(self, mode, first_frame_image, last_frame_image=None, audio_url="", **kwargs):
|
|
images = image_tensor_to_base64_data_url(first_frame_image)
|
|
if mode == "first_last_frame":
|
|
if last_frame_image is None:
|
|
raise ValueError("Last frame image is required for first_last_frame mode")
|
|
images.extend(image_tensor_to_base64_data_url(last_frame_image))
|
|
payload = registry.call("Wan Bailian CN", "video.i2v.build", images=images, mode=mode, audio_url=audio_url, **kwargs)
|
|
return _request("Wan Bailian CN", "video.submit", payload)
|
|
|
|
|
|
def _hh_t2v_inputs():
|
|
return {"required": {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["happyhorse-1.0-t2v"],),
|
|
"resolution": (["720P", "1080P"],),
|
|
"ratio": (["16:9", "9:16", "1:1", "4:3", "3:4", "4:5", "5:4", "9:21", "21:9"],),
|
|
"duration": ("INT", {"default": 5, "min": 3, "max": 15}),
|
|
"watermark": ("BOOLEAN", {"default": True}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
}}
|
|
|
|
|
|
class HappyHorseBailianCNT2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _hh_t2v_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/HappyHorse Bailian CN/Video"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("HappyHorse Bailian CN", "video.t2v.build", **kwargs)
|
|
return _request("HappyHorse Bailian CN", "video.submit", payload)
|
|
|
|
|
|
def _hh_i2v_inputs():
|
|
return {"required": {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["happyhorse-1.0-i2v"],),
|
|
"resolution": (["720P", "1080P"],),
|
|
"duration": ("INT", {"default": 5, "min": 3, "max": 15}),
|
|
"watermark": ("BOOLEAN", {"default": True}),
|
|
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
"first_frame_image": IMAGE_INPUT,
|
|
}}
|
|
|
|
|
|
class HappyHorseBailianCNI2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _hh_i2v_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/HappyHorse Bailian CN/Video"
|
|
|
|
def build(self, first_frame_image, **kwargs):
|
|
images = image_tensor_to_base64_data_url(first_frame_image)
|
|
payload = registry.call("HappyHorse Bailian CN", "video.i2v.build", images=images, **kwargs)
|
|
return _request("HappyHorse Bailian CN", "video.submit", payload)
|
|
|
|
|
|
class MediaHubGenerateImage:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "request": ("MEDIAHUB_IMAGE_REQUEST", {"forceInput": True})}}
|
|
RETURN_TYPES = ("IMAGE", "STRING", "STRING")
|
|
RETURN_NAMES = ("image", "image_urls", "raw_json")
|
|
FUNCTION = "generate"
|
|
CATEGORY = "MediaHub/Image"
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs): return float("NaN")
|
|
|
|
def generate(self, api_key, request):
|
|
result = generate_image(api_key, request)
|
|
return image_sources_to_tensor_batch(result.sources), json.dumps(result.urls, ensure_ascii=False), json.dumps(result.raw, ensure_ascii=False, indent=2)
|
|
|
|
|
|
def _minimax_t2v_inputs():
|
|
return {"required": {
|
|
"prompt": PROMPT_INPUT,
|
|
"model": (["MiniMax-Hailuo-2.3", "MiniMax-Hailuo-02", "T2V-01-Director", "T2V-01"],),
|
|
"resolution": (["768P", "1080P"],),
|
|
"duration": ([6, 10],),
|
|
"prompt_optimizer": ("BOOLEAN", {"default": True}),
|
|
"fast_pretreatment": ("BOOLEAN", {"default": False}),
|
|
"aigc_watermark": ("BOOLEAN", {"default": False}),
|
|
}}
|
|
|
|
|
|
class MiniMaxCNT2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _minimax_t2v_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/MiniMax CN/Video"
|
|
|
|
def build(self, **kwargs):
|
|
return _request("MiniMax CN", "video.submit", registry.call("MiniMax CN", "video.t2v.build", **kwargs))
|
|
|
|
|
|
class MiniMaxCNI2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {"required": {
|
|
"mode": (["i2v", "fl2v", "s2v"],), "prompt": PROMPT_INPUT,
|
|
"model": (["MiniMax-Hailuo-2.3", "MiniMax-Hailuo-2.3-Fast", "MiniMax-Hailuo-02", "I2V-01-Director", "I2V-01-live", "I2V-01", "S2V-01"],),
|
|
"resolution": (["768P", "1080P"],), "duration": ([6, 10],),
|
|
"prompt_optimizer": ("BOOLEAN", {"default": True}), "fast_pretreatment": ("BOOLEAN", {"default": False}), "aigc_watermark": ("BOOLEAN", {"default": False}),
|
|
}, "optional": {"first_frame_image": IMAGE_INPUT, "last_frame_image": IMAGE_INPUT, "subject_image": IMAGE_INPUT}}
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/MiniMax CN/Video"
|
|
|
|
def build(self, mode, first_frame_image=None, last_frame_image=None, subject_image=None, **kwargs):
|
|
first = image_tensor_to_base64_data_url(first_frame_image)[0] if first_frame_image is not None else ""
|
|
last = image_tensor_to_base64_data_url(last_frame_image)[0] if last_frame_image is not None else ""
|
|
subjects = image_tensor_to_base64_data_url(subject_image) if subject_image is not None else []
|
|
payload = registry.call("MiniMax CN", "video.i2v.build", mode=mode, first_frame_data_url=first, last_frame_data_url=last, subject_image_data_urls=subjects, **kwargs)
|
|
return _request("MiniMax CN", "video.submit", payload)
|
|
|
|
|
|
def _agnes_video_inputs(with_image=False):
|
|
required = {
|
|
"prompt": PROMPT_INPUT,
|
|
"width": ("INT", {"default": 1152, "min": 64, "max": 4096, "step": 8}),
|
|
"height": ("INT", {"default": 768, "min": 64, "max": 4096, "step": 8}),
|
|
"num_frames": ("INT", {"default": 121, "min": 1, "max": 441, "step": 8}),
|
|
"frame_rate": ("FLOAT", {"default": 24, "min": 1, "max": 60, "step": 1}),
|
|
"num_inference_steps": ("INT", {"default": 30, "min": 1, "max": 100}),
|
|
"use_seed": ("BOOLEAN", {"default": False}), "seed": SEED_INPUT,
|
|
"negative_prompt": ("STRING", {"default": "", "multiline": True}),
|
|
}
|
|
if with_image:
|
|
required["mode"] = (["i2v", "multi_image", "keyframes"],)
|
|
required["image"] = IMAGE_INPUT
|
|
return {"required": required}
|
|
|
|
|
|
class AgnesVideo20T2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _agnes_video_inputs()
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Agnes/Video"
|
|
|
|
def build(self, **kwargs):
|
|
payload = registry.call("Agnes", "video.build", images=[], mode="t2v", **kwargs)
|
|
return _request("Agnes", "video.submit", payload)
|
|
|
|
|
|
class AgnesVideo20I2VConfig:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return _agnes_video_inputs(True)
|
|
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
|
|
RETURN_NAMES = ("request",)
|
|
FUNCTION = "build"
|
|
CATEGORY = "MediaHub/Provider/Agnes/Video"
|
|
|
|
def build(self, image, mode, **kwargs):
|
|
payload = registry.call("Agnes", "video.build", images=image_tensor_to_base64_data_url(image), mode=mode, **kwargs)
|
|
return _request("Agnes", "video.submit", payload)
|
|
|
|
|
|
class MediaHubSubmitVideo:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "request": ("MEDIAHUB_VIDEO_REQUEST", {"forceInput": True})}}
|
|
RETURN_TYPES = ("MEDIAHUB_JOB", "STRING")
|
|
RETURN_NAMES = ("job", "raw_json")
|
|
FUNCTION = "submit"
|
|
CATEGORY = "MediaHub/Video"
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs): return float("NaN")
|
|
|
|
def submit(self, api_key, request):
|
|
job = submit_video(api_key, request)
|
|
return job, json.dumps(job.to_dict(), ensure_ascii=False, indent=2)
|
|
|
|
|
|
class MediaHubResolveVideo:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "job": ("MEDIAHUB_JOB", {"forceInput": True})}}
|
|
RETURN_TYPES = ("VIDEO", "STRING", "STRING")
|
|
RETURN_NAMES = ("video", "video_url", "raw_json")
|
|
FUNCTION = "resolve"
|
|
CATEGORY = "MediaHub/Video"
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs): return float("NaN")
|
|
|
|
def resolve(self, api_key, job):
|
|
result = resolve_video(api_key, job)
|
|
from comfy_api.latest import InputImpl
|
|
return InputImpl.VideoFromFile(str(result.path)), result.url, json.dumps(result.raw, ensure_ascii=False, indent=2)
|
|
|
|
|
|
class MediaHubAPIKey:
|
|
@classmethod
|
|
def INPUT_TYPES(cls): return {"required": {"api_key": ("STRING", {"default": "", "password": True, "placeholder": "API Key"})}}
|
|
RETURN_TYPES = ("STRING",)
|
|
RETURN_NAMES = ("api_key",)
|
|
FUNCTION = "get_api_key"
|
|
CATEGORY = "MediaHub/Inputs"
|
|
|
|
def get_api_key(self, api_key): return (api_key,)
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"MiniMaxCNT2IConfig": MiniMaxCNT2IConfig, "MiniMaxCNI2IConfig": MiniMaxCNI2IConfig,
|
|
"AgnesImage21T2IConfig": AgnesImage21T2IConfig, "AgnesImage21I2IConfig": AgnesImage21I2IConfig,
|
|
"SeedVolcengineT2IConfig": SeedVolcengineT2IConfig, "SeedVolcengineI2IConfig": SeedVolcengineI2IConfig,
|
|
"WanBailianCNT2IConfig": WanBailianCNT2IConfig, "WanBailianCNI2IConfig": WanBailianCNI2IConfig,
|
|
"MediaHubGenerateImage": MediaHubGenerateImage,
|
|
"MiniMaxCNT2VConfig": MiniMaxCNT2VConfig, "MiniMaxCNI2VConfig": MiniMaxCNI2VConfig,
|
|
"AgnesVideo20T2VConfig": AgnesVideo20T2VConfig, "AgnesVideo20I2VConfig": AgnesVideo20I2VConfig,
|
|
"SeedVolcengineT2VConfig": SeedVolcengineT2VConfig, "SeedVolcengineI2VConfig": SeedVolcengineI2VConfig,
|
|
"WanBailianCNT2VConfig": WanBailianCNT2VConfig, "WanBailianCNI2VConfig": WanBailianCNI2VConfig,
|
|
"HappyHorseBailianCNT2VConfig": HappyHorseBailianCNT2VConfig, "HappyHorseBailianCNI2VConfig": HappyHorseBailianCNI2VConfig,
|
|
"MediaHubSubmitVideo": MediaHubSubmitVideo, "MediaHubResolveVideo": MediaHubResolveVideo,
|
|
"MediaHubAPIKey": MediaHubAPIKey,
|
|
}
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"MiniMaxCNT2IConfig": "MiniMax CN T2I Config", "MiniMaxCNI2IConfig": "MiniMax CN I2I Config",
|
|
"AgnesImage21T2IConfig": "Agnes Image 2.1 T2I Config", "AgnesImage21I2IConfig": "Agnes Image 2.1 I2I Config",
|
|
"SeedVolcengineT2IConfig": "Seed Volcengine T2I Config", "SeedVolcengineI2IConfig": "Seed Volcengine I2I Config",
|
|
"WanBailianCNT2IConfig": "Wan Bailian CN T2I Config", "WanBailianCNI2IConfig": "Wan Bailian CN I2I Config",
|
|
"MediaHubGenerateImage": "MediaHub Generate Image",
|
|
"MiniMaxCNT2VConfig": "MiniMax CN T2V Config", "MiniMaxCNI2VConfig": "MiniMax CN I2V Config",
|
|
"AgnesVideo20T2VConfig": "Agnes Video 2.0 T2V Config", "AgnesVideo20I2VConfig": "Agnes Video 2.0 I2V Config",
|
|
"SeedVolcengineT2VConfig": "Seed Volcengine T2V Config", "SeedVolcengineI2VConfig": "Seed Volcengine I2V Config",
|
|
"WanBailianCNT2VConfig": "Wan Bailian CN T2V Config", "WanBailianCNI2VConfig": "Wan Bailian CN I2V Config",
|
|
"HappyHorseBailianCNT2VConfig": "HappyHorse T2V Config", "HappyHorseBailianCNI2VConfig": "HappyHorse I2V Config",
|
|
"MediaHubSubmitVideo": "MediaHub Submit Video", "MediaHubResolveVideo": "MediaHub Resolve Video",
|
|
"MediaHubAPIKey": "MediaHub API Key",
|
|
}
|