1

我正在使用以下代码来检测 AirPlay 是否是当前选择的路线:

let airPlayActive = AVAudioSession
  .sharedInstance()
  .currentRoute
  .outputs
  .first?
  .portType == .airPlay
print("AirPlay active: \(airPlayActive)")

但是,这在非常特定的情况下不起作用。我的用例是知道在播放视频之前选择了空中播放。我有两个视图控制器,比如AB。出于测试目的,我在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 相关的东西混为一谈:

  1. 如果我在视图控制器B上激活 AirPlay然后将其关闭,AirPlay 就会被停用。现在电流又portType变成.builtInSpeaker了。因此,在重新打开B(播放视频)之前,我无法判断 AirPlay 是否处于活动状态。

  2. 即使portType.builtInSpeaker关闭B之后,我仍然会收到trueif I call MPVolumeView().isWirelessRouteActive,这告诉我无线路由处于活动状态,但这不一定是 AirPlay(例如,它可能是蓝牙耳机)。

  3. 如果我重新打开B,视频开始播放后portType.builtInSpeaker到。.airPlay

  4. 音频路由更改通知也停止正常工作。观察AVAudioSession.routeChangeNotification时,有时不触发,触发时,用户信息AVAudioSessionRouteChangeReasonKey大部分时间为.unknown

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

谢谢!

4

1 回答 1

1

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

我刚刚在视图控制器B上播放视频之前向远程命令添加了一个目标。然后我只是等待音频路由更改通知(或超时,以防不活动)。这表明播放视频是“安全的”。

于 2019-04-06T22:36:43.637 回答