在使用AVPlayer播放视频之前,如何检测AirPlay是否处于活动状态?

时间:2019-04-04 20:07:40

标签: ios arrays avplayer airplay mpremotecommandcenter

我使用以下代码来检测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相关的东西弄混了:

  1. 如果我在视图控制器 B 上激活AirPlay,然后将其关闭,则会停用AirPlay。现在,当前的deinit再次变为let center = MPRemoteCommandCenter.shared() let pauseCommand = center.pauseCommand pauseCommand.isEnabled = false pauseCommand.addTarget(nil) 。因此,在重新打开 B (播放视频)之前,我无法确定AirPlay是否处于活动状态。

  2. 即使portType在关闭 B 之后是.builtInSpeaker,但如果我拨打portType,我仍然会得到.builtInSpeaker,这告诉我无线路由处于活动状态,但不一定是AirPlay(例如,它可以是蓝牙耳机)。

  3. 如果我重新打开 B ,则在视频开始播放后,trueMPVolumeView().isWirelessRouteActive变为portType

  4. 音频路由更改通知也将停止正常工作。观察.builtInSpeaker时,它有时不会触发,而触发时,.airPlay上大多数时间的用户信息是AVAudioSession.routeChangeNotification

对我来说,这显然是Apple方面的错误,但是你们中的任何一个碰巧都知道替代方法吗?在播放视频之前,我基本上需要知道AirPlay是否处于活动状态。

谢谢!

1 个答案:

答案 0 :(得分:0)

好吧,我找到了解决方法。和问题本身一样奇怪,但是它正在起作用...

我刚刚在视图控制器 B 上播放视频之前将目标添加到了远程命令中。然后,我只等待音频路由更改通知(如果未激活则超时)。这表明播放视频是“安全的”。