swiftui dealloc 和 realloc AVplayer 有很多视频
Posted
技术标签:
【中文标题】swiftui dealloc 和 realloc AVplayer 有很多视频【英文标题】:swiftui dealloc and realloc AVplayer with many videos 【发布时间】:2020-04-07 16:10:01 【问题描述】:我有很多同步视频。通过 Int var (var test1 和 var test2) 我希望能够只添加某个视频并删除所有其他视频,以免出现内存问题
一旦加载视图,就会为每个播放器分配值“nil”,当 test1 == test 2 时,它应该将视频加载到某个播放器和另一个“nil”中
问题在于,尽管它是绑定中的测试变量(struct VideoPlayer @Binding var testing),但它不会更新始终保持为 Nil 的播放器状态
低于我目前获得的最佳解决方案
有什么想法吗?谢谢大家
struct CustomPlayer: View
@Binding var test1:Int
@Binding var test2:Int
@State var path:String
@State var testing:AVPlayer? = nil
var body: some View
if(test1 == test2 )
self.testing? = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "\(path)", ofType: "mp4")!) )
self.testing?.play()
else
self.testing?.replaceCurrentItem(with: nil)
return ZStack
VideoPlayer(testing: self.$testing)
struct VideoPlayer : UIViewControllerRepresentable
@Binding var testing : AVPlayer?
func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPlayer>) -> AVPlayerViewController
let controller = AVPlayerViewController()
controller.player = testing
controller.showsPlaybackControls = false
controller.view.backgroundColor = UIColor.white
return controller
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayer>)
【问题讨论】:
【参考方案1】:这是一个如何同时加载多个视频的示例(我添加了一个自动播放功能),并删除所有其他视频,但不删除所选视频。 要删除视频,请点按您要保存的视频
我不确定我是否能解决您最初的问题,但这可以为您提供下一步寻找方向的线索
代码可以复制/粘贴,因为我在一个文件中声明它以方便***使用
import SwiftUI
import AVKit
struct VideoModel: Identifiable
let id: Int
let name: String
let type: String = ".mp4"
final class VideoData: ObservableObject
@Published var videos = [VideoModel(id: 100, name: "video"),
VideoModel(id: 101, name: "wow"),
VideoModel(id: 102, name: "okay")]
//Multiple item player
struct MultipleVideoPlayer: View
@EnvironmentObject var userData: VideoData
var body: some View
VStack(alignment: .center, spacing: 8)
ForEach(userData.videos) video in
VideoPlayer(video: .constant(video))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 250, maxHeight: 250, alignment: .center)
//Single item player
struct VideoPlayer : UIViewControllerRepresentable
@EnvironmentObject var userData: VideoData
@Binding var video: VideoModel
func makeUIViewController(context: Context) -> AVPlayerViewController
guard let path = Bundle.main.path(forResource: video.name, ofType: video.type) else
fatalError("\(video.name)\(video.type) not found")
let url = URL(fileURLWithPath: path)
let playerItem = AVPlayerItem(url: url)
context.coordinator.player = AVPlayer(playerItem: playerItem)
context.coordinator.player?.isMuted = true
context.coordinator.player?.actionAtItemEnd = .none
NotificationCenter.default.addObserver(context.coordinator,
selector: #selector(Coordinator.playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: context.coordinator.player?.currentItem)
let controller = AVPlayerViewController()
controller.player = context.coordinator.player
controller.showsPlaybackControls = false
controller.view.backgroundColor = UIColor.white
controller.delegate = context.coordinator
let tapRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.playerDidTap))
controller.view.addGestureRecognizer(tapRecognizer)
return controller
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context)
uiViewController.player?.play()
func makeCoordinator() -> Coordinator
let coord = Coordinator(self)
return coord
class Coordinator: NSObject, AVPlayerViewControllerDelegate
var parent: VideoPlayer
var player: AVPlayer?
init(_ playerViewController: VideoPlayer)
self.parent = playerViewController
@objc func playerItemDidReachEnd(notification: NSNotification)
if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem
playerItem.seek(to: CMTime.zero, completionHandler: nil)
@objc func playerDidTap()
parent.userData.videos = parent.userData.videos.filter videoItem in
return videoItem.id == parent.video.id
//preview
struct AnotherEntry_Previews: PreviewProvider
static var previews: some View
MultipleVideoPlayer()
并在“SceneDelegate.swift”中将应用入口点替换为
window.rootViewController = UIHostingController(rootView: MultipleVideoPlayer().environmentObject(VideoData()))
这个动作的关键是要有“VideoData”资源,你可以通过EnvironmentObject,或者其他一些共享数据的例子来实现
我添加到项目中的以下视频,包括项目的目标成员
@Published var videos = [VideoModel(id: 100, name: "video"),
VideoModel(id: 101, name: "wow"),
VideoModel(id: 102, name: "okay")]
【讨论】:
【参考方案2】:您的代码似乎没问题。你确定 AVPlayer(...) 路径是正确的 并且测试不是零。放
.....
self.testing?.play()
print("-----> testing: \(testing.debugDescription)")
那时 testing = nil 吗?
【讨论】:
是...调试描述返回零。我尝试在 if(test1 == test2 ) 之前添加 DispatchQueue.main.async 但结果是一样的。谢谢! 如果此时测试为零,那是因为 AVPlayer(url:..) 无法找到具有给定 url 的资源。您需要先解决此问题,然后其余代码(可能)才能工作。以上是关于swiftui dealloc 和 realloc AVplayer 有很多视频的主要内容,如果未能解决你的问题,请参考以下文章
free、dealloc、release 和 autorelease 有啥区别?
零基础学C语言内存知识总结:realloc函数和free函数