From 22d9a567fd39058d1410eff8a2ee0a5b4ce55a27 Mon Sep 17 00:00:00 2001 From: Pigidiy Date: Sun, 1 Jun 2025 22:35:20 +0600 Subject: [PATCH] Add files via upload --- LICENSE | 21 ++++++++++++++ README.md | 23 ++++++++++++++++ __init__.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ info.json | 7 +++++ 4 files changed, 130 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 __init__.py create mode 100644 info.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..24fefb3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Pigidiy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b8f4183 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# ComfyUI-LikeSpiderAI-SaveMP3 + +🎧 A custom ComfyUI node that saves input AUDIO as `.mp3` using `ffmpeg`. + +## Features + +- Saves `.mp3` to `output/audio/` +- Selectable bitrate: 64 / 128 / 192 / 256 / 320 kbps +- Works with any node that outputs `AUDIO` +- No UI hacks or extra files + +## Requirements + +- Python ≥ 3.10 +- ffmpeg (must be installed and available in PATH) + +## Installation + +Clone this repository into your `ComfyUI/custom_nodes` directory: + +```bash +cd ComfyUI/custom_nodes +git clone https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-SaveMP3.git diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..41a9bc5 --- /dev/null +++ b/__init__.py @@ -0,0 +1,79 @@ +import os +import subprocess +import shutil +from pathlib import Path +import numpy as np +import torch +import folder_paths +from scipy.io.wavfile import write + +class SaveAudioAsMP3: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "audio": ("AUDIO",), + "bitrate_kbps": ([64, 128, 192, 256, 320], {"default": 192}), + } + } + + RETURN_TYPES = ("AUDIO",) + RETURN_NAMES = ("audio",) + FUNCTION = "save_as_mp3" + OUTPUT_NODE = True + CATEGORY = "LikeSpiderAI" + + def save_as_mp3(self, audio, bitrate_kbps): + if not shutil.which("ffmpeg"): + raise Exception("❌ ffmpeg not found. Please install and add to PATH.") + + # Extract waveform + samples = audio["waveform"] + if isinstance(samples, torch.Tensor): + samples = samples.detach().cpu().numpy() + if samples.ndim == 3 and samples.shape[0] == 1: + samples = samples[0] + + max_val = np.max(np.abs(samples)) + if max_val > 1.0: + samples = samples / max_val + samples = np.clip(samples, -1.0, 1.0) + audio_int16 = (samples * 32767).astype(np.int16) + + if audio_int16.ndim == 2 and audio_int16.shape[0] in [1, 2]: + wav_data = audio_int16.T + elif audio_int16.ndim == 1: + wav_data = audio_int16 + else: + raise Exception(f"❌ Unsupported audio shape: {audio_int16.shape}") + + # Save as .mp3 in output/audio + output_dir = Path(folder_paths.get_output_directory()) / "audio" + output_dir.mkdir(parents=True, exist_ok=True) + existing = sorted(output_dir.glob("audio_*.mp3")) + index = len(existing) + mp3_path = output_dir / f"audio_{index:05d}.mp3" + + # Save .wav temporarily for ffmpeg conversion + temp_wav = output_dir / "temp_input.wav" + write(temp_wav, 44100, wav_data) + + subprocess.run([ + "ffmpeg", "-y", "-i", str(temp_wav), + "-codec:a", "libmp3lame", "-b:a", f"{bitrate_kbps}k", + str(mp3_path) + ], check=True) + os.remove(temp_wav) + + print(f"[SaveAudioAsMP3] ✅ MP3 saved: {mp3_path}") + + # Return original audio to enable UI preview (if possible) + return (audio,) + +NODE_CLASS_MAPPINGS = { + "SaveAudioAsMP3": SaveAudioAsMP3 +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "SaveAudioAsMP3": "Save Audio As MP3" +} diff --git a/info.json b/info.json new file mode 100644 index 0000000..b12e32c --- /dev/null +++ b/info.json @@ -0,0 +1,7 @@ +{ + "name": "ComfyUI-LikeSpiderAI-SaveMP3", + "author": "Pigidiy", + "version": "1.0", + "description": "Save AUDIO to .mp3 in ComfyUI with bitrate selection and ffmpeg conversion.", + "python_version": ">=3.10" +}