Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

picture in picture support #73

Open
coucoseth opened this issue Jan 4, 2023 · 1 comment
Open

picture in picture support #73

coucoseth opened this issue Jan 4, 2023 · 1 comment

Comments

@coucoseth
Copy link

How can this be achieved?

Based off this comment , I was looking for this functionality but cannot seem to find how to do it

@ibcylon
Copy link

ibcylon commented Feb 10, 2023

I reference apple document - custom player picture in picture
warn: pip uses copied(?) playerLayer. so you need to pause original player's state

// MARK: PIP VC and Observer
  var pipController: AVPictureInPictureController!
  var pipPossibleObservation: NSKeyValueObservation?

// Call when playerLayer set e.g. viewWillAppear
func setupPicutreInPicture(_ playerLayer: AVPlayerLayer) {
    if AVPictureInPictureController.isPictureInPictureSupported() {
      pipController = AVPictureInPictureController(playerLayer: playerLayer)
      pipController.delegate = self
      
      pipPossibleObservation = pipController.observe(\AVPictureInPictureController.isPictureInPicturePossible, options: [.initial, .new]) { [weak self] controller, change in
        self?.isPIPEnabled = change.newValue ?? false
        print("isEnabled: \(change)")
      }
    }
  }

// Bind Notification Foreground and Background
func bind() {
    NotificationCenter.default.rx.notification(UIApplication.willResignActiveNotification)
          .take(until: self.rx.deallocated)
          .asDriverOnErrorJustComplete()
          .debug("toBackground")
          .drive(onNext: { [weak self] _ in
            if self?.isPIPEnabled == true {
              self?.pipController.startPictureInPicture()
            }
          }).disposed(by: bag)
    
    NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification)
      .take(until: self.rx.deallocated)
      .asDriverOnErrorJustComplete()
      .debug("toForeground")
      .drive(onNext: { [weak self] _ in
        self?.pipController.stopPictureInPicture()
      }).disposed(by: bag)
  }

// PIP Delegate
extension BasicFullscreenViewController: AVPictureInPictureControllerDelegate {
  func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
    print("before restore")
    completionHandler(true)
    print("after restore")
    self.transitioner.playerView?.resume()
  }
  
  func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
      // Hide the playback controls.
      // Show the placeholder artwork.
    self.transitioner.playerView?.pause(reason: .userInteraction)
    pictureInPictureController.playerLayer.player?.play()
    print("PIP will Start")
  }

  func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
      // Hide the placeholder artwork.
      // Show the playback controls.
    print("PIP did Stop") 
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants