From 8a751817e895b9e1145606d31df45aca1ba5368f Mon Sep 17 00:00:00 2001 From: justumen Date: Thu, 23 Jan 2025 17:14:02 +0100 Subject: [PATCH] 0.67 --- README.md | 16 +++- __init__.py | 5 ++ pyproject.toml | 4 +- requirements.txt | 3 +- screenshots/kokoro_tts.png | Bin 0 -> 55772 bytes text_to_speech_kokoro.py | 145 ++++++++++++++++++++++++++++++++ web/js/text_to_speech_kokoro.js | 14 +++ 7 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 screenshots/kokoro_tts.png create mode 100644 text_to_speech_kokoro.py create mode 100644 web/js/text_to_speech_kokoro.js diff --git a/README.md b/README.md index 90f3461..863cf2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# πŸ”— Comfyui : Bjornulf_custom_nodes v0.66 πŸ”— +# πŸ”— Comfyui : Bjornulf_custom_nodes v0.67 πŸ”— -A list of 119 custom nodes for Comfyui : Display, manipulate, create and edit text, images, videos, loras, generate characters and more. +A list of 120 custom nodes for Comfyui : Display, manipulate, create and edit text, images, videos, loras, generate characters and more. You can manage looping operations, generate randomized content, trigger logical conditions, pause and manually control your workflows and even work with external AI tools, like Ollama or Text To Speech. # Coffee : β˜•β˜•β˜•β˜•β˜• 5/5 @@ -192,6 +192,7 @@ Support me and my work : ❀️❀️❀️ ❀️ `59.` [πŸ“ΉπŸ”Š Combine Video + Audio](#59----combine-video--audio) `66.` [πŸ”ŠβžœπŸ“ STT - Speech to Text](#66----stt---speech-to-text) `118.` [πŸ”Š TTS Configuration βš™](#118----tts-configuration-) +`120.` [πŸ“βžœπŸ”Š Kokoro - Text to Speech](#120) ## πŸ’» System πŸ’» `34.` [🧹 Free VRAM hack](#34----free-vram-hack) @@ -360,6 +361,7 @@ cd /where/you/installed/ComfyUI && python main.py - **0.64**: remove "import wget", added some keywords to text generators. - **0.65**: ❗Breaking changes : Combine Text inputs are now all optional (PLease remake your nodes, sorry.) Add 6 new nodes : any2int, any2float, load text from folder, load text from path, load lora from path. Also upgraded the Save text node. - **0.66**: Add lora hunyuan CIVIT ai + download, add TTS configuration node, edit requirements.txt +- **0.67**: Add kokoro TTS node. # πŸ“ Nodes descriptions @@ -1679,4 +1681,12 @@ Take a CivitAI Lora to use with Hunyuan. (NSFW list not on github of course.) The workflow below is included : `workflows/HUNYUAN_basic_lora.json`) : -![hunyuan lora](screenshots/hunyuan_lora.png) \ No newline at end of file +![hunyuan lora](screenshots/hunyuan_lora.png) + +#### 120 - πŸ“βžœπŸ”Š Kokoro - Text to Speech + +**Description:** +Another Text to Speech node based on Kokoro. : https://github.com/thewh1teagle/kokoro-onnx +Lightweight, much simpler, no configuration and fully integrated into Comfyui. (No external backend to run.) + +![tts kokoro](screenshots/kokoro_tts.png) \ No newline at end of file diff --git a/__init__.py b/__init__.py index 22568b0..6e49b95 100644 --- a/__init__.py +++ b/__init__.py @@ -94,10 +94,12 @@ from .loader_lora_with_path import LoaderLoraWithPath from .load_text import LoadTextFromFolder, LoadTextFromPath from .string_splitter import TextSplitin5 from .line_selector import LineSelector +from .text_to_speech_kokoro import KokoroTTS # from .text_generator_t2v import TextGeneratorText2Video NODE_CLASS_MAPPINGS = { "Bjornulf_LineSelector": LineSelector, "Bjornulf_XTTSConfig": XTTSConfig, + "Bjornulf_KokoroTTS": KokoroTTS, # "Bjornulf_TextGeneratorText2Video": TextGeneratorText2Video, "Bjornulf_LatentResolutionSelector": LatentResolutionSelector, "Bjornulf_LoaderLoraWithPath": LoaderLoraWithPath, @@ -223,10 +225,13 @@ NODE_CLASS_MAPPINGS = { } NODE_DISPLAY_NAME_MAPPINGS = { + "Bjornulf_XTTSConfig": "πŸ”Š TTS Configuration βš™", + "Bjornulf_TextToSpeech": "πŸ“βžœπŸ”Š TTS - Text to Speech", # "Bjornulf_HiResFix": "HiResFix", # "Bjornulf_ImageBlend": "🎨 Image Blend", # "Bjornulf_APIHiResCivitAI": "🎨➜🎨 API Image hires fix (CivitAI)", # "Bjornulf_CivitAILoraSelector": "lora Civit", + "Bjornulf_KokoroTTS": "πŸ“βžœπŸ”Š Kokoro - Text to Speech", "Bjornulf_LineSelector": "πŸ“πŸ‘ˆ Line selector (🎲 Or random)", "Bjornulf_LoaderLoraWithPath": "πŸ“₯πŸ‘‘ Load Lora with Path", # "Bjornulf_TextGeneratorText2Video": "πŸ”₯πŸ“πŸ“Ή Text Generator for text to video πŸ“ΉπŸ“πŸ”₯", diff --git a/pyproject.toml b/pyproject.toml index 3b8447a..5251bb8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "bjornulf_custom_nodes" -description = "116 ComfyUI nodes : Display, manipulate, and edit text, images, videos, loras, generate characters and more. Manage looping operations, generate randomized content, use logical conditions and work with external AI tools, like Ollama or Text To Speech." -version = "0.66" +description = "120 ComfyUI nodes : Display, manipulate, and edit text, images, videos, loras, generate characters and more. Manage looping operations, generate randomized content, use logical conditions and work with external AI tools, like Ollama or Text To Speech Kokoro, etc..." +version = "0.67" license = {file = "LICENSE"} [project.urls] diff --git a/requirements.txt b/requirements.txt index 08e983d..d3594b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ faster_whisper ffmpeg-python civitai-py fal_client -importlib \ No newline at end of file +sounddevice +kokoro_onnx \ No newline at end of file diff --git a/screenshots/kokoro_tts.png b/screenshots/kokoro_tts.png new file mode 100644 index 0000000000000000000000000000000000000000..df488a064881677213747b2698016ff93cc2036a GIT binary patch literal 55772 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 CuGatn literal 0 HcmV?d00001 diff --git a/text_to_speech_kokoro.py b/text_to_speech_kokoro.py new file mode 100644 index 0000000..c8e1612 --- /dev/null +++ b/text_to_speech_kokoro.py @@ -0,0 +1,145 @@ +import os +import requests +import random + +VOICE_OPTIONS = { + "af_bella": "Bella (American Female) - af_bella", + "af_nicole": "Nicole (American Female) - af_nicole", + "af_sarah": "Sarah (American Female) - af_sarah", + "af_sky": "Sky (American Female) - af_sky", + "af": "Default (American Female) - af", + "am_adam": "Adam (American Male) - am_adam", + "am_michael": "Michael (American Male) - am_michael", + "bf_emma": "Emma (British Female) - bf_emma", + "bf_isabella": "Isabella (British Female) - bf_isabella", + "bm_george": "George (British Male) - bm_george", + "bm_lewis": "Lewis (British Male) - bm_lewis" +} + +# Create a reversed mapping for display to value +VOICE_DISPLAY_TO_VALUE = {v: k for k, v in VOICE_OPTIONS.items()} + +LANGUAGE_OPTIONS = { + "en-us": "English (US)", + "en-gb": "English (UK)", + "fr-fr": "French", + "ja": "Japanese", + "ko": "Korean", + "cmn": "Chinese (Mandarin)" +} + +def download_if_not_exists(url, dest_path): + """Download a file from a URL if it doesn't already exist.""" + if not os.path.exists(dest_path): + print(f"Downloading {os.path.basename(dest_path)}...") + os.makedirs(os.path.dirname(dest_path), exist_ok=True) + response = requests.get(url, stream=True) + response.raise_for_status() + with open(dest_path, 'wb') as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + print(f"Downloaded {os.path.basename(dest_path)}") + +class KokoroTTS: + BASE_DIR = "Bjornulf/Kokoro" + MODEL_FILE = os.path.join(BASE_DIR, "kokoro-v0_19.onnx") + VOICES_FILE = os.path.join(BASE_DIR, "voices.bin") + + VOICE_LANGUAGES = { + 'af': 'en-us', 'am': 'en-us', 'bf': 'en-gb', 'bm': 'en-gb' + } + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "text": ("STRING", {"multiline": True}), + "voice": (list(VOICE_OPTIONS.values()), {"default": "Default (American Female) - af"}), + "language": (list(LANGUAGE_OPTIONS.keys()), {"default": "en-us"}), + "speed": ("FLOAT", {"default": 1.0, "min": 0.5, "max": 2.0, "step": 0.1}), + "autoplay": ("BOOLEAN", {"default": True}), + "save_audio": ("BOOLEAN", {"default": True}), + "overwrite": ("BOOLEAN", {"default": False}), + "seed": ("INT", {"default": 0}), + } + } + + RETURN_TYPES = ("AUDIO",) + FUNCTION = "generate_audio" + CATEGORY = "Bjornulf/Kokoro" + + def generate_audio(self, text: str, voice: str, language: str, speed: float, + autoplay: bool, save_audio: bool, + overwrite: bool, seed: int): + random.seed(seed) + + config = { + "model_path": self.MODEL_FILE, + "voices_path": self.VOICES_FILE, + "speed": speed, + "language": language + } + + download_if_not_exists( + "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files/kokoro-v0_19.onnx", + config["model_path"] + ) + download_if_not_exists( + "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files/voices.bin", + config["voices_path"] + ) + + try: + from kokoro_onnx import Kokoro + import soundfile as sf + import torch + import numpy as np + from pydub import AudioSegment + from pydub.playback import play + + voice_id = VOICE_DISPLAY_TO_VALUE[voice] + kokoro = Kokoro(config["model_path"], config["voices_path"]) + + # Check if file exists and overwrite is False + sanitized_text = ''.join(c if c.isalnum() else '_' for c in text[:50]) + save_path = os.path.join("Bjornulf_TTS_Kokoro", voice_id, f"{sanitized_text}.wav") + full_path = os.path.abspath(save_path) + + if os.path.exists(full_path) and not overwrite: + print(f"File exists: {full_path}. Loading existing audio.") + samples, sample_rate = sf.read(full_path) + if autoplay: + audio_segment = AudioSegment.from_file(full_path) + play(audio_segment) + else: + # Generate new audio + samples, sample_rate = kokoro.create( + text, + voice=voice_id, + speed=config["speed"], + lang=language + ) + + if save_audio: + os.makedirs(os.path.dirname(full_path), exist_ok=True) + sf.write(full_path, samples, sample_rate) + + if autoplay: + try: + audio_segment = AudioSegment( + samples.tobytes(), + frame_rate=sample_rate, + sample_width=samples.dtype.itemsize, + channels=1 + ) + play(audio_segment) + except Exception as e: + print(f"Autoplay error: {e}") + + audio_tensor = torch.from_numpy(samples).unsqueeze(0) + audio_output = {"waveform": audio_tensor.unsqueeze(0), "sample_rate": sample_rate} + return (audio_output,) + + except Exception as e: + print(f"Error in Kokoro TTS: {e}") + return ({"waveform": torch.zeros(1, 1, 1), "sample_rate": 22050},) \ No newline at end of file diff --git a/web/js/text_to_speech_kokoro.js b/web/js/text_to_speech_kokoro.js new file mode 100644 index 0000000..64ce6ac --- /dev/null +++ b/web/js/text_to_speech_kokoro.js @@ -0,0 +1,14 @@ +import { app } from "../../../scripts/app.js"; + +app.registerExtension({ + name: "Bjornulf.KokoroTTS", + async nodeCreated(node) { + if (node.comfyClass === "Bjornulf_KokoroTTS") { + // Set seed widget to hidden input + const seedWidget = node.widgets.find((w) => w.name === "seed"); + if (seedWidget) { + seedWidget.type = "HIDDEN"; + } + } + } +}); \ No newline at end of file