Files

171 lines
5.7 KiB
Python

"""
Wan Ratio & FPS — Magos Nodes
Author: Magos Digital Studio
Dashboard for outputting Mod-16 compliant width/height integers and frame rates
for WanAnimate video generation.
"""
from typing import Dict, Any, Tuple
class WanRatioAndFPS:
"""
A ComfyUI custom node that acts as a dashboard for WanAnimate video generation.
Outputs Mod-16 compliant resolution dimensions and frame rates.
Features:
- Preset aspect ratios with Mod-16 compliant resolutions
- Quality presets (480p, 720p, 1080p)
- Custom width/height override with Mod-16 safety rounding
- FPS presets with custom override option
"""
# Resolution lookup table: ratio -> quality -> (width, height)
# All values are Mod-16 compliant (divisible by 16)
RESOLUTION_TABLE: Dict[str, Dict[str, Tuple[int, int]]] = {
"16:9": {
"480p": (832, 480),
"720p": (1280, 720),
"1080p": (1920, 1088),
},
"9:16": {
"480p": (480, 832),
"720p": (720, 1280),
"1080p": (1088, 1920),
},
"1:1": {
"480p": (512, 512),
"720p": (768, 768),
"1080p": (1024, 1024),
},
"4:3": {
"480p": (640, 480),
"720p": (960, 720),
"1080p": (1440, 1088),
},
"3:4": {
"480p": (480, 640),
"720p": (720, 960),
"1080p": (1088, 1440),
},
"21:9": {
"480p": (1120, 480),
"720p": (1680, 720),
"1080p": (2528, 1088),
},
}
@classmethod
def INPUT_TYPES(cls) -> Dict[str, Any]:
return {
"required": {
# Aspect ratio selection
"ratio": (
["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "Custom"],
{"default": "16:9"},
),
# Quality preset selection
"quality": (
["480p", "720p", "1080p"],
{"default": "720p"},
),
# Custom width (used when ratio == "Custom")
"custom_width": (
"INT",
{"default": 512, "min": 64, "max": 8192, "step": 16, "display": "number"},
),
# Custom height (used when ratio == "Custom")
"custom_height": (
"INT",
{"default": 512, "min": 64, "max": 8192, "step": 16, "display": "number"},
),
# FPS preset selection
"fps_preset": (
["12", "15", "23.976", "24", "25", "30", "48", "50", "60", "Custom"],
{"default": "24"},
),
# Custom FPS (used when fps_preset == "Custom")
"custom_fps": (
"FLOAT",
{"default": 24.0, "min": 1.0, "max": 120.0, "step": 0.001, "display": "number"},
),
},
}
CATEGORY = "MAGOS Nodes/Utils"
RETURN_TYPES = ("INT", "INT", "FLOAT")
RETURN_NAMES = ("width", "height", "fps")
FUNCTION = "get_resolution_and_fps"
def _ensure_mod16(self, value: int) -> int:
"""
Ensure a value is Mod-16 compliant by rounding down.
Args:
value: The input integer value
Returns:
The nearest lower multiple of 16
"""
return (value // 16) * 16
def get_resolution_and_fps(
self,
ratio: str,
quality: str,
custom_width: int,
custom_height: int,
fps_preset: str,
custom_fps: float,
) -> Tuple[int, int, float]:
"""
Calculate and return width, height, and FPS based on inputs.
Args:
ratio: Selected aspect ratio preset or "Custom"
quality: Selected quality preset (480p, 720p, 1080p)
custom_width: Custom width value (used when ratio == "Custom")
custom_height: Custom height value (used when ratio == "Custom")
fps_preset: Selected FPS preset or "Custom"
custom_fps: Custom FPS value (used when fps_preset == "Custom")
Returns:
Tuple of (width, height, fps) - width/height as int, fps as float
"""
# =========================================
# RESOLUTION MATH
# =========================================
if ratio == "Custom":
# Use custom dimensions with Mod-16 safety rounding
width = self._ensure_mod16(custom_width)
height = self._ensure_mod16(custom_height)
else:
# Look up preset resolution from table
if ratio in self.RESOLUTION_TABLE and quality in self.RESOLUTION_TABLE[ratio]:
width, height = self.RESOLUTION_TABLE[ratio][quality]
else:
# Fallback to a safe default if something goes wrong
width, height = 512, 512
# =========================================
# FPS MATH
# =========================================
if fps_preset == "Custom":
fps = custom_fps
else:
# Convert preset string directly to float
fps = float(fps_preset)
return (width, height, fps)
# Node class mappings for ComfyUI registration
NODE_CLASS_MAPPINGS = {
"WanRatioAndFPS": WanRatioAndFPS,
}
# Display name mappings for the node menu
NODE_DISPLAY_NAME_MAPPINGS = {
"WanRatioAndFPS": "Wan Ratio & FPS",
}