Advertising plugin

The Advertising plugin allows to play video and text/overlay ads from multiple VAST (versions 2, 3 or 4)/VPAID (version 2) compliant tags or a single VMAP / adPod tag.

Installation

Manual installation

Load the core player and the Advertising plugin.

For versions before v3.4.5, you also need to load the Google IMA3 SDK.

Copy
Copied
<script src="//cdn.flowplayer.com/releases/native/3/stable/flowplayer.min.js"></script>
<!-- for player versions before 3.4.5>
<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script> -->
<script src="//cdn.flowplayer.com/releases/native/3/stable/plugins/ads.min.js"></script>

Configuration

You can configure the plugin manually using JavaScript.

Core plugin configuration

Ads are configured with the top level configuration option ima.

Property Description
ads array a list of ads to display
ads[].adTag string or array AdTag url to load VAST from, several tags can be configured for waterfalling
ads[].time number time to show adTag at: 0 is a preroll, -1 is postroll, values above 0 set the ad time in seconds
ads[].restart boolean whether the ad should attempt to restart the content. default: true
autopause boolean whether ads should automatically pause when the player is out of the viewport. Default: true
indicator boolean set to false to disable the Ad N/N ad indicator in the ad UI. Default is true.
show_all_ads_on_seek boolean when viewer seeks ahead in the timeline, show all ad breaks between current time and new seek position. Default is true.
timeout number how long to wait for ad response from the network in milliseconds. Default is 5000.
parameters object custom Ad Macro parameters injected into the Macro replacement engine
ui integer A bitmask configuring UI elements. Default is undefined.

UI configuration

Option Description
flowplayer.ads.ui.STICKY_CONTROLS Do not hide controls
flowplayer.ads.ui.NO_FULLSCREEN Hide fullscreen button
flowplayer.ads.ui.NO_AD_INDICATOR Hide ad indicator text
flowplayer.ads.ui.AD_CHOICES Show ad choices logo
flowplayer.ads.ui.REMAINING_TIME Show ad remaining time widget

Example

Copy
Copied
flowplayer('#player_container', {
  src: 'my_video.mp4',
  token: '<my_token>',
  ads: {ui: flowplayer.ads.ui.AD_CHOICES | flowplayer.ads.ui.AD_REMAINING_TIME},
  ima: {...}
})

Configuration example code

Javascript ima: object

Copy
Copied
"ima": {
        "ads":
         [
          { "time": 0, "adTag": "https://mydserver.com/path/vast.xml" }, // ad 1: preroll
          { "time": 20, "adTag": "https://mydserver.com/path/vast2.xml" }, //ad 2: midroll at 20 seconds
          { "time": 300, "adTag": "https://mydserver.com/path/vast3.xml" } //ad 2: midroll at 300 seconds
        ]
        ,"parameters": { "age": 25, "location": "us" }
        , "show_all_ads_on_seek" : false // do not show first and second midroll if user seeks after 300 seconds
        , "indicator": false // disable ad indicator
        , "ui":
      }

API

The API is under the ads namespace in the player instance. It provides the following methods, properties and events:

Methods

method description
pause() Pauses the ad
resume() Resumes the ad
requestAd(adTag: string) Attempts to request & play an adTag
resetSchedule(adSchedule: Array<{adTag: string, time: integer}>) Resets the internal ad schedule. The adSchedule is the same ad ima.ads in the code sample above.

Properties

property description
adPlaying Boolean to show when the ad is playing

Events

Event constants can be found under flowplayer.ads.events.

Events can be listened to under the ads namepsace in the player instance.

Example:

Copy
Copied
player.ads.on(flowplayer.ads.events.AD_REQUEST_ERROR, function(details) {
  console.log('ad request error, reason', details.reason)
})
event type description
AD_INIT general
AD_PLAYBACK_ERROR general Ad request was successful, but ad fails to play
AD_TEARDOWN general
AD_VIDEOTAG_ATTACHED general
AD_REQUEST_ERROR http Ad was requested, but the ad request fails
AD_REQUESTED http Fires when an ad request has been made
AD_REQUEST_COMPLETED http
AD_PAUSE_CONTENT timing
AD_STARTED timing Ad was received and starts to show
AD_COMPLETED timing When a single ad has finished
AD_PAUSED timing When the ad has been paused
AD_RESUMED timing When the ad resumes
AD_WAITING timing
AD_PROGRESS timing Fires when the ad progresses
AD_SKIPPED timing When the skip button has been clicked
AD_MUTED timing When the ad is muted
AD_VOLUME_CHANGED timing Volume has been changed during ad playback
AD_FULLSCREEN timing When the ad goes fullscreen
AD_TIMEOUT timing
AD_BREAK_COMPLETED ad groups When all ads for a specific timeslot have been shown
AD_POSTROLL_FINISHED ad groups Fires when content is starting. If there's a preroll configured, and it plays, this event will fire after the ad break is complete
AD_PREROLL_FINISHED ad groups Fires when both content and (possible) postroll are finished. Also fires when no postroll is configured.
AD_MIDROLL_FINISHED ad groups
VPAID_INIT ad groups
IMA_ADAPTER_INIT adapter A special event to expose the IMA SDK AdsManager instance for custom event handling. The AdsManager instance is passed as a parameter to the event handler.
IMA_BEFORE_ADS_REQUEST adapter A special event to expose the IMA SDK AdsRequest
IMA_ADS_RENDERING_SETTINGS adapter A special event to expose the IMA SDK AdsRenderingSettings
ADAPTER_INIT_FAILED adapter
AD_PLAY_REQUESTED adapter
RELOAD_AD_REQUESTED adapter
AD_ERROR adapter
REQUEST_AD_PAUSE ui
REQUEST_AD_PLAY ui
REQUEST_AD_MUTE_UNMUTE adapter

