Skip to content
Last updated

Listen for events with the Wowza Flowplayer Apple SDK

With the Wowza Flowplayer Apple SDK, you can consume player-emitted events. Your iOS or tvOS application can then respond to player status changes in real time, implementing custom logic or updating the user interface in a pre-determined way. For example, you can listen to event changes in the player state, player view, or ad behavior. You can capture events using the delegate method or the NotificationCenter class.

Listen with the delegate method

The SDK leverages the delegate pattern and pre-defined protocols to customize object behavior and inform you of events in your application. This section summarizes the delegates used to observe and respond to advertising events, player events, and changes in the player's view.

info

Both the FlowplayerAdDelegate and FlowplayerDelegate methods can be used to listen to iOS and tvOS application events. However, the FlowplayerViewDelegate only applies to capturing events for iOS applications.

FlowplayerAdDelegate

Applies to: iOS and tvOS

DelegateDescription
FlowplayerAdDelegateApplies to capturing events for iOS and tvOS applications. Handles advertisement-related events, such as changes in the advertisement state and advertisement errors.
Example
extension MyViewController: FlowplayerAdDelegate {
  func player(_: FlowplayerAPI, didAdFailWith error: AdError) {
    print("Ad failed with error: \(error)")
  }

  func player(_: FlowplayerAPI, didChangeAdState state: AdState, for adType: AdType) {
    print("Ad of type: \(adType) changed state: \(state)")
  }
}

Event listeners reference

player(_:didAdFailWith:) or player(_:didAdFailWith:for:with:)
Description: Called when the player encounters an error related to advertisement playback.
func player(_ player: FlowplayerAPI, didAdFailWith error: AdError)

Use the type enumeration to indicate the AdType that failed (for example, pre-roll, mid-roll, or post-roll). Include the optional IMAMetadata parameter to provide additional Interactive Media Ads (IMA) SDK metadata for the ad error.

func player(_ player: FlowplayerAPI, didAdFailWith error: AdError, for type: AdType, with metadata: IMAMetadata?)
ParameterDescription
playerThe FlowplayerAPI instance reporting the advertisement error.
errorThe AdError object describing the encountered error.
typeThe AdType causing the error.
metadataThe IMAMetadata object containing the IMA SDK metadata for the advertisement error.
player(_:didChangeAdState:)
Description: Called when the player's advertisement state changes.
func player(_ player: FlowplayerAPI, didChangeAdState state: AdState, for adType: AdType)
ParameterDescription
playerThe FlowplayerAPI instance reporting the advertisement state.
stateThe new AdState representing the updated advertisement state. Use this property to check if the player is currently playing an advertisement.
adTypeThe type of advertisement that the state changed for.

FlowplayerDAIDelegate

Applies to: iOS and tvOS

DelegateDescription
FlowplayerDAIDelegateApplies to capturing events for iOS and tvOS applications. When using Googles IMA Dynamic Ad Insertion (DAI) SDK, handles stream-related events, such as stream errors, stream state changes, and stream ad playback progress.
Example
extension MyViewController: FlowplayerDAIDelegate {
  func player(_: any FlowplayerAPI, didStreamFailWith error: AdError) {
    print("Stream error:", error)
  }

  func player(_: any FlowplayerAPI, didStreamChangeState state: DAIStateStream) {
    print("Stream state changed:", state)
  }

  func player(_: any FlowplayerAPI, didStreamChangeAdProgress adProgress: DAIAdProgress) {
    print("Stream ad progress changed:", adProgress)
  }
}

Event listeners reference

