运行 Apple API 需要什么权限?

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

我编写了访问 Apple Core Audio API 的代码,但每次运行它时,它都会返回分段错误。我确信它与我的设备上的权限有关,但我不确定需要什么权限才能让它工作。如果您知道我能做些什么来解决这个问题,我将不胜感激。

我的代码:

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

# Define constants
kAudioObjectSystemObject = 1
kAudioObjectPropertyScopeGlobal = 1735159650
kAudioObjectPropertyElementMaster = 0
kAudioHardwarePropertyDevices = 1684370979
kAudioDevicePropertyDeviceNameCFString = 1819173229

# 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,  # Removed .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  # Removed .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']}")

错误: zsh:分段错误 /usr/local/bin/python3 /Users/MYNAME/Desktop/Core_Audio.py

我尝试以适应内存过度使用的方式重写代码。该代码的主要目标是拆分 Fromm 上层应用程序的音频通道,以便我可以自定义每个应用程序的音量,而无需更改整个计算机的音量。

python ios macos api
1个回答
0
投票

您遇到的问题很可能与您设备上的权限无关。分段错误通常是由于以下原因发生的:

  1. 代码中的内存访问问题。以下是潜在问题的细分以及如何在代码中修复这些问题:

    device_name_buffer = ctypes.create_string_buffer(property_data_size.value) 状态 = coreaudio.AudioObjectGetPropertyData( 设备 ID, byref(属性地址), 0, 没有任何, property_data_size.value, byref(设备名称缓冲区) )

    if status != 0: raise RuntimeError(f"AudioObjectGetPropertyData failed for device {device_id} with status {status}") # Decode the device name from the buffer and free the memory device_name = device_name_buffer.value.decode('utf-8') del device_name_buffer # Free the allocated memory
    
    
  2. 空指针取消引用:您正在通过设备迭代的循环内修改 property_address 的 mSelector 字段。如果第一次调用 AudioObjectGetPropertyDataSize 失败,这可能会导致访问空指针。 以下是修复方法:

    对于 device_ids 中的 device_id: # 为每个设备创建一个新的属性地址 new_property_address = AudioObjectPropertyAddress( mSelector=kAudioHardwarePropertyDevices, # 删除 .value mScope=kAudioObjectPropertyScopeGlobal, mElement=kAudioObjectPropertyElementMaster )

    property_data_size = c_uint32(0) status = coreaudio.AudioObjectGetPropertyDataSize( device_id, byref(new_property_address), # Use a new property address 0, None, byref(property_data_size) ) # ... rest of the code for retrieving device name ...
    
    
  3. 不正确的数据类型:虽然可能性较小,但设备名称的预期数据类型和检索到的数据之间可能不匹配。仔细检查 kAudioDevicePropertyDeviceNameCFString 的文档,以确保您使用正确的数据类型来存储设备名称。

关于分割音频通道: 不幸的是,在 macOS 上使用 CoreAudio API 无法直接操作来自单独应用程序的音频通道。但是,您可以使用“Soundflower”(第三方应用程序)等系统实用程序或“系统偏好设置”>“声音”中的“多输出设备”等内置功能来实现类似的功能。它允许您创建虚拟输出设备,组合来自不同应用程序的音频流,然后您可以独立控制其音量。

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