3

I have a controller with a AVPlayer in collection view cell. When orientation changes to Landscape, the player should get FullScreen.

For this I am presenting an AVPlayerController with same instance of player in Collection View Cell. The video works fine when it is rotated in playing mode. However, when video is paused and I change orientation to Landscape, the frame at current moment changes i.e video moves forward.

I have tested, even when the orientation is kept same, when player is passed, the duration skips few seconds.

Here is the code:

In ViewController where cell is present.

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

    guard let videoCell = contentGalleryController.curatorVideoCell else {return}
    if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
        let player = videoCell.getVideoPlayer
        playerViewController = (storyboard!.instantiateViewController(withIdentifier: "FullScreenPlayerController") as! FullScreenPlayerController)
        playerViewController?.player = player
        playerViewController?.didPlayedToEnd = videoCell.isVideoFinishedPlaying ?? false
        playerViewController?.isMuteTurnedOn = player.isMuted
        let wasVideoPlaying: Bool = player.isPlaying
        present(playerViewController!, animated: false){
            if wasVideoPlaying {
                player.play()
            }
        }
    }
    else {
        videoCell._setMuteIcon()
        videoCell._setPlayPauseIcon()
        playerViewController?.dismiss(animated: false, completion: nil)
    }
}

In FullscreenPlayer View Controller

override func viewDidLoad() {
        super.viewDidLoad()
        setPlayPauseIcon()
        setMuteIcon()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(customControlViewTapped))
        customView.addGestureRecognizer(tapGesture)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        if !view.subviews.contains(customView) {
            customView.frame = view.bounds
            view.addSubview(customView)
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidPlayToEnd), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        NotificationCenter.default.removeObserver(self)
    }

I am doing nothing else in controller.

Screenshots: Portrait Video Paused In Portrait

LANDSCAPE When rotated to landscape

When orientation changes, video moves forward even on pause state.

Thanks for help in advance.

udbhateja
  • 948
  • 6
  • 21

1 Answers1

3

You should try capturing the currentTime and then use the seek(to time: CMTime) method on the player to start at that exact time. I am not sure exactly why this is happening to you, but I think this would get you the result you are looking for.

jacob bullock
  • 651
  • 4
  • 14
  • I've tried seeking but I am unable to seek to exact pos. because the difference is in milliseconds. – udbhateja Nov 28 '18 at 13:11
  • are you familiar with how CMTime works? You can provide an exact time with it. https://developer.apple.com/documentation/coremedia/cmtime-u58 – jacob bullock Nov 29 '18 at 01:43
  • 2
    if u get player.currentTime when orientation changes, you can seek that time. for precise seek use seek(to:toleranceBefore:toleranceAfter:) with kCMTimeZero for both tolerances instead. – ugur Dec 02 '18 at 23:50
  • I am using tolerance too, but there is slight displacement of frames when moved from portrait to landscape. – udbhateja Dec 06 '18 at 16:18
  • @bhatejaud can you provide updated code where you are capturing the time and then using it to play? – jacob bullock Dec 08 '18 at 03:34