This guide walks through integration with iOS and TVOS Kaltura player to collect video performance metrics with Mux data.
Features
The features supported by Mux Data for this player.
Install the Mux Data SDK
Install Mux-Stats-Kaltura
and import the framework into your application.
Initialize the monitor for your Kaltura player instance
Make your data actionable
Use metadata fields to make the data collected by Mux actionable and useful.
Set or update metadata after monitor
If you do not have all the metadata available at initialization time update metadata fields later.
Advanced
Depending on the details of your implementation, you may want to leverage some of the advanced options of Mux-Stats-Kaltura.
Release notes
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.
The following data can be collected by the Mux Data SDK when you use the Kaltura iOS SDK, as described below.
Supported Features:
renditionchange
eventsPackaged 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
Get your ENV_KEY
from the Mux environments dashboard.
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.
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
)
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)
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:
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
.
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.
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)
}
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")
setCustomerDataForPlayer
to update metadata after monitor callvideoChangeForPlayer
to update metadata when a video change occursprogramChangeForPlayer:name:customerData:
to update metadata when a program change within a streamorientationChangeForPlayer
to track orientation changesdispatchError