首页 > 编程语言 > 详细

精确控制windows全局音量(Python)

时间:2020-03-31 14:49:42      阅读:132      评论:0      收藏:0      [点我收藏+]

话不多说,直接上代码:

  1 import ctypes,time
  2 import comtypes
  3 from ctypes import wintypes
  4 
  5 MMDeviceApiLib = comtypes.GUID(
  6     {2FDAAFA3-7523-4F66-9957-9D5E7FE698F6})
  7 IID_IMMDevice = comtypes.GUID(
  8     {D666063F-1587-4E43-81F1-B948E807363F})
  9 IID_IMMDeviceCollection = comtypes.GUID(
 10     {0BD7A1BE-7A1A-44DB-8397-CC5392387B5E})
 11 IID_IMMDeviceEnumerator = comtypes.GUID(
 12     {A95664D2-9614-4F35-A746-DE8DB63617E6})
 13 IID_IAudioEndpointVolume = comtypes.GUID(
 14     {5CDF2C82-841E-4546-9722-0CF74078229A})
 15 CLSID_MMDeviceEnumerator = comtypes.GUID(
 16     {BCDE0395-E52F-467C-8E3D-C4579291692E})
 17 
 18 # EDataFlow
 19 eRender = 0 # audio rendering stream
 20 eCapture = 1 # audio capture stream
 21 eAll = 2 # audio rendering or capture stream
 22 
 23 # ERole
 24 eConsole = 0 # games, system sounds, and voice commands
 25 eMultimedia = 1 # music, movies, narration
 26 eCommunications = 2 # voice communications
 27 
 28 LPCGUID = REFIID = ctypes.POINTER(comtypes.GUID)
 29 LPFLOAT = ctypes.POINTER(ctypes.c_float)
 30 LPDWORD = ctypes.POINTER(wintypes.DWORD)
 31 LPUINT = ctypes.POINTER(wintypes.UINT)
 32 LPBOOL = ctypes.POINTER(wintypes.BOOL)
 33 PIUnknown = ctypes.POINTER(comtypes.IUnknown)
 34 
 35 class IMMDevice(comtypes.IUnknown):
 36     _iid_ = IID_IMMDevice
 37     _methods_ = (
 38         comtypes.COMMETHOD([], ctypes.HRESULT, Activate,
 39             ([in], REFIID, iid),
 40             ([in], wintypes.DWORD, dwClsCtx),
 41             ([in], LPDWORD, pActivationParams, None),
 42             ([out,retval], ctypes.POINTER(PIUnknown), ppInterface)),
 43         comtypes.STDMETHOD(ctypes.HRESULT, OpenPropertyStore, []),
 44         comtypes.STDMETHOD(ctypes.HRESULT, GetId, []),
 45         comtypes.STDMETHOD(ctypes.HRESULT, GetState, []))
 46 
 47 PIMMDevice = ctypes.POINTER(IMMDevice)
 48 
 49 class IMMDeviceCollection(comtypes.IUnknown):
 50     _iid_ = IID_IMMDeviceCollection
 51 
 52 PIMMDeviceCollection = ctypes.POINTER(IMMDeviceCollection)
 53 
 54 class IMMDeviceEnumerator(comtypes.IUnknown):
 55     _iid_ = IID_IMMDeviceEnumerator
 56     _methods_ = (
 57         comtypes.COMMETHOD([], ctypes.HRESULT, EnumAudioEndpoints,
 58             ([in], wintypes.DWORD, dataFlow),
 59             ([in], wintypes.DWORD, dwStateMask),
 60             ([out,retval], ctypes.POINTER(PIMMDeviceCollection),
 61              ppDevices)),
 62         comtypes.COMMETHOD([], ctypes.HRESULT, GetDefaultAudioEndpoint,
 63             ([in], wintypes.DWORD, dataFlow),
 64             ([in], wintypes.DWORD, role),
 65             ([out,retval], ctypes.POINTER(PIMMDevice), ppDevices)))
 66     @classmethod
 67     def get_default(cls, dataFlow, role):
 68         enumerator = comtypes.CoCreateInstance(
 69             CLSID_MMDeviceEnumerator, cls, comtypes.CLSCTX_INPROC_SERVER)
 70         return enumerator.GetDefaultAudioEndpoint(dataFlow, role)
 71 
 72 class IAudioEndpointVolume(comtypes.IUnknown):
 73     _iid_ = IID_IAudioEndpointVolume
 74     _methods_ = (
 75         comtypes.STDMETHOD(ctypes.HRESULT, RegisterControlChangeNotify, []),
 76         comtypes.STDMETHOD(ctypes.HRESULT, UnregisterControlChangeNotify, []),
 77         comtypes.COMMETHOD([], ctypes.HRESULT, GetChannelCount,
 78             ([out, retval], LPUINT, pnChannelCount)),
 79         comtypes.COMMETHOD([], ctypes.HRESULT, SetMasterVolumeLevel,
 80             ([in], ctypes.c_float, fLevelDB),
 81             ([in], LPCGUID, pguidEventContext, None)),
 82         comtypes.COMMETHOD([], ctypes.HRESULT, SetMasterVolumeLevelScalar,
 83             ([in], ctypes.c_float, fLevel),
 84             ([in], LPCGUID, pguidEventContext, None)),
 85         comtypes.COMMETHOD([], ctypes.HRESULT, GetMasterVolumeLevel,
 86             ([out,retval], LPFLOAT, pfLevelDB)),
 87         comtypes.COMMETHOD([], ctypes.HRESULT, GetMasterVolumeLevelScalar,
 88             ([out,retval], LPFLOAT, pfLevel)),
 89         comtypes.COMMETHOD([], ctypes.HRESULT, SetChannelVolumeLevel,
 90             ([in], wintypes.UINT, nChannel),
 91             ([in], ctypes.c_float, fLevelDB),
 92             ([in], LPCGUID, pguidEventContext, None)),
 93         comtypes.COMMETHOD([], ctypes.HRESULT, SetChannelVolumeLevelScalar,
 94             ([in], wintypes.UINT, nChannel),
 95             ([in], ctypes.c_float, fLevel),
 96             ([in], LPCGUID, pguidEventContext, None)),
 97         comtypes.COMMETHOD([], ctypes.HRESULT, GetChannelVolumeLevel,
 98             ([in], wintypes.UINT, nChannel),
 99             ([out,retval], LPFLOAT, pfLevelDB)),
100         comtypes.COMMETHOD([], ctypes.HRESULT, GetChannelVolumeLevelScalar,
101             ([in], wintypes.UINT, nChannel),
102             ([out,retval], LPFLOAT, pfLevel)),
103         comtypes.COMMETHOD([], ctypes.HRESULT, SetMute,
104             ([in], wintypes.BOOL, bMute),
105             ([in], LPCGUID, pguidEventContext, None)),
106         comtypes.COMMETHOD([], ctypes.HRESULT, GetMute,
107             ([out,retval], LPBOOL, pbMute)),
108         comtypes.COMMETHOD([], ctypes.HRESULT, GetVolumeStepInfo,
109             ([out,retval], LPUINT, pnStep),
110             ([out,retval], LPUINT, pnStepCount)),
111         comtypes.COMMETHOD([], ctypes.HRESULT, VolumeStepUp,
112             ([in], LPCGUID, pguidEventContext, None)),
113         comtypes.COMMETHOD([], ctypes.HRESULT, VolumeStepDown,
114             ([in], LPCGUID, pguidEventContext, None)),
115         comtypes.COMMETHOD([], ctypes.HRESULT, QueryHardwareSupport,
116             ([out,retval], LPDWORD, pdwHardwareSupportMask)),
117         comtypes.COMMETHOD([], ctypes.HRESULT, GetVolumeRange,
118             ([out,retval], LPFLOAT, pfLevelMinDB),
119             ([out,retval], LPFLOAT, pfLevelMaxDB),
120             ([out,retval], LPFLOAT, pfVolumeIncrementDB)))
121     @classmethod
122     def get_default(cls):
123         endpoint = IMMDeviceEnumerator.get_default(eRender, eMultimedia)
124         interface = endpoint.Activate(cls._iid_, comtypes.CLSCTX_INPROC_SERVER)
125         return ctypes.cast(interface, ctypes.POINTER(cls))
126 
127 
128 
129 
130 
131 if __name__ == __main__:
132 
133     def show_vol(ev):
134         time.sleep(2)
135         voldb = ev.GetMasterVolumeLevel()
136         volsc = ev.GetMasterVolumeLevelScalar()
137         volst, nstep = ev.GetVolumeStepInfo()
138         print(Master Volume (dB): %0.4f % voldb)
139         print(Master Volume (scalar): %0.4f % volsc)#当前音量
140         print(Master Volume (step): %d / %d % (volst, nstep))
141 
142     def test():
143         ev = IAudioEndpointVolume.get_default()
144         vol = ev.GetMasterVolumeLevelScalar()
145         vmin, vmax, vinc = ev.GetVolumeRange()
146         print(Volume Range (min, max, step) (dB): 
147               %0.4f, %0.4f, %0.4f % (vmin, vmax, vinc))
148         show_vol(ev)
149         try:
150             print(\nIncrement the master volume)
151             ev.VolumeStepUp()#音量加
152             show_vol(ev)
153             print(\nDecrement the master volume twice)
154             ev.VolumeStepDown()#音量减
155             ev.VolumeStepDown()
156             show_vol(ev)
157             print(\nSet the master volume to 0.75 scalar)
158             ev.SetMasterVolumeLevelScalar(0.75)#音量百分比设置
159             show_vol(ev)
160             print(\nSet the master volume to 0.25 scalar)
161             ev.SetMasterVolumeLevelScalar(0.25)#音量百分比设置
162             show_vol(ev)
163         finally:
164             ev.SetMasterVolumeLevelScalar(vol)
165 
166     comtypes.CoInitialize()
167     try:
168         test()
169     finally:
170         comtypes.CoUninitialize()

