"""本机能力探测:GPU 等(供控制台 UI)。""" from __future__ import annotations import platform import socket import subprocess import threading import time from typing import Any def detect_nvidia_gpu() -> bool: if platform.system().lower() not in ("windows", "linux"): return False try: _kw: dict = {"capture_output": True, "timeout": 4} if platform.system().lower() == "windows": _kw["creationflags"] = subprocess.CREATE_NO_WINDOW r = subprocess.run(["nvidia-smi"], **_kw) return r.returncode == 0 except Exception: return False def detect_nvenc_available(nvidia_present: bool | None = None) -> bool: if nvidia_present is None: nvidia_present = detect_nvidia_gpu() if not nvidia_present: return False try: _kw = {"capture_output": True, "text": True, "timeout": 8} if platform.system().lower() == "windows": _kw["creationflags"] = subprocess.CREATE_NO_WINDOW r = subprocess.run(["ffmpeg", "-hide_banner", "-encoders"], **_kw) return r.returncode == 0 and "h264_nvenc" in (r.stdout or "") except Exception: return False _GPU_STATUS_CACHE_TTL_SECONDS = 60.0 _gpu_status_lock = threading.Lock() _gpu_status_cache: tuple[float, dict[str, Any]] | None = None def gpu_status_payload(force_refresh: bool = False) -> dict[str, Any]: global _gpu_status_cache now = time.time() with _gpu_status_lock: if not force_refresh and _gpu_status_cache and (now - _gpu_status_cache[0]) < _GPU_STATUS_CACHE_TTL_SECONDS: return dict(_gpu_status_cache[1]) nv = detect_nvidia_gpu() enc = detect_nvenc_available(nv) payload = { "nvidia_detected": nv, "nvenc_available": enc, } with _gpu_status_lock: _gpu_status_cache = (time.time(), payload) return dict(payload) def machine_summary_payload() -> dict[str, Any]: """供远程 App 遥测:本机标识与系统信息。""" return { "hostname": socket.gethostname(), "os": platform.system(), "os_release": platform.release(), "machine": platform.machine(), "python": platform.python_version(), }