Hacking macOS Sierra's PIP

One of the headline features in macOS Sierra is Picture in Picture. Unfortunately Apple decided to restrict this to Safari and iTunes which means the majority of users will never get to use it.
Digging into the Sierra GM PrivateFrameworks directory revealed a very helpfully named framework called PIP.framework
.
As with any framework it can be included in a project and used like any other. However Apple remove the headers from their private frameworks which stops us from using them freely. I ran the framework through Steve Nygard's excellent class-dump spitting out a number of helpful header files in the process.
Reading through the PIPViewController.h
file it gave me I noticed a PIPViewControllerDelegate
that the class-dump didn't uncover. Thank fully WebKit is open-source and Apple happened to include the header files for both the view controller and the delegate online and I stumbled across them on Github.
Using PIP.framework
I put together a little test project (at 1am last night so it's far from complete) to figure out how the framework works. Here's what I uncovered:
- The
PIPViewController
is displayed in aPIPPanel
that is ran via aPIPAgent
. This seems to be a global daemon with the bundle ID ofcom.apple.PIPAgent
. - The
PIPViewController
is a class that can present anotherNSViewController
as a Picture in Picture window. - ANY view controller — not just video — can be displayed but the play/pause button cannot be removed or hidden (at least not via any accessible method).
- The
PIPViewControllerDelegate
has methods to control play, pause, stop and close. - Replacement windows, views and rects control the segue between the original window and the Picture in Picture panel.
There are also a number of methods/properties that control the behaviour of the PIPPanel
.
aspectRatio
is aCGSize
that restricts resizing of the panel to a specific ratio. Useful to set the panel to 16:9 or 4:3.setPlaying()
sets the state of the play/pause button. Likewise the read-onlyplaying
property shows the current state of the panel.userCanResize
is there but doesn't seem to be respected by the panel. I'd guess this was added as a possibility but never used by Apple.
Test Project
Piecing it all together I managed to hack together a project that will present a video in the PIPPanel
. The video is in an AVPlayerView
and I'm then just presenting the containing view controller. The PIPViewControllerDelegate
methods are being used to control the player with play/pause.
Currently the view will not return to its original window when closing the PIPPanel
and I'm not entirely sure why. Maybe one day I'll spend the time to figure it out 😊
Download on Github
I'm still unsure why Apple chose to keep this private and not allow developers to use it. Even if it was restricted to the AVPlayerView
and functioned in the same way as the iOS PIP it would have been a great addition and I'm sure many developers would have jumped at the chance to add this to their media applications.
Maybe in 10.13? Or maybe we'll finally get UIKit (or perhaps that's just wishful thinking).