Skip to content

Instantly share code, notes, and snippets.

@ysc3839
Created June 8, 2020 18:47
Show Gist options
  • Save ysc3839/5ab3899f9d095d750f88114aee94db75 to your computer and use it in GitHub Desktop.
Save ysc3839/5ab3899f9d095d750f88114aee94db75 to your computer and use it in GitHub Desktop.
# SPDX-License-Identifier: MIT
from ctypes import c_int, POINTER, c_void_p, byref, c_float
from ctypes.wintypes import DWORD
from comtypes import GUID, IUnknown, STDMETHOD, HRESULT, COMMETHOD, CoCreateInstance
EDataFlow_eRender = 0
ERole_eMultimedia = 1
CLSID_MMDeviceEnumerator = GUID('{BCDE0395-E52F-467C-8E3D-C4579291692E}')
class IMMDevice(IUnknown):
_iid_ = GUID('{D666063F-1587-4E43-81F1-B948E807363F}')
_methods_ = [
COMMETHOD([], HRESULT, 'Activate',
(['in'], POINTER(GUID), 'iid'),
(['in'], DWORD, 'dwClsCtx'),
(['in'], c_void_p, 'pActivationParams'),
(['out'], POINTER(c_void_p), 'ppInterface'))
# The rest is not defined/needed
]
def activate(self, interface, clsctx=0):
ptr = POINTER(interface)()
iid = interface._iid_
self.__com_Activate(byref(iid), clsctx, None, ptr)
return ptr
class IMMDeviceEnumerator(IUnknown):
_iid_ = GUID('{A95664D2-9614-4F35-A746-DE8DB63617E6}')
_methods_ = [
STDMETHOD(HRESULT, 'EnumAudioEndpoints'), # Unused
COMMETHOD([], HRESULT, 'GetDefaultAudioEndpoint',
(['in'], c_int, 'dataFlow'),
(['in'], c_int, 'role'),
(['out'], POINTER(POINTER(IMMDevice)), 'ppEndpoint'))
# The rest is not defined/needed
]
def get_default_audio_endpoint(self, data_flow, role):
ptr = POINTER(IMMDevice)()
self.__com_GetDefaultAudioEndpoint(data_flow, role, ptr)
return ptr
class IAudioMeterInformation(IUnknown):
_iid_ = GUID('{C02216F6-8C67-4B5B-9D00-D008E73E0064}')
_methods_ = [
# HRESULT GetPeakValue([out] float *pfPeak);
COMMETHOD(['propget'], HRESULT, 'peak_value',
(['retval', 'out'], POINTER(c_float), 'pfPeak'))
# The rest is not defined/needed
]
def is_windows_playing_sound():
enumerator = CoCreateInstance(CLSID_MMDeviceEnumerator, IMMDeviceEnumerator)
speakers = enumerator.get_default_audio_endpoint(EDataFlow_eRender, ERole_eMultimedia)
meter = speakers.activate(IAudioMeterInformation)
value = meter.peak_value;
print(value)
return value > 1e-08
if __name__ == '__main__':
print(f'is_windows_playing_sound(): {is_windows_playing_sound()}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment