GuidesAPI ReferenceRelease Notes
HomeLog InHome
Guides

Live streaming - iOS

Live streaming lets your app play live video streams (live events) through the standard Blaze Videos player and widgets, side by side with on-demand videos. There is no separate "live" player — a live stream is a video that carries stream metadata, so it flows through the same widgets, inline player, and full-screen player you already use for on-demand videos.

A video is treated as a stream when it has a stream state (.live, .upcoming, or .ended) and a start time. Every stream moves through the same lifecycle:

  • Upcoming — scheduled but not started yet. The player shows a waiting room (thumbnail, title, and start time) until the stream goes live.
  • Live — currently broadcasting. The player shows a live indicator and supports live-edge playback with DVR (pause, rewind, and return to live).
  • Ended — the broadcast has finished. The recording remains available for replay.
📘

Live streams are delivered as HLS and are enabled per account by WSC Sports. Once enabled, streams are managed in the CMS and appear in your existing Videos widgets and player with no code changes required.

Content types and stream states

BlazeVideoContentType identifies whether a video is on-demand or a live stream:

public enum BlazeVideoContentType: String {
    case video = "Video"
    case stream = "Stream"
}

BlazeLiveStreamStatus is the lifecycle state of a stream (on-demand videos have no stream state):

public enum BlazeLiveStreamStatus: String {
    case live
    case upcoming
    case ended
}

Discovering and filtering streams

By default, the Videos API returns on-demand videos only (this preserves backwards compatibility). To include streams, pass a BlazeVideosFilterParams:

public struct BlazeVideosFilterParams {
    public let contentTypes: [BlazeVideoContentType]?
    public let streamStates: [BlazeLiveStreamStatus]?

    public init(contentTypes: [BlazeVideoContentType]? = nil,
                streamStates: [BlazeLiveStreamStatus]? = nil)
}
  • contentTypes — which content types to include (.video, .stream). When nil, only regular videos are returned.
  • streamStates — which stream states to include (.live, .upcoming, .ended). When nil, no stream-state filter is applied.
📘

Because contentTypes defaults to videos-only, you must include .stream to surface any live content.

On a widget

Set videosFilterParams on the Videos widget (BlazeVideosWidgetView for UIKit, or the SwiftUI widget view model):

widget.videosFilterParams = BlazeVideosFilterParams(
    contentTypes: [.stream],
    streamStates: [.live, .upcoming]
)

On the full-screen player

playVideos and prepareVideos on Blaze.shared accept videosFilterParams:

Blaze.shared.playVideos(
    dataSourceType: dataSource,
    videosFilterParams: BlazeVideosFilterParams(
        contentTypes: [.video, .stream],
        streamStates: [.live, .upcoming, .ended]
    )
)

Ordering streams

Ordering is configured on the data source (BlazeDataSourceType.labels / .ids) through orderType and advancedOrderType:

  • BlazeOrderType.startTimeDesc / .startTimeAsc — order by the content/stream start time (descending / ascending).
  • BlazeAdvancedOrderType.liveFirst — surface currently-live items first. It takes priority over orderType.
let dataSource = BlazeDataSourceType.labels(
    yourLabel, // your BlazeWidgetLabel
    orderType: .startTimeDesc,
    advancedOrderType: .liveFirst
)

The stream lifecycle

Upcoming (waiting room)

When a stream's state is .upcoming, the player shows a waiting room instead of playback controls: the stream's thumbnail, an UPCOMING indicator, the start time formatted for the user's locale, and a waiting-room message. The message text is set by BlazeVideosPlayerStyle.waitingRoomMessage (it has a localized default). Playback and seeking are disabled in this state.

When the stream transitions to .live, the waiting room automatically switches to the live player — no reload and no user action required.

Live

While a stream is .live, the player:

  • shows a live indicator (a red dot with a "LIVE" label);
  • plays at the live edge (the furthest available point in the stream);
  • supports DVR — the viewer can pause, rewind, and scrub back through the available window, then return to live.

Ended

When a stream ends (state changes to .ended), the item is not removed from the widget or player — the recording stays available for replay. Behavior depends on where the viewer is:

  • At the live edge — the player auto-advances to the next item immediately. If there is no next item, the standard end-of-content behavior applies.
  • Behind the live edge — playback continues to the end of the recorded content, then auto-advances. The status chip changes from "LIVE" to "ENDED" and the live / back-to-live indicator is removed.

Live edge and DVR

For a live stream, the player tracks whether the viewer is watching at the live edge or behind live:

  • When the viewer pauses or scrubs back, they move behind live and a Back to Live control appears.
  • Tapping Back to Live, seeking forward to the edge, or dragging the scrubber to the live-edge position returns the viewer to live.
  • While behind live, the elapsed time is shown as negative relative to the live edge (for example, -0:45).

The seek bar reflects the DVR window (from the oldest available point up to the live edge); the size of that window is determined by the backend. Live-edge detection and DVR seeking are handled by the SDK automatically.

Keeping streams up to date

The player keeps stream state current with a lightweight polling mechanism — you do not need to trigger anything:

  • Polling runs when the player loads and then at a regular interval (about every 10 seconds).
  • It refreshes the stream items currently loaded in the player (those with an active, non-ended stream), so a stream flipping .upcoming → .live → .ended is picked up automatically.
  • Updates are reflected both in the player and at the widget level (the status chip on the card updates in place).
  • Polling is lifecycle-aware (it pauses while the app is backgrounded) and backs off automatically if requests fail.

Live UI in the player

The in-player live UI is customizable through BlazeVideosPlayerStyle:

  • statusIndicator — the LIVE / UPCOMING / ENDED chip in the player. See BlazeVideosPlayerStatusIndicatorStyle.
  • backToLiveButton — the badge that reads "Live" at the live edge and "Back to Live" when behind live. See BlazeVideosPlayerBackToLiveButtonStyle.
  • waitingRoomMessage — the message shown in the upcoming-stream waiting room (a String on BlazeVideosPlayerStyle, with a localized default).
var playerStyle = BlazeVideosPlayerStyle.base()
playerStyle.statusIndicator.streamStates.liveStreamState.text = "ON AIR"
Blaze.shared.setDefaultVideosPlayerStyle(playerStyle)

Customizing live UI at the widget level

The live indicators shown on widget cards are customizable through BlazeWidgetItemStyle:

Related


Did this page help you?