Silvering
Silvering

Reputation: 787

AVPlayer video doesn't resize after device rotation

I'm trying to make a AVPlayer video always full screen after device rotation. Here is my complete code. I do not understand why the video is not resized. Even if I use subclass like layerClass. After device rotation the videoView is cut, I do not see the video in full with. If someone has an idea. Thanks in advance.

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {

    var player: AVPlayer?
    var videoView: VideoContainerView!
    var playerLayer: AVPlayerLayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.videoView = VideoContainerView()
        self.videoView.frame = self.view.bounds
        self.videoView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        let path = Bundle.main.path(forResource: "GAVIDEO", ofType: "mp4")
        self.player = AVPlayer(url: NSURL(fileURLWithPath: path!) as URL)
        self.player?.isMuted = true

        self.playerLayer = AVPlayerLayer(player: self.player)
        self.playerLayer.frame = self.videoView.bounds
        self.playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

        self.videoView.layer.addSublayer(playerLayer)

        self.videoView.layer.masksToBounds = true

        self.view.addSubview(self.videoView)

        self.player?.play()
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

        self.videoView.frame = self.view.bounds
        self.playerLayer.frame = self.videoView.bounds

    }

}

class VideoContainerView: UIView {

    override class var layerClass: AnyClass {
        get {
            return AVPlayerLayer.self
        }
    }

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

}

Upvotes: 3

Views: 2753

Answers (2)

fivewood
fivewood

Reputation: 391

The following worked for me, where vc is a reference to the AVPlayerViewController that contains the AVPlayer view you would like to resize.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
   super.viewWillTransition(to: size, with: coordinator)
   coordinator.animate(alongsideTransition: nil) { (context) in
      if size.height <= vc.view.bounds.height || size.width <= vc.view.bounds.width {
         vc.videoGravity = .resizeAspect
      }
      else {
         vc.videoGravity = .resizeAspectFill
      }
   }
}

Upvotes: 0

mugx
mugx

Reputation: 10105

try to use the size from the viewWillTransition, doing so:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
   super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: { (context) in
    }) { (context) in
        self.videoView.frame.size = size
        self.playerLayer.frame.size = size
    }
}

Upvotes: 10

Related Questions