swiftui取消分配并重新分配带有许多视频的AVplayer

问题描述 投票:0回答:2

我同时有很多视频。通过一个Int var(var test1和var test2),我希望能够仅添加某个视频并删除所有其他视频,以免出现内存问题

一旦加载视图,就会为每个播放器分配值“ nil”,并且当test1 == test 2时,它应该将视频加载到某个播放器中,而将视频加载到另一个播放器中” nil”

问题是尽管绑定中是测试变量(结构VideoPlayer @Binding var测试),但它不会更新始终保持为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>) {


    }
}
swift uikit swiftui avplayer
2个回答
1
投票
这里有一个示例,如何同时加载多个视频(我添加了自动播放功能),并删除所有其他视频,但不删除所选的视频。要删除视频,请点击您要保存的视频

而且我不确定我是否能解决您的第一个问题,但这可以为您提供下一步寻找的线索

可以复制/粘贴代码,因为我在一个文件中声明了代码,以方便使用stackoverflow

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或其他一些共享数据示例来实现它

以下视频我添加到了项目中,包括它们成为项目的目标成员

enter image description here

@Published var videos = [VideoModel(id: 100, name: "video"), VideoModel(id: 101, name: "wow"), VideoModel(id: 102, name: "okay")]


0
投票
您的代码似乎还可以。您确定AVPlayer(...)路径正确吗测试不是零。放

..... self.testing?.play() print("-----> testing: \(testing.debugDescription)")

当时的测试是否等于零? 
© www.soinside.com 2019 - 2024. All rights reserved.