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

Delegate Description
FlowplayerAdDelegate Applies to capturing events for iOS and tvOS applications. Handles advertisement-related events, such as changes in the advertisement state and advertisement errors.
Example
Copy
Copied
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.
Copy
Copied
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.

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

FlowplayerDAIDelegate

Applies to: iOS and tvOS

Delegate Description
FlowplayerDAIDelegate Applies 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
Copy
Copied
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.
Copy
Copied
func player(_ player: FlowplayerAPI, didStreamChangeAdProgress adProgress: DAIAdProgress)
Parameter Description
player The FlowplayerAPI instance where the DAI stream originates.
adProgress The 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.
Copy
Copied
func player(_ player: FlowplayerAPI, didStreamChangeState state: DAIStateStream)
Parameter Description
player The FlowplayerAPI instance where the DAI stream originates.
state The DAIStateStream enum representing the state of the DAI stream.
player(_:didStreamFailWith:)
Description: Called when the player encounters an error with a DAI stream.
Copy
Copied
func player(_ player: FlowplayerAPI, didStreamFailWith error: AdError)
Parameter Description
player The FlowplayerAPI instance reporting the DAI stream error.
error The AdError object describing the encountered DAI stream error.

FlowplayerDelegate

Applies to: iOS and tvOS

Delegate Description
FlowplayerDelegate Applies 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
Copy
Copied
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, duration, and rate events
player(_:didChangeDuration:)
Description:Called when the player's media duration changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeDuration duration: Double)
Parameter Description
player The player instance reporting the duration change.
progress The new media duration represented in seconds.
player(_:didChangePlaybackState:)
Description: Called when the player's playback state changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangePlaybackState state: PlaybackState)
Parameter Description
player The player instance reporting the playback state change.
state The new playback state.
player(_:didChangePosition:)
Description: Called when the player's position changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangePosition position: Double)
Parameter Description
player The player instance reporting the position change.
progress The new position value represented in seconds.
player(_:didChangeRate:)
Description: Called when the player's playback rate changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeRate rate: Float)
Parameter Description
player The player instance reporting the rate change.
rate The new playback rate.
player(_:didChangeState:)
Description:Called when the player's state changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeState state: PlayerState)
Parameter Description
player The player instance reporting the state change.
state The new player state.
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.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeBufferState state: PlaybackBufferState)
Parameter Description
player The FlowplayerAPI instance that triggered the event.
state The 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.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeDVRWindow dvrWindow: DVRWindow)
Parameter Description
player The FlowplayerAPI instance notifying the delegate.
dvrWindow DVRWindow 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.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangePlaybackType type: PlaybackType)
Parameter Description
player The FlowplayerAPI instance that triggered the event.
state The new PlaybackType that the player changed to.
Volume events
player(_:didChangeMute:)
Description: Called when the player's mute state changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeMute mute: Bool)
Parameter Description
player The player instance reporting the mute state change.
mute The new mute state. Returns true if muted and false otherwise.
player(_:didChangeVolume:)
Description: Called when the player's volume changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeVolume volume: Float)
Parameter Description
player The player instance reporting the volume change.
volume The new volume level.
Audio and subtitle events
player(_:loadedTracks audioList:)
Description: Called when the player loads a list of audio tracks.
Copy
Copied
func player(_ player: FlowplayerAPI, loadedTracks audioList: [AudioTrack])
Parameter Description
player The player instance reporting the loaded audio tracks.
audioList An array of AudioTrack objects representing the loaded audio tracks.
player(_:loadedTracks subtitleList:)
Description: Called when the player loads a list of subtitle tracks.
Copy
Copied
func player(_ player: FlowplayerAPI, loadedTracks subtitleList: [SubtitleTrack])
Parameter Description
player The player instance reporting the loaded subtitle tracks.
subtitleList An array of SubtitleTrack objects representing the loaded subtitle tracks.
player(_:selectedTrack audio:)
Description: Called when the player selects an audio track.
Copy
Copied
func player(_ player: FlowplayerAPI, selectedTrack audio: AudioTrack)
Parameter Description
player The player instance reporting the selected audio track.
audio The AudioTrack object representing the selected audio track.
player(_:selectedTrack subtitle:)
Description: Called when the player selects a subtitle track.
Copy
Copied
func player(_ player: FlowplayerAPI, selectedTrack subtitle: SubtitleTrack)
Parameter Description
player The player instance reporting the selected subtitle track.
subtitle The SubtitleTrack object representing the selected subtitle track.
player(_:didReceiveConfig:)
Description: Called when the player loads a Wowza Video configuration for the current media.
Copy
Copied
func player(_ player: FlowplayerAPI, didReceiveConfig ovpConfig: OVPConfig)
Parameter Description
player The player instance reporting the loaded configuration.
ovpConfig The 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.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeQuality quality: PlayerQuality)
Parameter Description
player The FlowplayerAPI instance that triggered the presentation size change.
size The new PlayerQuality representing the video quality.
player(_:didChangeSeek:)
Description: Called when the seek state of the player changes.
Copy
Copied
func player(_ player: FlowplayerAPI, didChangeSeek state: PlaybackSeekState, to position: Double)
Parameter Description
player The FlowplayerAPI instance reporting the seek state change.
state The 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.
position The position that the player has seeked to.
player(_:didFailWith:)
Description: Called when the player encounters an error.
Copy
Copied
func player(_ player: FlowplayerAPI, didFailWith error: PlayerError)
Parameter Description
player The player instance reporting the error.
error The PlayerError text describing the error.

