diff --git a/config.example.yaml b/config.example.yaml index 45a05a8..dc5cbcf 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -20,6 +20,16 @@ debug: # 留空或不匹配时将回退为全量模式。 target_site: "" +# ---------------------------------------------------------------------------- +# 自动化静音:打开站点/安能应用时是否静音。 +# true(默认)= 启动时给 Chromium 和安能附加 --mute-audio 开关,整个自动化会话 +# 全程静音(防止深夜任务执行时浏览器/应用发出提示音打扰); +# false = 不静音,站点声音正常播放。 +# 运行期切换需重启服务生效。 +# ---------------------------------------------------------------------------- +mute: + enabled: true + # ---------------------------------------------------------------------------- # 顺心捷达 (https://sxne.sxjdfreight.com) # ---------------------------------------------------------------------------- diff --git a/inbound_verify/runtime.py b/inbound_verify/runtime.py index 39c1687..b0bd9cd 100644 --- a/inbound_verify/runtime.py +++ b/inbound_verify/runtime.py @@ -76,6 +76,16 @@ def _wait_cdp_up(port, timeout=60.0): return False +def read_mute_enabled() -> bool: + """读 config.yaml 的 mute.enabled(缺失默认 True=静音;读取失败也按 True)。""" + try: + with open(CONFIG_PATH, "r", encoding="utf-8") as f: + cfg = yaml.safe_load(f) or {} + return bool((cfg.get("mute", {}) or {}).get("enabled", True)) + except Exception: + return True + + # 【环境兼容】宿主 shell(Codex/VS Code 插件、WorkBuddy 等)会向子进程注入一批与业务 # 无关的变量,实测会让安能应用登录后反复弹出“获取试用网点接口报错”: # - HTTP(S)_PROXY=http://127.0.0.1:8800(QuickQ 加速器代理):安能的 wnp.ane56.com @@ -100,8 +110,11 @@ _ANNENG_STRIP_EXACT = { } -def launch_anneng(app_path): - """以调试模式启动安能 Electron 应用(自动选取空闲端口),返回子进程对象。""" +def launch_anneng(app_path, mute=True): + """以调试模式启动安能 Electron 应用(自动选取空闲端口),返回子进程对象。 + + mute:True 时附加 --mute-audio 开关(静音应用声音,由 config.yaml mute.enabled 决定)。 + """ anneng_env = { key: value for key, value in os.environ.items() @@ -109,9 +122,10 @@ def launch_anneng(app_path): } port = _find_free_port() print(f">> 以调试模式启动【安能】应用(端口 {port}):{app_path}") - proc = subprocess.Popen( - [app_path, f"--remote-debugging-port={port}"], env=anneng_env - ) + anneng_args = [app_path, f"--remote-debugging-port={port}"] + if mute: + anneng_args.append("--mute-audio") + proc = subprocess.Popen(anneng_args, env=anneng_env) anneng.set_cdp_port(port) if not _wait_cdp_up(port): raise RuntimeError( @@ -251,6 +265,10 @@ def launch_and_prepare(debug_mode=False, debug_target="", foreground=True): print(f"⚠️ 读取 config.yaml(debug) 失败: {e}") anneng_app_path = state_store.get_setting("安能", "app_path") + # 1.5 静音开关(config.yaml mute.enabled,缺失默认静音) + mute = read_mute_enabled() + print(f">> 静音已{'开启' if mute else '关闭'}(config.yaml mute.enabled={mute})") + # 2. 确定要挂载的网页站点 + 安能标记 anneng_active = False if debug_mode: @@ -283,7 +301,9 @@ def launch_and_prepare(debug_mode=False, debug_target="", foreground=True): pw = sync_playwright().start() # 调试模式临时开启 CDP 端口,便于外部 Playwright(如 Playwright CLI 技能) # 通过 connectOverCDP 挂载到已登录的页面读取内容。仅调试模式生效,不影响服务模式。 - _launch_args = ["--remote-debugging-port=9223"] if debug_mode else [] + _launch_args = (["--mute-audio"] if mute else []) + ( + ["--remote-debugging-port=9223"] if debug_mode else [] + ) browser = pw.chromium.launch(headless=False, args=_launch_args) context = browser.new_context(viewport={"width": 1920, "height": 1080}) # 默认禁用麦克风/摄像头:在每个页面/iframe 加载前覆盖 getUserMedia 为“直接拒绝”, @@ -338,7 +358,7 @@ def launch_and_prepare(debug_mode=False, debug_target="", foreground=True): anneng_proc = None if anneng_active: try: - anneng_proc = launch_anneng(anneng_app_path) + anneng_proc = launch_anneng(anneng_app_path, mute=mute) pages_map["安能"] = True # 哨兵:已启动(无 Playwright page) except Exception as e: print(f"⚠️ 启动安能应用失败,已跳过安能:{e}")