我正在努力在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()
}
}
第一次完成播放时,第一部电影完成后,下一部电影将开始播放 .
我遇到的问题是我的通知观察员似乎只注册了一次;在第一个视频结束时...当第二个视频停止播放时,不会触发通知 .
任何人都知道为什么会这样
1 回答
没有为第二个项调用通知处理程序的原因是这一位,在注册通知处理程序的末尾:
object: avplayer.currentItem
. 当 that item 完成播放时,处理程序会被调用一次,但是当下一个项目结束时,通知会发布一个不同的object
- 其他项目 - 与您注册的项目不匹配,因此您的处理程序无法获取调用 . 如果在注册处理程序时将object
更改为nil
,则会在 any 项结束时调用它,这将更接近您所追求的内容 .也就是说,这不是一个很好的方法来做你想要的 - 手动交换项目可能会导致每次项目即将播放时加载每个项目的成本和延迟 . 使用内置功能按顺序播放视频并循环播放它们会更好,即AVQueuePlayer和AVPlayerLooper . 有一个如何在this question的答案中使用两者的例子 .