player(_:didStreamChangeAdProgress:)
Description: Called when there is a change in ad playback progress within a DAI stream. This method provides detailed information about the current ad's playback status within the DAI stream, such as the time elapsed, total duration, and its position within the ad break.
func player(_ player: FlowplayerAPI, didStreamChangeAdProgress adProgress: DAIAdProgress)
ParameterDescription
playerThe FlowplayerAPI instance where the DAI stream originates.
adProgressThe optional DAIAdProgress structure providing detailed progress information for the current ad within the DAI stream.
player(_:didStreamChangeState:)
Description: Called when the DAI stream state changes within the player. This method informs the delegate of changes unrelated to specific ad content, such as stream initialization, pausing, or resuming. For changes related to ad content, such as detecting the start or end of an ad, use the FlowplayerAdDelegate.
func player(_ player: FlowplayerAPI, didStreamChangeState state: DAIStateStream)
ParameterDescription
playerThe FlowplayerAPI instance where the DAI stream originates.
stateThe DAIStateStream enum representing the state of the DAI stream.
player(_:didStreamFailWith:)
Description: Called when the player encounters an error with a DAI stream.
func player(_ player: FlowplayerAPI, didStreamFailWith error: AdError)
ParameterDescription
playerThe FlowplayerAPI instance reporting the DAI stream error.
errorThe AdError object describing the encountered DAI stream error.

FlowplayerDelegate

Applies to: iOS and tvOS

DelegateDescription
FlowplayerDelegateApplies to capturing events for iOS and tvOS applications. Handles general player events, such as playback state changes, volume changes, position updates, playback rate changes, and errors.
Example
extension MyViewController: FlowplayerDelegate {
  func player(_: FlowplayerAPI, didChangeState state: PlayerState) {
    if case .ready = state {
      print("The player is ready!")
    }
  }

  func player(_: FlowplayerAPI, didFailWith error: PlayerError) {
      print("The player encountered an error.", error)
  }
}

Event listeners reference

