Loading... ## 前言 最近写Boss-Key程序,有个需求是在隐藏窗口后静音该窗口,在显示时恢复。经过各类测试,发现pycaw库更符合要求,下面就来讲一讲如何使用pycaw库静音指定程序、进程 使用win32api的SendMessage似乎也能实现一样的功能,不过实测发现pycaw更好用 ## Pycaw库 Pypi项目页:[pycaw · PyPI](https://pypi.org/project/pycaw/) 主要用途:使用python控制Windows的各类音频设备、调整系统和程序音量等 这里主要用于获取所有音频会话和调整音量 安装指令:`pip install pycaw` ## 基本实现 ```python from pycaw.pycaw import AudioUtilities def changeMute(pid,flag=1): """ pid: process id flag=1 mute flag=0 unmute """ sessions = AudioUtilities.GetAllSessions() for session in sessions: volume = session.SimpleAudioVolume if session.Process and session.Process.pid == pid: volume.SetMute(flag, None) break ``` 通过上述代码,传入一个pid和flag即可实现禁音指定会话进程 ## 代码解释 首先通过pycaw.pycaw.AudioUtilities的GetAllSessions方法获取到当前所有的音频会话。 之后遍历所有会话,通过session对象的Process属性的pid,选出对应的会话,并使用SetMute进行静音即可。 ## 代码进阶 虽然通常来说,这个函数已经能够满足大部分需求。但是在Boss-Key的开发过程中,实测发现,通常程序会单独创建一个进程来提供音频服务,如Edge就会创建专门的Audio Service进程来处理播放音频。 ![image.png](https://blog.ivan-hanloth.cn/usr/uploads/2024/10/503850132.png) 那么此时需要被隐藏的窗口对应的pid与音频处理的pid不同,无法通过直接比较的方式进行判断。但是似乎创建出来的进程对应的名字是相同的,于是便有了一下进阶代码: ```python from pycaw.pycaw import AudioUtilities import psutil def changeMute(pid,flag=1): """ pid: 视图进程的pid flag=1 mute flag=0 unmute """ sessions = AudioUtilities.GetAllSessions() for session in sessions: volume = session.SimpleAudioVolume if session.Process and session.Process.name() == psutil.Process(pid).name(): volume.SetMute(flag, None) break ``` 通过psutil获取到视图进程的pid对应的程序名,再与原来的名称进行比较即可 ## 完全代码 有时我们可能更希望通过窗口句柄禁音指定程序,此处将提供能够接受窗口句柄或程序名称或pid为参数的禁音切换函数代码: 其中,优先级pid>窗口句柄>名称,即,如果提供了pid,则提供的窗口句柄、名称都将失效。 注意额外需要安装psutil、pywin32库 ```python from pycaw.pycaw import AudioUtilities import psutil from win32process import GetWindowThreadProcessId def changeMute(flag:int=1, pid:int=0, hwnd:int=0, title:str=""): """ pid: process id hwnd: window handle title: window title 优先级: pid > hwnd > title flag=1 mute flag=0 unmute """ if not pid and not hwnd and not title: return False if not pid: if hwnd: pid = GetWindowThreadProcessId(hwnd)[1] else: for p in psutil.process_iter(): if p.name() == title: pid = p.pid break sessions = AudioUtilities.GetAllSessions() for session in sessions: volume = session.SimpleAudioVolume if session.Process and session.Process.name() == psutil.Process(pid).name(): volume.SetMute(flag, None) break ``` Last modification:October 11, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 1 如果觉得我的文章对你有用,请随意赞赏