FlowplayerViewDelegate

Applies to: iOS

Delegate Description
FlowplayerViewDelegate Only 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
Copy
Copied
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.
Copy
Copied
func view(_ view: FlowplayerViewAPI, didChangeControlsVisibility isVisible: Bool)
Parameter Description
view The 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.
Copy
Copied
func view(_ view: FlowplayerViewAPI, didChangeFullscreen isFullscreen: Bool)
Parameter Description
view The player view that has changed its full-screen mode.
isFullscreen Boolean 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.
Copy
Copied
func view(_ view: FlowplayerViewAPI, didChangeLifecycle lifecycle: ViewLifecycle)
Parameter Description
view The FlowplayerViewAPI instance whose lifecycle state has changed.
lifecycle The new ViewLifecycle representing the updated lifecycle state.
view(_:didChangeViewVisibility:)
Description: Called when FlowplayerViewAPI changes its visibility to either hidden or visible.
Copy
Copied
func view(_ view: FlowplayerViewAPI, didChangeViewVisibility isVisible: Bool)
Parameter Description
view The player view that has changed its visibility.
isVisible Boolean value indicating whether the view is visible or not.
view(_:didEncounterError:)
Description: Called when the FlowplayerViewAPI encounters an error.
Copy
Copied
func view(_ view: FlowplayerViewAPI, didEncounterError error: Error?)
Parameter Description
view The FlowplayerViewAPI instance reporting the encountered error.
error An 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.

Advertisement notifications

Applies to: iOS and tvOS

Notification Object Description
flowplayerAdDidChangeState AdState, AdType Triggered when the state of an ad changes.
flowplayerAdDidFail AdError Triggered when an ad fails to load or display.
flowplayerAdDidFailWithMetadata AdError, AdType, IMAMetadata(optional) Triggered when an ad fails to load or display the ad type and the optional IMA metadata snapshot.
Example
Copy
Copied
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

Notification Object Description
flowplayerDAIStreamDidChangeAdProgress DAIAdProgress Triggered when the progress of an ad within a DAI stream changes.
flowplayerDAIStreamDidChangeState DAIStateStream Triggered when the state of a DAI stream changes.
flowplayerDAIStreamDidFailWithError AdError Triggered when a DAI stream experiences an error.
Example
Copy
Copied
// 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

Notification Object Description
flowplayerDidChangeBufferState PlaybackBufferState Triggered when the buffer state of the player changes.
flowplayerDidChangeDuration Double Triggered when the player updates its duration.
flowplayerDidChangeDVRWindow DVRWindow Triggered when the DVR window changes. Only valid for live streams.
flowplayerDidChangeIsMuted Bool Triggered when the player's mute value changes.
flowplayerDidChangePlaybackState PlaybackState Triggered when the player's playback state changes.
flowplayerDidChangePlaybackType PlaybackType Triggered when the playback type of the player changes.
flowplayerDidChangePosition Double (seconds) Triggered when the player updates its position.
flowplayerDidChangeQuality PlayerQuality Triggered when the player changes its presentation quality.
flowplayerDidChangeRate Float Triggered when the playback rate changes.
flowplayerDidChangeSeekState PlaybackSeekState, Double Triggered when the player changes its seek state for a certain position.
flowplayerDidChangeState PlayerState Triggered when the player's state changes.
flowplayerDidChangeVolume Float Triggered when the volume value changes.
flowplayerDidFailWithError FlowplayerError Triggered 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.
flowplayerDidReceiveConfig OVPConfig Triggered when the player receives a Wowza Video configuration.
flowplayerDidReceiveMediaItem Media Triggered when the player receives a media item to process.
flowplayerDidSelectAudioTrack AudioTrack Triggered when the player changes audio tracks.
flowplayerDidSelectSubtitleTrack SubtitleTrack Triggered when the player changes subtitle tracks.
Example
Copy
Copied
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

Notification Object Description
flowplayerViewDidChangeControlsVisibility Bool Triggered when the controls visibility of the player view changes.
flowplayerViewDidChangeFullscreen Bool Triggered 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).
flowplayerViewDidChangeLifecycle ViewLifecycle Triggered when the lifecycle of the player view changes.
flowplayerViewDidChangeVisibility Bool Triggered when the visibility of the player view changes. Boolean value indicates if the view is visible (true) or hidden (false).
flowplayerViewDidEncounterError Error Triggered when the player view encounters an error.
Example
Copy
Copied
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")
  }

}