From 01b540d2baf9204dc45e988b59436e6030f940c8 Mon Sep 17 00:00:00 2001 From: ImpactFrames Date: Mon, 25 Aug 2025 15:42:19 +0100 Subject: [PATCH] Add files via upload --- __init__.py | 56 +++++++++++++++++--- web/resolution_selector.js | 103 +++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 web/resolution_selector.js diff --git a/__init__.py b/__init__.py index feb8834..6b39c28 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,7 @@ import math +import os + +WEB_DIRECTORY = os.path.join(os.path.dirname(__file__), "web") VAE_STRIDE = (4, 8, 8) PATCH_SIZE = (1, 2, 2) @@ -190,19 +193,31 @@ class VideoResolutionSelector: }, } - @classmethod + @classmethod def INPUT_TYPES(cls): modes = list(cls.RESOLUTIONS.keys()) + # Get all possible aspect ratios but organize them better + all_aspect_ratios = set() + for mode_resolutions in cls.RESOLUTIONS.values(): + all_aspect_ratios.update(mode_resolutions.keys()) + + # Sort aspect ratios in a logical order + aspect_order = ["Horizontal", "Vertical", "Squarish", "Square", "Cinematic", + "Landscape", "Portrait", "Wide", "Tall", "UltraWide", "UltraTall"] + sorted_aspects = [ar for ar in aspect_order if ar in all_aspect_ratios] + # Add any remaining aspects not in our predefined order + sorted_aspects.extend(sorted([ar for ar in all_aspect_ratios if ar not in aspect_order])) + return { "required": { "mode": (modes, {"default": modes[0], "tooltip": "Generation mode"}), - "aspect_ratio": (["Horizontal", "Vertical", "Squarish", "Cinematic", "Square", "Landscape", "Portrait", "Wide", "Tall", "UltraWide", "UltraTall"], {"default": "Horizontal"}), + "aspect_ratio": (sorted_aspects, {"default": "Horizontal", "tooltip": "Aspect ratio (some options may not be available for all modes)"}), "quality": (["HQ", "MQ", "LQ"], {"default": "HQ"}), }, "optional": { "enable_radial_attention": ("BOOLEAN", {"default": False, "tooltip": "Enable radial attention compatibility"}), "radial_mode": (["upscale", "downscale", "closest"], {"default": "upscale", "tooltip": "How to adjust resolutions for radial attention"}), - "block_size": ([64, 128], {"default": 64, "tooltip": "Radial attention block size"}), + "block_size": ([64, 128], {"default": 128, "tooltip": "Radial attention block size"}), } } @@ -211,8 +226,37 @@ class VideoResolutionSelector: FUNCTION = "get_resolution" CATEGORY = "ImpactFrames💥🎞️/utils" - def get_resolution(self, mode, aspect_ratio, quality, enable_radial_attention=False, radial_mode="upscale", block_size=64): + def get_resolution(self, mode, aspect_ratio, quality, enable_radial_attention=False, radial_mode="upscale", block_size=128): try: + # Check if aspect ratio is valid for the selected mode + if aspect_ratio not in self.RESOLUTIONS[mode]: + available_aspects = list(self.RESOLUTIONS[mode].keys()) + if available_aspects: + # Try to find a sensible fallback + fallback_mapping = { + "Cinematic": "Horizontal", + "Square": "Squarish", + "Landscape": "Horizontal", + "Portrait": "Vertical", + "Wide": "Horizontal", + "Tall": "Vertical", + "UltraWide": "Horizontal", + "UltraTall": "Vertical" + } + + # Try the mapped fallback first + fallback = fallback_mapping.get(aspect_ratio) + if fallback and fallback in available_aspects: + aspect_ratio = fallback + else: + # Use first available + aspect_ratio = available_aspects[0] + + print(f"Warning: '{aspect_ratio}' aspect ratio not available for '{mode}' mode. Available options: {', '.join(available_aspects)}. Using '{aspect_ratio}' instead.") + else: + print(f"Error: No aspect ratios available for mode '{mode}'") + return (832, 480) + w, h = self.RESOLUTIONS[mode][aspect_ratio][quality] # Apply radial attention compatibility if enabled @@ -220,8 +264,8 @@ class VideoResolutionSelector: w, h = calculate_radial_compatible_resolution(w, h, radial_mode, block_size) return (w, h) - except KeyError: - # fallback default + except KeyError as e: + print(f"Error getting resolution for {mode}-{aspect_ratio}-{quality}: {e}") return (832, 480) diff --git a/web/resolution_selector.js b/web/resolution_selector.js new file mode 100644 index 0000000..3c1f10b --- /dev/null +++ b/web/resolution_selector.js @@ -0,0 +1,103 @@ +import { app } from "../../scripts/app.js"; + +// Resolution configuration matching the Python code +const RESOLUTIONS = { + "I2V720p": { + "Horizontal": {"HQ": [1280, 720], "MQ": [832, 480], "LQ": [704, 544]}, + "Vertical": {"HQ": [720, 1280], "MQ": [480, 832], "LQ": [544, 704]}, + "Squarish": {"HQ": [624, 624], "MQ": [624, 624], "LQ": [624, 624]}, + }, + "I2V480p": { + "Horizontal": {"HQ": [832, 480], "MQ": [704, 544], "LQ": [704, 544]}, + "Vertical": {"HQ": [480, 832], "MQ": [544, 704], "LQ": [544, 704]}, + "Squarish": {"HQ": [624, 624], "MQ": [624, 624], "LQ": [624, 624]}, + }, + "T2V14B": { + "Horizontal": {"HQ": [1280, 720], "MQ": [1088, 832], "LQ": [832, 480]}, + "Vertical": {"HQ": [720, 1280], "MQ": [832, 1088], "LQ": [480, 832]}, + "Squarish": {"HQ": [960, 960], "MQ": [624, 624], "LQ": [544, 704]}, + }, + "T2V1.3B": { + "Horizontal": {"HQ": [832, 480], "MQ": [704, 544], "LQ": [704, 544]}, + "Vertical": {"HQ": [480, 832], "MQ": [544, 704], "LQ": [544, 704]}, + "Squarish": {"HQ": [624, 624], "MQ": [624, 624], "LQ": [624, 624]}, + }, + "IMG": { + "Horizontal": {"HQ": [1600, 900], "MQ": [1280, 720], "LQ": [1024, 576]}, + "Vertical": {"HQ": [900, 1600], "MQ": [720, 1280], "LQ": [576, 1024]}, + "Squarish": {"HQ": [1600, 1600], "MQ": [1024, 1024], "LQ": [512, 512]}, + "Cinematic": {"HQ": [1600, 688], "MQ": [1280, 550], "LQ": [1024, 440]}, + }, + "KONTEXT": { + "Vertical": {"HQ": [672, 1568], "MQ": [720, 1456], "LQ": [832, 1248]}, + "Horizontal": {"HQ": [1568, 672], "MQ": [1456, 720], "LQ": [1248, 832]}, + "Squarish": {"HQ": [1024, 1024], "MQ": [944, 1104], "LQ": [880, 1184]}, + }, + "QWEN": { + "Square": {"HQ": [1024, 1024], "MQ": [768, 768], "LQ": [512, 512]}, + "Landscape": {"HQ": [1280, 720], "MQ": [1024, 768], "LQ": [832, 624]}, + "Portrait": {"HQ": [720, 1280], "MQ": [768, 1024], "LQ": [624, 832]}, + "Wide": {"HQ": [1536, 768], "MQ": [1280, 640], "LQ": [1024, 512]}, + "Tall": {"HQ": [768, 1536], "MQ": [640, 1280], "LQ": [512, 1024]}, + "UltraWide": {"HQ": [1792, 768], "MQ": [1536, 640], "LQ": [1280, 544]}, + "UltraTall": {"HQ": [768, 1792], "MQ": [640, 1536], "LQ": [544, 1280]}, + }, +}; + +app.registerExtension({ + name: "VideoResolutionSelector.DynamicFiltering", + + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name === "VideoResolutionSelector") { + const onNodeCreated = nodeType.prototype.onNodeCreated; + + nodeType.prototype.onNodeCreated = function() { + if (onNodeCreated) { + onNodeCreated.apply(this, arguments); + } + + this.updateAspectRatioOptions = () => { + const modeWidget = this.widgets.find(w => w.name === "mode"); + const aspectRatioWidget = this.widgets.find(w => w.name === "aspect_ratio"); + + if (modeWidget && aspectRatioWidget) { + const selectedMode = modeWidget.value; + const validAspectRatios = Object.keys(RESOLUTIONS[selectedMode] || {}); + + // Store current value + const currentValue = aspectRatioWidget.value; + + // Update options + aspectRatioWidget.options.values = validAspectRatios; + + // Reset to first valid option if current value is not valid + if (!validAspectRatios.includes(currentValue)) { + aspectRatioWidget.value = validAspectRatios[0] || "Horizontal"; + } + + // Force widget to update its display + this.setDirtyCanvas(true, true); + } + }; + + // Set up the mode widget callback + const modeWidget = this.widgets.find(w => w.name === "mode"); + if (modeWidget) { + const originalCallback = modeWidget.callback; + modeWidget.callback = (value, graphCanvas, node, pos, event) => { + // Call original callback first + if (originalCallback) { + originalCallback.call(this, value, graphCanvas, node, pos, event); + } + + // Update aspect ratio options + this.updateAspectRatioOptions(); + }; + } + + // Initialize aspect ratio options on creation + this.updateAspectRatioOptions(); + }; + } + } +}); \ No newline at end of file