Search code examples
iosswiftavplayeravplayerlayer

Adding a looped mp4 Background to iOS app signup


I want to end up applying this code to make my app look a little nicer when users are logging into their social media accounts. I've tried the following code already but my app seems to crash as soon as the mp4 ends.

import UIKit

import AVFoundation

class ViewController: UIViewController {

  var avPlayer: AVPlayer!
  var avPlayerLayer: AVPlayerLayer!
  var paused: Bool = false

  override func viewDidLoad() {
    super.viewDidLoad()
    let theURL = Bundle.main.url(forResource: "Yeet", withExtension: "mp4")

    avPlayer = AVPlayer(url: theURL!)
    avPlayerLayer = AVPlayerLayer(player: avPlayer)
    avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
    avPlayer.volume = 0
    avPlayer.actionAtItemEnd = AVPlayer.ActionAtItemEnd.none

    avPlayerLayer.frame = view.layer.bounds
    view.backgroundColor = UIColor.clear;
    view.layer.insertSublayer(avPlayerLayer, at: 0)

    NotificationCenter.default.addObserver(self, selector: Selector(("playerItemDidReachEnd:")), name:       NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem)
  }

    @objc func playerItemDidReachEnd(notification: NSNotification) {
    let p: AVPlayerItem = notification.object as! AVPlayerItem
      p.seek(to: CMTime.zero)
  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    avPlayer.play()
    paused = false
  }

  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    avPlayer.pause()
    paused = true
  }
  override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
  }

}

Solution

  • Have you tried using AVPlayerLooper?

    Looks like @iwasrobbed has a solution for iOS 10+ devices. Here's the example code:

    private var looper: AVPlayerLooper?
    
    ...
    
    let queuePlayer = AVQueuePlayer(playerItem: item)
    looper = AVPlayerLooper(player: queuePlayer, templateItem: item)
    videoPlayerLayer.player = queuePlayer
    

    To disable the loop after leaving the view, add this piece of code in the end:

    looper?.disableLooping()