Skip to Content
Mux Docs: Home
Welcome to the new Mux Docs.
The old version is still available here

Monitor Kaltura Player (iOS)

This guide walks through integration with iOS and TVOS Kaltura player to collect video performance metrics with Mux data.

Mux Data Mux-Stats-Kaltura supports iOS 9.0 or newer and TVOS 9.0 or newer. The Mux integration with Kaltura is built on top of Mux's core Objective-C SDK, and the full code can be seen here: muxinc/mux-stats-sdk-kaltura-ios.

This SDK is built with XCFramework bundle type and supports Mac Catalyst.

Features

The following data can be collected by the Mux Data SDK when you use the Kaltura iOS SDK, as described below.

Supported Features:

  • Engagement metrics
  • Quality of Experience Metrics
  • Available for deployment from a package manager
  • Custom Dimensions
  • Average Bitrate metrics and renditionchange events
  • Request metrics
  • Customizable Error Tracking
  • Preroll Ads metrics
Notes:

Packaged with: cocoapods.

1Install the Mux Data SDK

Installing with CocoaPods

To install with CocoaPods, modify your Podfile to use frameworks by including use_frameworks! and then add the following pods to your Podfile:

pod 'Mux-Stats-Kaltura', '~>1.0'

This will install Mux-Stats-Kaltura and the latest current release of our core Objective-C Library. There will be no breaking updates in major versions, so you can safely run pod update for future versions.

Next, add correct import statement into your application.

import MUXSDKKaltura

2Initialize the monitor for your Kaltura player instance

Get your ENV_KEY from the Mux environments dashboard.

Env Key is different than your API token

ENV_KEY is a client-side key used for Mux Data monitoring. These are not to be confused with API tokens which are created in the admin settings dashboard and meant to access the Mux API from a trusted server.

The example below uses monitorPlayer:player:playerName:customerData:.

The playerName parameter is a string that identifies this instance of your player. When calling destroyPlayer later on, you will need this string. Each instance of a player that runs simultaneously in your application should have a different playerName.

let playerName = "iOS KalturaPlayer"
let playerData = MUXSDKCustomerPlayerData(environmentKey: "ENV_KEY")
playerData?.playerName = self.playerName

let videoData = MUXSDKCustomerVideoData()
videoData.videoTitle = "Title Video Kaltura"
videoData.videoId = "my-video-id"

let viewData = MUXSDKCustomerViewData()
viewData.viewSessionId = "my-session-id"

let customData = MUXSDKCustomData()
customData.customData1 = "my-custom-data"

let viewerData = MUXSDKCustomerViewerData()
viewerData.viewerApplicationName = "my-app-name"

let customerData = MUXSDKCustomerData(
    customerPlayerData: playerData,
    videoData: videoData,
    viewData: viewData,
    customData: customData,
    viewerData: viewerData
)

guard let player = self.kalturaPlayer, let data = customerData else {
    return
}

MUXSDKStats.monitorPlayer(
    player: player,
    playerName: playerName,
    customerData: data
)

For more complete examples check the demo apps in the repo.

After you've integrated, start playing a video in your player. A few minutes after you stop watching, you'll see the results in your Mux data dashboard. Login to the dashboard and find the environment that corresponds to your env_key and look for video views.

3Make your data actionable

The only required field is env_key. But without some more metadata the metrics in your dashboard will lack the necessary information to take meaningful actions. Metadata allows you to search and filter on important fields in order to diagnose issues and optimize the playback experience for your end users.

Metadata fields are provided via the MUXSDKCustomerPlayerData and MUXSDKCustomerVideoData objects.

For the full list of properties view the header files for this interfaces:

For more details about each property, view the Make your data actionable guide.

let playerName = "My Main Player"
let playerData = MUXSDKCustomerPlayerData(environmentKey: "ENV_KEY")
playerData.experimentName = "player_test_A"
playerData.playerName = playerName
playerData.playerVersion = "1.0.0"

let videoData = MUXSDKCustomerVideoData()
videoData.videoId = "abcd123"
videoData.videoTitle = "My Great Video"
videoData.videoSeries = "Weekly Great Videos"
videoData.videoDuration = 120000 // in milliseconds
videoData.videoIsLive = false
videoData.videoCdn = "cdn"

