我希望在耳机插孔插入或拔出耳机时收到通知。
我在stackoverflow上搜索了这个,但我似乎找不到我要寻找的Mac,我只能找到iOS。
那么,您对如何执行此操作有任何想法吗?我想要做的是:当耳机被拔出时,我想以编程方式暂停 iTunes(类似 iOS 的功能)。
谢谢!
问问题
6349 次
2 回答
28
CoreAudio
您可以使用框架观察变化。
耳机和扬声器都是同一音频输出设备(内置类型)上的数据源。根据是否插入耳机,两者之一将在音频设备上。
要获得通知,您可以在内置输出设备上监听活动数据源的变化。
1.获取内置输出设备
为了保持简短,我们将使用默认输出设备。在大多数情况下,这是内置输出设备。在现实生活中的应用程序中,您需要循环所有可用的设备来找到它,因为默认设备可以设置为不同的音频设备(例如 soundflower 或 airplay)。
AudioDeviceID defaultDevice = 0;
UInt32 defaultSize = sizeof(AudioDeviceID);
const AudioObjectPropertyAddress defaultAddr = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioObjectGetPropertyData(kAudioObjectSystemObject, &defaultAddr, 0, NULL, &defaultSize, &defaultDevice);
2.读取其当前数据源
设备上的当前数据源由类型 ID 标识UInt32
。
AudioObjectPropertyAddress sourceAddr;
sourceAddr.mSelector = kAudioDevicePropertyDataSource;
sourceAddr.mScope = kAudioDevicePropertyScopeOutput;
sourceAddr.mElement = kAudioObjectPropertyElementMaster;
UInt32 dataSourceId = 0;
UInt32 dataSourceIdSize = sizeof(UInt32);
AudioObjectGetPropertyData(defaultDevice, &sourceAddr, 0, NULL, &dataSourceIdSize, &dataSourceId);
3. 观察数据源的变化
AudioObjectAddPropertyListenerBlock(_defaultDevice, &sourceAddr, dispatch_get_current_queue(), ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses) {
// move to step 2. to read the updated value
});
确定数据源类型
当您拥有数据源 ID 时,UInt32
您可以使用值转换器查询音频对象的属性。例如,要将源名称作为字符串使用kAudioDevicePropertyDataSourceNameForIDCFString
. 这将产生字符串“内部扬声器”或“耳机”。但是,这可能因用户区域设置而异。
更简单的方法是直接比较数据源 id:
if (dataSourceId == 'ispk') {
// Recognized as internal speakers
} else if (dataSourceId == 'hdpn') {
// Recognized as headphones
}
但是我找不到为这些值定义的任何常量,所以这有点无证。
于 2013-01-23T22:49:14.960 回答
4
我一直在寻找类似的解决方案,并在应用商店中找到了AutoMute 。它运作良好。
我也在编写自己的一些脚本,并编写了这个脚本来测试是否插入了耳机:
#!/bin/bash
if system_profiler SPAudioDataType | grep --quiet Headphones; then
echo plugged in
else
echo not plugged in
fi
于 2019-03-21T18:27:43.170 回答