Search code examples
swiftavfoundationavplayeravplayerlayer

videoGravity resizeAspectFill doesn't work - Swift - AVFoundation


I'm displaying a video inside a UIView, everything works fine and Video Layer Bounds are the same of the UIView in which it is embedded.

The problem is that the video is not displayed correctly inside the view's bounds, I can only see a part of it (precisely the center).

So I searched and found out that there's a property of AVPlayerLayer which is supposed to solve this problem: .videoGravity

I implemented it with .resizeAspectFill but it doesn't change anything.

Here is the code:

 class PlaceHolderVideoView : UIView{

  var player = AVPlayer()
  var playerLayer = AVPlayerLayer()
  let containerImageView = UIImageView(image: #imageLiteral(resourceName: "VideoContainerView"), contentMode: .scaleAspectFit)



override init(frame: CGRect) {
super.init(frame: frame)

setUpUI()

setUpPlayer()



}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

fileprivate func setUpUI(){
clipsToBounds = true
translatesAutoresizingMaskIntoConstraints = false

addSubview(containerImageView)
containerImageView.clipsToBounds = true
containerImageView.fillSuperview()


}

fileprivate func setUpPlayer(){

let urlPathString = Bundle.main.path(forResource: "dance", ofType: "mp4")

if let videoURL = urlPathString{
    
    let url = URL(fileURLWithPath: videoURL)
    player = AVPlayer(url: url)
    playerLayer = AVPlayerLayer(player: player)
    playerLayer.cornerRadius = 20
    playerLayer.bounds = self.containerImageView.bounds
    print(self.containerImageView.bounds)
    playerLayer.videoGravity = .resizeAspectFill
    
    
    self.layer.masksToBounds = true
    self.layer.cornerRadius = 20
    self.layer.addSublayer(playerLayer)
    
    player.play()
    
    }
}
}

Solution

  • To solve this problem I needed to call layoutSublayers method like this:

    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        
        playerLayer.frame = self.bounds
    }
    

    this method can set the bounds of the playerLayer correctly