简单逻辑就是先获取ev对象(

ev = IAudioEndpointVolume.get_default()

然后有几个方法:

方法一(获取当前音量):(

volsc = ev.GetMasterVolumeLevelScalar()

方法二(音量加/减):(

ev.VolumeStepUp()#音量加
ev.VolumeStepDown()#音量减

方法三(设置音量):(

ev.SetMasterVolumeLevelScalar(0.75)#音量百分比设置

另附简单调用win32API加减音量:

import ctypes,operator

WM_APPCOMMAND = 0x319
APPCOMMAND_VOLUME_UP = 0x0a
APPCOMMAND_VOLUME_DOWN = 0x09
APPCOMMAND_VOLUME_MUTE = 0x08

def setSpeakerVol(volume):
        hwnd = ctypes.windll.user32.GetForegroundWindow()

        # ctypes.windll.winmm.waveOutSetVolume(hwnd, 0xffffffff)

        print(hwnd)
        ctypes.windll.user32.PostMessageA(hwnd, WM_APPCOMMAND, 0, APPCOMMAND_VOLUME_DOWN * 0x10000)
#
if __name__ == __main__:

    setSpeakerVol(0)

利用:

PostMessageA

 

精确控制windows全局音量(Python)

原文:https://www.cnblogs.com/wohuiyijiu/p/12604857.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!