Search code examples
pythonc++compywin32wasapi

How to control windows master audio in python script


going off of the suggestion by abarnert in Python: Change Windows 7 master volume

I'm trying to write a python script to control the master volume in windows 7

I understand that in C++ this can be done like so:

const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
mmde = CoCreateInstance(
    CLSID_MMDeviceEnumerator, NULL,
    CLSCTX_ALL, IID_IMMDeviceEnumerator,
    (void**)&pEnumerator);
mmd = mmde.GetDefaultAudioEndpoint(eRender, eMultimedia);
mgr = mmd.Activate(IID_IAudioSessionManager);
sav = mgr.GetSimpleAudioVolume(None, True);
sav.SetMasterVolume(0.5);

I'm trying to get that functionality in python using pywin32, but I find myself stuck. The code I have so far is:

import pythoncom

CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator)
IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator)
mmde = pythoncom.CoCreateInstance(CLSID_MMDeviceEnumerator, None, CLSCTX_ALL, IID_IMMDeviceEnumerator)
mmd = mmde.GetDefaultAudioEndpoint(eRender, eMultimedia)
mgr = mmd.Activate(IID_IAudioSessionManager)
sav = mgr.GetSimpleAudioVolume(None, True)
sav.SetMasterVolume(0.5)

CoCreateInstance wants the class ID (CLSID) of the MMDeviceEnumerator, but doesn't seem to have any function like __uuidof() to use to get the class ID. (Not that I could find anyway.)

Does anyone have any ideas / suggestions? I'm new to both COM/OLE programming and pywin32 and feeling a little lost.


Solution

  • From the documentation

    PyIUnknown = CoCreateInstance(clsid, unkOuter , context , iid )
    

    where clsid : PyIID Class identifier (CLSID) of the object

    A PyIID object is used whenever a COM GUID is used. PyIID objects can be created using the pywintypes.IID() function, although all functions that accept a GUID also accept a string in the standard GUID format.

    PyIID = IID(iidString, is_bytes )
    

    where iidString is a string representation of an IID, or a ProgID.

    MMDeviceEnumerator CLSID is BCDE0395-E52F-467C-8E3D-C4579291692E

    so try this

    PyIID = IID("BCDE0395-E52F-467C-8E3D-C4579291692E", is_bytes )