iOS GAM Bidding-Only Integration - Instream Video

Back to Bidding-Only Integration

Ads within video content are often called ‘in-stream’ video ads. See the IAB’s format guidelines for more information and the precise definition.

Integration example:

// 1. Create InstreamVideoAdUnit
adUnit = InstreamVideoAdUnit(configId: CONFIG_ID, size: CGSize(width: 1,height: 1))

// 2. Configure Video Parameters
let parameters = VideoParameters(mimes: ["video/mp4"])
parameters.protocols = [Signals.Protocols.VAST_2_0]
parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOn]
adUnit.videoParameters = parameters

// 3. Prepare IMAAdsLoader
adsLoader = IMAAdsLoader(settings: nil)
adsLoader.delegate = self

// 4. Make a bid request
adUnit.fetchDemand { [weak self] (resultCode, prebidKeys: [String: String]?) in
    guard let self = self else { return }
    if resultCode == .prebidDemandFetchSuccess {
        do {

            // 5. Generate GAM Instream URI
            let adServerTag = try IMAUtils.shared.generateInstreamUriForGAM(adUnitID: gamAdUnitVideo, adSlotSizes: [.Size320x480], customKeywords: prebidKeys!)

            // 6. Load IMA ad request
            let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.instreamView, viewController: self)
            let request = IMAAdsRequest(adTagUrl: adServerTag, adDisplayContainer: adDisplayContainer, contentPlayhead: nil, userContext: nil)
            self.adsLoader.requestAds(with: request)
        } catch {
            PrebidDemoLogger.shared.error("\(error.localizedDescription)")
            self.contentPlayer?.play()
        }
    } else {
        PrebidDemoLogger.shared.error("Error constructing IMA Tag")
        self.contentPlayer?.play()
    }
}

// Step: 7
// MARK: - IMAAdsLoaderDelegate

func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
    // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
    adsManager = adsLoadedData.adsManager
    adsManager?.delegate = self

    // Initialize the ads manager.
    adsManager?.initialize(with: nil)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
    PrebidDemoLogger.shared.error("IMA did fail with error: \(adErrorData.adError)")
    contentPlayer?.play()
}

// Step: 8
// MARK: - IMAAdsManagerDelegate

func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
    if event.type == IMAAdEventType.LOADED {
        // When the SDK notifies us that ads have been loaded, play them.
        adsManager.start()
    }
}

func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
    PrebidDemoLogger.shared.error("AdsManager error: \(error.message ?? "nil")")
    contentPlayer?.play()
}

func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
    // The SDK is going to play ads, so pause the content.
    contentPlayer?.pause()
}

func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
    // The SDK is done playing ads (at least for now), so resume the content.
    contentPlayer?.play()
}

Starting from PrebidMobile 2.1.0 the VideoAdUnit class is deprecated. Use InstreamVideoAdUnit class instead.

Step 1: Create an InstreamVideoAdUnit

Initialize the Instream Video Ad Unit with properties:

  • configId - an ID of Stored Impression on the Prebid Server
  • size - Width and height of the video ad unit.

Step 2: Configure video parameters

Provide configuration properties for the video ad using the VideoParameters object.

Using the VideoParameters object you can customize the bid request for video ads.

placement

Not needed for Instream video integration, which uses placement=1 and plcmt=1.

The OpenRTB 2.6 Placement Type for the auction can be expressed as an integer array or you can use an enum for easier readability.

  • 2 or InBanner : In-Banner placement exists within a web banner that leverages the banner space to deliver a video experience as opposed to another static or rich media format. The format relies on the existence of display ad inventory on the page for its delivery.
  • 3 or InArticle : In-Article placement loads and plays dynamically between paragraphs of editorial content; existing as a standalone branded message.
  • 4 or InFeed : In-Feed placement is found in content, social, or product feeds.
  • 5 or Slider, Floating or Interstitial : Open RTB supports one of three values for option 5 as either Slider, Floating or Interstitial. If an enum value is supplied in placement, bidders will receive value 5 for placement type and assume to be interstitial with the instl flag set to 1.

