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
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.
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:
PIPViewControlleris displayed in a
PIPPanelthat is ran via a
PIPAgent. This seems to be a global daemon with the bundle ID of
PIPViewControlleris a class that can present another
NSViewControlleras 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).
PIPViewControllerDelegatehas 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
CGSizethat 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-only
playingproperty shows the current state of the panel.
userCanResizeis 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.
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).