2014-09-27 64 views
2

这很简单(我认为)。我只是想在用户更改系统偏好设置 - 声音中的默认声音输入或声音输出设备时,在我的应用程序中获得通知。但是,如果我能够从Apple文档中挖掘出来,我将会感到厌烦。如何获得系统偏好设置默认声音变化

作为一个方面说明,这是用于OSX,而​​不是IOS。

谢谢你们!

+0

尝试使用搜索(http://stackoverflow.com/questions/6747016/how-do-i-register-for-a-notification-for - 然后音量改变) – toohtik 2014-09-29 14:57:18

+0

当默认声音输入或输出设备选择改变时,这不起作用。非常适合检测音量级别,不适用于检测设备选择更改。 – 2014-09-30 14:46:43

回答

2

搭建AudioObjectPropertyAddress为默认输出设备:

AudioObjectPropertyAddress outputDeviceAddress = { 
    kAudioHardwarePropertyDefaultOutputDevice, 
    kAudioObjectPropertyScopeGlobal, 
    kAudioObjectPropertyElementMaster 
}; 

然后,使用AudioObjectSetPropertyData注册一个监听器在默认设备更改:

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); 
2

这里是如何做到这一点的斯威夫特:

  1. 注册时通过视图控制器加载其视图添加监听块,例如通知。 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)) 
        } 
    
    ... 
    
  2. 提供一个监听器模块功能来接收通知。你给出一个数组,可能有不止一个属性地址,这样循环并寻找您想要的:

    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 
        } 
    
    } 
    

当然,你可以简单地添加更多的casesswitch声明如果你想监视其他音频设备属性。致电addListenerBlock添加您感兴趣的任何设备和属性地址。

+0

在'let address:AudioObjectPropertyAddress = addresses [0]'这一行上,你的意思是把'index'而不是'0'? – GWRodriguez 2016-12-23 19:26:43