Skip to content

pycaw example code examples/audio_endpoint_volume_example.py does not run because it fails get device.FriendlyName #105

Description

@KnightChaser

In a clean Python 3.12 Windows environment, I installed pycaw library as follows:

comtypes==1.4.11
psutil==7.0.0
pycaw==20240210

And my Windows environment is as follows:

Image

I executed the same code uploaded at https://github.com/AndreMiras/pycaw/blob/develop/examples/audio_endpoint_volume_example.py and got the following error because device.FriendlyName failed to run.

Traceback (most recent call last):
  File "C:\Users\3NR1QUE\Downloads\test\audio_endpoint_volume_example.py", line 21, in <module>
    main()
  File "C:\Users\3NR1QUE\Downloads\test\audio_endpoint_volume_example.py", line 10, in main
    print("Device found: %s" % device.FriendlyName)
                               ^^^^^^^^^^^^^^^^^^^
AttributeError: 'POINTER(IMMDevice)' object has no attribute 'FriendlyName'

Instead of directly getting FriendlyName property, the code works without any error like above by getting its 'FriendlyName' manually like below.

from comtypes import CLSCTX_ALL
from ctypes import cast, POINTER
import warnings

from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume

def get_friendly_name(dev) -> str:
    with warnings.catch_warnings():
        # suppress deprecation warning for GetAllDevices
        warnings.simplefilter("ignore", UserWarning)
        
        # get the unique endpoint ID
        dev_id = dev.GetId()
        
        # AudioUtilities.GetAllDevices() yields AudioDevice wrappers
        for d in AudioUtilities.GetAllDevices():
            if d.id == dev_id:
                return d.FriendlyName
        return "Unknown Device"

def main():
    device = AudioUtilities.GetSpeakers()
    name = get_friendly_name(device)
    print(f"Device found: {name}")
    
    # now get the endpoint-volume interface
    interface = device.Activate(
        IAudioEndpointVolume._iid_, CLSCTX_ALL, None
    )
    volume = cast(interface, POINTER(IAudioEndpointVolume))
    
    print("Muted?:", "Yes" if volume.GetMute() else "No")
    print("Level (dB):", volume.GetMasterVolumeLevel())
    print("Range (dB):", volume.GetVolumeRange())
    
    print("Setting to -20 dB…")
    volume.SetMasterVolumeLevel(-20.0, None)
    print("New level:", volume.GetMasterVolumeLevel())

if __name__ == "__main__":
    main()

(Output I obtained after executing the above code)

Device found: 스피커 (Realtek(R) Audio)  (Note: "스피커" means "Speaker" in Korean. Just language difference)
Muted?: No
Level (dB): -5.547224998474121
Range (dB): (-65.25, 0.0, 0.03125)
Setting to -20 dB…
New level: -20.0

Anyway, whether to use my example code or not, I think you should modify the current example code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions