Swift iOS - 如何管理 Notification.Name.AVPlayerItemDidPlayToEndTime 多个 类 中的不同视频

Swift iOS -How to manage Notification.Name.AVPlayerItemDidPlayToEndTime for different videos in multiple classes

我的应用使用 AVFoundation 在 vc 秒内播放视频。例如,FirstController 播放视频,然后用户可以推动也播放视频的 SecondController,然后他们可以推动也播放视频的 ThirdController ... 如果他们切换选项卡,同样的事情也适用。 TabOne、TabTwo 和 TabThree 上有一个视频屏幕。

我没有在每个 class 中设置与 AVFoundation 关联的所有 playLayer 代码,而是创建了一个包含 AVPlayerViewController() 的 class 并将 class 添加到每个 vc 使用 addChildViewController().

问题是因为我有一个 class 来管理 AVFoundation Notification.Name.AVPlayerItemDidPlayToEndTime 在播放器完成播放时收到通知无法区分一个 vc 上的一个视频与另一个视频在不同的vc。例如,在视频播放完毕后,我会显示一个重播按钮。如果第一个选项卡中的视频正在播放,当我切换到 TabTwo 时我会暂停该视频,在 TabTwo 上的视频结束并且出现 replayButton 之后,如果我切换回 TabOne,replayButton 也会出现在 TabOne 的屏幕上(它应该仍然显示暂停按钮)。

问题是即使我有不同的 AVFoundationManager 实例,所有实例都访问通知触发时触发的那个 showReplayButton() function

我该如何解决这个问题?

我知道我可以检查 AVFoundationManager 的 parent 以找出哪个父级正在管理它并在 showReplayButton() 函数中使用它,但我不知道要检查哪个 运行就可以了。

AVFoundationManager:

class AVFoundationManager: UIViewController {

    ....

    override func viewDidLoad() {
        super.viewDidLoad()
        configureAVPlayerController()
    }

    func configureAVPlayerController() {

        let avPlayerVC = AVPlayerViewController()
        avPlayerVC.player = player
        avPlayerVC.view.frame = view.bounds
        avPlayerVC.showsPlaybackControls = false
        avPlayerVC.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
        addChildViewController(avPlayerVC)
        view.addSubview(avPlayerVC.view)
        avPlayerVC.didMove(toParentViewController: self)

        player?.replaceCurrentItem(with: playerItem!)
        player?.play()

        NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)

        playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
                            options: [.old, .new],
                            context: &itemContext)
    }

    @obj func showReplayButton(){

        // if self.parent ... run a bool on the parent and enclose these two in the paranthesis?
        pausePlayButton.isHidden = true
        replayButton.isHidden = false
    }
}

TabOneClass:

let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)

TabTwoClass:

let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)

TabThree 中的 FirstController(根):

let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)

TabThree 中的第二个控制器(子):

let avFoundationManager = AVFoundationManager()
addChildViewController(avFoundationManager)
avFoundationManager.didMove(toParentViewController: self)

我并不是说这是最好的答案,如果有人能想出更好的解决方案,请 post :) 据我了解,玩家无法区分观察者的数量。

(旁注,目前在我的 phone 上,对伪代码深表歉意)

class PlayerViewController {
// other code and functions
    func removeObservers() {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

viewWillDisappear调用remove observers函数

请记住在需要时重新初始化观察者,无论是在显示视图时,还是在初始化下一个视频时。

我得到了the answer from here

在通知中,不要将最后一个参数 object 设置为 nil,而是将其设置为 player.currentItem:

像这样:

NotificationCenter.default.addObserver(self, selector: #selector(showReplayButton),
                                     name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                     object: player?.currentItem)