When i start picture in picture from my custom video player, pip starts for a moment and then fails. I found the following error log in the debug console:
PGPictureInPictureProxy (0x12710a280) _updateAutoPIPSettingsAndNotifyRemoteObjectWithReason:] - Acquiring remote object proxy for connection <NSXPCConnection: 0x2825a32a0> connection to service with pid 63 named com.apple.pegasus failed with error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 63 named com.apple.pegasus was invalidated from this process." UserInfo={NSDebugDescription=The connection to service with pid 63 named com.apple.pegasus was invalidated from this process.}
Here's how i manage pip in code:-
CustomVideoPlayer's code to setup pip vc:
private func setupPIPIfEligible() {
if AVPictureInPictureController.isPictureInPictureSupported() {
// Create a new controller, passing the reference to the AVPlayerLayer.
pipVC = nil
if let layer = playerLayer {
pipVC = AVPictureInPictureController(playerLayer: layer)
pipVC?.delegate = self
}
}}
CustomVideoPlayer's code to toggle pip on press of a button:
private func togglePIP() {
if pipVC?.isPictureInPictureActive ?? false {
pipVC?.stopPictureInPicture()
} else {
pipVC?.startPictureInPicture()
}
}
The custom video player VC forwards the pip delegate methods to its delegate as:
extension CustomVideoPlayerViewController: AVPictureInPictureControllerDelegate {
func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
videoPlayerDelegate?.playerViewControllerWillStartPictureInPicture(self)
}
func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
videoPlayerDelegate?.playerViewControllerWillStopPictureInPicture(self)
}
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
videoPlayerDelegate?.playerViewController(self, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler: completionHandler)
}}
CustomVideoPlayerViewController's delegate handles the pip methods:
extension TabBarViewController: CustomVideoPlayerDelegate {
func playerViewController(_ playerViewController: UHVideoPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
shouldReleaseVideoPlayer = false
let currentviewController = navigationController?.visibleViewController
if currentviewController != playerViewController, currentviewController != nil {
if !(currentviewController?.isKind(of: CustomVideoPlayerViewController.self) ?? false) {
currentviewController?.present(playerViewController, animated: false) {
}
}
}
}
func playerViewControllerWillStartPictureInPicture(_ playerViewController: UHVideoPlayerViewController) {
playerViewController.dismiss(animated: true, completion: nil)
}
func playerViewControllerWillStopPictureInPicture(_ playerViewController: UHVideoPlayerViewController) {
if shouldReleaseVideoPlayer {
currentVideoPlayer = nil
}
shouldReleaseVideoPlayer = true
}}
var currentVideoPlayer: CustomVideoPlayerViewController? is a strong reference i keep for the video player.
I've already checked: no memory leaks/early release of video player reference.
What am i doing wrong here?