TTS_all_in_one / TTSs /base_tts.py
jianuo
改个字
1d3143e
raw
history blame contribute delete
No virus
4.62 kB
import abc
import io
import scipy.io.wavfile as wavfile
from pydub import AudioSegment
import traceback
import gradio as gr
def mix_background_music(original_audio, 背景音乐, TTS_up, bg_up):
original_audio = original_audio + TTS_up
ori_out = io.BytesIO()
original_audio.export(ori_out, format="mp3")
ori_out.seek(0)
original_audio_bytes = ori_out.read()
if 背景音乐 is None: # 没有背景音乐
return original_audio_bytes, None
else: # 有背景音乐
# 读取用户上传的背景音乐文件
wav_io = io.BytesIO()
wavfile.write(wav_io, 背景音乐[0], 背景音乐[1])
wav_io.seek(0)
background_music = AudioSegment.from_wav(wav_io)
background_music = background_music + bg_up
# 将背景音乐合并到原始音频中
combined = original_audio.overlay(background_music)
# 使用BytesIO导出合并后的音频为字节串
mix_out = io.BytesIO()
combined.export(mix_out, format="mp3")
mix_out.seek(0) # 重置指针到开始位置
combined_audio_bytes = mix_out.read()
return original_audio_bytes, combined_audio_bytes
class Base_TTS(metaclass=abc.ABCMeta):
default_show = False
@abc.abstractmethod
def _get_config_page(self):
"""要求返回2个参数:config和inputs
config: gr.Group对象,用于包裹所有的输入项
inputs: 一个列表,包含所有的输入项,用于后续的事件绑定,列表的顺序必须和后续_generate方法中参数args的顺序一致
例如:
:return: config, inputs
"""
@abc.abstractmethod
def _generate(self, text, *args):
"""要求返回一个AudioSegment对象
:param text: str,要转换为语音的文本
:param args: 其他参数,与_get_config_page方法中的inputs一一对应
:return: original_audio
示例:
original_audio = AudioSegment.from_file(io.BytesIO(original_audio_bytes), format="mp3")
return original_audio
"""
@abc.abstractmethod
def get_name(self):
"""要求返回一个str,是TTS的名称
:return: name
示例:
return '原神语音合成引擎'
"""
def is_show(self):
"""
是否显示这个TTS
:return: True or False
"""
return True
def _get_submit_button(self):
"""
要求返回1个参数:btn
btn: gr.Button对象,是提交按钮
:return: btn
"""
btn = gr.Button(value="合成", variant="primary", interactive=True, visible=False)
return btn
def get_config_page(self):
self.config, self.inputs = self._get_config_page()
if self.default_show:
self.config.visible = True
else:
self.config.visible = False
def get_submit_button(self):
self.btn = self._get_submit_button()
if self.default_show:
self.btn.visible = True
else:
self.btn.visible = False
def set_visible(self, visible: bool):
# 检查是否已经获取了config和btn
if not hasattr(self, 'config') or not hasattr(self, 'btn'):
raise Exception('请先调用get_config_page和get_submit_button方法')
self.btn.visible = visible
self.config.visible = visible
def create_interface_event(self, text, audio, TTS_up, bg_up, text_output, ori_audio_output, mix_audio_output):
"""如果交互方法只是的点击提交按钮,可以不用重写这个方法"""
# 检查是否已经获取了config和btn
if not hasattr(self, 'config') or not hasattr(self, 'btn'):
raise Exception('请先调用get_config_page和get_submit_button方法')
self.btn.click(self.generate, inputs=[
text,
audio,
TTS_up,
bg_up
] + self.inputs,
outputs=[text_output, ori_audio_output, mix_audio_output])
def generate(self, text, 背景音乐, TTS_up, bg_up, *args):
try:
original_audio = self._generate(text, *args)
return None, *mix_background_music(original_audio, 背景音乐, TTS_up, bg_up)
except Exception as e:
msg = traceback.format_exc()
return msg + '\n\n' + str(e), None, None