这应该是 AVQueuePlayer 对象的责任,而不是您的视图控制器本身,因此您应该使其可重用并通过扩展公开其他答案实现,并以类似的方式使用它 advanceToNextItem() :
extension AVQueuePlayer {
func advanceToPreviousItem(for currentItem: Int, with initialItems: [AVPlayerItem]) {
self.removeAllItems()
for i in currentItem..<initialItems.count {
let obj: AVPlayerItem? = initialItems[i]
if self.canInsert(obj!, after: nil) {
obj?.seek(to: kCMTimeZero, completionHandler: nil)
self.insert(obj!, after: nil)
}
}
}
}
用法(您只需存储索引和对初始队列播放器项目的引用):
self.queuePlayer.advanceToPreviousItem(for: self.currentIndex, with: self.playerItems)
维护索引的一种方法是观察每个视频项目的 AVPlayerItemDidPlayToEndTime 通知:
func addDidFinishObserver() {
queuePlayer.items().forEach { item in
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: item)
}
}
func removeDidFinishObserver() {
queuePlayer.items().forEach { item in
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
}
}
@objc func playerDidFinishPlaying(note: NSNotification) {
if queuePlayer.currentItem == queuePlayer.items().last {
print("last item finished")
} else {
print("item \(currentIndex) finished")
currentIndex += 1
}
}
这种观察对于其他用例(进度条、当前视频计时器重置......)也非常有用。