Merge branch 'newsnow' into add_local_tts_change_voice

This commit is contained in:
hrz
2025-06-30 10:48:06 +08:00
committed by GitHub
131 changed files with 5529 additions and 1786 deletions
@@ -43,7 +43,6 @@ class TTSProviderBase(ABC):
self.tts_text_buff = []
self.punctuations = (
"",
".",
"",
"?",
"",
@@ -59,7 +58,6 @@ class TTSProviderBase(ABC):
"",
",",
"",
".",
"",
"?",
"",
@@ -171,7 +169,7 @@ class TTSProviderBase(ABC):
)
)
# 对于单句的文本,进行分段处理
segments = re.split(r'([。!?!?;\n])', content_detail)
segments = re.split(r"([。!?!?;\n])", content_detail)
for seg in segments:
self.tts_text_queue.put(
TTSMessageDTO(
@@ -37,7 +37,9 @@ class TTSProvider(TTSProviderBase):
self.api_url = config.get("api_url")
self.authorization = config.get("authorization")
self.header = {"Authorization": f"{self.authorization}{self.access_token}"}
check_model_key("TTS", self.access_token)
model_key_msg = check_model_key("TTS", self.access_token)
if model_key_msg:
logger.bind(tag=TAG).error(model_key_msg)
async def text_to_speak(self, text, output_file):
request_json = {
@@ -94,8 +94,9 @@ class TTSProvider(TTSProviderBase):
self.format = config.get("response_format", "wav")
self.audio_file_type = config.get("response_format", "wav")
self.api_key = config.get("api_key", "YOUR_API_KEY")
have_key = check_model_key("FishSpeech TTS", self.api_key)
if not have_key:
model_key_msg = check_model_key("FishSpeech TTS", self.api_key)
if model_key_msg:
logger.bind(tag=TAG).error(model_key_msg)
return
self.normalize = str(config.get("normalize", True)).lower() in (
"true",
@@ -12,6 +12,8 @@ from core.utils.util import check_model_key
from core.providers.tts.base import TTSProviderBase
from core.handle.abortHandle import handleAbortMessage
from core.providers.tts.dto.dto import SentenceType, ContentType, InterfaceType
from asyncio import Task
TAG = __name__
logger = setup_logging()
@@ -141,6 +143,7 @@ class TTSProvider(TTSProviderBase):
super().__init__(config, delete_audio_file)
self.ws = None
self.interface_type = InterfaceType.DUAL_STREAM
self._monitor_task = None # 监听任务引用
self.appId = config.get("appid")
self.access_token = config.get("access_token")
self.cluster = config.get("cluster")
@@ -157,7 +160,9 @@ class TTSProvider(TTSProviderBase):
self.opus_encoder = opus_encoder_utils.OpusEncoderUtils(
sample_rate=16000, channels=1, frame_size_ms=60
)
check_model_key("TTS", self.access_token)
model_key_msg = check_model_key("TTS", self.access_token)
if model_key_msg:
logger.bind(tag=TAG).error(model_key_msg)
async def open_audio_channels(self, conn):
try:
@@ -202,6 +207,10 @@ class TTSProvider(TTSProviderBase):
if message.sentence_type == SentenceType.FIRST:
# 初始化参数
try:
if not getattr(self.conn, "sentence_id", None):
self.conn.sentence_id = uuid.uuid4().hex
logger.bind(tag=TAG).info(f"自动生成新的 会话ID: {self.conn.sentence_id}")
logger.bind(tag=TAG).info("开始启动TTS会话...")
future = asyncio.run_coroutine_threadsafe(
self.start_session(self.conn.sentence_id),
@@ -264,10 +273,9 @@ class TTSProvider(TTSProviderBase):
try:
# 建立新连接
if self.ws is None:
await handleAbortMessage(self.conn)
logger.bind(tag=TAG).error(f"WebSocket连接不存在,终止发送文本")
logger.bind(tag=TAG).warning(f"WebSocket连接不存在,终止发送文本")
return
# 过滤Markdown
filtered_text = MarkdownCleaner.clean_markdown(text)
@@ -287,6 +295,25 @@ class TTSProvider(TTSProviderBase):
async def start_session(self, session_id):
logger.bind(tag=TAG).info(f"开始会话~~{session_id}")
try:
task = self._monitor_task
if (
task is not None
and isinstance(task, Task)
and not task.done()
):
logger.bind(tag=TAG).info("等待上一个监听任务结束...")
if self.ws is not None:
logger.bind(tag=TAG).info("强制关闭上一个WebSocket连接以唤醒监听任务...")
try:
await self.ws.close()
except Exception as e:
logger.bind(tag=TAG).warning(f"关闭上一个ws异常: {e}")
self.ws = None
try:
await asyncio.wait_for(task, timeout=8)
except Exception as e:
logger.bind(tag=TAG).warning(f"等待监听任务异常: {e}")
self._monitor_task = None
# 建立新连接
await self._ensure_connection()
@@ -457,6 +484,8 @@ class TTSProvider(TTSProviderBase):
except:
pass
self.ws = None
# 监听任务退出时清理引用
self._monitor_task = None
async def send_event(
self,
@@ -166,7 +166,9 @@ class TTSProvider(TTSProviderBase):
) as resp:
if resp.status != 200:
logger.error(f"TTS请求失败: {resp.status}, {await resp.text()}")
logger.bind(tag=TAG).error(
f"TTS请求失败: {resp.status}, {await resp.text()}"
)
self.tts_audio_queue.put((SentenceType.LAST, [], None))
return
@@ -229,7 +231,7 @@ class TTSProvider(TTSProviderBase):
self._process_before_stop_play_files()
except Exception as e:
logger.error(f"TTS请求异常: {e}")
logger.bind(tag=TAG).error(f"TTS请求异常: {e}")
self.tts_audio_queue.put((SentenceType.LAST, [], None))
def to_tts(self, text: str) -> list:
@@ -263,7 +265,7 @@ class TTSProvider(TTSProviderBase):
self.api_url, params=params, headers=headers, timeout=5
) as response:
if response.status_code != 200:
logger.error(
logger.bind(tag=TAG).error(
f"TTS请求失败: {response.status_code}, {response.text}"
)
return []
@@ -299,5 +301,5 @@ class TTSProvider(TTSProviderBase):
return opus_datas
except Exception as e:
logger.error(f"TTS请求异常: {e}")
logger.bind(tag=TAG).error(f"TTS请求异常: {e}")
return []
@@ -25,7 +25,9 @@ class TTSProvider(TTSProviderBase):
self.speed = float(speed) if speed else 1.0
self.output_file = config.get("output_dir", "tmp/")
check_model_key("TTS", self.api_key)
model_key_msg = check_model_key("TTS", self.api_key)
if model_key_msg:
logger.bind(tag=TAG).error(model_key_msg)
async def text_to_speak(self, text, output_file):
headers = {