State, position, source, duration, and rate events
player(_:didChangeDuration:)
Description:Called when the player's media duration changes.
func player(_ player: FlowplayerAPI, didChangeDuration duration: Double)
ParameterDescription
playerThe player instance reporting the duration change.
progressThe new media duration represented in seconds.
player(_:didChangePlaybackState:)
Description: Called when the player's playback state changes.
func player(_ player: FlowplayerAPI, didChangePlaybackState state: PlaybackState)
ParameterDescription
playerThe player instance reporting the playback state change.
stateThe new playback state.
player(_:didChangePosition:)
Description: Called when the player's position changes.
func player(_ player: FlowplayerAPI, didChangePosition position: Double)
ParameterDescription
playerThe player instance reporting the position change.
progressThe new position value represented in seconds.
player(_:didChangeRate:)
Description: Called when the player's playback rate changes.
func player(_ player: FlowplayerAPI, didChangeRate rate: Float)
ParameterDescription
playerThe player instance reporting the rate change.
rateThe new playback rate.
player(_:didChangeState:)
Description: Called when the player's state changes.
func player(_ player: FlowplayerAPI, didChangeState state: PlayerState)
ParameterDescription
playerThe player instance reporting the state change.
stateThe new player state.
player(_:didReceiveSource:)
Description: Called when the player receives a new source URL to load. This source can stem from a MediaOVP, MediaExternal, or MediaDAI media type. The asset URL will be loaded by the underlying AVPlayer instance.
func player(_ player: FlowplayerAPI, didReceiveSource source: URL)
ParameterDescription
playerThe FlowplayerAPI player instance notifying the delegate.
sourceThe URL object representing the raw asset.
Playback type, buffering, and Digital Video Recording (DVR) events
player(_:didChangeBufferState:)
Description: Called when there's a change in the buffer state of the player. Indicates if the player is currently buffering or not.
func player(_ player: FlowplayerAPI, didChangeBufferState state: PlaybackBufferState)
ParameterDescription
playerThe FlowplayerAPI instance that triggered the event.
stateThe new PlaybackBufferState state of the player.
player(_:didChangeDVRWindow:)
Description: Notifies the delegate that the DVR window has changed. The DVR window represents the available playback duration for seeking and playback control in DVR-enabled content.
func player(_ player: FlowplayerAPI, didChangeDVRWindow dvrWindow: DVRWindow)
ParameterDescription
playerThe FlowplayerAPI instance notifying the delegate.
dvrWindowDVRWindow providing information about the start and end times of the DVR window.
player(_:didChangePlaybackType:)
Description: Called when there's a change in the playback type, such as switching between a live stream and video-on-demand (VOD) playback.
func player(_ player: FlowplayerAPI, didChangePlaybackType type: PlaybackType)
ParameterDescription
playerThe FlowplayerAPI instance that triggered the event.
stateThe new PlaybackType that the player changed to.
Volume events
player(_:didChangeMute:)
Description: Called when the player's mute state changes.
func player(_ player: FlowplayerAPI, didChangeMute mute: Bool)
ParameterDescription
playerThe player instance reporting the mute state change.
muteThe new mute state. Returns true if muted and false otherwise.
player(_:didChangeVolume:)
Description: Called when the player's volume changes.
func player(_ player: FlowplayerAPI, didChangeVolume volume: Float)
ParameterDescription
playerThe player instance reporting the volume change.
volumeThe new volume level.
Audio and subtitle events
player(_:loadedTracks audioList:)
Description: Called when the player loads a list of audio tracks.
func player(_ player: FlowplayerAPI, loadedTracks audioList: [AudioTrack])
ParameterDescription
playerThe player instance reporting the loaded audio tracks.
audioListAn array of AudioTrack objects representing the loaded audio tracks.
player(_:loadedTracks subtitleList:)
Description: Called when the player loads a list of subtitle tracks.
func player(_ player: FlowplayerAPI, loadedTracks subtitleList: [SubtitleTrack])
ParameterDescription
playerThe player instance reporting the loaded subtitle tracks.
subtitleListAn array of SubtitleTrack objects representing the loaded subtitle tracks.
player(_:selectedTrack audio:)
Description: Called when the player selects an audio track.
func player(_ player: FlowplayerAPI, selectedTrack audio: AudioTrack)
ParameterDescription
playerThe player instance reporting the selected audio track.
audioThe AudioTrack object representing the selected audio track.
player(_:selectedTrack subtitle:)
Description: Called when the player selects a subtitle track.
func player(_ player: FlowplayerAPI, selectedTrack subtitle: SubtitleTrack)
ParameterDescription
playerThe player instance reporting the selected subtitle track.
subtitleThe SubtitleTrack object representing the selected subtitle track.
player(_:didReceiveConfig:)
Description: Called when the player loads a Wowza Video configuration for the current media.
func player(_ player: FlowplayerAPI, didReceiveConfig ovpConfig: OVPConfig)
ParameterDescription
playerThe player instance reporting the loaded configuration.
ovpConfigThe OVPConfig object representing the loaded configuration.
Quality, seek state, and error events
player(_:didChangeQuality:)
Description: Called when the presentation size of the player changes, typically due to a change in the media content or the player's dimensions.
func player(_ player: FlowplayerAPI, didChangeQuality quality: PlayerQuality)
ParameterDescription
playerThe FlowplayerAPI instance that triggered the presentation size change.
sizeThe new PlayerQuality representing the video quality.
player(_:didChangeSeek:)
Description: Called when the seek state of the player changes.
func player(_ player: FlowplayerAPI, didChangeSeek state: PlaybackSeekState, to position: Double)
ParameterDescription
playerThe FlowplayerAPI instance reporting the seek state change.
stateThe new PlaybackSeekState representing the updated seek state of the player. The failed stated indicates the player hasn't been able to seek to the desired position.
positionThe position that the player has seeked to.
player(_:didFailWith:)
Description: Called when the player encounters an error.
func player(_ player: FlowplayerAPI, didFailWith error: PlayerError)
ParameterDescription
playerThe player instance reporting the error.
errorThe PlayerError text describing the error.

FlowplayerViewDelegate

Applies to: iOS

DelegateDescription
FlowplayerViewDelegateOnly applies to capturing events for iOS applications. Handles events related to the player view, such as changes in full-screen mode, controls visibility, encountered errors, and view visibility changes.
Example
extension MyViewController: FlowplayerViewDelegate {
  func view(_: FlowplayerViewAPI, didEncounterError error: Error?) {
    guard let error else { return }
    print("Oh no, I've encountered an error!")
    print(error)
  }

  func view(_: FlowplayerViewAPI, didChangeFullscreen isFullscreen: Bool) {
    print("isFullscreen:", isFullscreen)
  }

  func view(_: FlowplayerViewAPI, didChangeControlsVisibility isVisible: Bool) {
    print("ControlsVisibility:", isVisible)
  }

  func view(_: FlowplayerViewAPI, didChangeViewVibility isVisible: Bool) {
    print("View changed visibility to:", isVisible ? "visible" : "hidden")
  }
}

Event listener reference

