diff --git a/README.MD b/README.MD index 1caf578..1b5b67e 100644 --- a/README.MD +++ b/README.MD @@ -1,26 +1,43 @@ ## 增加节点: +由于引入了新的节点,请重新安装依赖包。 ### Play Sound -选项:音量和语速调节,音量调整范围0-1,语速调整范围0.1-2。这个节点支持多线程播放。 +可触发的声音播放节点,支持mp3和wav格式。这个节点支持多线程播放。 +选项说明: +path:声音文件路径。 +volume:音量调整范围0-1.0。 +speed:语速调整范围0.1-2.0。 +trigger:触发开关,当其值为True时开始播放。 ### Play Sound(loop) -选项:音量调节和循环选项,音量调整范围0-1。这个节点始终占一个声音播放线程。 +可触发的声音播放节点,支持mp3和wav格式。这个节点始终占用一个声音播放线程。 +选项说明: +path:声音文件路径。 +volume:音量调整范围0-1.0。 +loop:当其值为True时循环播放,否则播放一次。 +trigger:触发开关,当其值为True时开始播放。 - (由于引入了新的节点,请重新安装依赖包) +### Input Trigger +输入触发器,可接入任意类型的数据,当检测到有输入内容(非None)时输出True;如果没有接入输入,将一直输出False。 +输入:任意类型,包括且不限于image, latent, model, clip, string, float, int等等。 +输出:Boolean值。 +选项说明: +always_true:当此选项打开时,将忽略输入检测,直接输出True值; -![image](image/playsoundnode.png) # ComfyUI_MSSpeech_TTS ComfyUI下使用的文本转语音插件。使用Microsoft speech TTS 接口将文本内容转为MP3格式的语音文件。 -![image](image/ComfyUI_MSSpeech_TTS.png) -### 插件调整项: -**voice:** 语音种类。 -**rate:** 语音速度。默认是0,调整范围从-200到200。数字越大速度越快。 -**filename_prefix:** 文件名前缀。 +选项说明: +voice: 语音种类。 +rate: 语音速度。默认是0,调整范围从-200到200。数字越大速度越快。 +filename_prefix:文件名前缀。 -### 输出: +输出: MP3 File,字符串类型,其内容是语音文件地址。 +## 使用示例: + +![image](image/triggernode.png) ## 安装方法: - 解压zip文件,将"ComfyUI_MSSpeech_TTS"文件夹复制到 ComfyUI\custom_nodes\ - 安装依赖包,在资源管理器ComfyUI\custom_nodes\ComfyUI_MSSpeech_TTS\ 这个位置打开cmd窗口,输入以下命令: diff --git a/image/ComfyUI_MSSpeech_TTS.png b/image/ComfyUI_MSSpeech_TTS.png deleted file mode 100644 index 627a5d5..0000000 Binary files a/image/ComfyUI_MSSpeech_TTS.png and /dev/null differ diff --git a/image/playsoundnode.png b/image/playsoundnode.png deleted file mode 100644 index f22572c..0000000 Binary files a/image/playsoundnode.png and /dev/null differ diff --git a/image/triggernode.png b/image/triggernode.png new file mode 100644 index 0000000..a49ec3e Binary files /dev/null and b/image/triggernode.png differ diff --git a/py/__pycache__/inputtrigger.cpython-311.pyc b/py/__pycache__/inputtrigger.cpython-311.pyc new file mode 100644 index 0000000..37fa3f4 Binary files /dev/null and b/py/__pycache__/inputtrigger.cpython-311.pyc differ diff --git a/py/__pycache__/msspeechTTS.cpython-310.pyc b/py/__pycache__/msspeechTTS.cpython-310.pyc new file mode 100644 index 0000000..05decf0 Binary files /dev/null and b/py/__pycache__/msspeechTTS.cpython-310.pyc differ diff --git a/py/__pycache__/msspeechTTS.cpython-311.pyc b/py/__pycache__/msspeechTTS.cpython-311.pyc new file mode 100644 index 0000000..3f54376 Binary files /dev/null and b/py/__pycache__/msspeechTTS.cpython-311.pyc differ diff --git a/py/__pycache__/playsound.cpython-311.pyc b/py/__pycache__/playsound.cpython-311.pyc new file mode 100644 index 0000000..1224f37 Binary files /dev/null and b/py/__pycache__/playsound.cpython-311.pyc differ diff --git a/py/__pycache__/playsoundarcade.cpython-311.pyc b/py/__pycache__/playsoundarcade.cpython-311.pyc new file mode 100644 index 0000000..e01d7b9 Binary files /dev/null and b/py/__pycache__/playsoundarcade.cpython-311.pyc differ diff --git a/py/__pycache__/playsoundloop.cpython-311.pyc b/py/__pycache__/playsoundloop.cpython-311.pyc new file mode 100644 index 0000000..9bfe56b Binary files /dev/null and b/py/__pycache__/playsoundloop.cpython-311.pyc differ diff --git a/py/__pycache__/playsoundpygame.cpython-311.pyc b/py/__pycache__/playsoundpygame.cpython-311.pyc new file mode 100644 index 0000000..e134e92 Binary files /dev/null and b/py/__pycache__/playsoundpygame.cpython-311.pyc differ diff --git a/py/__pycache__/playsoundpyglet.cpython-311.pyc b/py/__pycache__/playsoundpyglet.cpython-311.pyc new file mode 100644 index 0000000..d9ee298 Binary files /dev/null and b/py/__pycache__/playsoundpyglet.cpython-311.pyc differ diff --git a/py/__pycache__/timertrigger.cpython-311.pyc b/py/__pycache__/timertrigger.cpython-311.pyc new file mode 100644 index 0000000..1f86709 Binary files /dev/null and b/py/__pycache__/timertrigger.cpython-311.pyc differ diff --git a/py/inputtrigger.py b/py/inputtrigger.py new file mode 100644 index 0000000..17d0ea5 --- /dev/null +++ b/py/inputtrigger.py @@ -0,0 +1,44 @@ + +class AnyType(str): + """always equal in 'not equal comparisons(__ne__)' """ + + def __ne__(self, __value: object) -> bool: + return False + +any = AnyType("*") + + +class Trigger: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "always_true": ("BOOLEAN", {"default": False}), + }, + "optional": { + "anything": (any, {}), + }, + } + + RETURN_TYPES = ("BOOLEAN",) + FUNCTION = "check_input" + OUTPUT_NODE = True + CATEGORY = "MicrosoftSpeech_TTS" + + def check_input(self, always_true, anything=None): + + ret = False + if always_true or (anything is not None): + ret = True + print(f"Input Trigger: {ret}") + + return (ret,) + + +NODE_CLASS_MAPPINGS = { + "Input Trigger": Trigger +} diff --git a/py/msspeechTTS.py b/py/msspeechTTS.py index 18f9f83..3c463ce 100644 --- a/py/msspeechTTS.py +++ b/py/msspeechTTS.py @@ -10,7 +10,7 @@ async def gen_tts(_text,_voice,_rate,filename): tts = edge_tts.Communicate(text = _text, voice = _voice, rate = _rate) await tts.save(filename) -class Text2AutioEdgeTts: +class Text2AudioEdgeTts: def __init__(self): self.output_dir = os.path.join(folder_paths.get_output_directory(), 'audio') if not os.path.exists(self.output_dir): @@ -36,34 +36,34 @@ class Text2AutioEdgeTts: } RETURN_TYPES = ("STRING",) RETURN_NAMES = ("MP3 file: String",) - FUNCTION = "text_2_autio" + FUNCTION = "text_2_audio" OUTPUT_NODE = True - CATEGORY = "MicorsoftSpeech_TTS" + CATEGORY = "MicrosoftSpeech_TTS" - def text_2_autio(self,voice,filename_prefix,text,rate): + def text_2_audio(self,voice,filename_prefix,text,rate): full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir) _datetime = datetime.datetime.now().strftime("%Y%m%d") _datetime = _datetime + datetime.datetime.now().strftime("%H%M%S%f") file = f"{filename}_{_datetime}_{voice}.mp3" - autio_path=os.path.join(full_output_folder, file) + audio_path=os.path.join(full_output_folder, file) _rate = str(rate) + "%" if rate < 0 else "+" + str(rate) + "%" - print(f"MicrosoftSpeech TTS: Generating voice files, voice=鈥榹voice}鈥�, rate={rate}, audiofile_path='{autio_path}, 'text='{text}'") - # asyncio.run(edge_tts_text_2_aution(voice,text,autio_path)) - asyncio.run(gen_tts(text,voice,_rate,autio_path)) + print(f"MicrosoftSpeech TTS: Generating voice files, voice=鈥榹voice}鈥�, rate={rate}, audiofile_path='{audio_path}, 'text='{text}'") + + asyncio.run(gen_tts(text,voice,_rate,audio_path)) return {"ui": {"text": "Audio file锛�"+os.path.join(full_output_folder, file), - 'autios':[{'filename':file,'type':'output','subfolder':'autio'}]}, "result": (autio_path, )} + 'audios':[{'filename':file,'type':'output','subfolder':'audio'}]}, "result": (audio_path, )} -async def edge_tts_text_2_aution(VOICE,TEXT,OUTPUT_FILE) -> None: +async def edge_tts_text_2_audion(VOICE,TEXT,OUTPUT_FILE) -> None: communicate = edge_tts.Communicate(TEXT, VOICE) await communicate.save(OUTPUT_FILE) NODE_CLASS_MAPPINGS = { - "MicorsoftSpeech_TTS": Text2AutioEdgeTts + "MicrosoftSpeech_TTS": Text2AudioEdgeTts } NODE_DISPLAY_NAME_MAPPINGS = { - "MicorsoftSpeech_TTS": "MicorsoftSpeech_TTS" + "MicrosoftSpeech_TTS": "MicrosoftSpeech_TTS" } diff --git a/py/playsound.py b/py/playsound.py index 520bc5e..f05d15a 100644 --- a/py/playsound.py +++ b/py/playsound.py @@ -1,13 +1,12 @@ -import sys -import os import threading from arcade import load_sound + def Play(path, volume, speed): s = load_sound(path) s.play(volume, 0, False, speed) -class Play_Sound_Now(): +class Play_Sound_Now: def __init__(self): pass @@ -19,6 +18,7 @@ class Play_Sound_Now(): "path": ("STRING", {"default": 'comfyui.mp3'}), "volume": ("FLOAT", {"default": 1, "min": 0.0, "max": 1.0, "step": 0.01}), "speed": ("FLOAT", {"default": 1, "min": 0.1, "max": 2.0, "step": 0.1}), + "trigger": ("BOOLEAN",{"default": True}), }, "optional": { }, @@ -27,12 +27,16 @@ class Play_Sound_Now(): RETURN_TYPES = () FUNCTION = "do_playsound" OUTPUT_NODE = True - CATEGORY = "MicorsoftSpeech_TTS" + CATEGORY = "MicrosoftSpeech_TTS" - def do_playsound(self, path, volume, speed): - t = threading.Thread(target=Play(path, volume, speed)) - t.start() - return {"ui": {"text": ("",)}} + def do_playsound(self, path, volume, speed, trigger): + + print(f"play sound: path={path},volume={volume},speed={speed},trigger={trigger}") + if trigger: + t = threading.Thread(target=Play(path, volume, speed)) + t.start() + + return {} NODE_CLASS_MAPPINGS = { diff --git a/py/playsoundloop.py b/py/playsoundloop.py index 7975860..9fc39d4 100644 --- a/py/playsoundloop.py +++ b/py/playsoundloop.py @@ -1,4 +1,3 @@ -import sys import os import threading from pygame import mixer @@ -14,7 +13,7 @@ def Play(path, volume, loop): else: mixer.music.play() -class Play_Sound_pygame_Now(): +class Play_Sound_pygame_Now: def __init__(self): pass @@ -26,6 +25,7 @@ class Play_Sound_pygame_Now(): "path": ("STRING", {"default": 'comfyui.mp3'}), "volume": ("FLOAT", {"default": 1, "min": 0.0, "max": 1.0, "step": 0.01}), "loop": ("BOOLEAN", {"default": False}), + "trigger": ("BOOLEAN", {"default": True}), }, "optional": { }, @@ -34,11 +34,15 @@ class Play_Sound_pygame_Now(): RETURN_TYPES = () FUNCTION = "do_playsound" OUTPUT_NODE = True - CATEGORY = "MicorsoftSpeech_TTS" + CATEGORY = "MicrosoftSpeech_TTS" + + def do_playsound(self, path, volume, loop, trigger): + + print(f"play sound: path={path},volume={volume},loop={loop},trigger={trigger}") + if trigger: + t = threading.Thread(target=Play(path, volume, loop)) + t.start() - def do_playsound(self, path, volume, loop): - t = threading.Thread(target=Play(path, volume, loop)) - t.start() return {}