skip to Main Content

I added a video to my viewController() as a background and I want to loop it or in other words make it repeat itself forever.
Here is all the code:

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)
    let player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "background", ofType: "mp4")!))
    let layer = AVPlayerLayer(player: player)
    layer.frame = view.bounds
    layer.videoGravity = .resizeAspectFill
    layer.repeatCount = .greatestFiniteMagnitude
    layer.repeatDuration = .greatestFiniteMagnitude
    
    view.layer.addSublayer(layer)
    player.play()

}

}

When I run the app It only plays once and never repeats itself.
Any suggestions? Thanks.

3

Answers


  1. One solution is to observe AVPlayerItemDidPlayToEndTime and then simply restart the video.

    NotificationCenter.default.addObserver(
        forName: .AVPlayerItemDidPlayToEndTime, 
        object: player.currentItem, 
        queue: .main
    ) { [weak player] _ in
        player?.seek(to: .zero)
        player?.play()
    }
    

    Don’t forget to detach this observer whenever it’s no longer necessary.

    Login or Signup to reply.
  2. Use an AVPlayerLooper. Its name tells you that this is exactly what it’s for.

    https://developer.apple.com/documentation/avfoundation/avplayerlooper

    Login or Signup to reply.
  3. A couple comments.

    1. According to AVPlayerLayer doc: Set one or the other. Not both.

    If both repeatDuration and repeatCount are specified the behavior is
    undefined.

    1. In general, I’ve struggled with getting AVPlayerLayer to repeat mp4’s using the repeatCount or repeatDuration way. Instead I use AVQueuePlayer with a AVPlayerLooper. Credit to: https://developer.apple.com/forums/thread/658909
        import AVFoundation
        var playerQueue: AVQueuePlayer!
        var playerLayer: AVPlayerLayer!
        var playerLooper: AVPlayerLooper!
    
        private func configLooper(file: String, ext: String) {
            guard let videoURL = Bundle.main.url(forResource: file, withExtension: ext) else { return }
    
            playerQueue = AVQueuePlayer()
            playerLayer = AVPlayerLayer(player: playerQueue)
            let playerItem = AVPlayerItem(url: videoURL)
            playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem)
            playerLayer.frame = view.bounds
            playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
            view.layer.insertSublayer(playerLayer, below: someOtherView.layer)
            playerQueue.play()
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search