How do you loop AVPlayer in Swift?
Solution 1:
Swift 5 (iOS 10.0+)
var playerLooper: AVPlayerLooper! // should be defined in class
var queuePlayer: AVQueuePlayer!
...
let asset: AVAsset = ... // AVAsset with its 'duration' property value loaded
let playerItem = AVPlayerItem(asset: asset)
self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
// Create a new player looper with the queue player and template item
self.playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)
< iOS 10.0
All below works in any iOS version. But, for < iOS 10.0 it's the only solution.
Swift 4
var player: AVPlayer!
...
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { [weak self] _ in
self?.player?.seek(to: CMTime.zero)
self?.player?.play()
}
Swift 3
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { [weak self] _ in
self?.player?.seek(to: kCMTimeZero)
self?.player?.play()
}
Swift 2
After AVPlayerItem is configured and player is created:
var player: AVPlayer!
...
// Invoke after player is created and AVPlayerItem is specified
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: self.player.currentItem)
...
func playerItemDidReachEnd(notification: NSNotification) {
self.player.seekToTime(kCMTimeZero)
self.player.play()
}
Don't forget to import AVFoundation
Solution 2:
Starting from iOS 10, there's no need to use notifications to loop a video, simply use a AVPlayerLooper, just like this:
let asset = AVAsset(url: videoURL)
let item = AVPlayerItem(asset: asset)
let player = AVQueuePlayer(playerItem: item)
videoLooper = AVPlayerLooper(player: player, templateItem: item)
make sure this looper is created outside of a function scope, in case it stops when function returns.
Solution 3:
@Christopher Pickslay's answer updated for Swift 4:
func loopVideo(videoPlayer: AVPlayer) {
NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in
videoPlayer.seek(to: CMTime.zero)
videoPlayer.play()
}
}
But, as I mentioned below his answer, be sure to specify the object as the AVPlayer's player item if you have multiple players.