Playback buttons do not appear in an AVPlayer after adding a layer - iOS 16
Asked Answered
J

2

2

I am using an AVPlayer to present a video. The app has only one .mp4 but for a different use case, the same video needs to get flipped.

The buttons are there and completely functional, you can press the play and the 15 seconds forward/backward buttons but they don't appear on the screen (4th video in the attached image)

The issue seems to be that the flip layer I am adding overlays the new layout buttons.

The potential fix I was thinking of is to flip the video before adding it to the player.

Do you know if there is a straightforward solution for this? Maybe there is an easy way to keep the iOS 15 playback button layout?

enter image description here

The code the app is using to flip the video is as follows:

  @IBAction func pressButton(_ sender: Any) {
    guard let path = Bundle.main.path(forResource: "sample-5s", ofType:"mp4") else {
       return
    }
    let avPlayer = AVPlayer(url: URL(fileURLWithPath: path))
    let avPlayerController = AVPlayerViewController()
    
    present(avPlayerController, animated: true, completion: {
   
      let flippedLayer = AVPlayerLayer(player: avPlayer)
      let transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
      flippedLayer.frame = (avPlayerController as UIViewController).view.frame
      flippedLayer.setAffineTransform(transform)
      (avPlayerController as UIViewController).view.layer.addSublayer(flippedLayer)
     
      avPlayerController.player = avPlayer
      avPlayer.play()
    })
  }
Jehoash answered 1/7, 2022 at 14:15 Comment(3)
Did you get to the bottom of this at all? I'm having the same issue, and can't seem to display the player controls by default.Nestor
@ChrisHefferman no, we could not fix it. We tried to push the layer to the bottom but did not work, also tried different things more, and did not work. We opened a ticket in Apple too and we did not get any response (attached). We ended up creating separate videos outside and flipped them with QuickTime. developer.apple.com/forums/thread/709485Jehoash
Thanks for the reply, I never got to a solution either and eventually came to the decision to display a button over the top of the UI if the cell was a video that disappears and plays the video if tapped. Shame that this is now not showing by default - I found this on one of the developer forums as well that I'm keeping an eye on: developer.apple.com/forums/thread/711360Nestor
D
2

Found a solution. It's all about adding AVPlayerViewController inside the parent view controller. Assume that you have a AVPlayerViewController inside a viewController. So first in viewDidLoad make sure to add it as a child.

var playerController = AVPlayerViewController()
lazy var playerBaseView: UIView = {
        let view = UIView()
        view.backgroundColor = .clear
        return view
}()

override func viewDidLoad() {
    // Make your player parent view constraints or do it on Storyboard
    playerBaseView.snp.makeConstraints { (make) in
       make.edges.equalTo(view.safeAreaLayoutGuide.snp.edges)
    }

   addChild(playerController) // Add as a child
   playerBaseView.addSubview(playerController.view)

   // Make your playerController view constraints or do it on Storyboard
   playerController.view.snp.makeConstraints { (make) in
       make.edges.equalToSuperview()
   }
}
Derek answered 17/9, 2022 at 22:21 Comment(4)
Thanks for sharing, our stack doesn't allow to add it this way without a major overhaul, so we've decided to stick a button over the top, but I saw something similar to this suggested on developer forums as well, so it's definitely dependant on how your views and subviews are laid out. ThanksNestor
Thank you. Just to clarify for others: the important line here is addChild(playerController) (or [self addChildViewController:playerController] in ObjC).Stanzel
However I found that you still need to tap the player view once in order for the controls to appear. Is there any way to make them appear immediately?Stanzel
I didn't check the player controller one. I will check that tooDerek
B
0

For Swift UI

CustomVideoPlayer()
   .compositingGroup()




struct CustomVideoPlayer : UIViewControllerRepresentable {

 var player: AVPlayer

 func makeUIViewController(context: UIViewControllerRepresentableContext<CustomVideoPlayer>) -> AVPlayerViewController {
     
     let controller = AVPlayerViewController()
     controller.player = player
     return controller

 }

 func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<CustomVideoPlayer>) {
 }

Fixed problem for me in IOS 16 Swift UI

Behnken answered 2/11, 2022 at 15:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.