Обновления экрана блокировки AVPlayer перестают работать, только после того, как другой экземпляр AVPlayer воспроизведет видеоконтент - PullRequest
1 голос
/ 14 марта 2019

Сводка:

Если вы используете AVPlayer только для воспроизведения потокового аудио только в своем приложении, тогда обновления экрана блокировки будут работать очень хорошо (многие потоки - один за другим).Однако если вы используете AVPlayer для воспроизведения как потокового аудио, так и локального видеофайла (даже при использовании отдельных экземпляров AVPlayer и на разных контроллерах представления), то при попытке воспроизведения потокового аудио снова - на экране блокировки ничего не появитсябольшеНе относится к очистке - потому что воспроизведение только нескольких аудиофайлов подряд работает нормально и отображается на экране блокировки каждый раз, но как только вы проигрываете 1 видеофайл (или даже инициализируете его для любого AVPlayer без вызова .play () наон), обновления звука экрана блокировки навсегда перестают работать, и вам нужно перезапустить приложение, чтобы оно снова заработало.Для меня это звучит как ошибка AVFoundation ...

Подробная разбивка:

У меня есть приложение с контроллерами вида A и B. Контроллер вида A является ведущимпросмотр контроллера B (толкает его с помощью навигационного контроллера).Оба A и B имеют отдельный AVPlayer внутри (A воспроизводит аудио. B воспроизводит видео. Аудио передается в потоковом режиме. Видео является локальным файлом в каталоге docs).

VC A настраивает свой AVPlayer для обновления экрана блокировки с изображением художественного произведения, состоянием прогресса, кнопками перемотки вперед 15 с и 15 с назад. Все прекрасно работает, если для воспроизведения звука используется только проигрыватель контроллера просмотра A - независимо от того, сколько раз я возвращаюсь к нему (плеер IE VC B никогда не используется для воспроизведения ()) .(Весь контроллер работает правильно). Экран блокировки всегда работает и всегда обновляет всю необходимую информацию о воспроизведении.

VC A (AVPlayer1) -> PUSH -> VC B (AVPlayer2)

Этот код регистрируется для обновления экрана блокировки (включая кнопку и ход выполнения).обратные вызовы):

func setupNowPlaying() {
    var nowPlayingInfo = [String : Any]()
    nowPlayingInfo[MPMediaItemPropertyTitle] = title
    nowPlayingInfo[MPMediaItemPropertyArtist] = artist

    let artwork = MPMediaItemArtwork.init(boundsSize: self.artImage.size, requestHandler: { (size) -> UIImage in
        return self.artImage
    })
    nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

    guard let player = self.player else { return }
    guard let currentItem = self.player?.currentItem else { return }

    nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.asset.duration.seconds
    nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
    nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentItem.currentTime().seconds

    let rcc = MPRemoteCommandCenter.shared()
    let skipBackwardCommand = rcc.skipBackwardCommand
    skipBackwardCommand.isEnabled = true
    skipBackwardCommand.addTarget(handler: skipBackward)
    skipBackwardCommand.preferredIntervals = [15]

    let skipForwardCommand = rcc.skipForwardCommand
    skipForwardCommand.isEnabled = true
    skipForwardCommand.addTarget(handler: skipForward)
    skipForwardCommand.preferredIntervals = [15]

    UIApplication.shared.beginReceivingRemoteControlEvents()

    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

Кроме того, в AppDelegate (applicationWillResignActive) подключено следующее, чтобы включить фоновое воспроизведение (стандартный материал):

    do {
        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay, .allowBluetooth, .allowBluetoothA2DP ])
        print("Playback OK")
        try AVAudioSession.sharedInstance().setActive(true)
        print("Session is Active")
    } catch {
        print(error)
    }

Проблема отсутствия отображения чего-либо наэкран блокировки начинает появляться, когда VC B отображается и воспроизводит видео, используя свой отдельный AVPlayer .AVPlayer VC A сначала приостановлен.Если я вызову .play () на проигрывателе VC B, то когда я вернусь к VC A (нажав Back <в навигационной панели), обновления прогресса на экране блокировки больше не будут отображаться (весь пользовательский интерфейс воспроизведения не отображается).), однако фоновое воспроизведение все еще работает.</p>

Поэтому, как только я использую другой AVPlayer на другом View Controller, мой оригинальный проигрыватель никогда не сможет публиковать обновления в пользовательском интерфейсе блокировки экрана, даже до тех пор, пока приложение не будет завершено и перезапущено.

  • Я пытался выполнить полную очистку и повторную инициализацию проигрывателя в VC A.
  • Я пытался просто не вызывать .play () на VC B. (Все работает нормальнос ВК в этом случае).
  • Плеер VC B не зарегистрирован для обновлений экрана блокировки, поскольку он просто воспроизводит видео в приложении для предварительного просмотра.

Что-то скрытое с Apple AVPlayer нарушает возможность обновлений блокировки экрана AVPlayer в VC A, как только другой экземпляр AVPlayer представлен и используется для воспроизведения в другом контроллере вида.

Я знаю, что проблема связана со вторым AVPlayer на отдельном контроллере, потому что просто не вызывает .play () на проигрывателе VC B, исправляет проблему исчезновения обновления блокировки экрана на проигрывателе VC A.

Как я могу обойти это?Я не хочу удалять проигрыватель VC A из суперпредставления, передавать его в VC B и перенастраивать его, а затем перенастроить заново в VC A, если пользователь вернется.(очень трудоемко и подвержено ошибкам).В настоящее время он также постоянно обновляет блокировку экрана, после того, как пользователь впервые прослушивает VC B (что является частью моего счастливого пути)

Заранее спасибо, Алекс

1 Ответ

0 голосов
/ 16 марта 2019

Мне удалось избежать этой проблемы, убрав зависимость от AVPlayerViewController в VC-B.Теперь я использую сторонний компонент под названием «Player» (Cocoapods: «Player»), который использует AVPlayerLayer, но не AVPlayerViewController.https://cocoapods.org/pods/Player

К сожалению, я потерял свои элементы управления пользовательским интерфейсом воспроизведения (индикатор выполнения, кнопка воспроизведения, кнопка полного экрана - которую AVPlayerViewController предоставил мне бесплатно).Поэтому мне придется создать несколько пользовательских элементов управления воспроизведением.

Похоже, что AVPlayerViewController вызывал проблему с экраном блокировки и ломал его.После переключения на использование «Player», который по-прежнему использует AVPlayer, но не AVPlayerViewController, проблема исчезла, и теперь я всегда вижу свои элементы управления воспроизведением на экране блокировки.

...