AVKit.AVPlayerViewController - controls not visibl

2019-09-20 02:03发布

问题:

I have a videoPlayer with controls. These are not visible with iOS11 + no problem up to iOS10

This is a demo with the iPhone8 simulator

iPhone 8 Demo

This is a demo with the iPhoneX simulator. The controls aren't showing at the bottom of the player

iPhone X Demo

I believe this has a lot to do with the new safe area. We are using contentOffset (below) to offset from the top. Changing the value makes no difference. No controls visible

This is the code below I am using to configure the player :

let statusBarHeight: CGFloat = 20
let contentOffset: CGFloat = 50

func setupPlayerView() {
        containerView.addSubview(moviePlayerController.view)
        moviePlayerController.videoGravity = AVLayerVideoGravity(rawValue: AVLayerVideoGravity.resizeAspect.rawValue)
        moviePlayerController.view.sizeToFit()
        moviePlayerController.showsPlaybackControls = true

        moviePlayerController.view.translatesAutoresizingMaskIntoConstraints = false

        if #available(iOS 11.0, *) {
            moviePlayerController.view.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: contentOffset).isActive = true
        } else {
            moviePlayerController.view.topAnchor.constraint(equalTo: topAnchor, constant: statusBarHeight + contentOffset).isActive = true
        }
        NSLayoutConstraint.activate([
            moviePlayerController.view.bottomAnchor.constraint(equalTo: bottomAnchor),
            moviePlayerController.view.leftAnchor.constraint(equalTo: leftAnchor),
            moviePlayerController.view.rightAnchor.constraint(equalTo: rightAnchor)
        ])
    }

showsPlaybackControls is set to True, this is the default though

Has anyone else ever encountered this issue ?

回答1:

Your code was always wrong. Even on iOS 10 the controls are way down at the bottom of the screen, far from the movie. The correct approach is to get the video track’s naturalSize and use it to configure the aspect ratio of the player view, so that the player view is the size of the movie. Now the controls will appear at the bottom of the movie, not the bottom of the screen.

Another problem is that what you're doing is totally illegal. You cannot just make an AVPlayerViewController, grab the view controller's view and stuff that view into the interface with addSubview. There is a rigorous dance that you are required to do in order to make the view controller a child view controller of self (the current view controller — and you are not doing the dance. Here is a working example:

    let url = // whatever
    let player = AVPlayer(url:url)
    let av = AVPlayerViewController()
    av.player = player
    av.view.frame = // whatever
    self.addChild(av) // <—- LOOK!
    self.view.addSubview(av.view)
    av.didMove(toParent:self) // <— LOOK!

(Note that this is Swift 4.2.)