Как правильно реализовать AVPlayer в SwiftUI? - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть пара проблем с игроком. Я знаю, что есть много примеров игроков, но почти все они предназначены для воспроизведения только одного URL-адреса и не имеют необходимых функций.

Прежде всего, это мой существующий код для игрока:

struct PlayerViewController: UIViewControllerRepresentable {

    var video: Video

    private let player = AVPlayer()

    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let playerVC = AVPlayerViewController()
        playerVC.player = self.player
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)
        } catch(let error) {
            print(error.localizedDescription)
        }
        playerVC.player?.play()

        return playerVC
    }

    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
        guard let url = URL(string: video.url) else { return }

        resetPlayer(uiViewController)

        let item = AVPlayerItem(url: url)           
        uiViewController.player?.replaceCurrentItem(with: item)
        uiViewController.player?.play()
        if((uiViewController.view.window) == nil)
        {
            uiViewController.player?.pause()
        }
        print("Player::UpdatePlayer: Player updated")
    }

    func resetPlayer(_ vc: AVPlayerViewController) {
        vc.player?.pause()
        vc.player?.replaceCurrentItem(with: nil)
        print("Player::ResetPlayer: Player reseted.!")
    }


}

struct Video: Identifiable, Equatable {
    var id: Int
    var url: String


}

И я использую это следующим образом. Это просто пример того, как я заменяю str на действие кнопки в реальном проекте.

struct TestTestView: View {
    @State var str: String = ""
    var body: some View {
        PlayerViewController(video: Video(id: 2, url: (str == "") ? chan.getDVR()[0].getHlsStreamURL() : self.str ))
    }
}

Теперь приведенный выше код работает до определенной степени. Он играет, вы можете обновить URL с помощью нажатия кнопки, и он играет новый URL. Но когда он входит в полноэкранный режим, видео останавливается, потому что оно обновляет весь плеер, хотя ничего не изменилось. Следующие строки заставляют его останавливаться при входе в полноэкранный режим:

        if((uiViewController.view.window) == nil)
        {
            uiViewController.player?.pause()
        }

Однако, если я удаляю эти строки при переходе на другой экран, он продолжает воспроизводиться, вы продолжаете слышать звук. Я пытался определить полноэкранный режим, чтобы обновить мой код, но я не смог этого сделать. Я попытался определить, есть ли на самом деле плеер на экране, но он не сработал. Итак, как правильно это реализовать. В основном я хочу сделать:

1 - иметь возможность обновлять плеер и воспроизводить разные потоки 2 - запускать автоматическое воспроизведение 3 - плавно продолжать играть при переключении в полноэкранный режим и из него 4 - останавливаться при переходе к другой экран.

Кстати, если он не в полноэкранном режиме, я не могу нажать кнопку воспроизведения или индикатор выполнения, но каким-то образом я могу нажать кнопку отключения звука или полноэкранный режим. Мне нужна помощь!!

...