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

时间:2018-06-24 13:46:19

标签: ios swift avfoundation nsnotificationcenter

我的应用程序使用AVFoundation在多个vc中播放视频。例如,FirstController播放视频,然后用户可以按下SecondController也播放视频,然后按下ThirdController也播放视频...如果切换选项卡,则同样适用。 TabOne,TabTwo和TabThree上有一个视频屏幕。

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

问题是因为我有一个管理AVFoundation的类,Notification.Name.AVPlayerItemDidPlayToEndTime会在播放器结束播放时得到通知,无法区分一个vc上的一个视频与另一个vc中的另一个视频。例如,视频播放完毕后,我会显示一个replayButton。如果正在播放第一个选项卡中的视频,则当我切换到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)
Tabp中的

SecondController(子级):

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

2 个答案:

答案 0 :(得分:0)

我并不是说这是最好的答案,如果其他人可以提出更好的解决方案,请发表:) 根据我的理解,玩家无法区分观察者的数量。

(旁注,目前在我的手机上,因此对伪代码表示歉意)

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

viewWillDisappear中调用删除观察者函数

请记住,当您需要观察者时,无论您是要看到视图还是在初始化下一个视频时,都要重新初始化它们。

答案 1 :(得分:0)

我有the answer from here

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

像这样:

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