AndreMiras / pycaw

Python Core Audio Windows Library
MIT License
385 stars 67 forks source link

POINTER(IAudioSessionControl2)' object has no attribute 'GetState‘ #32

Closed zhjy8827 closed 2 years ago

zhjy8827 commented 3 years ago

code:

from pycaw.pycaw import AudioUtilities
import time

def main():
    while True:
        sessions = AudioUtilities.GetAllSessions()
        for session in sessions:
            if session.Process and session.InstanceIdentifier.find("foobar") >= 0:
                print(session.InstanceIdentifier)
                print(session.State)

        time.sleep(1)

if __name__ == "__main__":
    main()

error:

{0.0.0.00000000}.{03b51635-f342-4dcd-b24d-c459985d9f01}|#%b{0B9C664C-1049-4DB7-8104-97016411F561}|1%b#
Traceback (most recent call last):
  File "D:/code/pystream/device.py", line 17, in <module>
    main()
  File "D:/code/pystream/device.py", line 12, in main
    print(session.State)
  File "D:\anaconda3\envs\pystream32\lib\site-packages\pycaw\pycaw.py", line 608, in State
    s = self._ctl.GetState()
AttributeError: 'POINTER(IAudioSessionControl2)' object has no attribute 'GetState'

https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessioncontrol2 The IAudioSessionControl2 interface inherits from IAudioSessionControl. I need to use getstate method,what should I do? https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getstate

TurboAnonym commented 3 years ago

Hi @zhjy8827 ;) I will make a pull request later but a quick fix for now is replacing this code from the pycaw.pycaw file: (your pycaw location: "D:\anaconda3\envs\pystream32\lib\site-packages\pycaw\pycaw.py")

class IAudioSessionControl(IUnknown):
    _iid_ = GUID('{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}')
    _methods_ = (
        # HRESULT GetState ([out] AudioSessionState *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl1'),

with the following:

class IAudioSessionControl(IUnknown):
    _iid_ = GUID('{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}')
    _methods_ = (
        # HRESULT GetState ([out] AudioSessionState *pRetVal);
        COMMETHOD([], HRESULT, 'GetState',
                  (['out'], POINTER(DWORD), 'pRetVal')),

After that session.State will return an int: 0 = AudioSessionStateInactive 1 = AudioSessionStateActive 2 = AudioSessionStateExpired

AndreMiras commented 3 years ago

Yeah please go ahead with a pull request that address just this part. I'll have time to review/merge this weekend

TurboAnonym commented 3 years ago

it is done https://github.com/AndreMiras/pycaw/pull/37 😀

zhjy8827 commented 3 years ago

thx !!!

AndreMiras commented 2 years ago

Fixed via #37, closing, thanks again TurboAnonym