An example usage of IMA_BEFORE_ADS_REQUEST to set the forceNonLinearFullslot option might look like:

Copy
Copied
player.on(flowplayer.ads.events.IMA_BEFORE_ADS_REQUEST, (e)=> {
  const req = e.data.request
  req.forceNonLinearFullslot = true
})

An example usage of the IMA_ADS_RENDERING_SETTINGS to set the maximum bitrate would look like:

Copy
Copied
player.on(flowplayer.ads.events.IMA_ADS_RENDERING_SETTINGS, (e)=> {
  const renderSettings = e.data
  renderSettings.bitrate = 1024 * 10 // 10kbs
})

async adTag loading

If you intend to load adTags asynchronously through the API, you'll have to implement a fetcher function returning a new Promise and pass this to the player in the ima: configuration object.

The code might look like this:

Copy
Copied
<script type="text/javascript">
// a basic asynchronous adTag fetcher
// can be integrated with any ad bidding systems
// must always return `Promise<string>` where  string` contains the async adTag

function asyncAdTagFetcher () {
  return new Promise(function(resolve, reject) {
		resolve("https://adserver.adcompany.com/pathto/adtag_vast.xml")
	})
}

//init player
  var fpInstance = flowplayer('#player_container', {
    src: "https://some.domain.com/pathto/media.mp4",
    autoplay: true,    
    token: '<your token>',
    ima: { preload: true
    ads: [{ time: 0
            // use the async fetcher to resolve the adTag
          , adTag: asyncAdTagFetcher
          }]
  }
  });
</script>

You can find another example in our prebid.js Codepen.

Macros

To help your ad server deliver better ads for your customers you can pass metadata along with the ad request to the ad server.

Metadata is transferred to the ad server in the ad tag url by replacing pre-defined placeholders with configured values.

For instance, https://myadserver.com/ad?gender=[gender]&age=[age] with parameters { gender: 'male', age: 25 } would get translated into https://myadserver.com/ad?gender=male&age=25.

We offer several built-in macros, which are available everywhere, including self-hosted content.

Built-in macros

These macros are available for self-hosted content.

macro description
autoplay whether the content is autoplayed
page_url url where the content is playing
domain domain playing the content
media_duration duration of the content media
player_height height of the current player
player_width width of the current player
random random integer for cache-busting
video_url url of the currently playing video source

Custom macros

There are two ways of passing your custom parameters to an Ad depending on development needs.

Via the advanced js api:

Copy
Copied
  const video = flowplayer(
    { src: "f576651c-4cc6-4664-84fa-bb3b35ef1aba"
    , ima: { ads: [{time: 0, adTag: adTag}]
           , parameters: {age: 25, location: "us"}
           }
    })

Or, via the __flowplayerAdParameters magic global:

Copy
Copied
window.__flowplayerAdParameters =
  { age      : 25,
  , location : "us"
  }

The __flowplayerAdParameters global can be mutated and the mutations will propogate to the next ad call. This exposes an easy interface for dynamically synchronizing parameters over time.

Waterfalling

Waterfalling is the idea that if one ad network cannot provide a valid slot, a fallback network is then checked for a second best offering, and so on. Our ad plugin offers a simple setup of this feature to maximize revenue.

When configurating the ima.ads property, if an adTag is an Array<string>, it will assume that the adTags are an ordered list of waterfall ad providers.

Here is an example:

Copy
Copied
  const video = flowplayer(
    { src: "f576651c-4cc6-4664-84fa-bb3b35ef1aba"
    , ima: { ads: [
               { time  : 0
               , adTag : [ "https://ads.network1.com/top_choice.xml"
                           // this ad network will only be tried
                           // if the first adTag fails to fill the slot
                         , "https://ads.network2.com/waterfall_1.xml"
                         ]
               }]
    })

IMA settings

It is possible to manually set any of the IMA SDK settings by passing the name of the method without the set prefix.

For example, to set the locale you would pass Locale which will be detected internally and proxied to the setLocale() method.

Here is a complete code sample:

Copy
Copied
const video = flowplayer(
    { src: "f576651c-4cc6-4664-84fa-bb3b35ef1aba"
    , ima: { ads: [{time: 0, adTag: adTag}]
           , Locale: "en"
           , NumRedirects: 3
           }
    })

Please note that when an option is an internal IMA setting, it will begin with an uppercase letter like CookiesEnabled.

Outstream ads

Outstream ads are video ads that unroll and display advertising to a reader mid-read during text content. They are called "Outstream" because the advertising content exists outside of a normal content video lifecycle. As the user scrolls down the page, when the Outstream player comes into view, it will unfold and attempt to play the ad.

Our ad plugin supports graceful fallback to muted autoplay when autoplay with audio is not supported, on devices/browsers that allow autoplaying video content. When autoplay is not allowed, it will also gracefully handle the error.

Info

Outstream ads are subject to the same autoplay rules as normal content.

Here is an example ima configuration option that would enable an Oustream ad:

Copy
Copied
ima: {
	ads: [
		// must be in preroll position
		{"time": 0
		// your ad tag
		,"adTag":"your.ads.com/vast.xml"
		// mark that this ad is outstream.
		,"outstream":true
		}
	]
}

Please also check the outstream ads demo.

Common outstream questions

  1. Can I enable unmute on hover?
    • It is not possible to safely do this. The onmouseenter event is not considered a trusted user-gesture for the purposes of toggling audio on during video playback.
  2. What happens if a user scrolls by an ad?
    • Once an ad is more than 50% outside of the viewport along the y-axis, the Outstream ad will pause playback.

Demo

Codepen

Helpful hints

Device support

Ads are currently not supported on Samsung Smart TVs and in the facebook in-app browser.