iOS 9 had brought some multitasking enhancements mainly for iPads. One of which is Picture in Picture (PIP) mode for video playback. In short, PIP allows user to leave the application and continue to watch a video in a floating resizable window. Also, the user can continue to use its iPad normally, without interrupting a playback. Overall, an enhanced multitasking!
An iOS application can use either AVPlayerViewController or AVPlayerLayer to present a video content. The difference is, AVPlayerViewController provides a standard iOS player interface with the system provided playback controls, as shown in the image below, whereas AVPlayerLayer just presents a video and let application provide a custom interface for the playback controls.
Configuring your application for PIP support
Configuring PIP in your application is a simple process. Make sure –
- Build Settings->Architectures->Base SDK is set to either Latest iOS or >iOS 9.0.
- Capabilities->Background Modes->Audio, Airplay, and Picture in Picture is selected.
- Add UIBackgroundModes key in your Info.plist and set its value to audio. This lets iOS know that your application wants to use audio output even in the background mode. Additionally, your application needs to set a AVAudioSessionCategoryPlayback category with an appropriate mode as follows –
Here, we are accessing the shared AVAudioSession instance and setting a category named AVAudioSessionCategoryPlayback with the AVAudioSessionModeMoviePlayback mode, considering our application will play movies in the PIP mode. This helps iOS to make voice signals optimized for your playback. Once the category is set, we need to activate the audio session. Apple suggests to defer from activating until your application begins playback.
PIP should always be user controlled and hence your application should not invoke PIP without user’s intention, especially when user is using the application. Apple recommends providing an option for your player to invoke PIP. If you’re using AVPlayerViewController to present a video playback, the standard iOS player interface automatically provides a button to invoke PIP. Whereas, if you have a custom interface for video controls, it’s your responsibility to provide an invocation point for PIP.
As an add-on, you can use native set of PIP images on the button so that user easily recognizes the PIP invocation point. AVPictureInPictureViewController provides a class level interface to get the native images – pictureInPictureButtonStartImage(compatibleWith:) and pictureInPictureButtonStopImage(compatibleWith:)
AVPlayerViewController automatically manages PIP, provided your app is configured as mentioned above. Though, to work with AVPlayerLayer, AVKit provides AVPictureInPictureViewController class to help manage the video in PIP mode. Let’s see how you can make use of AVPictureInPictureViewController to support PIP in your application –
I hope the code and comments are self-explanatory. I would emphasize to make note of Step #4 and #6, as they are the necessary checks in the PIP workflow. Once all the verifications are done, startPictureInPicture() takes care of presenting a video in the PIP mode. Similarly, stopPictureInPicture() stops and exits out of the PIP mode.
Finally, implement the AVPictureInPictureControllerDelegate to manage the states of the PIP video playback.
Application continue to run in a background mode when PIP is in progress. Consuming too many resources in background mode may cause your application to terminate. Hence, make sure to use minimal resources for seamless video playback.
I hope you manage to play video in PIP mode after this tutorial. Thank you for reading.