使用 NotificationCenter 在 AVPlayer 中交替播放视频文件

Using NotificationCenter to alternate videos files in AVPlayer

我正致力于在 Swift 中实现一个视频播放器,它将检测视频是否已停止播放,然后播放第二个。当第二个停止播放时,第一个视频应该会再次播放。

这是我设置播放器、资产和播放器项目的地方:

    //Create URLs
    let movieOneURL: URL = URL(fileURLWithPath: movieOnePath)
    let movieTwoURL: URL = URL(fileURLWithPath: movieTwoPath)

    //Create Assets
    let assetOne = AVAsset(url: movieOneURL)
    let assetTwo = AVAsset(url: movieTwoURL)

    //Create Player Items
    avPlayerItemOne = AVPlayerItem(asset: assetOne)
    avPlayerItemTwo = AVPlayerItem(asset: assetTwo)

    avplayer = AVPlayer(playerItem: avPlayerItemOne)
    let avPlayerLayer = AVPlayerLayer(player: avplayer)
    avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    avPlayerLayer.frame = UIScreen.main.bounds
    movieView.layer.addSublayer(avPlayerLayer)

    //Config player
    avplayer .seek(to: kCMTimeZero)
    avplayer.volume = 0.0

这里是我设置通知以检测播放器是否到达视频文件末尾的地方:

    NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avplayer.currentItem)

...调用此选择器:

    func playerItemDidReachEnd(_ notification: Notification) {
//        avplayer.seek(to: kCMTimeZero)
        changePlayerAsset()
//        avplayer.play()
    }

...然后将切换出资产:

func changePlayerAsset(){
    if avplayer.currentItem == avPlayerItemOne {
        avplayer.replaceCurrentItem(with: avPlayerItemTwo)
        avplayer.play()

    } else if avplayer.currentItem == avPlayerItemTwo {
        avplayer.replaceCurrentItem(with: avPlayerItemOne)
        avplayer.play()
    }
}

这在第一次运行时非常完美 - 当第一部电影播放完后,下一部电影就会开始播放。

我遇到的问题是我的通知观察者似乎只注册了一次;在第一个视频结束时...当第二个视频完全停止播放时,不会触发通知。

谁知道为什么会这样

您的通知处理程序未被第二项调用的原因是这一点,在您注册通知处理程序的末尾:object: avplayer.currentItem。当 那个项目 播放完毕时,处理程序被调用一次,但是当下一个项目播放完毕时,通知被发布到另一个 object - 另一个项目 - 而不是t 匹配您注册的内容,因此您的处理程序不会被调用。如果您在注册处理程序时将 object 更改为 nil,它将在 any 项目完成时被调用,这更接近您所追求的。

也就是说,这不是做你想做的事的好方法 - 手动换出项目可能会产生成本和每次播放时加载每个项目的延迟。您最好使用内置功能来按顺序播放视频并循环播放它们,即 AVQueuePlayer 和 AVPlayerLooper。 .

的答案中有一个如何同时使用两者的示例