prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.28k stars 2.05k forks source link

[I2I] Prebid support for long form video #3379

Closed mkendall07 closed 5 years ago

mkendall07 commented 5 years ago

Type of issue

Intent to implement. Status: Open for comment.

Table of Contents

Background

Today, premium video publishers do not have an effective solution to monetize long-form video content through programmatic partners. In most cases, programmatic partners are included via tag-based waterfalls in the primary ad server. These waterfalls are complex, detrimental to user experience, and suboptimal for monetization by functioning solely on remnant inventory and by limiting each demand partner's ability to see and bid on video impressions. Many premium video publishers are unwilling even to implement programmatic partners via waterfall, as there is no way to ensure that competitive separation rules will be enforced.

Prebid.js can provide a better solution for premium video publishers.

Goals

Requirements

Proposed Design

Architecture Diagram

In Phase 1, We are using FreeWheel as Ad Server alt text

Steps
  1. Prebid makes a bid request to configured demand partners
  2. Store bids in Prebid Cache.
  3. Send targeting kv pairs to Freewheel SDK.
    [
    {
    hb_pb_industry_duration: 10.00_airline_15s,
    },
    {
    hb_pb_industry_duration: 15.00_retail_30s,
    }
    ]
  4. Freewheel SDK makes request to Freewheel AdServer. KV pairs and slots are added as query param to http request. http://[customerId].v.fwmrm.net/ad/g/1[globalParams];hb_pb_industry_duration=10.00_airline_15s&hb_pb_industry_duration=15.00_retail_30s&hb_uuid=123;[ParamsForSlot1];[ParamsForSlot2];...;[ParamsForSlotN];
  5. Freewheel Adserver selects the creatives and sends back to FreeWheel SDK.
  6. FreeWheel SDK's VAST translator will make a request to Prebid Cache Endpoint and get the VAST XML. https://prebid.adnxs.com/pbc/v1/cache?uuid=10.00_airline_15s_123
  7. FreeWheel SDK will pass the VAST to player and will start playing the ad.

AdUnit Definition

Param Type Required Default Value Example Value Notes
adUnit.mediaTypes.video.context string x "longform" value is new, param already exists
adUnit.mediaTypes.video.playerSize array[number] x [480,600] exists today
adUnit.mediaTypes.video.adPodDurationSec number x 120 adPod total duration
adUnit.mediaTypes.video.durationRangeSec array[number] x [15, 30, 60] allowed creative duration(s)
adUnit.mediaTypes.video.requireExactDuration boolean false true
adUnit.mediaTypes.video.tvSeriesName string "TvSeriesName"
adUnit.mediaTypes.video.tvEpisodeName string "tvEpisodeName"
adUnit.mediaTypes.video.tvSeasonNumber number 42
adUnit.mediaTypes.video.tvEpisodeNumber number 15
adUnit.mediaTypes.video.contentLengthSec number 800
adUnit.mediaTypes.video.contentMode string "live" values can be any one of on-demand or live. Note: This has no affect on the pbjs core functionality, value will be a pass through to SSPs bidders.

Example

 var longFormatAdUnit = {
  video: {
    // required params
    context: 'longForm', // new value
    playerSize: [640, 480], // existing param
    adPodDurationSec: 300,
    durationRangeSec: [15, 30],
    // optional params
    requireExactDuration: true,
    tvSeriesName: 'TvName',
    tvEpisodeName: 'episodeName',
    tvSeasonNumber: 3,
    tvEpisodeNumber: 6,
    contentLength: 300, // time in seconds,
    contentMode: 'on-demand'
  }
}

Bidder Spec

Github issue: https://github.com/prebid/Prebid.js/issues/3115 We'll add support for the following params into the bid object.

