GuidesAPI ReferenceRelease Notes
HomeLog InHome
Guides

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.pipManager

BlazePipManager

MemberTypeDescription
delegateBlazePipDelegateAssign to receive PiP lifecycle callbacks
isActiveBool (read-only)true if any SDK player currently has an active PiP session
stopActivePiPSession()methodProgrammatically 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 (.on when PiP becomes active, .off when 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
📘

enterPipOnAppBackground applies 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 a playbackConfiguration is passed directly to playVideo or playVideos.

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 enterPipOnAppBackground setting.

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)

Did this page help you?