zoukankan      html  css  js  c++  java
  • 精确控制windows全局音量(Python)

    话不多说,直接上代码:

      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('
    Increment the master volume')
    151             ev.VolumeStepUp()#音量加
    152             show_vol(ev)
    153             print('
    Decrement the master volume twice')
    154             ev.VolumeStepDown()#音量减
    155             ev.VolumeStepDown()
    156             show_vol(ev)
    157             print('
    Set the master volume to 0.75 scalar')
    158             ev.SetMasterVolumeLevelScalar(0.75)#音量百分比设置
    159             show_vol(ev)
    160             print('
    Set 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
  • 相关阅读:
    Java 8 forEach简单例子
    Intellij IDEA 使用
    java中的sleep()和wait()的区别
    MySQL问答整理
    java 正则例子
    如何在两个线程之间共享数据
    蜻蜓FM涉嫌诈骗投资人和广告主源代码剖析
    玩DNF开启NVIDIA独显的方法
    WSAEventSelect模型编程 详解
    签名时加密失败 --“对程序集签名时出错
  • 原文地址:https://www.cnblogs.com/wohuiyijiu/p/12604857.html
Copyright © 2011-2022 走看看