Param Type Required Example Value Use Case
video.durationSeconds array[string] x 30 Required to know if the bid meets the criteria and fits into the ad pod.
meta.iabBrandSubCat string x 'iab2-3' Used for competitive category exclusion. If bid does not contain a IAB brand sub-category OR FW brand category, it will not be eligible for participating in freewheel auction if,requireBrandCategory = true
meta.freewheelBrandCat string "Food" Used for competitive category exclusion. If bid does not contain a IAB brand sub-category OR FW brand category, it will not be eligible for participating in freewheel auction if,requireBrandCategory = true

Bidder support of video.context = 'longForm'

In addition, bidders should recognize a new video format passed in the request such as `adUnit.mediaTypes.video.context = 'longForm'. Each bidder will need to either A) Send the request to the endpoint to determine the optimal number of bids for each AdUnit OR B) The adapter should use an algorithm to break the adUnit into multiple bid requests as described in the below uses cases

Use Cases

Examples of the proposed publisher configuration for various scenarios follows:

  1. As a user of Prebid.js, I want to get demand for long format video by only specifying total ad pod duration and a subset of video durations that maximizes my yield.
var longFormatAdUnit = {
  video: {
    context: 'longForm', 
    playerSize: [640, 480],
    adPodDurationSec: 300,
    durationRangeSec: [15, 30],
  }
}

SSP's should break out requests to maximize yield and return n number of bids where adPodDuration/durationRangeSec[0] <= n <= adPodDuration/durationRangeSec[length-1]. Bids returned should have duration in between 15s and 30s. Prebid will reject bids if duration is out of range. Any bid returned by SSP which falls within the duration range will be rounded upwards to the nearest duration in durationRangeSec.

  1. As a user of Prebid.js, I want to get demand for long format video by only specifying total ad pod duration and exact video durations that maximizes my yield.
var longFormatAdUnit = {
  video: {
    context: 'longForm', 
    playerSize: [640, 480],
    adPodDurationSec: 300,
    durationRangeSec: [15, 30, 45],
    requireExactDuration: true
  }
}

SSP's should break out requests to maximize yield and return n number of bids where adPodDuration/durationRangeSec[0] <= n <= adPodDuration/durationRangeSec[length-1]. Bids returned should exactly match duration defined in adUnit since requireExactDuration flag is set to true. Prebid will reject bids if duration does not match. Prebid core will make sure winning bids total duration does not exceed adPodDuration. Prebid will make sure no invalid durations are included.

  1. As a user of Prebid.js, I want to configure long format demand for N adPods, each with a set number of adSlots and/or max pod durations.
    var longFormatAdUnit = [{
    code: 'preroll_1'
    video: {
    context: 'longForm', 
    playerSize: [640, 480],
    adPodDurationSec: 300,
    durationRangeSec: [15, 30, 45],
    requireExactDuration: true
    }
    }, {
    code: 'midroll_1'
    video: {
    context: 'longForm', 
    playerSize: [640, 480],
    adPodDurationSec: 300,
    durationRangeSec: [15, 30, 45],
    requireExactDuration: true
    }
    }]

SSP's with single request architecture in such a case should break request into chunks if it will create too many individual requests to the SSP. This is at the SSP's discretion. Prebid core will provide utils functions to adapters to do this seamlessly if desired. For adPodDurationSec and durationRangeSec same rules explained in use case 1 and 2 will apply.

FreeWheel Module

A new Freewheel module will expose additional APIs to get targeting key value pairs for long form video bids. These KV's can then be added to ad server request url.

pbjs.adServers.freewheel.getTargeting(options)
Param Type Description
options.adUnitCodes array[string] AdUnit codes to include targeting for. Defaults to all
options.requireBrandCategory boolean Only select bids for K/V targeting that contain a FW brand category. Defaults to false.

Content Category Translation Module

Freewheel needs Industry group to do competitive separation. Each demand partner must return exactly 1 IAB sub category in their bid response to Prebid.js. This module will translate the IAB category into a FreeWheel industry group based on a mapping defined at an external URL. This should be similar to how the current currency conversion module works. Prebid will use a default mapping file and will be hosted on open source cdn. Since this mapping file will not change often, Prebid will store the mapping file in localStorage after first load.

Publisher can also configure to use their own mapping file.

pbjs.setConfig({
    "brandCategoryTranslation": {
       "translationFile": "<url_to_file>"
    }
});

Prebid Cache Updates

Add a new optional string key param that will allow users to specify a cache key used by the cache service. This will allow us to know the cache key ahead of time and send it to FW based on a known pattern. This is required because FW lacks the ability to send key/value pairs that are associated with a particular adUnit/Slot.

Example request:

{
  "puts": [
    {
      "type": "xml",
      "ttlseconds": 60,
      "value": "<tag>Your XML content goes here.</tag>",
      "key" : "${client_provided_key}"
    },
    {
      "type": "json",
      "ttlseconds": 300,
      "value": [1, true, "JSON value of any type can go here."]
    }
  ]
}

Constraints: If a key already exists in the cache for a given key or the write fails returns a 4xx error.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

harpere commented 5 years ago

I don't know a lot about longForm video but read through and have some questions:

spatnaik-prebid commented 5 years ago

LongForm video comments.pdf

@mkendall07 & @bretg fyi

jaiminpanchal27 commented 5 years ago

@spatnaik-prebid I have copied your questions from pdf.

Publishers must be able to get a list of key-values from Prebid.js that they will add to their Primary ad server's ad request URL. Q. Why is this a requirement?

A. This is a requirement because Prebid does not know which player is going to make request to Freewheel adserver. As of now we have very limited information regarding video player's api's supporting longform. So we have not developed any method to setTargeting automatically. We are just exposing getTargeting method for supported adserver. We started with Freewheel module which will return the targeting for longform when executed after auction.

Prebid.js must make sure that demand partners return a exactly one IAB category on each bid response. Q. best to make it clear that this is IAB content category

A. Demand partners must return only one iab sub category.

Q. many advertisers fit 1+ categories, is the requirement here to reject any such bids?

A. Yes any such bids would be rejected.

Prebid.js must provide a module for converting IAB category to FreeWheel Industry Group. Q. Again, IAB content category. Instead of a module, we could call it mapping. Is this 1-1 or 1 - many?

A. Refer to the description here. https://github.com/prebid/Prebid.js/pull/3513

is this Iab category in the kv pairs? then it should use the n,ming scheme IAB-x (instead of airline). Also please note that there are secondary, tertiary categories, such as

A. We have updated our targeting kv pairs.

pbjs.adServers.freewheel.getTargeting();
pbjs.adServers.freewheel.getTargeting({codes:['adUnitCode-1']});

Sample return
{
  'adUnitCode-1: [
    {
      'hb_pb_cat_dur': '10.00_403_15s'
    },
    {
      'hb_pb_cat_dur': '15.00_394_30s'
    },
    {
      'hb_uuid': '123'
    }
  ]
}

FreeWheel has Industry groups and sub industry under each group. We are only focusing on Industry group. Prebid's category translation module will convert IAB sub category to FreeWheel Industry Group Id. More can be found here https://github.com/prebid/Prebid.js/pull/3513

Freewheel Adserver selects the creatives and sends back to FreeWheel SDK. Q. is it selected based on competitive exclusion requirements?

A. It depends on the setup in FreeWheel.

FreeWheel SDK's VAST translator will make a request to Prebid Cache Endpoint and get the VAST XML.

https://prebid.adnxs.com/pbc/v1/cache?uuid=10.00_airline_15s_123 Q. is the uuid not good enough?

A. To target placement we need the first part that is 10.00_airline_15s and uuid is added to create unique cache key. More to come on this on Prebid.org

AdUnit Definition Q. IAB came up with param names for this in VAST 4.1 ; perhaps its better to standardize around those param names so that all of us speak the same language?

adUnit.mediaTypes.video.context Q. how does longform vs short clips matter

A. Need some more info here. Do you mean difference between adpod and instream or outstream ?

Q. is there ,concept of mid roll vs pre roll here? if not, why?

A. In Prebid, we have not added any extra param to specify whether it is mid roll or pre roll. It depends on how you requestBids for adpod (previously longform) context. For example if there is an episode of 1 hr with 3 commercial breaks, Pub can configure any number of adunits to get as many bids as possible. Prebid will just send maximum bids based on adpod duration and adserver will pick them up.

spatnaik-prebid commented 5 years ago

@spatnaik-prebid I have copied your questions from pdf.

Publishers must be able to get a list of key-values from Prebid.js that they will add to their Primary ad server's ad request URL. Q. Why is this a requirement?

A. This is a requirement because Prebid does not know which player is going to make request to Freewheel adserver. As of now we have very limited information regarding video player's api's supporting longform. So we have not developed any method to setTargeting automatically. We are just exposing getTargeting method for supported adserver. We started with Freewheel module which will return the targeting for longform when executed after auction.

I still dont get this requirement, @jaiminpanchal27, can we discuss?

Prebid.js must make sure that demand partners return a exactly one IAB category on each bid response. Q. best to make it clear that this is IAB content category

A. Demand partners must return only one iab sub category.

Q. many advertisers fit 1+ categories, is the requirement here to reject any such bids?

A. Yes any such bids would be rejected.

@jaiminpanchal27 - who rejects those advertisers - the bidder?

Prebid.js must provide a module for converting IAB category to FreeWheel Industry Group. Q. Again, IAB content category. Instead of a module, we could call it mapping. Is this 1-1 or 1 - many?

A. Refer to the description here. #3513

is this Iab category in the kv pairs? then it should use the n,ming scheme IAB-x (instead of airline). Also please note that there are secondary, tertiary categories, such as

A. We have updated our targeting kv pairs.

pbjs.adServers.freewheel.getTargeting();
pbjs.adServers.freewheel.getTargeting({codes:['adUnitCode-1']});

Sample return
{
  'adUnitCode-1: [
    {
      'hb_pb_cat_dur': '10.00_403_15s'
    },
    {
      'hb_pb_cat_dur': '15.00_394_30s'
    },
    {
      'hb_uuid': '123'
    }
  ]
}

FreeWheel has Industry groups and sub industry under each group. We are only focusing on Industry group. Prebid's category translation module will convert IAB sub category to FreeWheel Industry Group Id. More can be found here #3513

Freewheel Adserver selects the creatives and sends back to FreeWheel SDK. Q. is it selected based on competitive exclusion requirements?

A. It depends on the setup in FreeWheel.

FreeWheel SDK's VAST translator will make a request to Prebid Cache Endpoint and get the VAST XML.

https://prebid.adnxs.com/pbc/v1/cache?uuid=10.00_airline_15s_123 Q. is the uuid not good enough?

A. To target placement we need the first part that is 10.00_airline_15s and uuid is added to create unique cache key. More to come on this on Prebid.org

AdUnit Definition Q. IAB came up with param names for this in VAST 4.1 ; perhaps its better to standardize around those param names so that all of us speak the same language?

adUnit.mediaTypes.video.context Q. how does longform vs short clips matter

A. Need some more info here. Do you mean difference between adpod and instream or outstream ?

@jaiminpanchal27 - no, not instream, my question is why are you guys calling this long form, the only thing that matters here is saying context = adpod, not long form...

Q. is there ,concept of mid roll vs pre roll here? if not, why?

A. In Prebid, we have not added any extra param to specify whether it is mid roll or pre roll. It depends on how you requestBids for adpod (previously longform) context. For example if there is an episode of 1 hr with 3 commercial breaks, Pub can configure any number of adunits to get as many bids as possible. Prebid will just send maximum bids based on adpod duration and adserver will pick them up. -- @jaiminpanchal27 - that info is required for transparency to DSPs

mkendall07 commented 5 years ago

This feature has been implemented and thus closing out. Any concerns on the documentation should be in a new issue.