fix any
This commit is contained in:
parent
f93b880d3f
commit
7bfaa76190
@ -1,6 +1,6 @@
|
|||||||
WEB_DIRECTORY = "js"
|
WEB_DIRECTORY = "js"
|
||||||
from .nodes import NODE_CLASS_MAPPINGS
|
from .nodes import NODE_CLASS_MAPPINGS,NODE_DISPLAY_NAME_MAPPINGS
|
||||||
__all__ = ['NODE_CLASS_MAPPINGS']
|
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||||
|
|
||||||
from aiohttp import ClientSession, web
|
from aiohttp import ClientSession, web
|
||||||
from server import PromptServer
|
from server import PromptServer
|
||||||
|
96
nodes.py
96
nodes.py
@ -1,48 +1,86 @@
|
|||||||
import requests
|
import requests
|
||||||
import io
|
import io
|
||||||
import librosa.core as core
|
import librosa # Changed from librosa.core
|
||||||
import torch
|
import torch
|
||||||
|
import numpy # For type hinting, though librosa.load returns numpy array
|
||||||
|
import warnings
|
||||||
|
|
||||||
class AudioLoadPath:
|
class AudioLoadPath:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(cls): # Changed s to cls for convention
|
||||||
return {"required": { "path": ("STRING", {"default": "X://insert/path/here.mp4"}),
|
return {
|
||||||
"sample_rate": ("INT", {"default": 22050, "min": 6000, "max": 192000, "step": 1}),
|
"required": {
|
||||||
"offset": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1e6, "step": 0.001}),
|
"path": ("STRING", {"default": "X://insert/path/here.mp4"}),
|
||||||
"duration": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1e6, "step": 0.001})}}
|
"sample_rate": ("INT", {"default": 22050, "min": 6000, "max": 192000, "step": 1}),
|
||||||
|
"offset": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1e6, "step": 0.001}),
|
||||||
|
"duration": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1e6, "step": 0.001})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RETURN_TYPES = ("AUDIO", )
|
RETURN_TYPES = ("AUDIO",)
|
||||||
CATEGORY = "EasyAI"
|
CATEGORY = "EasyAI" # Or your preferred category
|
||||||
FUNCTION = "load"
|
FUNCTION = "load"
|
||||||
|
|
||||||
def load(self, path: str, sample_rate: int, offset: float, duration: float|None):
|
def load(self, path: str, sample_rate: int, offset: float, duration: float | None):
|
||||||
if duration == 0.0:
|
if duration == 0.0:
|
||||||
duration = None
|
duration = None
|
||||||
|
|
||||||
if path.startswith(('http://', 'https://')):
|
audio_data_source = None
|
||||||
try:
|
try:
|
||||||
response = requests.get(path)
|
if path.startswith(('http://', 'https://')):
|
||||||
response.raise_for_status()
|
# For network paths, download and load from memory
|
||||||
audio_data = io.BytesIO(response.content)
|
response = requests.get(path, timeout=10) # Added timeout
|
||||||
|
response.raise_for_status() # Raises an exception for bad status codes
|
||||||
|
audio_data_source = io.BytesIO(response.content)
|
||||||
|
else:
|
||||||
|
# For local paths (absolute or relative)
|
||||||
|
audio_data_source = path
|
||||||
|
|
||||||
import warnings
|
# Use librosa to load audio.
|
||||||
with warnings.catch_warnings():
|
# mono=False ensures that the output numpy array is always 2D (channels, samples).
|
||||||
warnings.simplefilter("ignore")
|
# For mono audio, this will be (1, samples).
|
||||||
audio, _ = core.load(audio_data, sr=sample_rate, offset=offset, duration=duration)
|
# librosa.load will resample to the target 'sample_rate' if it's provided.
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.simplefilter("ignore") # Suppress librosa warnings if any
|
||||||
|
audio_np, loaded_sr = librosa.load(
|
||||||
|
audio_data_source,
|
||||||
|
sr=sample_rate,
|
||||||
|
offset=offset,
|
||||||
|
duration=duration,
|
||||||
|
mono=False # Ensures audio_np is 2D: (channels, samples)
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
# Convert numpy array to PyTorch tensor
|
||||||
raise Exception(f"加载网络音频失败: {str(e)}")
|
audio_tensor = torch.from_numpy(audio_np) # Shape: (channels, samples)
|
||||||
else:
|
|
||||||
audio, _ = core.load(path, sr=sample_rate, offset=offset, duration=duration)
|
|
||||||
|
|
||||||
# 修改维度处理方式
|
# Add a batch dimension to conform to (batch_size, channels, samples)
|
||||||
audio = torch.from_numpy(audio).float()
|
# Here, batch_size is 1 as we are loading a single audio file.
|
||||||
# 确保音频是二维张量 [channels, samples]
|
audio_tensor = audio_tensor.unsqueeze(0) # Shape: (1, channels, samples)
|
||||||
if audio.dim() == 1:
|
|
||||||
audio = audio.unsqueeze(0) # 添加channel维度
|
|
||||||
|
|
||||||
return (audio,)
|
# Prepare the output dictionary for the "AUDIO" type
|
||||||
|
output_audio_dict = {
|
||||||
|
"waveform": audio_tensor,
|
||||||
|
"sample_rate": loaded_sr # Use the actual loaded sample rate (should match input 'sample_rate')
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return as a tuple, as ComfyUI expects
|
||||||
|
return (output_audio_dict,)
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
# Handle network-specific errors
|
||||||
|
raise Exception(f"Failed to load audio from URL: {str(e)}")
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
# Handle local file not found errors
|
||||||
|
raise Exception(f"Audio file not found: {path} - {str(e)}")
|
||||||
|
except Exception as e:
|
||||||
|
# Handle other potential errors (e.g., librosa failing to decode, invalid path)
|
||||||
|
raise Exception(f"Failed to load audio: {str(e)}")
|
||||||
|
|
||||||
|
# Node mappings for ComfyUI
|
||||||
NODE_CLASS_MAPPINGS = {
|
NODE_CLASS_MAPPINGS = {
|
||||||
"AudioLoadPath": AudioLoadPath,
|
"AudioLoadPath": AudioLoadPath
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||||
|
"AudioLoadPath": "Load Audio (Path/URL)"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user