我使用以下代码来检测AirPlay是否为当前选定的路线:
let airPlayActive = AVAudioSession
.sharedInstance()
.currentRoute
.outputs
.first?
.portType == .airPlay
print("AirPlay active: \(airPlayActive)")
但是,这在特定情况下不起作用。我的用例是在播放视频之前知道选择了空中播放。我有两个视图控制器,分别是 A 和 B 。为了进行测试,我在 A 上设置了一个计时器,使用上面的代码每秒打印一次AirPlay是否处于活动状态。
在 A 中,我呈现了模态视图控制器 B ,该控制器基本上使用AVPlayer
播放视频,并使用{{1}控制当前选定的路线}。如果我出现 B ,等待视频播放,然后将其更改为AirPlay的路线,则可以看到更改已反映在 A 上(它将开始打印{{1 }})。然后,如果我关闭 B 然后重新打开它,则可以在播放视频之前就知道AirPlay是否处于活动状态,而这正是我想要的。
但是在某些情况下,这是行不通的。
这种情况是(看起来很奇怪),如果我使用MPVolumeView
将目标添加到远程命令中,我上面描述的行为只会改变!这是我添加目标的方式(在视图控制器 B 中):
true
我还将在 B 的MPRemoteCommandCenter
中删除该目标:
let center = MPRemoteCommandCenter.shared()
let pauseCommand = center.pauseCommand
pauseCommand.isEnabled = true
pauseCommand.addTarget(handler: { _ -> MPMPRemoteCommandHandlerStatus in
// ... doing some business logic
return .success
})
好吧,这完全与所有与AirPlay相关的东西弄混了:
如果我在视图控制器 B 上激活AirPlay,然后将其关闭,则会停用AirPlay。现在,当前的deinit
再次变为let center = MPRemoteCommandCenter.shared()
let pauseCommand = center.pauseCommand
pauseCommand.isEnabled = false
pauseCommand.addTarget(nil)
。因此,在重新打开 B (播放视频)之前,我无法确定AirPlay是否处于活动状态。
即使portType
在关闭 B 之后是.builtInSpeaker
,但如果我拨打portType
,我仍然会得到.builtInSpeaker
,这告诉我无线路由处于活动状态,但不一定是AirPlay(例如,它可以是蓝牙耳机)。
如果我重新打开 B ,则在视频开始播放后,true
从MPVolumeView().isWirelessRouteActive
变为portType
。
音频路由更改通知也将停止正常工作。观察.builtInSpeaker
时,它有时不会触发,而触发时,.airPlay
上大多数时间的用户信息是AVAudioSession.routeChangeNotification
。
对我来说,这显然是Apple方面的错误,但是你们中的任何一个碰巧都知道替代方法吗?在播放视频之前,我基本上需要知道AirPlay是否处于活动状态。
谢谢!
答案 0 :(得分:0)
好吧,我找到了解决方法。和问题本身一样奇怪,但是它正在起作用...
我刚刚在视图控制器 B 上播放视频之前将目标添加到了远程命令中。然后,我只等待音频路由更改通知(如果未激活则超时)。这表明播放视频是“安全的”。