Notes:

  • VideoInterstitialAdUnit and rewarded video ads will default to placement= 5 if no placement value is supplied.

api

The api property is dedicated to adding values for API Frameworks to bid response according to the OpenRTB 2.6 spec. The supported values for GMA SDK integration are:

  • 1 or Signals.Api.VPAID_1 : VPAID 1.0
  • 2 or Signals.Api.VPAID_2 : VPAID 2.0
  • 3 or Signals.Api.MRAID_1 : MRAID-1 support signal
  • 5 or Signals.Api.MRAID_2 : MRAID-2 support signal
  • 6 or Signals.Api.MRAID_3 : MRAID-3 support signal
  • 7 or Signals.Api.OMID_1 : signals OMSDK support

maxBitrate

Integer representing the OpenRTB 2.6 maximum bit rate in Kbps.

minBitrate

Integer representing the OpenRTB 2.6 minimum bit rate in Kbps.

maxDuration

Integer representing the OpenRTB 2.6 maximum video ad duration in seconds.

minDuration

Integer representing the OpenRTB 2.6 minimum video ad duration in seconds.

mimes

Array of strings representing the supported OpenRTB 2.6 content MIME types (e.g., “video/x-ms-wmv”, “video/mp4”). Required property.

playbackMethod

Array of OpenRTB 2.6 playback methods. If none are specified, any method may be used. Only one method is typically used in practice. It is strongly advised to use only the first element of the array.

  • 1 or Signals.PlaybackMethod.AutoPlaySoundOn : Initiates on Page Load with Sound On
  • 2 or Signals.PlaybackMethod.AutoPlaySoundOff : Initiates on Page Load with Sound Off by Default
  • 3 or Signals.PlaybackMethod.ClickToPlay : Initiates on Click with Sound On
  • 4 or Signals.PlaybackMethod.MouseOver : Initiates on Mouse-Over with Sound On
  • 5 or Signals.PlaybackMethod.EnterSoundOn : Initiates on Entering Viewport with Sound On
  • 6 or Signals.PlaybackMethod.EnterSoundOff: Initiates on Entering Viewport with Sound Off by Default

protocols

Array or enum of OpenRTB 2.6 supported Protocols. Values can be one of:

  • 1 or Signals.Protocols.VAST_1_0 : VAST 1.0
  • 2 or Signals.Protocols.VAST_2_0 : VAST 2.0
  • 3 or Signals.Protocols.VAST_3_0 : VAST 3.0
  • 4 or Signals.Protocols.VAST_1_0_Wrapper : VAST 1.0 Wrapper
  • 5 or Signals.Protocols.VAST_2_0_Wrapper : VAST 2.0 Wrapper
  • 6 or Signals.Protocols.VAST_3_0_Wrapper : VAST 3.0 Wrapper
  • 7 or Signals.Protocols.VAST_4_0 : VAST 4.0
  • 8 or Signals.Protocols.VAST_4_0_Wrapper : VAST 4.0 Wrapper

Step 3: Prepare IMAAdsLoader

Prepare the in-stream setup according to the Google’s docs.

Step 4: Make a bid request

The fetchDemand method makes a bid request to the Prebid Server. You should use the version of the fetchDemand which returns the targeting keywords in the callback. Later you will construct the IMA ad request using these keywords.

Step 5: Generate GAM Instream URI

Using Prebid util method, generate Google IMA URI for downloading the cached creative from the winning bid.

Step 6: Load IMA ad request

Create an ad display container for ad rendering. Then create an ad request with our ad tag, display container, and optional user context. Load the ad. Follow the in-stream video guide for additional details.

Step 7: Set up an ads loader delegate

On a successful load event, the IMAAdsLoader calls the adsLoadedWithData method of its assigned delegate, passing it an instance of IMAAdsManager. You can then initialize the ads manager, which loads the individual ads as defined by the response to the ad tag URL.

Step 8: Set up an ads manager delegate

Lastly, to manage events and state changes, the ads manager needs a delegate of its own. The IMAAdManagerDelegate has methods to handle ad events and errors, as well as methods to trigger play and pause on your video content.

Further Reading