【问题标题】:How to stop playback of AVPlayerViewController as UIViewRepresentable after dismissal?如何在解雇后停止播放 AVPlayerViewController 作为 UIViewRepresentable?
【发布时间】:2019-11-04 16:34:49
【问题描述】:

我创建了一个 UIViewRepresentable 版本的 AVPlayerViewController 来使用 SwiftUI 播放电影,并提供了 URL 和可选的启用/禁用控件。这是代码:

struct PlayerViewController: UIViewRepresentable {
    // Provide the player to this swiftui view
    var url: URL
    var showControls: Bool = true

    typealias UIViewType = UIView

    func makeUIView(context: UIViewRepresentableContext<PlayerViewController>) -> UIView {
        let controller = AVPlayerViewController()
        controller.player = AVPlayer(url: url)
        controller.showsPlaybackControls = showControls
        context.coordinator.controller = controller
        return controller.view
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerViewController>) {
    }

    func makeCoordinator() -> PlayerViewController.Coordinator {
        Coordinator()
    }

    class Coordinator: NSObject {
        var controller: AVPlayerViewController?

        deinit {
            print("deinit coordinator")
        }
    }
}

播放器是从嵌入在 NavigationView 中的列表访问的详细视图的一部分,如下所示:

NavigationView {
    List {
        NavigationLink(destination: DetailView(url: URL("url to movie")))
    }
}

DetailView 只是用提供的 url 实例化 PlayerViewController

我遇到的问题是,如果我在 DetailView 中播放电影,当我点击返回按钮从 DetailView 返回到主屏幕时,我仍然可以听到电影中的音频它显然仍在播放屏幕外。

其他 SO 问题表明这是因为在关闭视图后保留了对 AVPlayer 的引用。如果是真的,我不知道为什么;或者,我似乎无法控制。

如果在返回主视图并听到后台播放的视频后,我点击另一个列表项,播放立即停止并且我看到“deinit coordinator”调试消息。

当 PlayerViewController 被关闭并且用户返回主视图时如何停止播放?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    你可以通过viewWillDisappear方法通过添加扩展来暂停播放

    extension AVPlayerViewController {
        open override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            self.player?.pause()
            print("*** Video paused.")
        }
    }
    

    【讨论】:

    • 此解决方案在进入全屏模式时会产生问题。它将再次暂停视频。
    • 文档明确指出 The framework doesn’t support subclassing AVPlayerViewController. 这意味着你甚至不应该覆盖,除非你喜欢麻烦
    • 这在这种情况下不起作用,因为 SwiftUI 不会调用控制器上的任何方法。
    【解决方案2】:

    您可能希望拥有自己的UIViewControllerType,而不是AVPlayerViewController,而是自定义ContainerViewController。然后你添加一个AVPlayerViewController 的实例作为它的子元素,并保留对它的引用。 然后在ContainerViewController 的覆盖viewXDisappear 中,您将拥有avPlayerViewControllerInstance.stop()。 应该这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      相关资源
      最近更新 更多