Picture-in-Picture
The videos player supports Picture-in-Picture (PiP), allowing video playback to continue in a floating overlay window while the user navigates away from the app or switches to another app. PiP is powered by Apple's native PiP framework and requires no additional integration beyond a capability flag.
App Setup
Enable Audio, AirPlay, and Picture in Picture under Background Modes in your Xcode project's Signing & Capabilities tab.
Entry Point
Access PiP functionality through the pipManager on the Blaze.shared singleton:
Blaze.shared.pipManagerBlazePipManager
| Member | Type | Description |
|---|---|---|
delegate | BlazePipDelegate | Assign to receive PiP lifecycle callbacks |
isActive | Bool (read-only) | true if any SDK player currently has an active PiP session |
stopActivePiPSession() | method | Programmatically stop the active PiP session |
Observing PiP State
Assign a BlazePipDelegate to receive callbacks whenever PiP starts or stops. Callbacks are always delivered on the main thread.
Blaze.shared.pipManager.delegate = BlazePipDelegate(
onPiPStateChanged: { playerType, sourceId, newState in
// playerType: BlazePlayerType — which player triggered the change
// sourceId: String? — optional entry-point identifier
// newState: BlazePipState (.on / .off)
}
)Parameters:
- playerType:
BlazePlayerType— identifies which player type (.videos,.moments,.stories) triggered the PiP state change, allowing the host app to respond per player context. - sourceId:
String?— the optional entry-point identifier passed when the player was opened. - newState:
BlazePipState— the new PiP state (.onwhen PiP becomes active,.offwhen it ends).
BlazePipState
public enum BlazePipState: String {
case on // PiP overlay is active
case off // PiP is not active
}Configuration
PiP behavior is controlled per-session or globally through BlazeVideosPlaybackConfiguration.
PiPConfiguration
public struct PiPConfiguration: Equatable {
/// When true, PiP starts automatically when the app moves to the background.
/// When false, PiP only starts on explicit user tap of the PiP button.
/// Applies to the full-screen player only.
public var enterPipOnAppBackground: Bool
}- Default (
BlazeVideosPlaybackConfiguration.base()):enterPipOnAppBackground = true
enterPipOnAppBackgroundapplies to the full-screen player only. Inline players do not auto-enter PiP when the app moves to the background.
Per-Session Configuration
var playbackConfig = BlazeVideosPlaybackConfiguration.base()
playbackConfig.pipConfiguration = .init(enterPipOnAppBackground: false)
Blaze.shared.playVideo(
for: "video123",
playbackConfiguration: playbackConfig,
completion: nil
)Global Configuration
var playbackConfig = BlazeVideosPlaybackConfiguration.base()
playbackConfig.pipConfiguration = .init(enterPipOnAppBackground: false)
Blaze.shared.setDefaultVideosPlaybackConfiguration(playbackConfig)
Global configuration is overridden when aplaybackConfigurationis passed directly toplayVideoorplayVideos.
Button Styling
The PiP button is accessible via BlazeVideosPlayerStyle.buttons.pictureInPicture and uses the BlazeVideosPlayerButtonStyle type.
Defaults: visible, 44×44 pt, white, hidden during ads.
var playerStyle = BlazeVideosPlayerStyle.base()
playerStyle.buttons.pictureInPicture.isVisible = true
playerStyle.buttons.pictureInPicture.width = 44
playerStyle.buttons.pictureInPicture.height = 44
playerStyle.buttons.pictureInPicture.color = .white
playerStyle.buttons.pictureInPicture.isVisibleForAds = false
playerStyle.buttons.pictureInPicture.customImage = BlazeVideosPlayerButtonCustomImageStates(
default: myDefaultImage,
selected: mySelectedImage
)See BlazeVideosPlayerButtonStyle for the full list of configurable properties.
Behavior Notes
- Automatic restoration — when the user returns to the app while PiP is active, the SDK automatically restores the full-screen player. No client-side handling is required.
- Stopping PiP programmatically — call
Blaze.shared.pipManager.stopActivePiPSession()to stop an active session from your own code (e.g., in response to a custom UI action). - Inline players — inline players do not auto-enter PiP on app backgrounding regardless of the
enterPipOnAppBackgroundsetting.
Usage Examples
Observing PiP Events
Blaze.shared.pipManager.delegate = BlazePipDelegate(
onPiPStateChanged: { playerType, sourceId, newState in
switch newState {
case .on:
print("PiP started for player: \(playerType), source: \(sourceId ?? "unknown")")
case .off:
print("PiP ended for player: \(playerType)")
}
}
)Disabling Auto-PiP on Background
var playbackConfig = BlazeVideosPlaybackConfiguration.base()
playbackConfig.pipConfiguration = .init(enterPipOnAppBackground: false)
Blaze.shared.setDefaultVideosPlaybackConfiguration(playbackConfig)Customizing the PiP Button
var playerStyle = BlazeVideosPlayerStyle.base()
playerStyle.buttons.pictureInPicture.color = .systemBlue
playerStyle.buttons.pictureInPicture.width = 50
playerStyle.buttons.pictureInPicture.height = 50
Blaze.shared.setDefaultVideosPlayerStyle(playerStyle)Updated about 2 months ago
