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

如何获取激活状态AirPlay设备名称以用于VoiceOver无障碍开发

你当前遇到的问题是iOS系统层面的API限制导致的,不是需求无法实现。
从iOS 7开始,苹果为了保护用户隐私,对AVAudioSession的portName字段做了权限限制:当输出端口为AirPlay类型时,直接读取该属性只会返回固定的AirPlay字符串,无法拿到真实的设备名称。

可行实现方案

方案一:基于AVPlayer的公开API(推荐,无审核风险)

如果你的场景中使用AVPlayer播放音视频,可以通过KVO监听externalPlaybackAirPlayDeviceLocalizedName属性获取真实设备名,代码示例如下:

// 初始化AVPlayer后添加监听
player.addObserver(self, forKeyPath: "externalPlaybackAirPlayDeviceLocalizedName", options: [.new], context: nil)

// 监听回调处理
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == "externalPlaybackAirPlayDeviceLocalizedName",
          let deviceName = change?[.newKey] as? String,
          !deviceName.isEmpty else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }
    // 拿到设备名后可直接赋值给无障碍属性
    yourView.accessibilityLabel = "当前已连接到AirPlay设备\(deviceName)"
}

使用该方案需要注意在页面销毁时移除KVO监听,避免内存泄漏。

方案二:基于MPVolumeView的实现(存在审核风险)

如果需要在无播放内容的场景下获取AirPlay设备名,可以通过遍历MPVolumeView的子视图读取对应属性,但该方案用到了苹果私有API,上架App Store可能被拒绝:

import MediaPlayer

func getAirPlayDeviceName() -> String {
    let volumeView = MPVolumeView(frame: CGRect.zero)
    for subview in volumeView.subviews {
        if NSStringFromClass(type(of: subview)) == "MPAirPlayVideoActiveRouteButton" {
            if let deviceName = subview.accessibilityValue {
                return deviceName
            }
        }
    }
    return AVAudioSession.sharedInstance().currentRoute.outputs.first { $0.portType == .airPlay }?.portName ?? "unknown"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:00