You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

kAudioDevicePropertyDeviceIsRunningSomewhere针对AirPods等设备返回值异常求助

解决AirPods等无线音频设备kAudioDevicePropertyDeviceIsRunningSomewhere返回值异常问题

针对AirPods这类无线音频设备,kAudioDevicePropertyDeviceIsRunningSomewhere属性存在已知兼容性问题:设备处于活跃使用状态时,该属性始终返回0(而非预期的1);即便添加ListenerBlock能触发回调,返回值依然不符合实际状态。

以下是几个可靠的替代方案:

1. 结合流配置与采样率判断设备状态

无线设备活跃时,其音频流配置和采样率会发生明显变化:

  • 查询kAudioDevicePropertyStreamConfiguration,检查输入/输出流的数量是否大于0;
  • 查询kAudioDevicePropertyNominalSampleRate,确认采样率是否切换到实际工作值(如44100Hz、48000Hz),而非默认的0或极低数值。

示例代码片段:

UInt32 propSize = 0;
AudioObjectPropertyAddress streamConfigAddr = {
    kAudioDevicePropertyStreamConfiguration,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMain
};
// 先获取属性大小
AudioObjectGetPropertyDataSize(deviceID, &streamConfigAddr, 0, NULL, &propSize);
AudioBufferList* bufferList = malloc(propSize);
AudioObjectGetPropertyData(deviceID, &streamConfigAddr, 0, NULL, &propSize, bufferList);
// 检查输出流数量
BOOL hasActiveStream = (bufferList->mNumberBuffers > 0);
free(bufferList);

// 检查采样率
Float64 sampleRate = 0;
propSize = sizeof(Float64);
AudioObjectPropertyAddress sampleRateAddr = {
    kAudioDevicePropertyNominalSampleRate,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMain
};
AudioObjectGetPropertyData(deviceID, &sampleRateAddr, 0, NULL, &propSize, &sampleRate);
BOOL isSampleRateActive = (sampleRate >= 44100.0);

2. 监听系统音频路由变化

借助AVAudioSession的路由变更通知,结合当前路由的设备信息判断状态:

  • 监听AVAudioSessionRouteChangeNotification;
  • 在回调中解析AVAudioSessionRouteDescription,检查输出/输入端口是否为目标无线设备,且端口处于活跃状态。

示例代码片段:

[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionRouteChangeNotification
                                                  object:[AVAudioSession sharedInstance]
                                                   queue:[NSOperationQueue mainQueue]
                                              usingBlock:^(NSNotification *note) {
    AVAudioSessionRouteDescription* currentRoute = [[AVAudioSession sharedInstance] currentRoute];
    for (AVAudioSessionPortDescription* port in currentRoute.outputs) {
        if ([port.portType isEqualToString:AVAudioSessionPortBluetoothA2DP] || 
            [port.portType isEqualToString:AVAudioSessionPortBluetoothHFP]) {
            // AirPods等蓝牙设备处于活跃输出状态
            BOOL isDeviceActive = YES;
            // 执行后续逻辑
            break;
        }
    }
}];

3. 查询设备活跃IO客户端数量

使用kAudioDevicePropertyIOClientCount属性直接获取当前使用设备的客户端数量,该属性在无线设备上的表现更稳定:

  • 当客户端数量大于0时,说明设备处于活跃使用状态。

示例代码片段:

UInt32 clientCount = 0;
UInt32 propSize = sizeof(UInt32);
AudioObjectPropertyAddress clientCountAddr = {
    kAudioDevicePropertyIOClientCount,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMain
};
OSStatus status = AudioObjectGetPropertyData(deviceID, &clientCountAddr, 0, NULL, &propSize, &clientCount);
if (status == noErr && clientCount > 0) {
    // 设备处于活跃状态
}

补充说明

出现"监听触发但值异常"的现象,是因为Core Audio对无线设备的状态变更通知逻辑与属性更新不同步:设备状态变化会触发ListenerBlock,但kAudioDevicePropertyDeviceIsRunningSomewhere的内部更新存在逻辑滞后或错误,因此完全依赖该属性不可靠,建议结合上述方案交叉验证。

内容的提问来源于stack exchange,提问作者espc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:02:53