swiftui dealloc和realloc AVplayer,包含许多视频
我有很多同步视频。通过一个Int-var(var-test1和var-test2),我希望能够只添加一个特定的视频并删除所有其他视频,这样就不会出现内存问题 一旦加载视图,值“nil”就分配给每个播放器,当test1==test2时,它应该在某个播放器和另一个“nil”中加载视频 问题在于,尽管它是绑定中的测试变量(struct VideoPlayer@binding var testing),但它不会更新始终保持为零的播放器状态 以下是我迄今为止得到的最佳解决方案 有什么想法吗?谢谢大家swiftui dealloc和realloc AVplayer,包含许多视频,swift,uikit,swiftui,avplayer,Swift,Uikit,Swiftui,Avplayer,我有很多同步视频。通过一个Int-var(var-test1和var-test2),我希望能够只添加一个特定的视频并删除所有其他视频,这样就不会出现内存问题 一旦加载视图,值“nil”就分配给每个播放器,当test1==test2时,它应该在某个播放器和另一个“nil”中加载视频 问题在于,尽管它是绑定中的测试变量(struct VideoPlayer@binding var testing),但它不会更新始终保持为零的播放器状态 以下是我迄今为止得到的最佳解决方案 有什么想法吗?谢谢大家 st
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>) {
}
}
struct CustomPlayer:视图{
@绑定var test1:Int
@绑定var test2:Int
@状态变量路径:字符串
@状态变量测试:AVPlayer?=nil
var body:一些观点{
if(test1==test2){
self.testing?=AVPlayer(url:url(fileURLWithPath:Bundle.main.path(forResource:\(path)”,类型为:“mp4”)!)
自我测试?.play()
}否则{
自检?.replaceCurrentItem(带:无)
}
返回ZStack{
视频播放器(测试:自测试)
}
结构视频播放器:UIViewControllerRepresentable{
@绑定var测试:AVPlayer?
func makeUIViewController(上下文:UIViewControllerRepresentableContext)->AVPlayerViewController{
let controller=avplayervewcontroller()
controller.player=测试
controller.showsPlaybackControls=false
controller.view.backgroundColor=UIColor.white
返回控制器
}
func updateUIViewController(uViewController:AVPlayServiceWController,上下文:UIViewControllerRepresentableContext){
}
}
您的代码似乎正常。您确定AVPlayer(…)路径正确吗
测试也不是零
.....
self.testing?.play()
print("-----> testing: \(testing.debugDescription)")
此时testing=nil吗?这里有一个示例,说明如何同时加载多个视频(我添加了一个自动播放功能),并删除所有其他视频,但不删除所选视频。 要删除视频,请点击要保存的视频 我不确定我是否解决了你最初的问题,但这可以给你下一步的方向 代码可以复制/粘贴,正如我在一个文件中声明的那样,以方便使用
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()))
这一举措的关键是拥有“视频数据”资源,您可以通过EnvironmentObject或其他一些共享数据示例来实现
我将下面的视频添加到项目中,包括它们以项目的成员身份为目标
是的…调试描述返回nil。我尝试在if(test1==test2){之前添加DispatchQueue.main.async{,但结果是一样的。谢谢!如果测试在那一点上为nil,那是因为AVPlayer(url:..)找不到具有给定url的资源。您需要首先修复此问题,然后代码的其余部分(可能)将工作。
@Published var videos = [VideoModel(id: 100, name: "video"),
VideoModel(id: 101, name: "wow"),
VideoModel(id: 102, name: "okay")]