在 macOS 中使用 CoreAudio 切换输出音频设备

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

我一直在使用CoreAudio来切换音频输出的输出设备,但这种技术在macOS 13 Ventura中不再可用。

如何在 Ventura 中切换输出设备?

正确的可用输出设备是

private func availableDevices() -> Array<AudioDeviceID> {
    var property: AudioObjectPropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDevices, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster)
    var dataSize:UInt32 = 0
    let status: OSStatus = AudioObjectGetPropertyDataSize(AudioObjectID(kAudioObjectSystemObject), &property, 0, nil, &dataSize)
    var devices:Array<AudioDeviceID> = Array()
    if status != kAudioHardwareNoError {
        devices = Array()
    } else {
        let deviceCount: Int = Int(dataSize) / MemoryLayout<AudioDeviceID>.size
        var foundDevices: Array<AudioDeviceID> = Array<AudioDeviceID>(repeating: 0, count: deviceCount)
        foundDevices.withUnsafeMutableBufferPointer { ( item: inout UnsafeMutableBufferPointer<AudioDeviceID>) -> () in
            let error: OSStatus = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &property, 0, nil, &dataSize, item.baseAddress!)
            if error != kAudioHardwareNoError { print("each device ID Get Error: \(error)") }
        }// end withUnsafeMutableBufferPointer
        devices = Array(foundDevices)
    }// end if

    return devices
}// end availableDevices

并将输出音频设备分配给输出节点是

internal func assignAudioDeviceTo (engine audioEngine: AVAudioEngine, selector key: SpeechPreferenceKey) {
    let output: AVAudioOutputNode = audioEngine.outputNode
    if let audioUnit: AudioUnit = output.audioUnit {
        let audioDevices: AudioDevices = AudioDevices()
        var deviceID: AudioDeviceID = AudioDevices.currentOutputtDevice().deviceID
        if let deviceName: String = key.string {
            if let device = audioDevices.outputDevices[deviceName]?.deviceID { deviceID = device }
        }// end if output device name is defined
        let error: OSStatus = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Output, 0, &deviceID, UInt32(MemoryLayout<AudioDeviceID>.size))
        if error != noErr {
            print("output device can not assign user selected device: \(error)")
        }// end if
        audioEngine.connect(audioEngine.mainMixerNode, to: output, fromBus: 0, toBus: 0, format: nil)
    }// end if output node have audio unit

    do {
        audioEngine.prepare()
        try audioEngine.start()
    } catch let error {
        print("output device start error: \(error)")
    }// end do try - catch start output device engine
}// end func assignAudioDeviceTo
macos core-audio
1个回答
0
投票

我不确定为什么你的方法不成功,但使用

audioEngine.outputNode.auAudioUnit.setDeviceID(deviceID)

在我的测试中有效。

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