diff --git a/comfyui-audio/comfyui_audiocraft/nodes.py b/comfyui-audio/comfyui_audiocraft/nodes.py index 11b7fbd..e5b8e21 100644 --- a/comfyui-audio/comfyui_audiocraft/nodes.py +++ b/comfyui-audio/comfyui_audiocraft/nodes.py @@ -2,6 +2,8 @@ import torch import torchaudio import os import time +import glob as globmod +import re class MusicGenNode: @@ -10,6 +12,7 @@ class MusicGenNode: return { "required": { "prompt": ("STRING", {"multiline": True, "default": "dark dungeon ambience, slow, mysterious"}), + "name": ("STRING", {"default": "music"}), "duration": ("FLOAT", {"default": 10.0, "min": 1.0, "max": 120.0, "step": 1.0}), "model": (["facebook/musicgen-stereo-medium", "facebook/musicgen-stereo-large", "facebook/musicgen-medium", "facebook/musicgen-large", "facebook/musicgen-small"],), "seed": ("INT", {"default": 0, "min": 0, "max": 2**32 - 1}), @@ -26,7 +29,7 @@ class MusicGenNode: CATEGORY = "AudioCraft" OUTPUT_NODE = True - def generate(self, prompt, duration, model, seed, temperature, cfg_coef, top_k, extend_stride): + def generate(self, prompt, name, duration, model, seed, temperature, cfg_coef, top_k, extend_stride): from audiocraft.models import MusicGen from audiocraft.data.audio import audio_write @@ -49,9 +52,12 @@ class MusicGenNode: output_dir = "/app/ComfyUI/output/audio" os.makedirs(output_dir, exist_ok=True) - filename = f"musicgen_{int(time.time())}" + base_name = re.sub(r'[^\w\-]', '_', name.strip().lower()) + num = _next_number(output_dir, base_name) + filename = f"{base_name}_{num:03d}" out_path = os.path.join(output_dir, filename) audio_write(out_path, wav[0].cpu(), mg.sample_rate, strategy="loudness") + print(f"[MusicGen] Saved: {filename}.wav") return (out_path + ".wav",) @@ -63,6 +69,7 @@ class MusicGenLongNode: return { "required": { "prompt": ("STRING", {"multiline": True, "default": "dark fantasy orchestral music, deep cello, french horn, slow war drums, mysterious ambient"}), + "name": ("STRING", {"default": "music_long"}), "total_duration": ("FLOAT", {"default": 90.0, "min": 10.0, "max": 300.0, "step": 5.0}), "segment_duration": ("FLOAT", {"default": 30.0, "min": 10.0, "max": 30.0, "step": 5.0}), "context_seconds": ("FLOAT", {"default": 5.0, "min": 1.0, "max": 10.0, "step": 0.5}), @@ -80,7 +87,7 @@ class MusicGenLongNode: CATEGORY = "AudioCraft" OUTPUT_NODE = True - def generate_long(self, prompt, total_duration, segment_duration, context_seconds, model, seed, temperature, cfg_coef, top_k): + def generate_long(self, prompt, name, total_duration, segment_duration, context_seconds, model, seed, temperature, cfg_coef, top_k): from audiocraft.models import MusicGen from audiocraft.data.audio import audio_write @@ -128,19 +135,34 @@ class MusicGenLongNode: output_dir = "/app/ComfyUI/output/audio" os.makedirs(output_dir, exist_ok=True) - filename = f"musicgen_long_{int(time.time())}" + base_name = re.sub(r'[^\w\-]', '_', name.strip().lower()) + num = _next_number(output_dir, base_name) + filename = f"{base_name}_{num:03d}" out_path = os.path.join(output_dir, filename) audio_write(out_path, result, sample_rate, strategy="loudness") - print(f"[MusicGenLong] Fertig: {out_path}.wav ({result.shape[1]/sample_rate:.1f}s)") + print(f"[MusicGenLong] Fertig: {filename}.wav ({result.shape[1]/sample_rate:.1f}s)") return (out_path + ".wav",) +def _next_number(output_dir, base_name): + """Findet die nächste fortlaufende Nummer für einen Dateinamen""" + pattern = os.path.join(output_dir, f"{base_name}_*.wav") + existing = globmod.glob(pattern) + max_num = 0 + for f in existing: + match = re.search(rf"{re.escape(base_name)}_(\d+)", os.path.basename(f)) + if match: + max_num = max(max_num, int(match.group(1))) + return max_num + 1 + + class AudioGenNode: @classmethod def INPUT_TYPES(cls): return { "required": { "prompt": ("STRING", {"multiline": True, "default": "sword clash metal sound effect"}), + "name": ("STRING", {"default": "sfx"}), "duration": ("FLOAT", {"default": 3.0, "min": 0.5, "max": 30.0, "step": 0.5}), "seed": ("INT", {"default": 0, "min": 0, "max": 2**32 - 1}), "temperature": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 2.0, "step": 0.05}), @@ -155,7 +177,7 @@ class AudioGenNode: CATEGORY = "AudioCraft" OUTPUT_NODE = True - def generate(self, prompt, duration, seed, temperature, cfg_coef, top_k): + def generate(self, prompt, name, duration, seed, temperature, cfg_coef, top_k): from audiocraft.models import AudioGen from audiocraft.data.audio import audio_write @@ -176,9 +198,12 @@ class AudioGenNode: output_dir = "/app/ComfyUI/output/audio" os.makedirs(output_dir, exist_ok=True) - filename = f"audiogen_{int(time.time())}" + base_name = re.sub(r'[^\w\-]', '_', name.strip().lower()) + num = _next_number(output_dir, base_name) + filename = f"{base_name}_{num:03d}" out_path = os.path.join(output_dir, filename) audio_write(out_path, wav[0].cpu(), ag.sample_rate, strategy="loudness") + print(f"[AudioGen] Saved: {filename}.wav") return (out_path + ".wav",) diff --git a/comfyui-audio/workflow_sfx_optimized.json b/comfyui-audio/workflow_sfx_optimized.json index 577dbf5..bbc8c5c 100644 --- a/comfyui-audio/workflow_sfx_optimized.json +++ b/comfyui-audio/workflow_sfx_optimized.json @@ -17,6 +17,7 @@ "properties": {"Node name for S&R": "AudioGen"}, "widgets_values": [ "fast metal sword swing whoosh close range", + "heavy_strike", 1.5, 0, "fixed", @@ -72,6 +73,7 @@ "properties": {"Node name for S&R": "AudioGen"}, "widgets_values": [ "magical energy charging electric crackling buildup impact", + "spell_effect", 2.5, 0, "fixed", @@ -127,6 +129,7 @@ "properties": {"Node name for S&R": "AudioGen"}, "widgets_values": [ "wind blowing through dark stone dungeon corridor echoing", + "dungeon_ambient", 8.0, 0, "fixed",