'commit'
This commit is contained in:
@@ -21,14 +21,20 @@ MY_VOICE_ID = "qwen-tts-vc-guanyu-voice-20260131160431051-8e51"
|
||||
REPLY_TEXT = "我是少惠林的大张老师,您的孩子几年级了?我们周六周日上班,您可以带孩子过来试听一下。"
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.StreamHandler(sys.stdout),
|
||||
logging.FileHandler(os.path.join(WxUtil.LOG_DIR, "T7_TTS_VoiceReply.log"), mode='w', encoding='utf-8')
|
||||
]
|
||||
)
|
||||
# 强制重新配置日志,确保输出到文件
|
||||
root_logger = logging.getLogger()
|
||||
for handler in root_logger.handlers[:]:
|
||||
root_logger.removeHandler(handler)
|
||||
|
||||
file_handler = logging.FileHandler(os.path.join(WxUtil.LOG_DIR, "T7_TTS_VoiceReply.log"), mode='w', encoding='utf-8')
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
file_handler.setFormatter(formatter)
|
||||
stream_handler.setFormatter(formatter)
|
||||
root_logger.addHandler(file_handler)
|
||||
root_logger.addHandler(stream_handler)
|
||||
root_logger.setLevel(logging.INFO)
|
||||
|
||||
logger = logging.getLogger("T7_TTS")
|
||||
|
||||
def tts_worker(tts_manager, voice_id, text, finished_event, start_event):
|
||||
@@ -53,7 +59,7 @@ def tts_worker(tts_manager, voice_id, text, finished_event, start_event):
|
||||
finished_event.set()
|
||||
|
||||
def run_t7_task():
|
||||
logger.info("开始执行 T7: 集成 TTS 克隆引擎与微信语音回复 (优化连贯性版本)")
|
||||
logger.info("开始执行 T7: 集成 TTS 克隆引擎与微信语音回复 (优化延迟版)")
|
||||
|
||||
# 1. 连接设备
|
||||
d = WxUtil.connect_device()
|
||||
@@ -63,16 +69,13 @@ def run_t7_task():
|
||||
|
||||
# 2. 初始化 TTS 管理器
|
||||
try:
|
||||
# 增加缓冲区到 1.0 秒以解决断续问题
|
||||
tts_manager = QwenTTSManager()
|
||||
# 这里虽然 init 没传参,但我们可以在 start_synthesis 逻辑里或者修改 AlyTtsKit 让它支持传参
|
||||
except Exception as e:
|
||||
logger.error(f"初始化 TTS 失败: {e}")
|
||||
return
|
||||
|
||||
# 3. 准备微信环境:确保处于语音输入模式
|
||||
logger.info("步骤1: 准备微信环境...")
|
||||
# 先尝试寻找 "按住说话" 按钮,如果找不到则尝试切换
|
||||
tmp_screen = os.path.join(WxUtil.OUTPUT_DIR, "t7_check_mode.jpg")
|
||||
d.screenshot(tmp_screen)
|
||||
press_say_template = os.path.join(WxUtil.TEMPLATE_DIR, "press_say.jpg")
|
||||
@@ -80,7 +83,6 @@ def run_t7_task():
|
||||
|
||||
if not pos:
|
||||
logger.info(">>> [状态] 未发现 '按住说话' 按钮,尝试切换模式...")
|
||||
# 尝试点击键盘图标切换回语音模式
|
||||
audio_reply_template = os.path.join(WxUtil.TEMPLATE_DIR, "audio_reply.jpg")
|
||||
switch_pos = WxUtil.match_template_center(tmp_screen, audio_reply_template, threshold=0.8)
|
||||
if switch_pos:
|
||||
@@ -96,25 +98,28 @@ def run_t7_task():
|
||||
|
||||
logger.info(f">>> [定位] 成功定位到语音按钮中心: {pos}")
|
||||
|
||||
# 4. 同步执行:开始长按 + 启动 TTS
|
||||
# 4. 同步执行:先按住 -> 等待2秒 -> 播放
|
||||
finished_event = threading.Event()
|
||||
playback_start_event = threading.Event()
|
||||
tts_thread = threading.Thread(target=tts_worker, args=(tts_manager, MY_VOICE_ID, REPLY_TEXT, finished_event, playback_start_event))
|
||||
|
||||
logger.info("步骤2: 开始同步录音与播放 (使用 Jitter Buffer 优化)...")
|
||||
logger.info("步骤2: 开始同步录音与播放 (先按住 2 秒再播放)...")
|
||||
|
||||
# 启动 TTS 线程
|
||||
# A. 先按住按钮
|
||||
logger.info(">>> [发送] 1. 立即按住发送语音按钮...")
|
||||
d.touch.down(pos[0], pos[1])
|
||||
|
||||
# B. 明确等待 2 秒(解决最前面语音丢失问题)
|
||||
logger.info(">>> [等待] 2. 录音已启动,等待 2 秒确保微信进入录音状态...")
|
||||
time.sleep(2.0)
|
||||
|
||||
# C. 启动 TTS 线程(开始合成并播放)
|
||||
logger.info(">>> [播放] 3. 启动 TTS 播音...")
|
||||
tts_thread.start()
|
||||
|
||||
# 等待 TTS 真正开始发出声音
|
||||
logger.info(">>> [等待] 等待音频缓冲区填充并开始播放...")
|
||||
if not playback_start_event.wait(timeout=10):
|
||||
logger.error("等待音频播放超时")
|
||||
return
|
||||
|
||||
# 按住按钮
|
||||
logger.info(">>> [发送] 检测到音频播放开始,立即按住发送语音按钮...")
|
||||
d.touch.down(pos[0], pos[1])
|
||||
# D. 等待音频真正开始播放(用于日志同步)
|
||||
if playback_start_event.wait(timeout=10):
|
||||
logger.info(">>> [同步] 检测到音频已开始从扬声器输出")
|
||||
|
||||
# 模拟计时
|
||||
start_time = time.time()
|
||||
@@ -122,17 +127,17 @@ def run_t7_task():
|
||||
while not finished_event.is_set():
|
||||
elapsed = int(time.time() - start_time)
|
||||
if elapsed > last_second:
|
||||
logger.info(f">>> [计时] {elapsed}")
|
||||
logger.info(f">>> [录音中] {elapsed}s")
|
||||
last_second = elapsed
|
||||
time.sleep(0.1)
|
||||
if elapsed > 30:
|
||||
logger.warning("录音时间超过 30 秒,强制结束")
|
||||
if elapsed > 40: # 调大超时时间
|
||||
logger.warning("录音时间过长,强制结束")
|
||||
break
|
||||
|
||||
# 释放按钮
|
||||
# E. 释放按钮
|
||||
d.touch.up(pos[0], pos[1])
|
||||
total_duration = time.time() - start_time
|
||||
logger.info(f">>> [完成] 录音完成,总时长约 {total_duration:.2f}s")
|
||||
total_duration = time.time() - start_time + 2.0 # 加上最开始等待的2秒
|
||||
logger.info(f">>> [完成] 录音结束,微信录音总时长约 {total_duration:.2f}s")
|
||||
|
||||
tts_thread.join()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user