Swift 3 中未调用 AudioObjectAddPropertyListenerBlock
AudioObjectAddPropertyListenerBlock not called in Swift 3
我想使用Swift观察音频设备参数的变化 3.我查找了一些信息并找到了这段代码。在我的视图模型中,我设置了一个侦听器块,结果状态为 0(成功):
override func viewDidLoad() {
super.viewDidLoad()
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster))
}
// Utility function to simplify adding listener blocks:
func addListenerBlock( listenerBlock: @escaping AudioObjectPropertyListenerBlock, onAudioObjectID: AudioObjectID, forPropertyAddress: AudioObjectPropertyAddress) {
var forPropertyAddress = forPropertyAddress
let status = AudioObjectAddPropertyListenerBlock(onAudioObjectID, &forPropertyAddress, nil, listenerBlock)
print(status)
}
func audioObjectPropertyListenerBlock (numberAddresses: UInt32, addresses: UnsafePointer<AudioObjectPropertyAddress>) {
var index: UInt32 = 0
while index < numberAddresses {
let address: AudioObjectPropertyAddress = addresses[index]
switch address.mSelector {
case kAudioHardwarePropertyDefaultOutputDevice:
let deviceID = getDefaultAudioOutputDevice()
print("kAudioHardwarePropertyDefaultOutputDevice: \(deviceID)")
default:
print("We didn't expect this!")
}
index += 1
}
}
// Utility function to get default audio output device:
func getDefaultAudioOutputDevice () -> AudioObjectID {
var devicePropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster)
var deviceID: AudioObjectID = 0
var dataSize = UInt32(truncatingBitPattern: MemoryLayout<AudioDeviceID>.size)
let systemObjectID = AudioObjectID(bitPattern: kAudioObjectSystemObject)
if (kAudioHardwareNoError != AudioObjectGetPropertyData(systemObjectID, &devicePropertyAddress, 0, nil, &dataSize, &deviceID)) { return 0 }
return deviceID
}
然而,即使 OSStatus 为 0 并且添加了侦听器,当我更改参数(在本例中为输出音量)时也不会调用它。我在我的 audioObjectPropertyListenerBlock 中设置了一个断点,但我的应用程序从未到达那里。我错过了什么?
问题出在这里:
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster))
onAudioObjectID
应该是默认输出设备:getDefaultAudioOutputDevice()
(这些 int-ly 类型的 API 令人困惑)
mScope
应该是kAudioObjectPropertyScopeOutput
,而
mElement
应该是1或2。(至少我的输出设备没有master元素!)
总计:
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: getDefaultAudioOutputDevice(),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeOutput,
mElement: 1))
进行这些更改后,当左声道输出音量更改时将调用您的侦听器块。
不过,我不确定您要在侦听器块中做什么,因为 mSelector
始终是您请求的 kAudioDevicePropertyVolumeScalar
,永远不会 kAudioObjectSystemObject
.
我想使用Swift观察音频设备参数的变化 3.我查找了一些信息并找到了这段代码。在我的视图模型中,我设置了一个侦听器块,结果状态为 0(成功):
override func viewDidLoad() {
super.viewDidLoad()
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster))
}
// Utility function to simplify adding listener blocks:
func addListenerBlock( listenerBlock: @escaping AudioObjectPropertyListenerBlock, onAudioObjectID: AudioObjectID, forPropertyAddress: AudioObjectPropertyAddress) {
var forPropertyAddress = forPropertyAddress
let status = AudioObjectAddPropertyListenerBlock(onAudioObjectID, &forPropertyAddress, nil, listenerBlock)
print(status)
}
func audioObjectPropertyListenerBlock (numberAddresses: UInt32, addresses: UnsafePointer<AudioObjectPropertyAddress>) {
var index: UInt32 = 0
while index < numberAddresses {
let address: AudioObjectPropertyAddress = addresses[index]
switch address.mSelector {
case kAudioHardwarePropertyDefaultOutputDevice:
let deviceID = getDefaultAudioOutputDevice()
print("kAudioHardwarePropertyDefaultOutputDevice: \(deviceID)")
default:
print("We didn't expect this!")
}
index += 1
}
}
// Utility function to get default audio output device:
func getDefaultAudioOutputDevice () -> AudioObjectID {
var devicePropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster)
var deviceID: AudioObjectID = 0
var dataSize = UInt32(truncatingBitPattern: MemoryLayout<AudioDeviceID>.size)
let systemObjectID = AudioObjectID(bitPattern: kAudioObjectSystemObject)
if (kAudioHardwareNoError != AudioObjectGetPropertyData(systemObjectID, &devicePropertyAddress, 0, nil, &dataSize, &deviceID)) { return 0 }
return deviceID
}
然而,即使 OSStatus 为 0 并且添加了侦听器,当我更改参数(在本例中为输出音量)时也不会调用它。我在我的 audioObjectPropertyListenerBlock 中设置了一个断点,但我的应用程序从未到达那里。我错过了什么?
问题出在这里:
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster))
onAudioObjectID
应该是默认输出设备:getDefaultAudioOutputDevice()
(这些 int-ly 类型的 API 令人困惑)mScope
应该是kAudioObjectPropertyScopeOutput
,而mElement
应该是1或2。(至少我的输出设备没有master元素!)
总计:
addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
onAudioObjectID: getDefaultAudioOutputDevice(),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioDevicePropertyVolumeScalar,
mScope: kAudioObjectPropertyScopeOutput,
mElement: 1))
进行这些更改后,当左声道输出音量更改时将调用您的侦听器块。
不过,我不确定您要在侦听器块中做什么,因为 mSelector
始终是您请求的 kAudioDevicePropertyVolumeScalar
,永远不会 kAudioObjectSystemObject
.