真实接口预热
This commit is contained in:
@ -79,9 +79,10 @@ class TextToBlendShapesService:
|
||||
yield {'type': 'error', 'message': '文本为空'}
|
||||
return
|
||||
|
||||
# 测试:只处理第一句
|
||||
sentences = sentences[:1]
|
||||
print(f"[测试模式] 只处理第一句: {sentences[0]}")
|
||||
# 确保 is_continuation 长度与 sentences 匹配
|
||||
if len(self.is_continuation) != len(sentences):
|
||||
print(f"[警告] is_continuation 长度 ({len(self.is_continuation)}) 与 sentences 长度 ({len(sentences)}) 不匹配,重置")
|
||||
self.is_continuation = [False] * len(sentences)
|
||||
|
||||
yield {
|
||||
'type': 'status',
|
||||
@ -92,9 +93,10 @@ class TextToBlendShapesService:
|
||||
}
|
||||
|
||||
# 打印句子列表用于调试
|
||||
print(f"[调试] 发送给前端的句子列表:")
|
||||
print(f"[调试] 发送给前端的句子列表 (共{len(sentences)}句, is_continuation长度={len(self.is_continuation)}):")
|
||||
for i, s in enumerate(sentences):
|
||||
print(f" [{i}] {s}")
|
||||
cont = self.is_continuation[i] if i < len(self.is_continuation) else False
|
||||
print(f" [{i}] {s} (连续={cont})")
|
||||
|
||||
# 使用队列来收集处理完成的句子
|
||||
result_queue = queue.Queue()
|
||||
@ -113,70 +115,85 @@ class TextToBlendShapesService:
|
||||
result_queue.put((index, 'error', None, str(e)))
|
||||
|
||||
# 提交所有句子到线程池并发处理(增加并发数以加速)
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
|
||||
for index, sentence in enumerate(sentences):
|
||||
executor.submit(process_and_queue, index, sentence)
|
||||
print(f"[调试] 准备提交 {len(sentences)} 个句子到线程池")
|
||||
try:
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
|
||||
futures = []
|
||||
for index, sentence in enumerate(sentences):
|
||||
future = executor.submit(process_and_queue, index, sentence)
|
||||
futures.append(future)
|
||||
print(f"[调试] 已提交句子 {index}: {sentence[:20]}...")
|
||||
|
||||
# 按顺序从队列中取出结果并推送
|
||||
completed = {}
|
||||
next_index = 0
|
||||
total_frames = 0
|
||||
cumulative_time = 0.0 # 累计时间,用于连续句子
|
||||
# 按顺序从队列中取出结果并推送
|
||||
completed = {}
|
||||
next_index = 0
|
||||
total_frames = 0
|
||||
cumulative_time = 0.0 # 累计时间,用于连续句子
|
||||
|
||||
while next_index < len(sentences):
|
||||
# 如果下一个句子还没完成,等待队列
|
||||
if next_index not in completed:
|
||||
yield {
|
||||
'type': 'status',
|
||||
'stage': 'processing',
|
||||
'sentence_index': next_index,
|
||||
'sentences': len(sentences),
|
||||
'message': f'正在处理 {next_index + 1}/{len(sentences)}'
|
||||
}
|
||||
print(f"[调试] 开始主循环,共 {len(sentences)} 个句子")
|
||||
while next_index < len(sentences):
|
||||
print(f"[调试] 主循环 next_index={next_index}, completed keys={list(completed.keys())}")
|
||||
# 如果下一个句子还没完成,等待队列
|
||||
if next_index not in completed:
|
||||
yield {
|
||||
'type': 'status',
|
||||
'stage': 'processing',
|
||||
'sentence_index': next_index,
|
||||
'sentences': len(sentences),
|
||||
'message': f'正在处理 {next_index + 1}/{len(sentences)}'
|
||||
}
|
||||
|
||||
# 从队列中获取结果
|
||||
while next_index not in completed:
|
||||
try:
|
||||
index, status, frames, error = result_queue.get(timeout=1)
|
||||
completed[index] = (status, frames, error)
|
||||
print(f"[主线程] 收到句子 {index} 的处理结果")
|
||||
except queue.Empty:
|
||||
continue
|
||||
# 从队列中获取结果
|
||||
while next_index not in completed:
|
||||
try:
|
||||
index, status, frames, error = result_queue.get(timeout=1)
|
||||
completed[index] = (status, frames, error)
|
||||
print(f"[主线程] 收到句子 {index} 的处理结果, status={status}")
|
||||
except queue.Empty:
|
||||
print(f"[调试] 队列为空,继续等待 next_index={next_index}")
|
||||
continue
|
||||
|
||||
# 推送下一个句子的帧
|
||||
status, frames, error = completed[next_index]
|
||||
if status == 'error':
|
||||
yield {'type': 'error', 'message': f'句子 {next_index} 处理失败: {error}'}
|
||||
return
|
||||
# 推送下一个句子的帧
|
||||
status, frames, error = completed[next_index]
|
||||
print(f"[主线程] 句子 {next_index} 状态: {status}, 帧数: {len(frames) if frames else 0}, 错误: {error}")
|
||||
if status == 'error':
|
||||
print(f"[错误] 句子 {next_index} 处理失败: {error}")
|
||||
yield {'type': 'error', 'message': f'句子 {next_index} 处理失败: {error}'}
|
||||
return
|
||||
|
||||
# 如果是连续句子,调整时间码使其无缝衔接
|
||||
is_continuation = self.is_continuation[next_index] if next_index < len(self.is_continuation) else False
|
||||
# 如果是连续句子,调整时间码使其无缝衔接
|
||||
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'}")
|
||||
print(f"[主线程] 正在推送句子 {next_index}/{len(sentences)-1} 的 {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:
|
||||
cumulative_time = 0.0
|
||||
# 如果不是连续句子,重置累计时间
|
||||
if not is_continuation and next_index > 0:
|
||||
cumulative_time = 0.0
|
||||
|
||||
for frame in frames:
|
||||
# 调整时间码:从累计时间开始
|
||||
frame['timeCode'] = cumulative_time + frame['timeCode']
|
||||
frame['sentenceIndex'] = next_index
|
||||
total_frames += 1
|
||||
yield {'type': 'frame', 'frame': frame}
|
||||
for frame in frames:
|
||||
# 调整时间码:从累计时间开始
|
||||
frame['timeCode'] = cumulative_time + frame['timeCode']
|
||||
frame['sentenceIndex'] = next_index
|
||||
total_frames += 1
|
||||
yield {'type': 'frame', 'frame': frame}
|
||||
|
||||
# 更新累计时间为当前句子的最后一帧时间
|
||||
if frames:
|
||||
cumulative_time = frames[-1]['timeCode']
|
||||
# 更新累计时间为当前句子的最后一帧时间
|
||||
if frames:
|
||||
cumulative_time = frames[-1]['timeCode']
|
||||
|
||||
next_index += 1
|
||||
next_index += 1
|
||||
|
||||
print(f"[主线程] 流式传输完成,共 {total_frames} 帧")
|
||||
yield {
|
||||
'type': 'end',
|
||||
'frames': total_frames
|
||||
}
|
||||
print(f"[主线程] 流式传输完成,共 {total_frames} 帧,处理了 {next_index} 个句子")
|
||||
yield {
|
||||
'type': 'end',
|
||||
'frames': total_frames
|
||||
}
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"[错误] 流式处理异常: {e}")
|
||||
traceback.print_exc()
|
||||
yield {'type': 'error', 'message': f'流式处理异常: {str(e)}'}
|
||||
|
||||
def _process_sentence(self, sentence, output_dir, index):
|
||||
"""处理单个句子: TTS -> A2F -> 解析"""
|
||||
@ -286,6 +303,9 @@ class TextToBlendShapesService:
|
||||
# 12字以上:前6字,再6字,剩下的
|
||||
parts = [first[:6], first[6:12], first[12:]]
|
||||
|
||||
# 过滤空字符串
|
||||
parts = [p for p in parts if p.strip()]
|
||||
|
||||
# 替换第一句为多个小句
|
||||
sentences = parts + sentences[1:]
|
||||
# 标记后续部分为连续播放
|
||||
@ -293,18 +313,31 @@ class TextToBlendShapesService:
|
||||
print(f"[拆分优化] 第一句({length}字)拆分为{len(parts)}部分: {[len(p) for p in parts]} - 连续播放")
|
||||
|
||||
if not max_sentence_length or max_sentence_length <= 0:
|
||||
print(f"[拆分] 最终句子数: {len(sentences)}, is_continuation长度: {len(self.is_continuation)}")
|
||||
return sentences
|
||||
|
||||
limited = []
|
||||
for sentence in sentences:
|
||||
new_is_continuation = []
|
||||
for i, sentence in enumerate(sentences):
|
||||
if len(sentence) <= max_sentence_length:
|
||||
limited.append(sentence)
|
||||
new_is_continuation.append(self.is_continuation[i] if i < len(self.is_continuation) else False)
|
||||
continue
|
||||
|
||||
start = 0
|
||||
first_part = True
|
||||
while start < len(sentence):
|
||||
limited.append(sentence[start:start + max_sentence_length])
|
||||
# 第一部分继承原来的 is_continuation,后续部分标记为连续
|
||||
if first_part:
|
||||
new_is_continuation.append(self.is_continuation[i] if i < len(self.is_continuation) else False)
|
||||
first_part = False
|
||||
else:
|
||||
new_is_continuation.append(True)
|
||||
start += max_sentence_length
|
||||
|
||||
self.is_continuation = new_is_continuation
|
||||
print(f"[拆分] 最终句子数: {len(limited)}, is_continuation长度: {len(self.is_continuation)}")
|
||||
return limited
|
||||
|
||||
def _prepare_output_paths(self, output_dir: str = None, suffix: str = None):
|
||||
|
||||
Reference in New Issue
Block a user