From a4b6ebfed5d1e08235b4878d0f5ccf6f0de00c59 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Sat, 31 Jan 2026 16:45:10 +0800 Subject: [PATCH] 'commit' --- WeiXin/ChatMonitorAll_ReplyAudio.py | 13 ++-------- WeiXin/ChatMonitorAll_ReplyTxt.py | 11 --------- WeiXin/T7_TTS_VoiceReply.py | 8 +++--- WeiXin/WxUtil.py | 38 ++++++++++++++++++++++++----- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/WeiXin/ChatMonitorAll_ReplyAudio.py b/WeiXin/ChatMonitorAll_ReplyAudio.py index f3a0d14..a2ef1fa 100644 --- a/WeiXin/ChatMonitorAll_ReplyAudio.py +++ b/WeiXin/ChatMonitorAll_ReplyAudio.py @@ -226,8 +226,8 @@ class ChatMonitorAudioBot: logger.info(">>> 立即按住发送语音按钮...") self.device.touch.down(pos[0], pos[1]) - logger.info(">>> 等待 2 秒确保微信进入录音状态...") - await asyncio.sleep(2.0) + logger.info(">>> 等待 0.5 秒确保微信进入录音状态...") + await asyncio.sleep(0.5) logger.info(">>> 启动 TTS 播音...") tts_thread.start() @@ -333,15 +333,6 @@ class ChatMonitorAudioBot: if reply: logger.info(f"LLM 建议回复: {reply}") - # 如果触发回复的消息是语音,先点击语音条以清理状态 - if last_msg.get('type') == 'voice': - try: - cx, cy = last_msg.get('center', (0, 0)) - WxUtil.safe_device_click(self.device, cx, cy) - await asyncio.sleep(1.5) - except Exception as e: - logger.warning(f"清理语音状态失败: {e}") - # 发送语音回复 success = await self.send_voice_reply(reply) diff --git a/WeiXin/ChatMonitorAll_ReplyTxt.py b/WeiXin/ChatMonitorAll_ReplyTxt.py index b19f97a..b689008 100644 --- a/WeiXin/ChatMonitorAll_ReplyTxt.py +++ b/WeiXin/ChatMonitorAll_ReplyTxt.py @@ -297,17 +297,6 @@ class ChatMonitorBot: if reply: logger.info(f"LLM 建议回复: {reply}") if self.input_pos: - # 如果触发回复的消息是语音,先点击语音条以清理状态 - if last_msg.get('type') == 'voice': - logger.info("回复前点击语音消息中心以关闭转文字遮罩") - try: - cx, cy = last_msg.get('center', (0, 0)) - WxUtil.safe_device_click(self.device, cx, cy) - await asyncio.sleep(1.5) - self.device.screenshot(self.screenshot_path) - except Exception as e: - logger.warning(f"清理语音状态失败: {e}") - # 确定输入框位置 target_pos = self.input_pos[0] if isinstance(self.input_pos, (list, tuple)) and len(self.input_pos) == 2 else self.input_pos diff --git a/WeiXin/T7_TTS_VoiceReply.py b/WeiXin/T7_TTS_VoiceReply.py index 596925c..2feba5b 100644 --- a/WeiXin/T7_TTS_VoiceReply.py +++ b/WeiXin/T7_TTS_VoiceReply.py @@ -109,9 +109,9 @@ def run_t7_task(): logger.info(">>> [发送] 1. 立即按住发送语音按钮...") d.touch.down(pos[0], pos[1]) - # B. 明确等待 2 秒(解决最前面语音丢失问题) - logger.info(">>> [等待] 2. 录音已启动,等待 2 秒确保微信进入录音状态...") - time.sleep(2.0) + # B. 明确等待 0.5 秒(解决最前面语音丢失问题) + logger.info(">>> [等待] 2. 录音已启动,等待 0.5 秒确保微信进入录音状态...") + time.sleep(0.5) # C. 启动 TTS 线程(开始合成并播放) logger.info(">>> [播放] 3. 启动 TTS 播音...") @@ -136,7 +136,7 @@ def run_t7_task(): # E. 释放按钮 d.touch.up(pos[0], pos[1]) - total_duration = time.time() - start_time + 2.0 # 加上最开始等待的2秒 + total_duration = time.time() - start_time + 0.5 # 加上最开始等待的0.5秒 logger.info(f">>> [完成] 录音结束,微信录音总时长约 {total_duration:.2f}s") tts_thread.join() diff --git a/WeiXin/WxUtil.py b/WeiXin/WxUtil.py index f73d4ca..a8f5764 100644 --- a/WeiXin/WxUtil.py +++ b/WeiXin/WxUtil.py @@ -33,6 +33,17 @@ TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Templat # 全局调试图片计数器 _debug_counter = 0 +# 全局调试模式开关 +DEBUG_MODE = False + +def set_debug_mode(enabled): + """设置全局调试模式""" + global DEBUG_MODE + DEBUG_MODE = enabled + if enabled: + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.INFO) def parse_wechat_time(time_str): """ @@ -160,6 +171,8 @@ def parse_wechat_time(time_str): def get_next_debug_path(desc="step"): """获取下一个顺序命名的调试图片路径 (debug_N_desc.jpg)""" + if not DEBUG_MODE: + return None global _debug_counter _debug_counter += 1 filename = f"debug_{_debug_counter}_{desc}.jpg" @@ -767,7 +780,7 @@ async def analyze_chat_image(image_path, output_path, device=None, target_name=" m['sender'] = chat_title # 保存当前状态的调试图 - if current_output_path: + if current_output_path and DEBUG_MODE: cv2.imwrite(current_output_path, debug_img) logger.info(f"调试图已保存: {current_output_path}") @@ -834,8 +847,13 @@ async def analyze_chat_image(image_path, output_path, device=None, target_name=" poll_start = time.time() while time.time() - poll_start < 3.0: # 最多等 3 秒 menu_shot = get_next_debug_path("step_long_press_poll") - d.screenshot(menu_shot) - btn_pos = find_template_match(menu_shot, zhuan_template, threshold=0.7) + if menu_shot: + d.screenshot(menu_shot) + btn_pos = find_template_match(menu_shot, zhuan_template, threshold=0.7) + else: + # 调试模式关闭时,直接在内存中匹配 + btn_pos = find_template_match(d.screenshot(), zhuan_template, threshold=0.7) + if btn_pos: break time.sleep(0.2) # 快速轮询 @@ -853,8 +871,12 @@ async def analyze_chat_image(image_path, output_path, device=None, target_name=" # 1. 截图 (但不立即 OCR,而是丢给异步任务) peek_shot = get_next_debug_path("step_peek_content") + if not peek_shot: + # 如果不是调试模式,我们需要一个临时路径供 OCR 任务使用 + peek_shot = os.path.join(OUTPUT_DIR, f"temp_peek_{int(time.time())}.jpg") + d.screenshot(peek_shot) - logger.info(f"已截图 {peek_shot},启动异步OCR任务以提取内容...") + logger.info(f"已获取截图,启动异步OCR任务以提取内容...") async def _async_ocr_task(img_path, target_y): """内部异步任务:在线程池中运行 OCR""" @@ -910,8 +932,12 @@ async def analyze_chat_image(image_path, output_path, device=None, target_name=" poll_start = time.time() while time.time() - poll_start < 3.0: restore_menu_shot = get_next_debug_path("step_restore_poll") - d.screenshot(restore_menu_shot) - cancel_btn = find_template_match(restore_menu_shot, cancel_template, threshold=0.7) + if restore_menu_shot: + d.screenshot(restore_menu_shot) + cancel_btn = find_template_match(restore_menu_shot, cancel_template, threshold=0.7) + else: + cancel_btn = find_template_match(d.screenshot(), cancel_template, threshold=0.7) + if cancel_btn: break time.sleep(0.2)