Skip to content

harmonicinc-com/client-side-ad-tracking-ios-lib

Repository files navigation

HarmonicClientSideAdTracking

A library for sending ad beacons from the client-side. Works with both traditional SSAI and HLS interstitials. Compatible with iOS/tvOS 15 and above.

Installation

Using Swift Package Manager, enter the URL of this package:

https://github.com/harmonicinc-com/client-side-ad-tracking-ios-lib

Back to TOC

Usage

  1. Import the library

    import HarmonicClientSideAdTracking
  2. Create an AdBeaconingSession object:

    let mySession = AdBeaconingSession()
  3. Optionally, set the session's player to your own instance of AVPlayer:

    let myAVPlayer = AVPlayer()
    mySession.player = myAVPlayer
  4. Set the session's media URL to the master playlist of an HLS stream:

    mySession.mediaUrl = "<hls-master-playlist-url>"
    • Note that the AdBeaconingSession object will then do the following:
      • Try to obtain a manifest URL with a session ID (if the provided mediaUrl doesn't already contain one);
      • Try to obtain the corresponding metadata URL with the session ID.
  5. Observe the session's manifestUrl by using the .onReceive(_:perform:) method in SwiftUI (for UIKit, please see the example below). When it is set and not empty, create an AVPlayerItem with the URL and set it in the player:

    if !manifestUrl.isEmpty {
        let myPlayerItem = AVPlayerItem(url: URL(string: manifestUrl)!)
        mySession.player.replaceCurrentItem(with: myPlayerItem)
    }
  6. Create a HarmonicAdTracker object and initialize it with the session created above:

    let adTracker: HarmonicAdTracker?
    adTracker = HarmonicAdTracker(session: mySession)
  7. Start the ad tracker:

    adTracker?.start()
  8. Start playing and beacons will be sent when ads are played:

    mySession.player.play()
  9. You may observe the following information from the session instance:

    • To get the URLs with the session ID:
      let sessionInfo = mySession.sessionInfo
      URLs available:
      sessionInfo.mediaUrl                        // String
      sessionInfo.manifestUrl                     // String
      sessionInfo.adTrackingMetadataUrl           // String
    • To get the list of AdBreaks returned from the ad metadata along with the status of the beaconing for each event.
      let adPods = mySession.adPods
      For example, in the first AdBreak of adPods:
      adPods[0].id                                // String
      adPods[0].startTime                         // Double: millisecondsSince1970
      adPods[0].duration                          // Double: milliseconds
      adPods[0].ads                               // [Ad]
      In the first Ad of adPods[0].ads:
      ads[0].id                                   // String
      ads[0].startTime                            // Double: millisecondsSince1970
      ads[0].duration                             // Double: milliseconds
      ads[0].trackingEvents                       // [TrackingEvent]
      In the first TrackingEvent of ads[0].trackingEvents:
      trackingEvents[0].event                     // EventType
      trackingEvents[0].startTime                 // Double: millisecondsSince1970
      trackingEvents[0].duration                  // Double: milliseconds
      trackingEvents[0].signalingUrls             // [String]
      trackingEvents[0].reportingState            // ReportingState
    • To get the latest DataRange returned from the ad metadata.
      let latestDataRange = mySession.latestDataRange
      To get the time in millisecondsSince1970:
      latestDataRange.start                       // Double: millisecondsSince1970
      latestDataRange.end                         // Double: millisecondsSince1970
    • To get the status and information of the player.
      let playerObserver = mySession.playerObserver
      Information available:
      playerObserver.currentDate                  // Date
      playerObserver.playhead                     // Double: millisecondsSince1970
      playerObserver.primaryStatus                // AVPlayer.TimeControlStatus
      playerObserver.hasInterstitialEvents        // Bool
      playerObserver.interstitialStatus           // AVPlayer.TimeControlStatus
      playerObserver.interstitialDate             // Double: millisecondsSince1970
      playerObserver.interstitialStoppedDate      // Double: millisecondsSince1970
      playerObserver.interstitialStartTime        // Double: seconds
      playerObserver.interstitialStopTime         // Double: seconds
      playerObserver.currentInterstitialDuration  // Double: milliseconds
    • To get the messages logged by the library.
      let logMessages = mySession.logMessages
      For example, in the first LogMessage:
      logMessages[0].timeStamp                    // Double: secondsSince1970
      logMessages[0].message                      // String
      logMessages[0].isError                      // Bool
  10. Stop the ad tracker when it is not needed:

    adTracker?.stop()

Back to TOC

Minimal working examples

In these examples, ad beacons will be sent while the stream is being played, but no UI is shown to indicate the progress of beaconing.

SwiftUI

import SwiftUI
import AVKit
import HarmonicClientSideAdTracking

struct ContentView: View {
    @StateObject private var mySession = AdBeaconingSession()
    @State private var adTracker: HarmonicAdTracker?

    var body: some View {
        VideoPlayer(player: mySession.player)
            .onAppear {
                mySession.mediaUrl = "<hls-master-playlist-url>"
                adTracker = HarmonicAdTracker(session: mySession)
            }
            .onReceive(mySession.sessionInfo.$manifestUrl) { manifestUrl in
                if !manifestUrl.isEmpty {
                    let myPlayerItem = AVPlayerItem(url: URL(string: manifestUrl)!)
                    mySession.player.replaceCurrentItem(with: myPlayerItem)
                    mySession.player.play()
                    adTracker?.start()
                }
            }
            .onDisappear {
                adTracker?.stop()
            }
    }
}

UIKit

import UIKit
import AVKit
import Combine
import HarmonicClientSideAdTracking

class ViewController: UIViewController {
    private var mySession = AdBeaconingSession()
    private var adTracker: HarmonicAdTracker?
    private var sessionSub: AnyCancellable?

    override func viewDidAppear(_ animated: Bool) {
        mySession.mediaUrl = "<hls-master-playlist-url>"
        adTracker = HarmonicAdTracker(session: mySession)

        let controller = AVPlayerViewController()
        controller.player = mySession.player
        present(controller, animated: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        sessionSub = mySession.$sessionInfo.sink { [weak self] sessionInfo in
            guard let self = self else { return }

            if !sessionInfo.manifestUrl.isEmpty {
                let myPlayerItem = AVPlayerItem(url: URL(string: sessionInfo.manifestUrl)!)
                mySession.player.replaceCurrentItem(with: myPlayerItem)
                mySession.player.play()
                adTracker?.start()
            }
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        adTracker?.stop()
    }
}

Back to TOC

Main SwiftUI views

The library consists of several SwiftUI views that are used in the demo project. They are used to show how to display the progress of beacon-sending, and are not required for the ad beaconing logic to work.

This view shows a list of AdBreakViews.

  • Each AdBreakView indicates an ad break, and shows a list of AdViews, each representing an ad in this ad break.

  • Each AdView indicates an ad, and shows a list of TrackingEventViews, each representing a tracking event in this ad.

  • Each TrackingEventView indicates a tracking event, and shows information for this particular tracking event, including:

    • The event name
    • The signaling URLs
    • The time of the event
    • The state of the beaconing of this event, which may be idle, connecting, done, or failed

Shows information about playback:

  • Playhead
  • Time to next ad beack
  • If interstitials are available:
    • Last interstitial's event date
    • Last interstitial's start time
    • Last interstitial's end time

Also, the different URLs of the session:

  • Media URL (set by the user)
  • Manifest URL (the redirected URL with a session ID)
  • Ad tracking metadata URL

Contains a VideoPlayer with a debug overlay showing the real-world time and the latency. It also reloads by creating a new instance of player when the session's automaticallyPreservesTimeOffsetFromLive option is changed.

Back to TOC

Demo app

A demo app (that can be run on both iOS and tvOS) on how this library (including the SwiftUI views) may be used is available at the following repository: https://github.com/harmonicinc-com/client-side-ad-tracking-ios

Back to TOC

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages