如何使用coreaudio获取MacOS上的输入设备列表?

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

我正在尝试使用核心音频获取 MacOS 中的音频设备列表,但无论出于何种原因,我只能获取输出设备。

我正在 XCode 13 中做一个 Swift UI 项目,我的代码如下所示:

import Foundation
import CoreAudio

struct AudioDevice: Identifiable {
    let id: AudioDeviceID
    let name: String
    let inputChannels: Int
    let outputChannels: Int
}

class AudioDevicesManager {
    static func getAudioDevices() -> [AudioDevice] {
        var devices = [AudioDevice]()
        
        var propertySize: UInt32 = 0
        var status: OSStatus = noErr
        
        // Get the number of devices
        var propertyAddress = AudioObjectPropertyAddress(
            mSelector: kAudioHardwarePropertyDevices,
            mScope: kAudioObjectPropertyScopeGlobal,
            mElement: kAudioObjectPropertyElementMain
        )
        status = AudioObjectGetPropertyDataSize(
            AudioObjectID(kAudioObjectSystemObject),
            &propertyAddress,
            0,
            nil,
            &propertySize
        )
        if status != noErr {
            print("Error: Unable to get the number of audio devices.")
            return devices
        }
        
        // Get the device IDs
        let deviceCount = Int(propertySize) / MemoryLayout<AudioDeviceID>.size
        var deviceIDs = [AudioDeviceID](repeating: 0, count: deviceCount)
        status = AudioObjectGetPropertyData(
            AudioObjectID(kAudioObjectSystemObject),
            &propertyAddress,
            0,
            nil,
            &propertySize,
            &deviceIDs
        )
        if status != noErr {
            print("Error: Unable to get the audio device IDs.")
            return devices
        }
        
        // Get device info for each device
        for deviceID in deviceIDs {
            var deviceName: String = ""
            var inputChannels: Int = 0
            var outputChannels: Int = 0
            
            // Get device name
            propertyAddress.mSelector = kAudioDevicePropertyDeviceNameCFString
            propertySize = UInt32(MemoryLayout<CFString>.size)
            var name: CFString? = nil
            status = AudioObjectGetPropertyData(
                deviceID,
                &propertyAddress,
                0,
                nil,
                &propertySize,
                &name
            )
            if status == noErr, let deviceNameCF = name as String? {
                deviceName = deviceNameCF
            }
            
            // Get input channels
            propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration
            propertyAddress.mScope = kAudioDevicePropertyScopeInput
            status = AudioObjectGetPropertyDataSize(deviceID, &propertyAddress, 0, nil, &propertySize)
            if status == noErr {
                let bufferListPointer = UnsafeMutablePointer<AudioBufferList>.allocate(capacity: 1)
                defer { bufferListPointer.deallocate() }
                status = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, bufferListPointer)
                if status == noErr {
                    let bufferList = UnsafeMutableAudioBufferListPointer(bufferListPointer)
                    for buffer in bufferList {
                        inputChannels += Int(buffer.mNumberChannels)
                    }
                }
            }
            
            // Get output channels
            propertyAddress.mScope = kAudioDevicePropertyScopeOutput
            status = AudioObjectGetPropertyDataSize(deviceID, &propertyAddress, 0, nil, &propertySize)
            if status == noErr {
                let bufferListPointer = UnsafeMutablePointer<AudioBufferList>.allocate(capacity: 1)
                defer { bufferListPointer.deallocate() }
                status = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, bufferListPointer)
                if status == noErr {
                    let bufferList = UnsafeMutableAudioBufferListPointer(bufferListPointer)
                    for buffer in bufferList {
                        outputChannels += Int(buffer.mNumberChannels)
                    }
                }
            }
            
            devices.append(AudioDevice(id: deviceID, name: deviceName, inputChannels: inputChannels, outputChannels: outputChannels))
        }
        
        return devices
        
    }
}

在调试它时,它似乎完全忽略了任何输入设备。就好像它们不存在一样。例如,它返回 MacBook 扬声器,但不返回 MacBook 麦克风。

可能是什么问题?

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

在 Xcode 中:

  1. 在项目导航器中选择您的项目
  2. 选择您要添加权限的目标
  3. 转到“签名和功能”
  4. 在“应用程序沙盒”部分的“硬件”组中,选中“音频输入”复选框

这对我有用。

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