TTS-with-RVC-dev
184 строки · 6.6 Кб
1import os2import edge_tts as tts3from edge_tts import VoicesManager4import asyncio, concurrent.futures5import gradio as gr6from rvc_tts_pipeline.rvc_infer import rvc_convert7import hashlib8from datetime import datetime9
10
11class TTS_RVC:12def __init__(self, rvc_path, input_directory, model_path, voice="ru-RU-DmitryNeural", output_directory=None):13self.pool = concurrent.futures.ThreadPoolExecutor()14self.current_voice = voice15self.input_directory = input_directory16self.can_speak = True17self.current_model = model_path18self.rvc_path = rvc_path19self.output_directory = output_directory20
21def set_voice(self, voice):22self.current_voice = voice23
24#def get_voices(self):25# loop = asyncio.new_event_loop()26# voices = loop.run_until_complete(get_voices())27# loop.close()28# return voices29
30def set_output_directory(directory_path):31self.output_directory = directory_path32
33def __call__(self,34text,35pitch=0,36tts_rate=0,37tts_volume=0,38tts_pitch=0,39output_filename=None):40path = (self.pool.submit41(asyncio.run, speech(model_path=self.current_model,42rvc_path=self.rvc_path,43input_directory=self.input_directory,44text=text,45pitch=pitch,46voice=self.current_voice,47tts_add_rate=tts_rate,48tts_add_volume=tts_volume,49tts_add_pitch=tts_pitch,50output_directory=self.output_directory,51filename=output_filename)).result())52return path53
54def speech(self, input_path, pitch=0, output_directory=None, filename=None):55global can_speak56if not can_speak:57print("Can't speak now")58return59output_path = rvc_convert(model_path=self.current_model,60input_path=input_path,61rvc_path=self.rvc_path,62f0_up_key=pitch,63output_filename=filename,64output_dir_path=output_directory)65name = date_to_short_hash()66if filename is None:67if output_directory is None:68output_directory = "temp"69
70new_path = os.path.join(output_directory, name + ".wav")71os.rename(output_path, new_path)72output_path = new_path73
74return os.path.abspath(output_path)75
76def process_args(self, text):77rate_param, text = process_text(text, param="--tts-rate")78volume_param, text = process_text(text, param="--tts-volume")79tts_pitch_param, text = process_text(text, param="--tts-pitch")80rvc_pitch_param, text = process_text(text, param="--rvc-pitch")81return [rate_param, volume_param, tts_pitch_param, rvc_pitch_param], text82
83
84def date_to_short_hash():85current_date = datetime.now()86date_str = current_date.strftime("%Y-%m-%d %H:%M:%S")87sha256_hash = hashlib.sha256(date_str.encode()).hexdigest()88short_hash = sha256_hash[:8]89return short_hash90
91
92async def get_voices():93voicesobj = await VoicesManager.create()94return [data["ShortName"] for data in voicesobj.voices]95
96can_speak = True97
98async def tts_comminicate(input_directory,99text,100voice="ru-RU-DmitryNeural",101tts_add_rate=0,102tts_add_volume=0,103tts_add_pitch=0):104communicate = tts.Communicate(text=text,105voice=voice,106rate=f'{"+" if tts_add_rate >= 0 else ""}{tts_add_rate}%',107volume=f'{"+" if tts_add_volume >= 0 else ""}{tts_add_volume}%',108pitch=f'{"+" if tts_add_pitch >= 0 else ""}{tts_add_pitch}Hz')109file_name = date_to_short_hash()110input_path = os.path.join(input_directory, file_name)111await communicate.save(input_path)112return input_path, file_name113
114async def speech(model_path,115input_directory,116rvc_path,117text,118pitch=0,119voice="ru-RU-DmitryNeural",120tts_add_rate=0,121tts_add_volume=0,122tts_add_pitch=0,123filename=None,124output_directory=None):125global can_speak126
127input_path, file_name = await tts_comminicate(input_directory=input_directory,128text=text,129voice=voice,130tts_add_rate=tts_add_rate,131tts_add_volume=tts_add_volume,132tts_add_pitch=tts_add_pitch)133
134while not can_speak:135await asyncio.sleep(1)136can_speak = False137
138output_path = rvc_convert(model_path=model_path,139input_path=input_path,140rvc_path=rvc_path,141f0_up_key=pitch,142output_filename=filename,143output_dir_path=output_directory)144name = date_to_short_hash()145if filename is None:146if output_directory is None:147output_directory = "temp"148new_path = os.path.join(output_directory, name + ".wav")149os.rename(output_path, new_path)150output_path = new_path151
152os.remove(input_path)153can_speak = True154return os.path.abspath(output_path)155
156
157def process_text(input_text, param, default_value=0):158try:159words = input_text.split()160
161value = default_value162
163i = 0164while i < len(words):165if words[i] == param:166if i + 1 < len(words):167next_word = words[i + 1]168if next_word.isdigit() or (next_word[0] == '-' and next_word[1:].isdigit()):169value = int(next_word)170words.pop(i)171words.pop(i)172else:173raise ValueError(f"Invalid type of argument in \"{param}\"")174else:175raise ValueError(f"There is no value for parameter \"{param}\"")176i += 1177
178final_string = ' '.join(words)179
180return value, final_string181
182except Exception as e:183print(f"Ошибка: {e}")184return 0, input_text185