如何实时捕获机器音视频状态,实现恐龙游戏Bot自动重启?
外部实现游戏7×24小时自动检测与恢复方案
针对你开发的类Chrome恐龙游戏,需要外部实现无侵入式的卡顿检测(画面冻结/无声音)并触发恢复操作,以下是两种可行方案:
一、画面动态检测(基于屏幕截图对比)
通过监控游戏窗口的画面像素变化判断是否冻结,无需修改游戏源码:
- 定位游戏窗口
先获取游戏窗口的坐标和尺寸,避免截取整个屏幕浪费资源:
import pygetwindow as gw import time import pyautogui from PIL import ImageGrab import numpy as np # 替换为你的游戏窗口标题 game_window = gw.getWindowsWithTitle("恐龙游戏")[0] x, y, w, h = game_window.left, game_window.top, game_window.width, game_window.height
- 实时像素差异检测
每隔固定时间截取游戏窗口,和上一次截图做像素差异计算,连续多次差异低于阈值则判定为卡顿:
def calculate_screen_diff(prev_img, curr_img): prev_arr = np.array(prev_img) curr_arr = np.array(curr_img) # 计算像素总差异值 total_diff = np.sum(np.abs(prev_arr - curr_arr)) return total_diff # 初始化参数 prev_screenshot = ImageGrab.grab(bbox=(x, y, x+w, y+h)) stuck_counter = 0 diff_threshold = 1500 # 根据游戏动态调整,正常游戏的差异会远大于此值 check_interval = 1 # 每秒检查一次 trigger_threshold = 3 # 连续3次差异低于阈值触发恢复 while True: curr_screenshot = ImageGrab.grab(bbox=(x, y, x+w, y+h)) diff_value = calculate_screen_diff(prev_screenshot, curr_screenshot) if diff_value < diff_threshold: stuck_counter += 1 if stuck_counter >= trigger_threshold: # 先激活游戏窗口,再执行恢复操作(比如按R键重启) game_window.activate() pyautogui.press('r') stuck_counter = 0 print("检测到画面冻结,已触发恢复") else: stuck_counter = 0 prev_screenshot = curr_screenshot time.sleep(check_interval)
优化建议:如果游戏只有特定区域(比如恐龙跑动区)是动态的,可以只截取该区域对比,进一步提升效率和准确性。
二、系统声音检测(监听实时音频输出)
通过捕获系统音频流的音量,判断游戏是否停止播放音乐:
- 依赖安装与音频捕获
使用sounddevice库监听系统输出,先执行安装命令:pip install sounddevice numpy
import sounddevice as sd import numpy as np def check_audio_activity(duration=1, sample_rate=44100): # 录制1秒音频 audio_data = sd.rec(int(duration * sample_rate), samplerate=sample_rate, channels=2, dtype='float32') sd.wait() # 计算RMS音量值,无声音时接近0 rms_volume = np.sqrt(np.mean(audio_data**2)) # 阈值根据实际游戏音量调整 return rms_volume > 0.001
- 整合到检测逻辑
可以和画面检测结合,双条件触发(既无声音又无画面变化)减少误判:
# 整合后的主循环 while True: has_sound = check_audio_activity() # 调用前面的画面检测逻辑,获取是否有画面变化 curr_screenshot = ImageGrab.grab(bbox=(x, y, x+w, y+h)) diff_value = calculate_screen_diff(prev_screenshot, curr_screenshot) has_motion = diff_value > diff_threshold if not has_sound and not has_motion: game_window.activate() pyautogui.press('r') print("检测到无声音且画面冻结,已触发恢复") stuck_counter = 0 else: stuck_counter = 0 if has_motion else stuck_counter + 1 prev_screenshot = curr_screenshot time.sleep(check_interval)
注意:不同系统的音频捕获需要对应设置:
- Windows:可配合Virtual Audio Cable将系统输出转成输入设备,或直接使用
sounddevice的默认输出监听(部分系统支持) - macOS:使用Soundflower虚拟音频设备
- Linux:通过PulseAudio配置音频捕获
三、稳定性优化
- 加入日志:记录每次触发恢复的时间和原因,方便排查问题
- 异常捕获:用
try-except包裹截图、音频捕获逻辑,避免程序意外崩溃 - 窗口激活:每次触发操作前确保游戏窗口处于激活状态,避免pyautogui操作失效
内容的提问来源于stack exchange,提问作者Francisco Lozada
相关产品推荐
相关产品推荐

