Picture-In-Picture not starting with Custom Player

Team,

I am trying to start PictureInPicture for my video from custom player as mentioned in the following link, but I am getting an error

Steps:

Created a player using AVPlayer.

Initiated AVPictureInPictureController with AVPlayerLayer

Added observer on PIP button enable status

When PIP button is tapped executed pipController.startPictureInPicture() statement. PIP is not getting started & getting following error

Project created in Xcode11 & currently using Xcode13.2

Error Domain=AVKitErrorDomain Code=-1001 "Failed to start picture in picture." UserInfo={NSLocalizedDescription=Failed to start picture in picture., NSLocalizedFailureReason=The UIScene for the content source has an activation state other than UISceneActivationStateForegroundActive, which is not allowed.}

I didn't get any solutions online, plz help me on this issue.

FYI: PIP button/mode is working if I use AVPlayerViewController(with default playerItem buttons) instead of AVPlayer & AVPictureInPictureController with custom controls

Thanks in advance.

Adopting Picture in Picture in a Custom Player

Did you have any luck?

Any solution for this? I'm facing the same problem in a SwiftUI app. If I log the activationState is UISceneActivationStateForegroundActive but still PiP is not starting.

Adding a second cause for -1001, since this thread is the top result for it and the failure reason in the original post doesn't cover the case in the July 2023 reply.

To be clear about what I can't help with: if your UIScene genuinely isn't ForegroundActive, the message in the first post is your answer and mine isn't. This is for the other case — the scene logs as UISceneActivationStateForegroundActive and startPictureInPicture() still fails.

AVKit will not start Picture in Picture for a player layer that isn't on screen. Foreground is not the same test. In my app the video lives on one tab and the control that starts PiP is on another, so the layer was alive, attached to the controller, and simply not being displayed. isPictureInPicturePossible stayed true the entire time. The call produced:

pip: calling startPictureInPicture() (active=false)
pip: FAILED to start -- AVKitErrorDomain -1001: Failed to start picture in picture.

The fix was to bring the layer on screen first and then ask, and to keep asking, because "is it laid out yet" isn't knowable up front — select the tab, then call startPictureInPicture() at 350/600/900/1200ms until isPictureInPictureActive comes back true. Verified on a physical iPhone 17. The same error turned up separately in a recovery path that built a fresh AVPlayerLayer while the app was backgrounded — a layer that has never been displayed behaves the same way, though that case is also consistent with the scene explanation so I'd not count it as independent evidence.

Two things worth doing whatever your cause turns out to be:

  1. Implement pictureInPictureController(_:failedToStartPictureInPictureWithError:) if you haven't. startPictureInPicture() returns Void and that delegate method is the only place AVKit hands back an NSError. I'd been reasoning from "the flag is true and nothing happened" for a while before I implemented it.

  2. Log ns.localizedFailureReason, not just ns.localizedDescription. localizedDescription is the useless half ("Failed to start picture in picture."); the failure reason is the field carrying the diagnosis in the original post above. I logged only the description and so I can't tell you what reason, if any, AVKit attached to mine.

One more thing that wasted my time and may be wasting someone's here: if you have a timeout around the start, check it isn't cutting off successes. Mine gave up at four seconds and the log showed a start landing in the same second as the giving-up, so users got told it had failed and then got a PiP window.

Longer write-up with the retry ladder and the isPictureInPicturePossible part: https://mcmizzle.com/blog/pip-wont-start-avkit-1001/

Picture-In-Picture not starting with Custom Player
 
 
Q