Macos 如何在系统首选项默认声音更改时获取通知
这相当简单(我认为)。我只是想在我的应用程序中得到一个通知,每当用户更改系统首选项-声音中的默认声音输入或声音输出设备时。然而,如果我能从苹果的文档中找到它,那我就倒霉了 作为补充说明,这是针对OSX的,而不是针对IOS的Macos 如何在系统首选项默认声音更改时获取通知,macos,cocoa,notifications,core-audio,Macos,Cocoa,Notifications,Core Audio,这相当简单(我认为)。我只是想在我的应用程序中得到一个通知,每当用户更改系统首选项-声音中的默认声音输入或声音输出设备时。然而,如果我能从苹果的文档中找到它,那我就倒霉了 作为补充说明,这是针对OSX的,而不是针对IOS的 谢谢大家 为默认输出设备设置AudioObjectPropertyAddress: AudioObjectPropertyAddress outputDeviceAddress = { kAudioHardwarePropertyDefaultOutputDevice
谢谢大家 为默认输出设备设置
AudioObjectPropertyAddress
:
AudioObjectPropertyAddress outputDeviceAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
然后,使用AudioObjectAddPropertyListener
为默认设备中的更改注册侦听器:
AudioObjectAddPropertyListener(kAudioObjectSystemObject,
&outputDeviceAddress,
&callbackFunction, nil);
回调函数如下所示:
OSStatus callbackFunction(AudioObjectID inObjectID,
UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[],
void *inClientData)
作为旁注,您还应该使用AudioObjectPropertyAddress
告诉HAL管理自己的通知线程。您可以通过将运行循环选择器设置为NULL来实现这一点。我实际上是在设置输出设备侦听器之前执行此步骤的
AudioObjectPropertyAddress runLoopAddress = {
kAudioHardwarePropertyRunLoop,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
CFRunLoopRef runLoop = NULL;
UInt32 size = sizeof(CFRunLoopRef);
AudioObjectSetPropertyData(kAudioObjectSystemObject,
&runLoopAddress, 0, NULL, size, &runLoop);
以下是如何在Swift中执行此操作:
addListenerBlock
函数简化了添加属性侦听器块的过程。Swift允许参数为变量,这对于forPropertyAddress
参数非常方便。调用addListenerBlock
时,只需插入属性地址参数
import Cocoa
import CoreAudio
class ViewController: NSViewController {
// Utility function to simplify adding listener blocks:
func addListenerBlock( listenerBlock: AudioObjectPropertyListenerBlock, onAudioObjectID: AudioObjectID, var forPropertyAddress: AudioObjectPropertyAddress) {
if (kAudioHardwareNoError != AudioObjectAddPropertyListenerBlock(onAudioObjectID, &forPropertyAddress, nil, listenerBlock)) {
print("Error calling: AudioObjectAddPropertyListenerBlock") }
}
override func viewDidLoad() { super.viewDidLoad()
addListenerBlock(audioObjectPropertyListenerBlock,
onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
forPropertyAddress: AudioObjectPropertyAddress(
mSelector: kAudioHardwarePropertyDefaultOutputDevice,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: kAudioObjectPropertyElementMaster))
}
...
func audioObjectPropertyListenerBlock (numberAddresses: UInt32, addresses: UnsafePointer<AudioObjectPropertyAddress>) {
var index: UInt32 = 0
while index < numberAddresses {
let address: AudioObjectPropertyAddress = addresses[0]
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: sizeof(AudioDeviceID))
let systemObjectID = AudioObjectID(bitPattern: kAudioObjectSystemObject)
if (kAudioHardwareNoError != AudioObjectGetPropertyData(systemObjectID, &devicePropertyAddress, 0, nil, &dataSize, &deviceID)) { return 0 }
return deviceID
}
}
func audioObjectPropertyListenerBlock(numberAddresses:UInt32,addresses:UnsafePointer){
var指数:UInt32=0
而指数AudioObjectID{
var devicePropertyAddress=AudioObjectPropertyAddress(mSelector:kAudioHardwarePropertyDefaultOutputDevice,mScope:kAudioObjectPropertyScopeGlobal,mElement:KaudioObjectPropertyYelementMaster)
var设备ID:AudioObjectID=0
var dataSize=UInt32(截断位模式:sizeof(AudioDeviceID))
让systemObjectID=AudioObjectID(位模式:kAudioObjectSystemObject)
if(kaudiohardwarenorerror!=AudioObjectGetPropertyData(systemObjectID,&devicePropertyAddress,0,nil,&dataSize,&deviceID)){返回0}
返回设备ID
}
}
当然,如果您想监视其他音频设备属性,只需在
开关
语句中添加更多案例
。调用addListenerBlock
添加您感兴趣的任何设备和属性地址。尝试使用默认声音输入或输出设备选择更改时不起作用的搜索()。非常适合检测音量水平,但不适合检测设备选择的变化。在第let address:AudioObjectPropertyAddress=addresses[0]
行中,您的意思是将index
改为0
?