Picture-in-Picture (PiP) is a video playback mode that displays content in a floating window on top of other applications, allowing users to continue watching while switching between apps or minimizing the current one. The PiP window automatically positions itself in a corner of the screen and can be moved by the user. According to Apple AVPictureInPictureController documentation (2026), PiP mode is supported on iOS starting from version 14 and on Android starting from version 8.0.
Key Takeaways
Picture-in-Picture (PiP) is a video display mode that shows content in a small floating window that stays on top of all other windows and applications. Users can move the PiP window around the screen, resize it (on some platforms), and continue watching content while working in other applications.
The PiP concept originated from television: back in the 1990s, TV sets allowed showing a second channel in a corner of the screen. On mobile devices, PiP first appeared on iPad in iOS 9 (2015) for Safari videos, while full system-level PiP for apps became available in iOS 14 (2020). Android support for PiP came earlier — in version 8.0 Oreo (2017), but only for video, and starting with Android 12 for all content types.
PiP differs from background playback in that the video continues to display on screen rather than playing only in the audio stream. Background audio playback is available on both platforms, but PiP gives users visual control over content: they can see frames, pause, rewind, or close the window. This is especially important for video tutorials, streams, and video calls where visual content matters as much as audio.
Architecturally, PiP is implemented through a system window manager that creates a separate window with lower display priority. The app delegates video output to a system service that continues rendering video even after the app moves to the background or is minimized.
The process begins when the user minimizes the app with active video or presses the PiP button (on iOS), or the system automatically transitions the Activity into PiP mode (on Android). The system window manager captures the video stream and creates a floating window with fixed proportions. Window size depends on the original video aspect ratio and platform constraints: on iOS, the PiP window takes roughly 1/6–1/4 of screen width; on Android, no less than 108 dp in width and 240 dp in height for mobile devices.
When the PiP window is active, the app can be in one of three states: in the background (minimized), in the active state (user returned to the app), or in a waiting state (system paused PiP due to resource constraints). When transitioning to PiP, the app should pause unnecessary UI operations (animations, interface rendering) and free memory, since system resources are more tightly allocated in multitasking mode. iOS automatically sends the app an AVPictureInPictureControllerWillStartNotification, while Android sends an onPictureInPictureModeChanged callback.
The PiP window has significant limitations: it cannot display standard UI control elements (pause button, progress slider) — only a minimal system overlay with basic controls: play/pause, close, expand to full screen. The system PiP UI on iOS includes pause and close buttons, while Android includes the same elements plus an additional settings button. Interacting with content inside PiP (rewinding, selecting subtitles) is not possible — for that, the app must be expanded to full screen.
On iOS, PiP is implemented through the AVKit framework and the AVPictureInPictureController class. This API is available on iOS 14+ for iPhone and iPad, but with different requirements: on iPad, PiP works through AVPlayerLayer; on iPhone, only through AVPlayerViewController.
For PiP to work on iOS, several conditions must be met: the app must use AVPlayer for video playback, the audio session must be set to the .playback or .playAndRecord category, and the app must have entitlements for background audio (UIBackgroundModes = audio). Without these settings, PiP will not start — the system will reject the PiP session request because it cannot guarantee proper playback after transitioning to the background.
On iOS, the PiP window automatically appears when the app is minimized if video is actively playing and the user has not disabled this feature in settings. Users can also manually minimize video into PiP using the button in AVPlayerViewController. The PiP window size on iOS is fixed and system-determined — developers cannot change it. The PiP window aspect ratio matches the original video, but maximum size is limited to 1/4 of screen width on iPhone and 1/3 on iPad.
Key PiP limitations on iOS: no custom UI in the PiP window, a single PiP stream at a time, and the requirement of an active AVPlayer for PiP to work. Multi-PiP — playing multiple PiP windows simultaneously — is not supported on iOS. Attempting to start a second PiP automatically closes the first one. This is a hardware limitation: the video processor cannot simultaneously handle two independent PiP channels due to DMA and video memory constraints.
Another important limitation is background playback duration. If the user does not interact with the PiP window, the system may pause playback after some time to save power. Automatic PiP pause on iOS occurs after 10–15 minutes of inactivity if the app has not implemented a keep-alive mechanism through a background task. For video calls and streams, it is recommended to use PushKit and VoIP certificates, which bypass this limitation.
On Android, PiP is implemented as a built-in Activity mode that activates via the enterPictureInPictureMode method. Since Android 8.0 (API 26), any Activity can enter PiP mode, and since Android 12 (API 31), PiP support for SurfaceView and TextureView is available without requiring MediaCodec.
To support PiP in the Android manifest, the android:supportsPictureInPicture attribute must be specified for the Activity in the
In Android, the PiP window by default has no control elements. Developers can add custom actions via RemoteAction in the setPictureInPictureParams method. Up to 3 actions are available (e.g., pause/play, rewind forward/backward, close). Each action appears in the system PiP overlay as an icon. Unlike iOS, where all UI elements are strictly fixed, Android offers more flexibility for basic controls.
PiP on Android has different capabilities depending on the OS version. On Android 8.0–8.1, PiP is only available for video played through MediaPlayer or MediaCodec with SurfaceView. Starting with Android 9, PictureInPictureArgs.Builder can be used to configure the PiP window aspect ratio. Android 12 added PiP support for custom SurfaceView and TextureView, along with improved transitions between full-screen and PiP mode. Android 13+ allows displaying the PiP window even when the screen is locked, provided the app has the appropriate permission.
| Android Version | PiP Capabilities | API |
|---|---|---|
| 8.0–8.1 | Basic PiP for MediaPlayer/MediaCodec | 26–27 |
| 9–11 | Aspect ratio configuration, custom actions | 28–30 |
| 12 | SurfaceView/TextureView PiP support | 31 |
| 13+ | PiP on lock screen, improved animations | 33+ |
A key difference in Android PiP from iOS is multi-PiP capability. On Android 12+, the system can display multiple PiP windows simultaneously if the apps support it and device performance allows. However, in practice, multi-PiP is limited by SoC capabilities: most devices support only one PiP window due to hardware decoder limitations, as each PiP window requires its own video stream and a separate decoding session.
Let’s look at a practical PiP implementation on both mobile platforms, taking into account the latest API changes.
import AVKit
import AVFoundation
class VideoPlayerViewController: UIViewController {
var player: AVPlayer!
var pipController: AVPictureInPictureController?
override func viewDidLoad() {
super.viewDidLoad()
let playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspect
view.layer.addSublayer(playerLayer)
guard AVPictureInPictureController.isPictureInPictureSupported()
else { return }
pipController = AVPictureInPictureController(playerLayer: playerLayer)
pipController?.delegate = self
}
@IBAction func startPiPTapped() {
pipController?.startPictureInPicture()
}
}
extension VideoPlayerViewController: AVPictureInPictureControllerDelegate {
func pictureInPictureControllerWillStart(
_ pictureInPictureController: AVPictureInPictureController
) {
// Hide UI elements, free memory
}
func pictureInPictureControllerDidStop(
_ pictureInPictureController: AVPictureInPictureController
) {
// Restore UI, resume rendering
}
}
In this example, AVPictureInPictureController is initialized with playerLayer after checking isPictureInPictureSupported (PiP is not supported on iPhone SE 1st generation and some iPads without sufficient memory). The delegate notifies the app about PiP start and end — in these callbacks, UI elements should be hidden and restored, as the app interface is not visible in PiP mode. When transitioning to PiP, it is recommended to stop all animations, hide player controls, and free unused memory to prevent the system from forcibly unloading the app.
class PipVideoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupVideoPlayer()
}
private fun enterPipMode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val aspectRatio = Rational(16, 9)
val pipParams = PictureInPictureParams.Builder()
.setAspectRatio(aspectRatio)
.setAutoEnterEnabled(true)
.build()
enterPictureInPictureMode(pipParams)
}
}
override fun onPictureInPictureModeChanged(
isInPictureInPictureMode: Boolean,
newConfig: Configuration
) {
if (isInPictureInPictureMode) {
// Hide UI, focus only on media
binding.controlsGroup.visibility = View.GONE
} else {
// Restore UI
binding.controlsGroup.visibility = View.VISIBLE
}
}
}
The Kotlin example uses PictureInPictureParams.Builder to configure PiP. The setAspectRatio method sets the PiP window aspect ratio (16:9 for typical video). setAutoEnterEnabled(true) enables automatic PiP transition when the app is minimized. The onPictureInPictureModeChanged callback is invoked when entering and exiting PiP — here UI elements should be hidden or displayed. For SurfaceView video, additional configuration handling is required by adding android:configChanges="screenSize|smallestScreenSize" to the manifest to prevent Activity recreation during PiP mode transition.
PiP is a powerful tool for improving user experience in apps where content remains relevant even when switching to other tasks. However, PiP implementation should be justified and not distract the user.
Video calls and conferences are one of the main PiP use cases. In Zoom, FaceTime, Google Meet, PiP allows users to see their interlocutor while working in other apps: reading notes, viewing a presentation, or checking email. PiP for video calls requires background camera support and proper audio session configuration to continue audio capture in the background. On iOS, this is done using AVSampleBufferDisplayLayer instead of AVPlayerLayer, since video calls do not use AVPlayer.
Streaming services (YouTube, Netflix, Twitch) actively use PiP for continued viewing while searching for new content. YouTube Premium offers PiP as a paid feature, and Netflix also restricts PiP to certain subscription plans due to content licensing restrictions. Implementing PiP in a streaming app requires integration with a DRM system (FairPlay, Widevine) that supports a secure pipeline in PiP mode.
PiP is not suitable for apps with interactive video content requiring user input: educational platforms with in-player tests, game streams with chat, shopping apps with product links in video. In these cases, the PiP window is too small to display additional information, and interactive elements are not supported by the system inside PiP. It is recommended to use PiP only for passive viewing when no interaction with content is required.
For music and podcast apps, PiP is excessive — background audio without a visual window is sufficient. PiP consumes additional GPU resources for rendering video in a floating window, reducing battery life. If the content is audio-based (music, podcasts, audiobooks), use background playback without PiP. If visual, implement PiP to enhance user experience.
Frequently Asked Questions
PiP on iOS requires iPhone 6s+, iOS 14+, and a supported region (US, Canada, Australia, EU, Russia, and others). The app must configure the audio session to the .playback category and add UIBackgroundModes = audio. Also check the settings: Settings > General > Picture in Picture.
On iOS, the PiP window size is fully determined by the system and cannot be configured by the developer. On Android, only the aspect ratio can be set via setAspectRatio in PictureInPictureParams.Builder, but the exact window size is determined by the system. Users can resize the PiP window on Android 12+ using a pinch-to-zoom gesture.
Yes, PiP works with DRM-protected content (FairPlay on iOS, Widevine L1 on Android) provided the DRM session supports a secure pipeline in PiP mode. Widevine L3 may not support PiP, as it does not guarantee security of decoded content in a floating window. Check DRM compatibility with PiP during the testing phase.
On iOS — only one PiP window. On Android 12+, multi-PiP is theoretically supported, but in practice most devices are limited to one window due to hardware constraints. Top-tier devices (Samsung Galaxy S24, Pixel 8) may support 2 PiP windows, but with reduced performance.
Yes, lifecycle handling is critically important. On iOS, when transitioning to PiP, the app receives a willStart notification where UI should be hidden and memory freed. On Android, onPictureInPictureModeChanged is called when entering/exiting PiP. Without proper lifecycle handling, the system may unload the app from memory, interrupting playback.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also