简体   繁体   中英

AVPlayer Aspect Ratio

Ok so in my iOS app there is a screen with an AVPlayerViewController that takes care of playing videos. When this video is played it fills the entire screen however on some videos they video seems stretched as if it is being forced to fit. Is there any way to make the video fit the entire screen without losing the aspect ratio.

The code below is what I use to lay out the AVPlayerController. I figured some error here is the cause of this flaw in aspect ratio.

/

// Setup the view for stories
    private func setupViews() {
        view.backgroundColor = .clear
        // Setup the blur view for loading
        blurView = UIVisualEffectView(frame: view.frame)
        blurView.effect = UIBlurEffect(style: .regular)

        self.view.addSubview(blurView)

        // Indicator for loading
        let indicatorFrame = CGRect(x: view.center.x - 20, y: view.center.y - 20, width: 40, height: 40)
        indicator = UIActivityIndicatorView(frame: indicatorFrame)
        indicator.hidesWhenStopped = true
        indicator.activityIndicatorViewStyle = .whiteLarge

        blurView.contentView.addSubview(indicator)

        // Setup the Progress bar
//        spb = SegmentedProgressBar(numberOfSegments: allStories.count)
////        spb.frame = CGRect(x: 0, y: 1, width: self.view.frame.width, height: 9)
//        self.view.addSubview(spb)
//        spb.snp.makeConstraints { (make) in
//            make.left.right.equalTo(view.safeAreaLayoutGuide)
//            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(1)
//            make.height.equalTo(9)
//        }
//
//        spb.delegate = self

        // Player Controller
        playerController = AVPlayerViewController()
        playerController.showsPlaybackControls = false

        self.addChildViewController(playerController)

        // Image view for the story
        imageView = UIImageView(frame: self.view.frame)

        infoView = UIView(frame: self.view.frame)
        infoView.backgroundColor = UIColor.clear

        // The image view for the user of the current story
        infoImageView = UIImageView()
        self.view.addSubview(imageView)
        self.view.addSubview(playerController.view)
//        self.view.bringSubview(toFront: spb)

        self.view.addSubview(infoView)

        self.infoView.addSubview(infoImageView)

        infoImageView.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(2)
            make.left.equalTo(view.safeAreaLayoutGuide.snp.left).offset(10)
            make.height.width.equalTo(30)
        }
        infoImageView.layer.cornerRadius = 15
        infoImageView.layer.masksToBounds = true

        // The name for the user of the current story
        infoNameLabel = UILabel()
        infoNameLabel.backgroundColor = UIColor.black.withAlphaComponent(0.1)
        infoNameLabel.textColor = UIColor.white
        infoNameLabel.font = UIFont.boldSystemFont(ofSize: 18)
        infoNameLabel.adjustsFontSizeToFitWidth = true

        self.infoView.addSubview(infoNameLabel)

        infoNameLabel.snp.makeConstraints { (make) in
            make.left.equalTo(infoImageView.snp.right).offset(5)
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(2)
            make.height.equalTo(30)
            make.width.equalTo(80)
        }

        // Time label for long ago the story was posted
        infoTimeLabel = UILabel()
        infoTimeLabel.backgroundColor = UIColor.black.withAlphaComponent(0.1)
        infoTimeLabel.textColor = UIColor.white

        self.infoView.addSubview(infoTimeLabel)

        infoTimeLabel.snp.makeConstraints { (make) in
            make.left.equalTo(infoNameLabel.snp.right).offset(5)
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(2)
            make.height.equalTo(30)
            make.width.equalTo(50)
        }

        infoView.isUserInteractionEnabled = true
        infoView.addGestureRecognizer(tapInfoView)
        infoView.addGestureRecognizer(swipeInfoView)

        infoTimeLabel.layer.cornerRadius = 10
        infoTimeLabel.layer.masksToBounds = true
        infoTimeLabel.textAlignment = .center

        infoNameLabel.layer.cornerRadius = 10
        infoNameLabel.layer.masksToBounds = true
        infoNameLabel.textAlignment = .center

        playerController.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
        playerController.view.frame = view.frame

//        spb.durations = durations
    }

Any help is greatly appreciated

I am not sure about it but use this :

playerController.view.frame = view.bounds

Instead of this:

playerController.view.frame = view.frame

The AVLayerVideoGravity.resizeAspectFill.rawValue should do what is says and I never had a problem with it. However, I use the bounds instead of the frame and I remember getting problem when using the frame.

You also have AVLayerVideoGravity.resizeAspect.rawValue that will fit the video instead of filling it.

You can also try setting the frame before the video gravity.

to keep the video aspect ratio in the defined view frame use AVLayerVideoGravity.resizeAspect . For the current case replace playerController.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue to playerController.videoGravity = AVLayerVideoGravity.resizeAspect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM