This commit is contained in:
HuangHai
2026-01-31 16:45:10 +08:00
parent d7b45f8e2d
commit a4b6ebfed5
4 changed files with 38 additions and 32 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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")
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")
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)