2015-08-21 6 views
5

Wie kann ich das Master-Volume auf meinem Laptop mit Python ändern? Ich kenne eine Methode, bei der ich Lautstärketasten mit ctypes simulieren kann, aber ohne das aktuelle Volumen zu kennen, müsste mein Code 50 aufeinanderfolgende Tasten drücken, wenn ich die Anwendung zum Kalibrieren starte es auf Null.Windows 8 Master Volume in Python lesen und/oder ändern

Gibt es eine Möglichkeit für mich, das aktuelle Systemvolumen zu erhalten, oder besser, das Mastervolumen auf einen bestimmten Wert einzustellen?

Ich habe ein Windows 8 64-Bit-System mit Python 3.4.

+0

Darf ich fragen, was Ihre Anwendung ist? Pythons integrierte Audiofunktionen sind sehr schlecht. – TigerhawkT3

+0

Rufen Sie Windows-APIs wie [mixerOpen] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd757308%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396) von Python auf . –

+0

@DavidChing, in Vista und später ändert die winmm.dll-API die Audioeinstellungen pro Anwendung. Zum Einstellen des Master-Volume muss die COM-Schnittstelle "IAudioEndpointVolume" verwendet werden. – eryksun

Antwort

5

Tim Roberts veröffentlicht ein comtypes Beispiel in der Python-Win32-Diskussionsliste in Bezug auf wie Control Volume on Windows. Im folgenden Beispiel habe ich Tims Code geändert und Klassenmethoden hinzugefügt, die den Standardaudioendpunkt und seine IAudioEndpointVolume Schnittstelle zurückgeben.

Der dB-Lautstärkenbereich auf den beiden getesteten Systemen (Windows 7 und Windows 10) normalisierte den Maximalpegel auf 0 dB, aber die Mindestpegel und Lautstärkeinkremente unterschieden sich zwischen den Systemen. Ich empfehle stattdessen, die skalaren und integralen Schrittmethoden zu verwenden. Der Skalarbereich liegt zwischen 0,0 und 1,0.

import ctypes 
import comtypes 
from ctypes import wintypes 

MMDeviceApiLib = comtypes.GUID(
    '{2FDAAFA3-7523-4F66-9957-9D5E7FE698F6}') 
IID_IMMDevice = comtypes.GUID(
    '{D666063F-1587-4E43-81F1-B948E807363F}') 
IID_IMMDeviceCollection = comtypes.GUID(
    '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}') 
IID_IMMDeviceEnumerator = comtypes.GUID(
    '{A95664D2-9614-4F35-A746-DE8DB63617E6}') 
IID_IAudioEndpointVolume = comtypes.GUID(
    '{5CDF2C82-841E-4546-9722-0CF74078229A}') 
CLSID_MMDeviceEnumerator = comtypes.GUID(
    '{BCDE0395-E52F-467C-8E3D-C4579291692E}') 

# EDataFlow 
eRender = 0 # audio rendering stream 
eCapture = 1 # audio capture stream 
eAll = 2 # audio rendering or capture stream 

# ERole 
eConsole = 0 # games, system sounds, and voice commands 
eMultimedia = 1 # music, movies, narration 
eCommunications = 2 # voice communications 

LPCGUID = REFIID = ctypes.POINTER(comtypes.GUID) 
LPFLOAT = ctypes.POINTER(ctypes.c_float) 
LPDWORD = ctypes.POINTER(wintypes.DWORD) 
LPUINT = ctypes.POINTER(wintypes.UINT) 
LPBOOL = ctypes.POINTER(wintypes.BOOL) 
PIUnknown = ctypes.POINTER(comtypes.IUnknown) 

class IMMDevice(comtypes.IUnknown): 
    _iid_ = IID_IMMDevice 
    _methods_ = (
     comtypes.COMMETHOD([], ctypes.HRESULT, 'Activate', 
      (['in'], REFIID, 'iid'), 
      (['in'], wintypes.DWORD, 'dwClsCtx'), 
      (['in'], LPDWORD, 'pActivationParams', None), 
      (['out','retval'], ctypes.POINTER(PIUnknown), 'ppInterface')), 
     comtypes.STDMETHOD(ctypes.HRESULT, 'OpenPropertyStore', []), 
     comtypes.STDMETHOD(ctypes.HRESULT, 'GetId', []), 
     comtypes.STDMETHOD(ctypes.HRESULT, 'GetState', [])) 

PIMMDevice = ctypes.POINTER(IMMDevice) 

class IMMDeviceCollection(comtypes.IUnknown): 
    _iid_ = IID_IMMDeviceCollection 

PIMMDeviceCollection = ctypes.POINTER(IMMDeviceCollection) 

