Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何在系统首选项默认声音更改时获取通知_Macos_Cocoa_Notifications_Core Audio - Fatal编程技术网

Macos 如何在系统首选项默认声音更改时获取通知

Macos 如何在系统首选项默认声音更改时获取通知,macos,cocoa,notifications,core-audio,Macos,Cocoa,Notifications,Core Audio,这相当简单(我认为)。我只是想在我的应用程序中得到一个通知,每当用户更改系统首选项-声音中的默认声音输入或声音输出设备时。然而,如果我能从苹果的文档中找到它,那我就倒霉了 作为补充说明,这是针对OSX的,而不是针对IOS的 谢谢大家 为默认输出设备设置AudioObjectPropertyAddress: AudioObjectPropertyAddress outputDeviceAddress = { kAudioHardwarePropertyDefaultOutputDevice

这相当简单(我认为)。我只是想在我的应用程序中得到一个通知,每当用户更改系统首选项-声音中的默认声音输入或声音输出设备时。然而,如果我能从苹果的文档中找到它,那我就倒霉了

作为补充说明,这是针对OSX的,而不是针对IOS的


谢谢大家

为默认输出设备设置
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