Как определить, активен ли AirPlay перед воспроизведением видео с помощью AVPlayer? - PullRequest
1 голос
/ 04 апреля 2019

Я использовал следующий код, чтобы определить, является ли 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 s deinit:

let center = MPRemoteCommandCenter.shared()
let pauseCommand = center.pauseCommand
pauseCommand.isEnabled = false
pauseCommand.addTarget(nil)

Что ж, это просто запутывает все, что связано с AirPlay:

  1. Если я активирую AirPlay на контроллере вида B , а затем отклонитьэто, AirPlay деактивируется.Теперь текущий portType снова становится .builtInSpeaker.Таким образом, я не могу сказать, активен ли AirPlay перед повторным открытием B (воспроизведение видео).

  2. Даже если portType равно .builtInSpeaker после закрытия B , я все равно получаю true, если позвоню MPVolumeView().isWirelessRouteActive, что говорит мне, что беспроводной маршрут активен, но это не обязательно AirPlay (это может быть, например, Bluetooth-наушники).

  3. Если я снова открою B , portType перейдет с .builtInSpeaker до .airPlay после начала воспроизведения видео.

  4. звуковое уведомление об изменении маршрута также перестает работать должным образом.Наблюдая AVAudioSession.routeChangeNotification, он иногда не срабатывает, а когда это происходит, информация пользователя в AVAudioSessionRouteChangeReasonKey в большинстве случаев составляет .unknown.

Для меня этоявно ошибка на стороне Apple, но кто-нибудь из вас знает альтернативу?Мне нужно знать, активен ли AirPlay перед воспроизведением видео.

Спасибо!

1 Ответ

0 голосов
/ 07 апреля 2019

Ну, я нашел обходной путь.Это так же странно, как и сама проблема, но она работает ...

Я только что добавил цель в удаленную команду прямо перед воспроизведением видео на контроллере представления B .Тогда я просто жду уведомления об изменении аудио маршрута (или тайм-аут, если он не активен).Это говорит о том, что «безопасно» воспроизводить видео.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...