let viewData = MUXSDKCustomerViewData()
viewData.viewSessionId = "my session id"

let customData = MUXSDKCustomData()
customData.customData1 = "Custom data 1"
customData.customData2 = "Custom Data 2"

let viewerData = MUXSDKCustomerViewerData()
viewerData.viewerApplicationName = "MUX Kaltura DemoApp"

let customerData = MUXSDKCustomerData(
    customerPlayerData: playerData,
    videoData: videoData,
    viewData: viewData,
    customData: customData,
    viewerData: viewerData
)

guard let player = self.kalturaPlayer, let data = customerData else {
    return
}

MUXSDKStats.monitorPlayer(
    player: player,
    playerName: playerName,
    customerData: data
)

4Set or update metadata after monitor

There are some cases where you may not have the full set of metadata until after the video playback has started. In this case, you should omit the values when you first call monitorPlayer. Then, once you have the metadata, you can update the metadata with the setCustomerDataForPlayer method.

// Sometime later before the player is destroyed you can do this:
// The player name ("iOS KalturaPlayer" in this example) should be a player that
// you have already called `monitorPlayer` method with
let videoData = MUXSDKCustomerVideoData()
videoData.videoTitle = "Big Buck Bunny"
videoData.videoSeries = "Updated animation"
// In this example we are updating videoData, but the same can be done
// for updating playerData, customData or viewData
// the values in customerData passed as nil will keep previously set data
// viewerData can't be updated
guard let customerData = MUXSDKCustomerData(
    customerPlayerData: nil,
    videoData: videoData,
    viewData: nil,
    customData: nil,
    viewerData: nil
) else {
    return
}
MUXSDKStats.setCustomerDataForPlayer(name: "iOS KalturaPlayer", customerData: customerData)

5Advanced

Changing the Video

​ There are two cases where the underlying tracking of the video view need to be reset. First, when you load a new source URL into an existing player, and second when the program within a singular stream changes (such as a program within a live stream).

Note: You do not need to change the video info when changing to a different source of the same video content (e.g. different resolution or video format). ​

​ When you change to a new video (in the same player) you need to update the information that Mux knows about the current video. Examples of when this is needed are: ​

  • The player advances to the next video in a playlist
  • The user selects a different video to play ​ This is done by calling videoChangeForPlayer which will remove all previous video data and reset all metrics for the video view. You can include any metadata when changing the video but you should only need to update the values that start with video_. ​ It is required to call videoChangeForPlayer immediately before telling the player which new source to play. ​
// Example of changing the media in Kaltura Player
// Call MUX videoChange before stop, because playkit stop will replace current item for nil
let playerData = MUXSDKCustomerPlayerData(environmentKey: self.environmentKey)
playerData?.playerName = self.playerName
        
let videoData = MUXSDKCustomerVideoData()
videoData.videoTitle = "Apple Video Kaltura"
videoData.videoId = "apple"
videoData.videoSeries = "conference"
        
let viewData = MUXSDKCustomerViewData()
viewData.viewSessionId = "my second session id"
        
let customData = MUXSDKCustomData()
customData.customData1 = "Kaltura test video change"
        
let viewerData = MUXSDKCustomerViewerData()
viewerData.viewerApplicationName = "MUX Kaltura DemoApp"
        
guard let customerData = MUXSDKCustomerData(
    customerPlayerData: playerData,
    videoData: videoData,
    viewData: viewData,
    customData: customData,
    viewerData: viewerData
) else {
    return
}
        
MUXSDKStats.videoChangeForPlayer(name: "iOS KalturaPlayer", customerData: customerData)
// Change media in your player (your steps may vary)
// For example:

// Resets The Player And Prepares for Change Media
self.kalturaPlayer?.stop()
        
// Prepare PlayKit player
self.kalturaPlayer?.prepare(newMediaConfig)
        
// Wait for `canPlay` event to play
self.kalturaPlayer?.addObserver(self, events: [PlayerEvent.canPlay]) { event in
    self.kalturaPlayer?.play()
}

​ In some cases, you may have the program change within a stream, and you may want to track each program as a view on its own. An example of this is a live stream that streams multiple programs back to back, with no interruptions. ​ In this case, call programChangeForPlayer:name:customerData. This will remove all previous video data and reset all metrics for the video view, creating a new video view. You can include any metadata when changing the video but you should only need to update the values that start with video.