class IMMDeviceEnumerator(comtypes.IUnknown): 
    _iid_ = IID_IMMDeviceEnumerator 
    _methods_ = (
     comtypes.COMMETHOD([], ctypes.HRESULT, 'EnumAudioEndpoints', 
      (['in'], wintypes.DWORD, 'dataFlow'), 
      (['in'], wintypes.DWORD, 'dwStateMask'), 
      (['out','retval'], ctypes.POINTER(PIMMDeviceCollection), 
      'ppDevices')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetDefaultAudioEndpoint', 
      (['in'], wintypes.DWORD, 'dataFlow'), 
      (['in'], wintypes.DWORD, 'role'), 
      (['out','retval'], ctypes.POINTER(PIMMDevice), 'ppDevices'))) 
    @classmethod 
    def get_default(cls, dataFlow, role): 
     enumerator = comtypes.CoCreateInstance(
      CLSID_MMDeviceEnumerator, cls, comtypes.CLSCTX_INPROC_SERVER) 
     return enumerator.GetDefaultAudioEndpoint(dataFlow, role) 

class IAudioEndpointVolume(comtypes.IUnknown): 
    _iid_ = IID_IAudioEndpointVolume 
    _methods_ = (
     comtypes.STDMETHOD(ctypes.HRESULT, 'RegisterControlChangeNotify', []), 
     comtypes.STDMETHOD(ctypes.HRESULT, 'UnregisterControlChangeNotify', []), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetChannelCount', 
      (['out', 'retval'], LPUINT, 'pnChannelCount')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'SetMasterVolumeLevel', 
      (['in'], ctypes.c_float, 'fLevelDB'), 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'SetMasterVolumeLevelScalar', 
      (['in'], ctypes.c_float, 'fLevel'), 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetMasterVolumeLevel', 
      (['out','retval'], LPFLOAT, 'pfLevelDB')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetMasterVolumeLevelScalar', 
      (['out','retval'], LPFLOAT, 'pfLevel')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'SetChannelVolumeLevel', 
      (['in'], wintypes.UINT, 'nChannel'), 
      (['in'], ctypes.c_float, 'fLevelDB'), 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'SetChannelVolumeLevelScalar', 
      (['in'], wintypes.UINT, 'nChannel'), 
      (['in'], ctypes.c_float, 'fLevel'), 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetChannelVolumeLevel', 
      (['in'], wintypes.UINT, 'nChannel'), 
      (['out','retval'], LPFLOAT, 'pfLevelDB')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetChannelVolumeLevelScalar', 
      (['in'], wintypes.UINT, 'nChannel'), 
      (['out','retval'], LPFLOAT, 'pfLevel')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'SetMute', 
      (['in'], wintypes.BOOL, 'bMute'), 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetMute', 
      (['out','retval'], LPBOOL, 'pbMute')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetVolumeStepInfo', 
      (['out','retval'], LPUINT, 'pnStep'), 
      (['out','retval'], LPUINT, 'pnStepCount')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'VolumeStepUp', 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'VolumeStepDown', 
      (['in'], LPCGUID, 'pguidEventContext', None)), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'QueryHardwareSupport', 
      (['out','retval'], LPDWORD, 'pdwHardwareSupportMask')), 
     comtypes.COMMETHOD([], ctypes.HRESULT, 'GetVolumeRange', 
      (['out','retval'], LPFLOAT, 'pfLevelMinDB'), 
      (['out','retval'], LPFLOAT, 'pfLevelMaxDB'), 
      (['out','retval'], LPFLOAT, 'pfVolumeIncrementDB'))) 
    @classmethod 
    def get_default(cls): 
     endpoint = IMMDeviceEnumerator.get_default(eRender, eMultimedia) 
     interface = endpoint.Activate(cls._iid_, comtypes.CLSCTX_INPROC_SERVER) 
     return ctypes.cast(interface, ctypes.POINTER(cls)) 

Zum Beispiel:

if __name__ == '__main__': 

    def show_vol(ev): 
     voldb = ev.GetMasterVolumeLevel() 
     volsc = ev.GetMasterVolumeLevelScalar() 
     volst, nstep = ev.GetVolumeStepInfo() 
     print('Master Volume (dB): %0.4f' % voldb) 
     print('Master Volume (scalar): %0.4f' % volsc) 
     print('Master Volume (step): %d/%d' % (volst, nstep)) 

    def test(): 
     ev = IAudioEndpointVolume.get_default() 
     vol = ev.GetMasterVolumeLevelScalar() 
     vmin, vmax, vinc = ev.GetVolumeRange() 
     print('Volume Range (min, max, step) (dB): ' 
       '%0.4f, %0.4f, %0.4f' % (vmin, vmax, vinc)) 
     show_vol(ev) 
     try: 
      print('\nIncrement the master volume') 
      ev.VolumeStepUp() 
      show_vol(ev) 
      print('\nDecrement the master volume twice') 
      ev.VolumeStepDown() 
      ev.VolumeStepDown() 
      show_vol(ev) 
      print('\nSet the master volume to 0.75 scalar') 
      ev.SetMasterVolumeLevelScalar(0.75) 
      show_vol(ev) 
      print('\nSet the master volume to 0.25 scalar') 
      ev.SetMasterVolumeLevelScalar(0.25) 
      show_vol(ev) 
     finally: 
      ev.SetMasterVolumeLevelScalar(vol) 

    comtypes.CoInitialize() 
    try: 
     test() 
    finally: 
     comtypes.CoUninitialize() 
+0

Danke! Funktioniert super! –

Verwandte Themen