如何在队列玩家的currentItem上设置观察者?

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

我正在尝试为

currentItem
AVQueueplayer
设置观察者,但收到一个名为
EXC_BAD_ACCESS
的错误。有人能帮助我吗?感谢您的关注。我期待着您的回复。这是我的代码:

struct VideoPlayerS : UIViewControllerRepresentable {
    var work : WorkoutDeS
    @Binding var player : AVQueuePlayer
    var playerLayer = AVPlayerLayer()
    
    public func makeUIViewController(context: Context) -> AVPlayerViewController {
        let items = [
            AVPlayerItem(url: URL(fileURLWithPath: String(work.url1))),
            AVPlayerItem(url: URL(fileURLWithPath: String(work.url2)))
        ]
        
        let player = AVQueuePlayer(items: items)
        let controller = AVPlayerViewController()
        
        DispatchQueue.main.async {
            self.player = player
        }
        
        controller.player = player
        controller.videoGravity = .resizeAspectFill
        
        player.actionAtItemEnd = .none
        
        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { _ in
            self.player.seek(to: CMTime.zero)
            self.player.play()
        }
        
        player.play()
        
        player.currentItem?.addObserver(AVQueuePlayer(), forKeyPath: "status", options: NSKeyValueObservingOptions(), context: nil)
    }
        
    func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if keyPath == "status" {
                print("Hello")
                
                player.currentItem?.removeObserver(AVQueuePlayer(), forKeyPath: "status")
            }
        }
        
        return controller
    }
    
    func rewindVideo(notification: Notification) {
        playerLayer.player?.seek(to: .zero)
    }
    
    public func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayerS>) {
        
    }

}
swift swiftui avplayer avkit avqueueplayer
1个回答
0
投票

Representable,即struct,不能用于KVO观察者。您可以使用

Coordinator
作为观察者。

这里是修改后的代码和可能的方法:

struct VideoPlayerS : UIViewControllerRepresentable {

    var work : WorkoutDeS
    @Binding var player : AVQueuePlayer
    var playerLayer = AVPlayerLayer()

    public func makeUIViewController(context: Context) -> AVPlayerViewController {
        let items = [

            AVPlayerItem(url: URL(fileURLWithPath: String(work.url1))),
            AVPlayerItem(url: URL(fileURLWithPath: String(work.url2)))

        ]
        let player = AVQueuePlayer(items: items)
        let controller = AVPlayerViewController()

        DispatchQueue.main.async {
            self.player = player
        }
        controller.player = player
        controller.videoGravity = .resizeAspectFill

        player.actionAtItemEnd = .none
        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { _ in
            self.player.seek(to: CMTime.zero)
            self.player.play()
        }

        player.currentItem?.addObserver(context.coordinator, forKeyPath: "status", options: [.new], context: nil)

        player.play()
        return controller
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(owner: self)
    }

    class Coordinator: NSObject {
        var owner : VideoPlayerS

        init(owner: VideoPlayerS) {
            self.owner = owner
        }

        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            guard let item = object as? AVPlayerItem else { return }

            if keyPath == "status" {
                print("Hello")
                item.removeObserver(self, forKeyPath: "status")
            }
        }
    }

    func rewindVideo(notification: Notification) {
        playerLayer.player?.seek(to: .zero)
    }

    public func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayerS>) {

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.