12.26
This commit is contained in:
@ -6,14 +6,26 @@ import queue
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from tts_service import TTSService
|
||||
from edge_tts_service import EdgeTTSService
|
||||
from a2f_service import A2FService
|
||||
from blend_shape_parser import BlendShapeParser
|
||||
|
||||
class TextToBlendShapesService:
|
||||
DEFAULT_SPLIT_PUNCTUATIONS = '。!?;!?;,,'
|
||||
|
||||
def __init__(self, lang='zh-CN', a2f_url="192.168.1.39:52000"):
|
||||
self.tts = TTSService(lang=lang)
|
||||
def __init__(self, lang='zh-CN', a2f_url="192.168.1.39:52000", tts_provider='edge-tts'):
|
||||
"""
|
||||
初始化服务
|
||||
:param lang: 语言
|
||||
:param a2f_url: A2F服务地址
|
||||
:param tts_provider: TTS提供商 ('pyttsx3' 或 'edge-tts')
|
||||
"""
|
||||
# 根据选择初始化TTS服务
|
||||
if tts_provider == 'edge-tts':
|
||||
self.tts = EdgeTTSService(lang=lang)
|
||||
else:
|
||||
self.tts = TTSService(lang=lang)
|
||||
|
||||
self.a2f = A2FService(a2f_url=a2f_url)
|
||||
self.parser = BlendShapeParser()
|
||||
|
||||
@ -67,7 +79,18 @@ class TextToBlendShapesService:
|
||||
yield {'type': 'error', 'message': '文本为空'}
|
||||
return
|
||||
|
||||
yield {'type': 'status', 'stage': 'split', 'sentences': len(sentences), 'message': f'已拆分为 {len(sentences)} 个句子'}
|
||||
yield {
|
||||
'type': 'status',
|
||||
'stage': 'split',
|
||||
'sentences': len(sentences),
|
||||
'sentence_texts': sentences, # 发送句子文本列表
|
||||
'message': f'已拆分为 {len(sentences)} 个句子'
|
||||
}
|
||||
|
||||
# 打印句子列表用于调试
|
||||
print(f"[调试] 发送给前端的句子列表:")
|
||||
for i, s in enumerate(sentences):
|
||||
print(f" [{i}] {s}")
|
||||
|
||||
# 使用队列来收集处理完成的句子
|
||||
result_queue = queue.Queue()
|
||||
@ -126,6 +149,7 @@ class TextToBlendShapesService:
|
||||
is_continuation = self.is_continuation[next_index] if next_index < len(self.is_continuation) else False
|
||||
|
||||
print(f"[主线程] 正在推送句子 {next_index} 的 {len(frames)} 帧 {'(连续)' if is_continuation else ''}")
|
||||
print(f"[调试] 句子 {next_index} 对应文本: {sentences[next_index] if next_index < len(sentences) else 'N/A'}")
|
||||
|
||||
# 如果不是连续句子,重置累计时间
|
||||
if not is_continuation and next_index > 0:
|
||||
@ -135,7 +159,6 @@ class TextToBlendShapesService:
|
||||
# 调整时间码:从累计时间开始
|
||||
frame['timeCode'] = cumulative_time + frame['timeCode']
|
||||
frame['sentenceIndex'] = next_index
|
||||
frame['isContinuation'] = is_continuation
|
||||
total_frames += 1
|
||||
yield {'type': 'frame', 'frame': frame}
|
||||
|
||||
@ -157,6 +180,7 @@ class TextToBlendShapesService:
|
||||
start_time = time.time()
|
||||
|
||||
print(f"[线程 {index}] 开始处理: {sentence[:30]}...")
|
||||
print(f"[调试] 线程 {index} 实际处理的完整文本: [{sentence}] (长度: {len(sentence)}字)")
|
||||
_, audio_path = self._prepare_output_paths(output_dir, suffix=f's{index:03d}')
|
||||
|
||||
print(f"[线程 {index}] TTS 开始...")
|
||||
@ -166,7 +190,7 @@ class TextToBlendShapesService:
|
||||
print(f"[线程 {index}] TTS 完成,耗时 {tts_time:.2f}秒,A2F 开始...")
|
||||
|
||||
a2f_start = time.time()
|
||||
csv_path = self.a2f.audio_to_csv(audio_path)
|
||||
csv_path, temp_dir = self.a2f.audio_to_csv(audio_path) # 接收临时目录路径
|
||||
a2f_time = time.time() - a2f_start
|
||||
print(f"[线程 {index}] A2F 完成,耗时 {a2f_time:.2f}秒,解析中...")
|
||||
|
||||
@ -174,6 +198,14 @@ class TextToBlendShapesService:
|
||||
frames = list(self.parser.iter_csv_to_blend_shapes(csv_path))
|
||||
parse_time = time.time() - parse_start
|
||||
|
||||
# 解析完成后清理临时目录
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||
print(f"[线程 {index}] 已清理临时目录: {temp_dir}")
|
||||
except Exception as e:
|
||||
print(f"[线程 {index}] 清理临时目录失败: {e}")
|
||||
|
||||
total_time = time.time() - start_time
|
||||
print(f"[线程 {index}] 完成!生成了 {len(frames)} 帧 | 总耗时: {total_time:.2f}秒 (TTS: {tts_time:.2f}s, A2F: {a2f_time:.2f}s, 解析: {parse_time:.2f}s)")
|
||||
|
||||
@ -239,12 +271,15 @@ class TextToBlendShapesService:
|
||||
length = len(first)
|
||||
parts = []
|
||||
|
||||
if length <= 12:
|
||||
# 12字以内分两部分
|
||||
if length <= 8:
|
||||
# 8字以下不拆分
|
||||
parts = [first]
|
||||
elif length <= 12:
|
||||
# 8-12字分两部分
|
||||
mid = length // 2
|
||||
parts = [first[:mid], first[mid:]]
|
||||
else:
|
||||
# 12字之后:前6字,再6字,剩下的
|
||||
# 12字以上:前6字,再6字,剩下的
|
||||
parts = [first[:6], first[6:12], first[12:]]
|
||||
|
||||
# 替换第一句为多个小句
|
||||
|
||||
Reference in New Issue
Block a user