使用 Python 集成 Apple Core 音频 API

问题描述 投票:0回答:1

我已经尝试让这段代码工作好几天了,老实说我不知道如何解决这个错误。该代码的主要目标是能够控制特定应用程序的音频输出,而不是更改整个计算机的音量。下面是我的代码和我无法修复的错误,感谢任何帮助。

我的代码:

import ctypes
from ctypes import c_uint32, c_void_p, byref, Structure, POINTER, c_int, c_char

# Define constants
kAudioObjectSystemObject = 1
kAudioObjectPropertyScopeGlobal = 1
kAudioObjectPropertyElementMaster = 0
kAudioHardwarePropertyDevices = ctypes.c_uint32(1)
kAudioDevicePropertyDeviceNameCFString = ctypes.c_uint32(2)

# Define the AudioObjectPropertyAddress structure
class AudioObjectPropertyAddress(Structure):
    _fields_ = [
        ('mSelector', c_uint32),
        ('mScope', c_uint32),
        ('mElement', c_uint32),  
    ]

# Load CoreAudio framework
coreaudio = ctypes.CDLL('/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio')

# OLD PATH: '/System/Library/Frameworks/CoreAudio.framework/CoreAudio'

# Define function prototypes
coreaudio.AudioObjectGetPropertyDataSize.argtypes = [c_uint32, POINTER(AudioObjectPropertyAddress), c_uint32, c_void_p, POINTER(c_uint32)]
coreaudio.AudioObjectGetPropertyDataSize.restype = c_int

coreaudio.AudioObjectGetPropertyData.argtypes = [c_uint32, POINTER(AudioObjectPropertyAddress), c_uint32, c_void_p, c_uint32, c_void_p]
coreaudio.AudioObjectGetPropertyData.restype = c_int

def list_audio_devices():
    devices = []

    # Define the property address for getting the list of devices
    property_address = AudioObjectPropertyAddress(
        mSelector=kAudioHardwarePropertyDevices.value,
        mScope=kAudioObjectPropertyScopeGlobal,
        mElement=kAudioObjectPropertyElementMaster
    )
    
    # Get the size of the property data
    property_data_size = c_uint32(0)
    
    status = coreaudio.AudioObjectGetPropertyDataSize(
        kAudioObjectSystemObject,
        byref(property_address),
        0,
        None,
        byref(property_data_size)
    )
    
    if status != 0:
        raise RuntimeError(f"AudioObjectGetPropertyDataSize failed with status {status}")
    
    # Determine the number of devices
    device_count = property_data_size.value // ctypes.sizeof(c_uint32)
    
    # Create an array to hold the device IDs
    device_ids = (c_uint32 * device_count)()
    
    # Get the device IDs
    status = coreaudio.AudioObjectGetPropertyData(
        kAudioObjectSystemObject,
        byref(property_address),
        0,
        None,
        property_data_size.value,
        byref(device_ids)
    )
    
    if status != 0:
        raise RuntimeError(f"AudioObjectGetPropertyData failed with status {status}")
    
    # Get the names of the devices
    for device_id in device_ids:
        property_address.mSelector = kAudioDevicePropertyDeviceNameCFString.value
        
        property_data_size = c_uint32(0)
        status = coreaudio.AudioObjectGetPropertyDataSize(
            device_id,
            byref(property_address),
            0,
            None,
            byref(property_data_size)
        )
        
        if status != 0:
            raise RuntimeError(f"AudioObjectGetPropertyDataSize failed for device {device_id} with status {status}")
        
        # Create a buffer for the device name
        device_name = ctypes.create_string_buffer(property_data_size.value)
        status = coreaudio.AudioObjectGetPropertyData(
            device_id,
            byref(property_address),
            0,
            None,
            property_data_size.value,
            byref(device_name)
        )
        
        if status != 0:
            raise RuntimeError(f"AudioObjectGetPropertyData failed for device {device_id} with status {status}")
        
        devices.append({
            'id': device_id,
            'name': device_name.value.decode('utf-8')
        })
    
    return devices

# List all devices and their IDs
devices = list_audio_devices()
for device in devices:
    print(f"Device ID: {device['id']}, Device Name: {device['name']}")

错误:

Traceback (most recent call last):
  File "/Users/MYNAME/Desktop/Core_Audio.py", line 112, in <module>
    devices = list_audio_devices()
              ^^^^^^^^^^^^^^^^^^^^
  File "/Users/MYNAME/Desktop/Core_Audio.py", line 53, in list_audio_devices
    raise RuntimeError(f"AudioObjectGetPropertyDataSize failed with status {status}")
RuntimeError: AudioObjectGetPropertyDataSize failed with status 2003332927

我尝试过重命名文件、卸载并重新安装所有导入的文件、ChatGPT、Perplexity。这段代码的主要目标是从不同的应用程序中提取音频源,这样我就可以在 MacOS 中单独自定义它们。

python macos core-audio
1个回答
0
投票

错误告诉您正在使用未知属性:

2003332927
=
kAudioHardwareUnknownPropertyError
=
'who?'

这是有道理的,因为你对属性的定义

kAudioHardwarePropertyDevices = ctypes.c_uint32(1)

是错误的。我的

AudioHardware.h
文件显示

kAudioHardwarePropertyDevices = 'dev#'
1684370979
)。

同样,

kAudioObjectPropertyScopeGlobal
应为
'glob' = 1735159650
kAudioDevicePropertyDeviceNameCFString
应为
'lnam' = 1819173229

尝试一下,看看是否还有错误。

© www.soinside.com 2019 - 2024. All rights reserved.