Merge branch 'main' into update-tts-voice-data

This commit is contained in:
Sakura-RanChen
2026-03-02 09:19:46 +08:00
committed by GitHub
5 changed files with 149 additions and 33 deletions
@@ -8,6 +8,7 @@ import traceback
import websockets
from asyncio import Task
from typing import Callable, Any
from config.logger import setup_logging
from core.utils.tts import MarkdownCleaner
from core.providers.tts.base import TTSProviderBase
@@ -392,6 +393,24 @@ class TTSProvider(TTSProviderBase):
finally:
self._monitor_task = None
def audio_to_opus_data_stream(
self, audio_file_path, callback: Callable[[Any], Any] = None
):
"""重写父类方法:使用独立的临时编码器处理音频文件,避免与TTS流式编码器并发冲突。
双流式TTS中,monitor任务在event loop线程接收TTS音频并使用self.opus_encoder编码,
同时tts_text_priority_thread处理音乐文件也使用self.opus_encoder
共享的encoder.buffer非线程安全,并发访问会导致SILK resampler断言失败。
"""
from core.utils.util import audio_to_data_stream
return audio_to_data_stream(
audio_file_path,
is_opus=True,
callback=callback,
sample_rate=self.conn.sample_rate,
opus_encoder=None,
)
def to_tts(self, text: str) -> list:
"""非流式生成音频数据,用于生成音频及测试场景"""
try:
@@ -13,6 +13,7 @@ import websockets
from asyncio import Task
from urllib import parse
from datetime import datetime
from typing import Callable, Any
from config.logger import setup_logging
from core.utils.tts import MarkdownCleaner
from core.providers.tts.base import TTSProviderBase
@@ -471,6 +472,24 @@ class TTSProvider(TTSProviderBase):
finally:
self._monitor_task = None
def audio_to_opus_data_stream(
self, audio_file_path, callback: Callable[[Any], Any] = None
):
"""重写父类方法:使用独立的临时编码器处理音频文件,避免与TTS流式编码器并发冲突。
双流式TTS中,monitor任务在event loop线程接收TTS音频并使用self.opus_encoder编码,
同时tts_text_priority_thread处理音乐文件也使用self.opus_encoder
共享的encoder.buffer非线程安全,并发访问会导致SILK resampler断言失败。
"""
from core.utils.util import audio_to_data_stream
return audio_to_data_stream(
audio_file_path,
is_opus=True,
callback=callback,
sample_rate=self.conn.sample_rate,
opus_encoder=None,
)
def to_tts(self, text: str) -> list:
"""非流式TTS处理,用于测试及保存音频文件的场景"""
try:
@@ -698,6 +698,20 @@ class TTSProvider(TTSProviderBase):
)
)
def audio_to_opus_data_stream(
self, audio_file_path, callback: Callable[[Any], Any] = None
):
"""重写父类方法:使用独立的临时编码器处理音频文件,避免与TTS流式编码器并发冲突。
双流式TTS中,monitor任务在event loop线程接收TTS音频并使用self.opus_encoder编码,
同时tts_text_priority_thread处理音乐文件也使用self.opus_encoder
共享的encoder.buffer非线程安全,并发访问会导致SILK resampler断言失败。
"""
from core.utils.util import audio_to_data_stream
return audio_to_data_stream(
audio_file_path, is_opus=True, callback=callback,
sample_rate=self.conn.sample_rate, opus_encoder=None
)
def wav_to_opus_data_audio_raw_stream(self, raw_data_var, is_end=False, callback: Callable[[Any], Any]=None):
return self.opus_encoder.encode_pcm_to_opus_stream(raw_data_var, is_end, callback=callback)
@@ -11,6 +11,7 @@ import traceback
import websockets
from asyncio import Task
from typing import Callable, Any
from config.logger import setup_logging
from core.utils.tts import MarkdownCleaner
from urllib.parse import urlencode, urlparse
@@ -481,9 +482,27 @@ class TTSProvider(TTSProviderBase):
return audio_data
except Exception as e:
logger.bind(tag=TAG).error(f"生成音频数据失败: {str(e)}")
return []
def _build_base_request(self, status,text=" "):
return []
def audio_to_opus_data_stream(
self, audio_file_path, callback: Callable[[Any], Any] = None
):
"""重写父类方法:使用独立的临时编码器处理音频文件,避免与TTS流式编码器并发冲突。
双流式TTS中,monitor任务在event loop线程接收TTS音频并使用self.opus_encoder编码,
同时tts_text_priority_thread处理音乐文件也使用self.opus_encoder
共享的encoder.buffer非线程安全,并发访问会导致SILK resampler断言失败。
"""
from core.utils.util import audio_to_data_stream
return audio_to_data_stream(
audio_file_path,
is_opus=True,
callback=callback,
sample_rate=self.conn.sample_rate,
opus_encoder=None,
)
def _build_base_request(self, status, text=" "):
"""构建基础请求结构"""
return {
"header": {