如何在解雇后停止播放 AVPlayerViewController 作为 UIViewRepresentable?
Posted
技术标签:
【中文标题】如何在解雇后停止播放 AVPlayerViewController 作为 UIViewRepresentable?【英文标题】:How to stop playback of AVPlayerViewController as UIViewRepresentable after dismissal? 【发布时间】: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 被关闭并且用户返回主视图时如何停止播放?
【问题讨论】:
【参考方案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()
。
应该这样做。
【讨论】:
以上是关于如何在解雇后停止播放 AVPlayerViewController 作为 UIViewRepresentable?的主要内容,如果未能解决你的问题,请参考以下文章
如何在游戏状态为暂停时停止游戏的播放列表,并在游戏完成暂停状态后重新播放? JavaScript