"""PortAudio/PyAudio 启动前调整动态库搜索路径。 conda 环境下 `.../envs/xxx/lib` 里的 libasound 会到同前缀的 alsa-lib 子目录找插件, 该目录常缺 libasound_module_*.so,日志里刷屏且采集电平可能异常。 处理:1) 去掉仅含插件目录的路径;2) 把系统 /usr/lib/ 插到 LD_LIBRARY_PATH 最前, 让动态链接优先用系统的 libasound。""" from __future__ import annotations import os import platform def strip_conda_alsa_from_ld_library_path() -> None: ld = os.environ.get("LD_LIBRARY_PATH", "") if not ld: return parts: list[str] = [] for p in ld.split(":"): if not p: continue pl = p.lower() if "conda" in pl or "miniconda" in pl or "mamba" in pl: if "alsa-lib" in pl or "alsa_lib" in pl: continue parts.append(p) if parts: os.environ["LD_LIBRARY_PATH"] = ":".join(parts) else: os.environ.pop("LD_LIBRARY_PATH", None) def prepend_system_lib_dirs_for_alsa() -> None: """Linux:把系统 lib 目录放在 LD_LIBRARY_PATH 最前面。""" if platform.system() != "Linux": return triplet = { "aarch64": ("/usr/lib/aarch64-linux-gnu", "/lib/aarch64-linux-gnu"), "x86_64": ("/usr/lib/x86_64-linux-gnu", "/lib/x86_64-linux-gnu"), "amd64": ("/usr/lib/x86_64-linux-gnu", "/lib/x86_64-linux-gnu"), }.get(platform.machine().lower()) if not triplet: return prepend: list[str] = [] for d in triplet: if os.path.isdir(d): prepend.append(d) if not prepend: return rest = [p for p in os.environ.get("LD_LIBRARY_PATH", "").split(":") if p] out: list[str] = [] for p in prepend + rest: if p not in out: out.append(p) os.environ["LD_LIBRARY_PATH"] = ":".join(out) def fix_ld_path_for_portaudio() -> None: prepend_system_lib_dirs_for_alsa() strip_conda_alsa_from_ld_library_path()