Adverts with Google IMA

The Player SDK for FPS is designed to be easily extendable through 3rd party components.

One of these components, called IMAWrapper, is a wrapper for the Google Interactive Media Ads (IMA) framework, which supports linear advertisements in conjunction with content played via the SDK. This page explains the steps you need to follow to implement and integrate, together with code examples. It should be used alongside the supplied example application, dynamic-ads-ima.

The following component diagram shows how it fits together:

arch

Adverts are only supported on iOS and not on tvOS.

Workflow

The following diagram shows the full workflow of the application, the IMAWrapper, and the IMA Framework:

lifecycle

Prerequisites

  • An ad server already configured and knowledge of the ad tag URLs that will be used to access it.

  • An understanding of the CocoaPods technology. See CocoaPods Guides.

  • A working integration of the Nagra OpenTV Player FPS SDK for iOS (the dynamic-ads-ima example code).

  • A device to show the content – a handheld device supporting iOS 11 or above.

  • A valid licence in the application bundle (see Integration Guidelines The Player Licence

Procedure

The following procedure is split into two stages:

  1. Installing the IMA CocoaPods pod

  2. Enabling playback of linear adverts

Installing the IMA CocoaPods pod

The dynamic-ads-ima example application includes a pod file so you may skip to step 3. If you want to do the pod integration from scratch, follow from step 1.

  1. install cocoapods by running the following command:

    sudo gem install cocoapods
    
  2. Create your app's podfile in the project's root folder by running pod init and add the IMA pod dependency, which should look something like this:

    target '<target_name>' do
    use_frameworks!
    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '9.0'
    pod 'GoogleAds-IMA-iOS-SDK', '~> 3.9'
    end
    
  3. To apply this into your project execute the following command in the project's root folder (where the Xcode project file is located):

    pod install  --repo-update
    

    The --repo-update switch is only required if you need the pod details to be reflected back into the corresponding project workspace files, for example the first time it has ever been run.

There will now be a .xcworkspace configured with the IMA Pod linking capability. You must use this instead of the .xcodeproj

Enabling playback of linear adverts

Follow the steps in the Integration Guidelines if you need to understand the process for basic playback, and the setting up of the PlayerView and main.storyboard.

  1. In ViewController.swift, we need the following imports:

    import OPYSDKFPS
    import GoogleInteractiveMediaAds
    
  2. Update the View Controller.

    a. Set the ad tag URL. You specify the configuration of adverts you want in an ad tag URL. For example:

      class ViewController: UIViewController {
    
        let otvPlayer : OTVAVPlayer
        @IBOutlet weak var playerView: PlayerView!
        let assetURL = URL(string:
          "https://d3bqrzf9w11pn3.cloudfront.net/basic_hls_bbb_clear/index.m3u8")!
    
        //VMAP Pre-, Mid-, and Post-rolls, Single Ads
        let adTagURL = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480" +
                      "&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&" +
                      "gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26" +
                      "sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=;"
    
        ...
    
  3. After the init method, add an attribute to access the IMAWrapper

      // IMAWrapper that is used to managed the IMA Google Framework
      var imaWrapper: IMAWrapper?
    
  4. In the same file we implement the IMAWrapperDelegate protocol. This allows the IMAWrapper class's functionality to be triggered for advert management. Do this by extending the ViewController class. For example:

      // ViewController must adopt the protocol IMAWrapperDelegate
      // so the IMAWrapper can access player fuctions.
      extension ViewController: IMAWrapperDelegate {
        func pauseContent() {
          print("IMAWrapper: pause video to show ads")
          otvPlayer.pause()
        }
    
        func resumeContent() {
          print("IMAWrapper: resume video")
          otvPlayer.play()
        }
    
        func allAdsCompleted() {
          print("IMAWrapper: all ads completed")
        }
    
        func log(event: String?) {
          print("IMAWrapper: AdsManager error: \(event ?? "empty message")")
        }
      }
    
  5. Add the viewDidAppear method, with the following:

    a. Instantiate the IMAWrapperAdsSettings class to override default Google IMA configuration.

    b. Instantiate the IMAWrapperPlayerDetails class which allows the provision of the UI elements and details of the Ad Tag URI to the IMAWrapper.

    c. Instantiate the IMAWrapper class, providing a reference to the class that implements the IMAWrapperDelegate protocol. In this example ViewController implements the protocol so we pass a reference to self.

    d. call requestAds() to start the ads

    Your viewDidAppear method should look like the following:

    override func viewDidAppear(_ animated: Bool) {
      super.viewDidAppear(animated)
    
      // Customise the settings of the IMAWrapper see API documention for details
      let setupSettings = IMAWrapperAdsSettings(settingsDictionary: [String: Any]() )
    
      // Set companionAdViews to nil if there are no companionAdViews
      let playerDetails = IMAWrapperPlayerDetails(contentPlayer: otvPlayer,
                                                      adsUIView: playerView,
                                                        adTagURL: adTagURL,
                                                companionAdViews: nil)
    
      // Initialise the IMAWrapper object
      imaWrapper = IMAWrapper(withPlayerDetails: playerDetails,
                                    withDelegate: self,
                                    withSettings: setupSettings)
    
      // Request ads to start, no need to call player.play() since the player will start once adverts complete
      // N.B. requestAds() will return false if the adTagURL hasn't been set/ is empty.
      if imaWrapper?.requestAds() == true {
        print("IMAWrapper: requestAds returned true")
      }
    }
    
  6. Build and run on a device to see ads