我正在使用以下代码来检测 AirPlay 是否是当前选择的路线:
let airPlayActive = AVAudioSession
.sharedInstance()
.currentRoute
.outputs
.first?
.portType == .airPlay
print("AirPlay active: \(airPlayActive)")
但是,这在非常特定的情况下不起作用。我的用例是知道在播放视频之前选择了空中播放。我有两个视图控制器,比如A和B。出于测试目的,我在A上有一个计时器,它使用上面的代码每秒打印一次 AirPlay 是否处于活动状态。
从A开始,我展示了模态视图控制器B,它基本上使用 播放视频AVPlayer
并使用MPVolumeView
. 如果我呈现B,等待视频播放然后将路由更改为 AirPlay,我可以看到更改反映在A上(它将开始打印true
)。然后,如果我关闭B然后重新打开它,甚至可以在播放视频之前判断 AirPlay 是否处于活动状态,这正是我想要的。
但是,有一种情况是行不通的。
情况是(尽管看起来很奇怪),如果我使用 将目标添加到远程命令MPRemoteCommandCenter
,我上面描述的行为就会改变!这是我添加目标的方式(在视图控制器B中):
let center = MPRemoteCommandCenter.shared()
let pauseCommand = center.pauseCommand
pauseCommand.isEnabled = true
pauseCommand.addTarget(handler: { _ -> MPMPRemoteCommandHandlerStatus in
// ... doing some business logic
return .success
})
我也在B中删除该目标deinit
:
let center = MPRemoteCommandCenter.shared()
let pauseCommand = center.pauseCommand
pauseCommand.isEnabled = false
pauseCommand.addTarget(nil)
好吧,这完全与所有与 AirPlay 相关的东西混为一谈:
如果我在视图控制器B上激活 AirPlay然后将其关闭,AirPlay 就会被停用。现在电流又
portType
变成.builtInSpeaker
了。因此,在重新打开B(播放视频)之前,我无法判断 AirPlay 是否处于活动状态。即使
portType
在.builtInSpeaker
关闭B之后,我仍然会收到true
if I callMPVolumeView().isWirelessRouteActive
,这告诉我无线路由处于活动状态,但这不一定是 AirPlay(例如,它可能是蓝牙耳机)。如果我重新打开B,视频开始播放后
portType
从.builtInSpeaker
到。.airPlay
音频路由更改通知也停止正常工作。观察
AVAudioSession.routeChangeNotification
时,有时不触发,触发时,用户信息AVAudioSessionRouteChangeReasonKey
大部分时间为.unknown
。
对我来说,这显然是苹果方面的一个错误,但你们中有人碰巧知道替代方案吗?在播放视频之前,我基本上需要知道 AirPlay 是否处于活动状态。
谢谢!