view(_:didChangeControlsVisibility:)
Description: Called when the FlowplayerViewAPI controls visibility changes between hidden and visible.
func view(_ view: FlowplayerViewAPI, didChangeControlsVisibility isVisible: Bool)
ParameterDescription
viewThe player view that has changed its controls visibility.
``isVisible`Boolean value indicating if the controls are visible or not.
view(_:didChangeFullscreen:)
Description: Called when the player enters or exits full-screen mode.
func view(_ view: FlowplayerViewAPI, didChangeFullscreen isFullscreen: Bool)
ParameterDescription
viewThe player view that has changed its full-screen mode.
isFullscreenBoolean value indicating if the player is now in full-screen mode (true) or not (false).
view(_:didChangeLifecycle:)
Description: Called when the view transitions between different lifecycle states, such as creation or destruction. Use this method to perform any necessary updates or actions based on the lifecycle state.
func view(_ view: FlowplayerViewAPI, didChangeLifecycle lifecycle: ViewLifecycle)
ParameterDescription
viewThe FlowplayerViewAPI instance whose lifecycle state has changed.
lifecycleThe new ViewLifecycle representing the updated lifecycle state.
view(_:didChangeViewVisibility:)
Description: Called when FlowplayerViewAPI changes its visibility to either hidden or visible.
func view(_ view: FlowplayerViewAPI, didChangeViewVisibility isVisible: Bool)
ParameterDescription
viewThe player view that has changed its visibility.
isVisibleBoolean value indicating whether the view is visible or not.
view(_:didEncounterError:)
Description: Called when the FlowplayerViewAPI encounters an error.
func view(_ view: FlowplayerViewAPI, didEncounterError error: Error?)
ParameterDescription
viewThe FlowplayerViewAPI instance reporting the encountered error.
errorAn optional Error object describing the error. If nil, no specific error information is provided.

Listen with the NotificationCenter

You can also take advantage of the notification dispatch mechanism included with the SDK to observe events within your application. This section summarizes the notifications used to detect and respond to changes in the player state, ad state, player view, track selection, error events, etc.

info

Player and advertisement notifications are accessible for both iOS and tvOS applications. However, player view notifications only apply to capturing events for iOS applications.

Applies to: iOS and tvOS

NotificationObjectDescription
flowplayerAdDidChangeStateAdState, AdTypeTriggered when the state of an ad changes.
flowplayerAdDidFailAdErrorTriggered when an ad fails to load or display.
flowplayerAdDidFailWithMetadataAdError, AdType, IMAMetadata(optional)Triggered when an ad fails to load or display the ad type and the optional IMA metadata snapshot.
Example
class MyViewController: UIViewController {

 override func viewDidLoad() {
    super.viewDidLoad()
     NotificationCenter.default.addObserver(
      self,
      selector: #selector(onReceivedAdState),
      name: .flowplayerAdDidChangeState,
      object: nil
     )
  }

 override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(
      self,
      name: .flowplayerAdDidChangeState,
      object: nil
    )
  }

  @objc
  func onReceivedAdState(_ notification: Notification) {
    guard let (state, type) = notification.object as? (AdState, AdType) else {
      return
    }

    print("Ad of type: \(type) changed state: \(state)")
  }

}

DAI stream notifications

Applies to: iOS and tvOS

NotificationObjectDescription
flowplayerDAIStreamDidChangeAdProgressDAIAdProgressTriggered when the progress of an ad within a DAI stream changes.
flowplayerDAIStreamDidChangeStateDAIStateStreamTriggered when the state of a DAI stream changes.
flowplayerDAIStreamDidFailWithErrorAdErrorTriggered when a DAI stream experiences an error.
Example
// Declare variable to hold player instance
var player: FlowplayerAPI?

// Load VOD stream into player using MediaDAI object
let media = MediaDAI(stream: DAIStreamVOD(contentSourceID: "[content-source-id]", videoID: "[video-id]"))
if let player = player {
  player.load(dai: media)
} else {
  print("Player is not initialized.")
}

// Register current object to receive notifications when stream state changes
NotificationCenter.default.addObserver(
  self,
  selector: #selector(onReceivedState),
  name: .flowplayerDAIStreamDidChangeState,
  object: nil
)

// Call onReceived method when notification is received and extract state information
@objc
private func onReceivedState(_ notification: Notification) {
  guard let state = notification.object as? DAIStateStream else {
    return
  }

  print("Stream state changed:", state)
}

Player notifications

Applies to: iOS and tvOS

NotificationObjectDescription
flowplayerDidChangeBufferStatePlaybackBufferStateTriggered when the buffer state of the player changes.
flowplayerDidChangeDurationDoubleTriggered when the player updates its duration.
flowplayerDidChangeDVRWindowDVRWindowTriggered when the DVR window changes. Only valid for live streams.
flowplayerDidChangeIsMutedBoolTriggered when the player's mute value changes.
flowplayerDidChangePlaybackStatePlaybackStateTriggered when the player's playback state changes.
flowplayerDidChangePlaybackTypePlaybackTypeTriggered when the playback type of the player changes.
flowplayerDidChangePositionDouble (seconds)Triggered when the player updates its position.
flowplayerDidChangeQualityPlayerQualityTriggered when the player changes its presentation quality.
flowplayerDidChangeRateFloatTriggered when the playback rate changes.
flowplayerDidChangeSeekStatePlaybackSeekState, DoubleTriggered when the player changes its seek state for a certain position.
flowplayerDidChangeStatePlayerStateTriggered when the player's state changes.
flowplayerDidChangeVolumeFloatTriggered when the volume value changes.
flowplayerDidFailWithErrorFlowplayerErrorTriggered when the player encounters an error.
flowplayerDidLoadAudioTracks[AudioTrack]Triggered when the player loads all available audio tracks.
flowplayerDidLoadSubtitleTracks[SubtitleTrack]Triggered when the player loads all available subtitle tracks.
flowplayerDidReceiveConfigOVPConfigTriggered when the player receives a Wowza Video configuration.
flowplayerDidReceiveMediaItemMediaTriggered when the player receives a media item to process.
flowplayerDidReceiveSourceURLTriggered when the player receives a valid source URL to load from a MediaOVP, MediaDAI, or MediaExternal media type.
flowplayerDidSelectAudioTrackAudioTrackTriggered when the player changes audio tracks.
flowplayerDidSelectSubtitleTrackSubtitleTrackTriggered when the player changes subtitle tracks.
Example
class MyViewController: UIViewController {

 override func viewDidLoad() {
    super.viewDidLoad()
     NotificationCenter.default.addObserver(
      self,
      selector: #selector(onReceivedState),
      name: .flowplayerDidChangeState,
      object: nil
     )
  }

 override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(
      self,
      name: .flowplayerDidChangeState,
      object: nil
    )
  }

  @objc
  func onReceivedState(_ notification: Notification) {
     guard let state = notification.object as? PlaybackState else { return }

     if case .ready = state {
       print("The player is ready!")
     }
  }

}

Player view notifications

Applies to: iOS

NotificationObjectDescription
flowplayerViewDidChangeControlsVisibilityBoolTriggered when the controls visibility of the player view changes.
flowplayerViewDidChangeFullscreenBoolTriggered when the full-screen mode of the player view changes. Boolean value indicates if the view is now in full-screen mode (true) or not (false).
flowplayerViewDidChangeLifecycleViewLifecycleTriggered when the lifecycle of the player view changes.
flowplayerViewDidChangeVisibilityBoolTriggered when the visibility of the player view changes. Boolean value indicates if the view is visible (true) or hidden (false).
flowplayerViewDidEncounterErrorErrorTriggered when the player view encounters an error.
Example
class MyViewController: UIViewController {

 override func viewDidLoad() {
    super.viewDidLoad()
     NotificationCenter.default.addObserver(
      self,
      selector: #selector(onFlowplayerDidChangeVisibility),
      name: .onFlowplayerDidChangeVisibility,
      object: nil
     )
  }

 override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(
      self,
      name: .flowplayerViewDidChangeVisibility,
      object: nil
    )
  }

  @objc
  func onFlowplayerDidChangeVisibility(_ notification: Notification) {
    guard let isVisible = notification.object as? Bool else {
      return
    }

    print("FlowplayerView is currently:", isVisible ? "Visible" : "Hidden")
  }

}