GuidesAPI ReferenceRelease Notes
HomeLog InHome
Guides

Controlling Playback in SwiftUI

BlazeSwiftUIVideoInlinePlayerController is a SwiftUI-native controller that manages the player lifecycle and gives you programmatic access to video player control methods.

The following usage patterns are supported:

  • Controller created with view: the player dies when the view dies (simple screens).
  • Controller stored in a model: the player outlives the view for better performance in feeds.

The controller provides an API for standard player operations such as play and pause, full-screen transitions, and interaction control.

Implementation

Usage pattern 1: Controller created with view

struct PlayerControlsExample: View {
    @StateObject private var playerController = BlazeSwiftUIVideoInlinePlayerController()
    @State private var isPlaying = false
    
    var body: some View {
        VStack {
            // Player view
            BlazeSwiftUIVideosInlinePlayerView(
                configuration: .init(
                    playerMode: .interactive(interactivePlyerStyle: .base()),
                    dataSourceType: .labels(.singleLabel("highlights")),
                    containerIdentifier: "main-player"
                ),
                playerController: playerController,
                embeddedState: .player(autoPlayOnStart: false)
            )
            .aspectRatio(16/9, contentMode: .fit)
            
            // Control buttons
            HStack(spacing: 20) {
                Button(isPlaying ? "Pause" : "Play") {
                    if isPlaying {
                        playerController.pausePlayer()
                    } else {
                        playerController.resumePlayer()
                    }
                    isPlaying.toggle()
                }
                .buttonStyle(.bordered)
                
                Button("Full Screen") {
                    playerController.enterFullScreen()
                }
                .buttonStyle(.bordered)
            }
            .padding()
        }
    }
}

Usage pattern 2: Controller in model outlives view

class FeedItem: ObservableObject {
    // Controller stored in model to outlive view instances
    let playerController = BlazeSwiftUIVideoInlinePlayerController()
    let id: String
    
    init(id: String) {
        self.id = id
    }
}

struct FeedCellView: View {
    @ObservedObject var feedItem: FeedItem
    var isVisible: Bool
    
    var body: some View {
        BlazeSwiftUIVideosInlinePlayerView(
            configuration: Configuration(
                playerMode: .preview(previewPlayerStyle: .base()),
                dataSourceType: .labels(.singleLabel("highlights")),
                containerIdentifier: feedItem.id
            ),
            playerController: feedItem.playerController,
            embeddedState: isVisible ? .player(autoPlayOnStart: true) : .placeholder
        )
    }
}

Playback control

// Resume playback
playerController.resumePlayer()

// Pause playback
playerController.pausePlayer()

// Enter full-screen mode
playerController.enterFullScreen()

Interaction management

// Block user interaction.
playerController.blockInteraction()

// Unblock user interaction
 playerController.unblockInteraction()

Initializer

init

public init()

Creates a new controller instance for managing video player operations.

The controller starts in a disconnected state and connects to a player instance automatically when passed to a BlazeSwiftUIVideosInlinePlayerView instance.

Usage example:

@StateObject private var playerController = BlazeSwiftUIVideoInlinePlayerController()

Methods

resumePlayer

@MainActor
public func resumePlayer()

Resumes video playback if the player is currently paused.

This method attempts to resume playback on the currently embedded video player. The operation has no effect if the player is not currently embedded or if the video is already playing.

Usage example:

Button("Play") {
    playerController.resumePlayer()
}

pausePlayer

@MainActor
public func pausePlayer()

Pauses video playback if the player is currently playing.

This method attempts to pause playback on the currently embedded video player. The operation has no effect if the player is not currently embedded or if the video is already paused.

Usage example:

Button("Pause") {
    playerController.pausePlayer()
}

enterFullScreen

@MainActor
public func enterFullScreen()

Transitions the player to full-screen mode with overlay controls.

This method presents the video player in a modal full-screen view controller with complete playback controls. The transition includes smooth animations and proper state management between inline and full-screen modes.

This method only works when the player is currently embedded (not in placeholder mode). Ensure the player is in an active state before calling this method.

Usage example:

Button("Full Screen") {
    playerController.enterFullScreen()
}

blockInteraction

@MainActor
public func blockInteraction()

Blocks user interaction with the player while maintaining playback functionality through a playerController.

This method adds a transparent overlay that prevents user touches from reaching the player controls, disabling user interaction while allowing video playback to continue normally. This is useful for preventing user input during loading states, transitions, or other critical operations.

Remember to call unblockInteraction() to restore user control when appropriate. The interaction remains blocked until explicitly unblocked.

Usage example:

// Block interaction during a loading operation
playerController.blockInteraction()

// Perform async operation
Task {
    await performLongRunningOperation()
    playerController.unblockInteraction()
}

unblockInteraction

@MainActor
public func unblockInteraction()

Restores user interaction with the player after it was previously blocked.

This method removes the interaction-blocking overlay, letting users interact with player controls normally. Call it after blockInteraction() when you want to restore normal user interaction. If interaction was not previously blocked, this method has no effect.

Usage example:

// Restore interaction after completing an operation
playerController.unblockInteraction()

Best practices

Lifecycle management

  • Use @StateObject when creating controllers in SwiftUI views.
  • Store controllers in model objects for feed scenarios where players should outlive views.
  • The controller automatically handles cleanup when deallocated.

State management

  • Use the controller together with EmbeddedState for proper state management.

Performance

  • For feed views, store controllers in your data model to avoid recreation during scrolling.
  • Only embed players when needed, using EmbeddedState.placeholder initially.
  • Use Configuration changes sparingly, as they trigger player recreation.

Error handling

The controller methods gracefully handle edge cases such as:

  • The player not being embedded.
  • The player already being in the requested state.
  • Attempting operations on a disconnected controller.

Did this page help you?