Usage with Google Interactive Media Ads (IMA)

If you are using Google Interactive Media Ads and the PlayKit_IMA SDK, then you can use mux-stats-google-ima-kaltura-ios to track ad playback events.

Please note: You should have a fully functioning PlayKit_IMA integration working in your iOS or TvOS application before adding the Mux ad tracking.

Add the following to your Podfile and run pod install

'Mux-Stats-Google-IMA-Kaltura' ~> '1.0.0'

Initialize the Mux monitor with MUXSDKStats.monitorPlayer. Create an listener instance by calling MUXSDKImaKalturaListener(playerBinding: playerBinding, player: player). Start dispatching the events by calling start on the listener instance.

import Mux_Stats_Google_IMA_Kaltura

// Follow the instructions from pod 'PlayKit_IMA' to set up 
// your IMA plugin configuration in the loadPlayer method
//
// When you call `monitorPlayer:withPlayer:playerName:customerData:` 
// from your ViewController, you will get back a MUXSDKPlayerBinding object
let playerBinding = MUXSDKStats.monitorPlayer(
  player: player,
  playerName: self.playerName,
  customerData: data
)

// Use the MUXSDKPlayerBinding object and the Player instance to initialize the MUXSDKImaKalturaListener class
// and call start on the listener object
let listener = MUXSDKImaKalturaListener(playerBinding: playerBinding, player: player)
listener.start()

You can find a complete example here.

Track orientation change events

You can optionally track orientationchange events. To use this functionality, call the orientationChangeForPlayer method. ​ These events will show up on the events log on the view views page.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    let orientation = UIDevice.current.orientation.isLandscape ? MUXSDKViewOrientation.landscape : MUXSDKViewOrientation.portrait
    MUXSDKStats.orientationChangeForPlayer(name: "iOS KalturaPlayer", orientation: orientation)
}

Handling errors manually

By default, automaticErrorTracking is enabled which means the Mux SDK will catch errors that the player throws and track an error event. Error tracking is meant for fatal errors. When an error is thrown it will mark the view as having encountered an error in the Mux dashboard and the view will no longer be monitored. ​ If you want to disable automatic and track errors manually you can do by passing in automaticErrorTracking: false to the monitorPlayer method that you are using. ​ Whether automatic error tracking is enabled or disabled, you can dispatch errors manually with dispatchError.

let playerName = "iOS KalturaPlayer"   
let playerData = MUXSDKCustomerPlayerData(environmentKey: "ENV_KEY")
// ...insert player metadata

let videoData = MUXSDKCustomerVideoData()
// ...insert video metadata

let customerData = MUXSDKCustomerData(customerPlayerData: playerData, videoData: videoData, viewData: nil, customData: nil, viewerData: nil)

guard let player = self.kalturaPlayer, let data = customerData else {
    return
}

MUXSDKStats.monitorPlayer(player: player, playerName: self.playerName, customerData: data, automaticErrorTracking: false)

// Later, you can dispatch an error yourself
MUXSDKStats.dispatchErrorForPlayer(name: playerName, code: "1234", message: "Something is not right")

Release notes

Current release

  • Fix: Change minimum deployment target to iOS 9.0 and tvOS 9.0

Previous Releases

  • Test: Unit test for destroy player
  • Feature: Support for Google IMA SDK Listener
  • Fix: Missing play event
  • Fix: Improve rendition change detection
  • Fix: Missing rebuffering metrics
  • Test: Unit test infrastructure
  • Test: Add test coverage
  • Third beta release of the Kaltura SDK for iOS
  • Adds tvOS support
  • Adds tvOS target to DemoApp and updates example project
  • Second beta release of the Kaltura SDK for iOS
  • Adds setCustomerDataForPlayer to update metadata after monitor call
  • Adds videoChangeForPlayer to update metadata when a video change occurs
  • Adds programChangeForPlayer:name:customerData: to update metadata when a program change within a stream
  • Adds orientationChangeForPlayer to track orientation changes
  • Adds manual error tracking with dispatchError
  • First beta release of the Kaltura SDK for iOS

Was this page helpful?