v1.2.36 增强 URL to Video 节点
This commit is contained in:
+4
-1
@@ -21,6 +21,8 @@ git clone https://github.com/1hew/ComfyUI-1hewNodes
|
||||
|
||||
## 📜 更新
|
||||
|
||||
**v1.2.36**
|
||||
- feat(conversion): 增强 `URL to Video` 节点
|
||||
**v1.2.35**
|
||||
- feat(image): 添加 `Image Resize Qwen Image` 节点,专为 Qwen 视觉模型优化的图像缩放器,提供 7 种预设分辨率和自动宽高比选择
|
||||
|
||||
@@ -233,8 +235,9 @@ git clone https://github.com/1hew/ComfyUI-1hewNodes
|
||||
| Image List to Batch | 将图像列表转换为批量图像,自动进行尺寸标准化 |
|
||||
| Mask Batch to List | 将批量遮罩转换为遮罩列表,用于单独处理 |
|
||||
| Mask List to Batch | 将遮罩列表转换为批量遮罩,自动进行尺寸标准化 |
|
||||
| String Coordinate to BBoxes | 将字符串格式坐标转换为BBOXES格式,支持多种输入格式 |
|
||||
| String Coordinate to BBoxes | 将字符串格式坐标转换为BBOXES格式,增强格式支持并改进SAM2兼容性 |
|
||||
| String Coordinate to BBox Mask | 将字符串格式坐标转换为BBoxMask格式,支持图像尺寸获取和灵活的输出模式 |
|
||||
| URL to Video | 将视频URL转换为ComfyUI VIDEO对象,改进错误处理、超时控制,支持同步和异步下载方法 |
|
||||
|
||||
### 🧠 逻辑节点
|
||||
| 节点名称 | 功能描述 |
|
||||
|
||||
@@ -21,6 +21,9 @@ git clone https://github.com/1hew/ComfyUI-1hewNodes
|
||||
|
||||
## 📜 Changelog
|
||||
|
||||
**v1.2.36**
|
||||
- feat(conversion): Enhanced `URL to Video` node
|
||||
|
||||
**v1.2.35**
|
||||
- feat(image): Added `Image Resize Qwen Image` node for Qwen vision model optimized image resizing with 7 preset resolutions and automatic aspect ratio selection
|
||||
|
||||
@@ -233,8 +236,9 @@ git clone https://github.com/1hew/ComfyUI-1hewNodes
|
||||
| Image List to Batch | Convert image lists to batch images with automatic size normalization |
|
||||
| Mask Batch to List | Convert batch masks to mask lists for individual processing |
|
||||
| Mask List to Batch | Convert mask lists to batch masks with automatic size normalization |
|
||||
| String Coordinate to BBoxes | Convert string format coordinates to BBOXES format with multiple input format support |
|
||||
| String Coordinate to BBoxes | Convert string format coordinates to BBOXES format with enhanced format support and improved SAM2 compatibility |
|
||||
| String Coordinate to BBox Mask | Convert string format coordinates to BBoxMask format with image dimension support and flexible output modes |
|
||||
| URL to Video | Convert video URLs to ComfyUI VIDEO objects with improved error handling, timeout control, and support for both synchronous and asynchronous download methods |
|
||||
|
||||
### 🧠 Logic Nodes
|
||||
| Node Name | Description |
|
||||
|
||||
+160
-1
@@ -2,7 +2,164 @@ import json
|
||||
import ast
|
||||
import re
|
||||
import torch
|
||||
from typing import List, Dict, Any, Union
|
||||
import io
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import requests
|
||||
import logging
|
||||
from typing import List, Dict, Any, Union, Optional
|
||||
|
||||
# 尝试导入ComfyUI VIDEO类型
|
||||
try:
|
||||
from comfy_api.input_impl import VideoFromFile
|
||||
from comfy_api.latest import io as comfy_io
|
||||
COMFYUI_VIDEO_AVAILABLE = True
|
||||
except ImportError:
|
||||
try:
|
||||
from comfy_api.input_impl.video_types import VideoFromFile
|
||||
COMFYUI_VIDEO_AVAILABLE = True
|
||||
except ImportError:
|
||||
COMFYUI_VIDEO_AVAILABLE = False
|
||||
logging.warning("ComfyUI VIDEO types not available, using fallback implementation")
|
||||
|
||||
|
||||
class URLToVideo:
|
||||
"""
|
||||
将视频URL转换为ComfyUI VIDEO对象
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"video_url": ("STRING", {
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "视频文件的URL地址"
|
||||
}),
|
||||
},
|
||||
"optional": {
|
||||
"timeout": ("INT", {
|
||||
"default": 30,
|
||||
"min": 5,
|
||||
"max": 300,
|
||||
"step": 1,
|
||||
"tooltip": "下载超时时间(秒)"
|
||||
}),
|
||||
"use_async": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "是否使用异步下载(推荐用于大文件)"
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VIDEO",) if COMFYUI_VIDEO_AVAILABLE else ("STRING",)
|
||||
RETURN_NAMES = ("video",) if COMFYUI_VIDEO_AVAILABLE else ("error_message",)
|
||||
FUNCTION = "convert_url_to_video"
|
||||
CATEGORY = "1hewNodes/conversion"
|
||||
|
||||
def download_video_from_url_sync(self, video_url: str, timeout: int = 30) -> Optional[io.BytesIO]:
|
||||
"""同步下载视频文件"""
|
||||
try:
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
||||
}
|
||||
|
||||
response = requests.get(video_url, headers=headers, timeout=timeout, stream=True)
|
||||
response.raise_for_status()
|
||||
|
||||
video_data = io.BytesIO()
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
if chunk:
|
||||
video_data.write(chunk)
|
||||
|
||||
video_data.seek(0)
|
||||
return video_data
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"同步下载视频失败: {str(e)}")
|
||||
return None
|
||||
|
||||
async def download_video_from_url_async(self, video_url: str, timeout: int = 30) -> Optional[io.BytesIO]:
|
||||
"""异步下载视频文件"""
|
||||
try:
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
||||
}
|
||||
|
||||
timeout_config = aiohttp.ClientTimeout(total=timeout)
|
||||
async with aiohttp.ClientSession(timeout=timeout_config) as session:
|
||||
async with session.get(video_url, headers=headers) as response:
|
||||
response.raise_for_status()
|
||||
|
||||
video_data = io.BytesIO()
|
||||
async for chunk in response.content.iter_chunked(8192):
|
||||
video_data.write(chunk)
|
||||
|
||||
video_data.seek(0)
|
||||
return video_data
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"异步下载视频失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def convert_url_to_video(self, video_url: str, timeout: int = 30, use_async: bool = False):
|
||||
"""将视频URL转换为ComfyUI VIDEO对象"""
|
||||
if not video_url or not video_url.strip():
|
||||
error_msg = "视频URL不能为空"
|
||||
if COMFYUI_VIDEO_AVAILABLE:
|
||||
raise ValueError(error_msg)
|
||||
else:
|
||||
return (error_msg,)
|
||||
|
||||
# 验证URL格式
|
||||
if not video_url.startswith(('http://', 'https://')):
|
||||
error_msg = "无效的URL格式,必须以http://或https://开头"
|
||||
if COMFYUI_VIDEO_AVAILABLE:
|
||||
raise ValueError(error_msg)
|
||||
else:
|
||||
return (error_msg,)
|
||||
|
||||
try:
|
||||
# 下载视频数据
|
||||
if use_async:
|
||||
# 在同步环境中运行异步函数
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
video_data = loop.run_until_complete(
|
||||
self.download_video_from_url_async(video_url, timeout)
|
||||
)
|
||||
finally:
|
||||
loop.close()
|
||||
else:
|
||||
video_data = self.download_video_from_url_sync(video_url, timeout)
|
||||
|
||||
if video_data is None:
|
||||
error_msg = "视频下载失败"
|
||||
if COMFYUI_VIDEO_AVAILABLE:
|
||||
raise RuntimeError(error_msg)
|
||||
else:
|
||||
return (error_msg,)
|
||||
|
||||
# 如果ComfyUI VIDEO类型不可用,返回成功消息
|
||||
if not COMFYUI_VIDEO_AVAILABLE:
|
||||
return ("视频下载成功,但ComfyUI VIDEO类型不可用",)
|
||||
|
||||
# 创建ComfyUI VIDEO对象
|
||||
try:
|
||||
video_object = VideoFromFile(video_data)
|
||||
return (video_object,)
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"创建VIDEO对象失败: {str(e)}")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"URL转换视频失败: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
if COMFYUI_VIDEO_AVAILABLE:
|
||||
raise RuntimeError(error_msg)
|
||||
else:
|
||||
return (error_msg,)
|
||||
|
||||
|
||||
class ImageBatchToList:
|
||||
@@ -357,6 +514,7 @@ class StringCoordinateToBBoxMask:
|
||||
|
||||
# 节点映射
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"URLToVideo": URLToVideo,
|
||||
"ImageBatchToList": ImageBatchToList,
|
||||
"ImageListToBatch": ImageListToBatch,
|
||||
"MaskBatchToList": MaskBatchToList,
|
||||
@@ -366,6 +524,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"URLToVideo": "URL to Video",
|
||||
"ImageBatchToList": "Image Batch to List",
|
||||
"ImageListToBatch": "Image List to Batch",
|
||||
"MaskBatchToList": "Mask Batch to List",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "ComfyUI-1hewNodes"
|
||||
description = "This is a custom node collection for ComfyUI that provides some utility nodes."
|
||||
version = "1.2.35"
|
||||
version = "1.2.36"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# String Coordinate to BBoxes
|
||||
|
||||
**Node Function:** The `String Coordinate to BBoxes` node converts string format coordinate lists to BBOXES format, supporting multiple input formats like "x1,y1,x2,y2" or "[x1,y1,x2,y2]" or multi-line coordinates, commonly used for coordinate data conversion and SAM2 compatibility.
|
||||
**Node Function:** The `String Coordinate to BBoxes` node converts string format coordinate lists to BBOXES format, supporting multiple input formats including "[x1,y1,x2,y2]" or multi-line coordinates for SAM2 compatibility.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Parameter | Required | Data Type | Default | Range | Description |
|
||||
| --------- | -------- | --------- | ------- | ----- | ----------- |
|
||||
| `coordinates_string` | Required | STRING | "" | Multi-line text | Coordinate string input, supports "[x1,y1,x2,y2]" or multi-line coordinates |
|
||||
|--|--|--|--|--|--|
|
||||
| `coordinates_string` | Required | STRING | "" | Multi-line text | String format coordinates supporting "[x1,y1,x2,y2]" or multi-line coordinates |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Output Name | Data Type | Description |
|
||||
|-------------|-----------|-------------|
|
||||
| `bboxes` | BBOXES | Converted bounding boxes in SAM2 compatible format |
|
||||
| `bboxes` | BBOXES | SAM2 compatible bounding boxes format |
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# String Coordinate to BBoxes - 字符串坐标转边界框
|
||||
|
||||
**节点功能:** `String Coordinate to BBoxes`节点将字符串格式的坐标列表转换为BBOXES格式,支持多种输入格式如"x1,y1,x2,y2"或"[x1,y1,x2,y2]"或多行坐标,常用于坐标数据转换和SAM2兼容性处理。
|
||||
**节点功能:** `String Coordinate to BBoxes`节点将字符串格式的坐标列表转换为BBOXES格式,支持多种输入格式包括"[x1,y1,x2,y2]"或多行坐标,用于SAM2兼容性。
|
||||
|
||||
## 输入
|
||||
|
||||
| 参数名称 | 入端选择 | 数据类型 | 默认值 | 取值范围 | 描述 |
|
||||
| -------- | -------- | -------- | ------ | -------- | ---- |
|
||||
| `coordinates_string` | 必选 | STRING | "" | 多行文本 | 坐标字符串输入,支持"[x1,y1,x2,y2]"或多行坐标格式 |
|
||||
| `coordinates_string` | 必选 | STRING | "" | 多行文本 | 字符串格式坐标,支持"[x1,y1,x2,y2]"或多行坐标 |
|
||||
|
||||
## 输出
|
||||
|
||||
| 输出名称 | 数据类型 | 描述 |
|
||||
|---------|----------|------|
|
||||
| `bboxes` | BBOXES | 转换后的SAM2兼容格式边界框 |
|
||||
| `bboxes` | BBOXES | SAM2兼容的边界框格式 |
|
||||
@@ -0,0 +1,18 @@
|
||||
# URL to Video
|
||||
|
||||
**Node Function:** The `URL to Video` node converts video URLs to ComfyUI VIDEO objects, supporting both synchronous and asynchronous download methods with comprehensive error handling and timeout control.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Parameter | Required | Data Type | Default | Range | Description |
|
||||
|--|--|--|--|--|--|
|
||||
| `video_url` | Required | STRING | "" | - | Video file URL address |
|
||||
| `timeout` | - | INT | 30 | 5-300 | Download timeout in seconds |
|
||||
| `use_async` | - | BOOLEAN | False | True/False | Whether to use asynchronous download (recommended for large files) |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Output Name | Data Type | Description |
|
||||
|-------------|-----------|-------------|
|
||||
| `video` | VIDEO | ComfyUI VIDEO object (when VIDEO types available) |
|
||||
| `error_message` | STRING | Error message (when VIDEO types unavailable) |
|
||||
@@ -0,0 +1,18 @@
|
||||
# URL to Video - URL转视频
|
||||
|
||||
**节点功能:** `URL to Video`节点将视频URL转换为ComfyUI VIDEO对象,支持同步和异步下载方法,具备完善的错误处理和超时控制功能。
|
||||
|
||||
## 输入
|
||||
|
||||
| 参数名称 | 入端选择 | 数据类型 | 默认值 | 取值范围 | 描述 |
|
||||
| -------- | -------- | -------- | ------ | -------- | ---- |
|
||||
| `video_url` | 必选 | STRING | "" | - | 视频文件的URL地址 |
|
||||
| `timeout` | - | INT | 30 | 5-300 | 下载超时时间(秒) |
|
||||
| `use_async` | - | BOOLEAN | False | True/False | 是否使用异步下载(推荐用于大文件) |
|
||||
|
||||
## 输出
|
||||
|
||||
| 输出名称 | 数据类型 | 描述 |
|
||||
|---------|----------|------|
|
||||
| `video` | VIDEO | ComfyUI VIDEO对象(当VIDEO类型可用时) |
|
||||
| `error_message` | STRING | 错误信息(当VIDEO类型不可用时) |
|
||||
Reference in New Issue
Block a user