提问人:Чайка 提问时间:9/26/2023 最后编辑:Чайка 更新时间:9/30/2023 访问量:100
在 macOS 中使用 CoreAudio 切换输出音频设备
Switching output audio device with CoreAudio in macOS
问:
我一直在使用 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
答:
2赞
sbooth
9/30/2023
#1
我不确定为什么你的方法不成功,但使用
audioEngine.outputNode.auAudioUnit.setDeviceID(deviceID)
在我的测试中有效。
评论
audioEngine.outputNode.auAudioUnit.setDeviceID()