Skip to content

Instantly share code, notes, and snippets.

@lanserxt
Last active October 25, 2023 16:18
Show Gist options
  • Save lanserxt/33fd8c479185cba181497315299e0e31 to your computer and use it in GitHub Desktop.
Save lanserxt/33fd8c479185cba181497315299e0e31 to your computer and use it in GitHub Desktop.
Loop playback with AVQueuePlayer and AVPlayerLooper
final class LoopedVideoPlayerView: UIView {
fileprivate var videoURL: URL?
fileprivate var queuePlayer: AVQueuePlayer?
fileprivate var playerLayer: AVPlayerLayer?
fileprivate var playbackLooper: AVPlayerLooper?
func prepareVideo(_ videoURL: URL) {
let playerItem = AVPlayerItem(url: videoURL)
self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
guard let playerLayer = self.playerLayer else {return}
guard let queuePlayer = self.queuePlayer else {return}
self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
playerLayer.videoGravity = .resizeAspectFill
playerLayer.frame = self.frame
self.layer.addSublayer(playerLayer)
}
func play() {
self.queuePlayer?.play()
}
func pause() {
self.queuePlayer?.pause()
}
func stop() {
self.queuePlayer?.pause()
self.queuePlayer?.seek(to: CMTime.init(seconds: 0, preferredTimescale: 1))
}
func unload() {
self.playerLayer?.removeFromSuperlayer()
self.playerLayer = nil
self.queuePlayer = nil
self.playbackLooper = nil
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
self.playerLayer?.frame = self.bounds
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment