Advertising with the IMA3 Plugin

Product(s)
Video Cloud
Brightcove Player
Role(s)
Player Developer
Topic(s)
Advertising
Plugins

This topic covers the use of the IMA plugin and how it can be implemented using Studio and through custom coding.

The IMA plugin integrates the Brightcove player with Google's Interactive Media Ads (IMA) for HTML5 version 3. This allows you to request and track VAST, VPAID and VMAP ads for your player. For details about Google IMA, see the Using the IMA HTML5 SDK Version 3 document.

Player sample

The sample video below demonstrates the use of the IMA Plugin. Play the video to see a pre-roll, a skippable mid-roll at 5 seconds, then finally a post-roll.

Testing the ad server

The first thing you should do is verify the validity of the ad tag you are planning to use. Be sure you have copied its URL and browse to the following page: Video Suite Inspector (clicking this link will cause the page to open in a new window or tab).

Paste your ad tag URL into the Input type form input field. Click Test Ad and you will see your ad(s) play, with the Google supplied video interspersed. If your ad tag is not working in this test environment, it will not work with Brightcove Player.

Implement using Players module - Advertising section

In this section of the document you will use Studio to implement advertising using the Advertising section. In this case, you are limited to what options the form provides. If you wish to customize the implementation using some of the many available options that happen NOT to be provided in this section, use the Implement using Players module - Plugins section, which provides the opportunity to supply options via JSON.

 

To implement the IMA Plugin using the Players module, follow these steps:

  1. Open the PLAYERS module and either create a new player or locate the player to which you wish to add advertising functionality.
  2. Click the link for the player to open the player's properties.
  3. Click Advertising in the left navigation menu.
  4. Check the Enable Client-Side (IMA) checkbox.
  5. Enter the Server URL for the ad server.
  6. Select the Request Ads setting.
    • On load - Ads are requested immediately when the player loads (this is normally the best experience for DFP / VPAID).
    • On play - The first ad request is delayed until playback is initiated.
    • On demand - All ad requests will be initiated programmatically using the player.ima3.adrequest() method. This mode does not support preroll or postroll ads.
    • On cue point - Ad requests will be initiated on a dispatched ad cue point. See the Display Ads Using Ad Cue Points document for complete details.
  7. Select the ad VPAID Mode. The VPAID Mode is used to enable VPAID 2 support in IMA ads.
    • Enabled - Play VPAID ads in an iframe with a different domain
    • Insecure - Play VPAID ads in an iframe with the same domain
    • Disabled - VPAID ads throw an error
  8. Set the Timeout value. This is the maximum amount of time to wait, in milliseconds, for an ad to initialize before playback.
  9. Make a choice for Hard timeouts. Unchecking this option could result in a slow loading advertisement interrupting video playback.
  10. For the Plugin Version, it is strongly recommended you use the latest version.
  11. View an example, completed form:
    IMA3 properties in Studio
  12. Click Save.
  13. To publish the player, click Publish & Embed > Publish Changes.
  14. To close the open dialog, click Close.

When the changes to the advertising properties are saved, the IMA plugin will be configured as part of the Plugin settings. The JavaScript and CSS will be hidden since you added them via the Advertising section.

The IMA plugin does support additional properties that are not available in this section of the UI. See the next section of this document for a way to use more configuration options.

Implement using Players module - Plugins section

If you wish to configure the IMA3 plugin beyond the options provided in the Advertising section, you can use the Plugins section, which provides a way to supply options via JSON.

To implement the IMA3 Plugin you will add the function name of the plugin and the URLs to the plugin's JavaScript and CSS files:

  1. Open the PLAYERS module and either create a new player or locate the player to which you wish to add the plugin.
  2. Click the link for the player to open the player's properties.
  3. Click Plugins in the left navigation menu.
  4. Next, click Add a Plugin.
  5. For the Plugin Name enter ima3.
  6. For the JavaScript URL, enter:
      https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.js
  7. For the CSS URL, enter:
      https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.css
  8. Enter the configuration options in the Options(JSON) text box. An example set of options are shown here:
    {
      "serverUrl": "//pubads.g.doubleclick.net/gampad/ads?sz=400x300&iu=%2F6062...",
      "timeout": 5000,
      "debug": true
    }
  9. View an example, completed form:
    IMA3 properties in Studio
  10. Click Save.
  11. To publish the player, click Publish & Embed > Publish Changes.
  12. To close the open dialog, click Close.

JSON vs JavaScript notation

If you examine the Options section above, you see the configuration information is supplied in JSON format. If you are using code to implement your IMA3 plugin, the notation for setting options with JavaScript is slightly different.

Here you see options in JSON format you could use in Studio:

{
  "requestMode": "onload",
  "serverUrl": "//solutions.brightcove.com/bcls/brightcove-player/vmap/simple-vmap.xml?cust_params={mediainfo.ad_keys}",
  "timeout": 5000
}

If you are using JavaScript to configure your options, the JSON format would work, but you could also use the JavaScript syntax as shown here:

{
  requestMode: 'onload',
  serverUrl: '//solutions.brightcove.com/bcls/brightcove-player/vmap/simple-vmap',
  timeout: 5000
}

Options

The video.js IMA3 plugin is built on top of the video.js ads framework and accepts any options that the ad framework provides. Take a look at the ad framework README for details on the current set of overrideable settings. Both the IMA plugin specific options and ad framework options are documented here.

clickTrackingElement

Type: HTMLElement Default Value: undefined

If the HTML ad tech is being used in custom ad playback mode, this specifies an alternative HTML element to be used to track advertisement taps on devices that don't support input events over the video element. More details are available in the parameter documentation for the IMA AdDisplayContainer. If you provide a click tracking element, it is your responsibility to show and hide it at the appropriate times on the appropriate platforms. In most cases, it's best to leave this setting undefined and allow the plugin and IMA to manage ad interaction.

debug

Type: boolean Default Value: false

If debug is set to true, the ads framework will output additional information about its current state during playback. This can be handy for diagnosing issues or unexpected behavior in an ad integration.

This option is part of the ad framework and is configured as follows:

player.ima3({
  debug: true
});

The following screenshot shows the extensive information displayed by turning debug on.

debug output in console

showVpaidControls

Type: boolean Default Value: false

Set to true to show custom Brightcove controls over VPAID ads. They may or may not work depending on the VPAID implementation, so Brightcove suggests testing this feature with your ads before enabling it in production.

hardTimeouts

Type: boolean Default Value: true

Abandon ads that finish loading after they have timed out. This will prevent slow preroll ads from interrupting after the timeout has elapsed and content video has begun playing.

This option is part of the ad framework and is configured as follows:

player.ima3({
  hardTimeouts: true
});

Setting this option to false will result in content flash before ads.

ima3SdkSettings

Type: object Default Value: undefined

If provided, the properties of this object are used to set the page-level Ima3SdkSettings when the IMA SDK has finished loading. The properties of this object are expected to be the camel-cased equivalent of setter methods on the SDK settings object, minus the 'set' prefix. For example, if you provided this object when initializing the plugin:

player.ima3({
  ima3SdkSettings: {
    'numRedirects': 3,
    'ppid': 'publisher-provided-id'
  }
}

Then the video.js IMA plugin would run code that looks something like this when IMA had loaded:

window.google.ima.ImaSdkSettings.setNumRedirects(3);
window.google.ima.ImaSdkSettings.setPpid('publisher-provided-id');

disableCustomPlaybackForIOS10Plus

Type: boolean Default Value: false

This property is part of the ima3SdkSettings object. It acts as a getter and setter to control whether to disable custom playback on iOS 10+ browsers. Behavior is as follows:

  • When true, ads will play inline if the content video is inline, which enables skippable ads. However, the ad will stay inline and not support iOS's native fullscreen.
  • When false, ads will play in the same player as your content.

See the iOS skippable ads section of this document for an example of usage of this setting.

requestMode

Type: string Default Value: onload

This option is part of the ad framework is configured as follows:

player.ima3({
  requestMode: 'onplay'
});

There are four possible values for this option:

  • onload: Ads are requested immediately when the player loads. This is normally the best experience for DFP / VPAID.
  • onplay: The first ad request is delayed until playback is initiated. This is important for ad networks which consider ad requests to be plays, so you would not want an ad request before a play request. This will cause ads trafficked to eventually drop, or the customer will receive less for the ads shown.
  • ondemand: Ads will only play when initiated using the player.ima3.adrequest() method manually. This mode does not support preroll or postroll ads.
  • oncue:This option behaves differently depending upon if it is use with the useMediaCuePoints option.

    Using cue points with Video Cloud

    You can create ad cue points for a video in Studio, then have an advertisement played when the cue point is triggered. For full details see the Display Ads Using Ad Cue Points document.

    Using cue points in a live stream

    Ads are requested based on ID3 cue points in a live stream. For this type of request to function correctly, the ID3 TXXX frame received must contain JSON data with the following fields:

    • name: Required; must be the string value adCue
    • id: Required; A unique value to identify the ad given that times are relative in live streams
    • serverUrl: Optional; Appended as a break length parameter to the server url
    • duration: Optional; ad duration

    Example:

    {"name": "adCue", "id": 123}

    You can also cancel ID3 cue points in a live stream created by an adCue by using adCancel. The following format must be used for the object sent:

    {"name": "adCancel", "id": 123}

    Both the name and id are required.

    • Live ID3 ad cues are not supported on Android.
    • Live ID3 ad cancellation cues are not supported on iOS.

serverUrl

Type: string or function

Default Value (a generic Google ad):

//pubads.g.doubleclick.net/gampad/ads?sz=400x300&iu=%2F6062%2Fiab_vast_samples&ciu_szs=300x250%2C728x90&gdfp_req=1&env=vp&output=xml_vast2&unviewed_position_start=1&url=[referrer_url]&correlator=[timestamp]&cust_params=iab_vast_samples%3Dlinear

Here, you will provide the URL to your ad server. This option can be configured in Brightcove Studio as shown above. You can also set the value in code. Two examples are shown next. (Remember, you should test the ad tag on your server before trying to use it in the plugin.)

If the value is a string, it represents the ad server URL from where ads are requested and can be set in code as follows:

player.ima3({
  serverUrl: 'your ad server'
});

If the value is a function, the function parameter is a callback function that should be called with your server URL as the argument. This provides support for asynchronous processes such as header bidding. In the following example you see information from the mediainfo object used to determine which ads URL should be used based on an account ID:

// Initialize IMA plugin
myPlayer.ima3({
  serverUrl: function(callback) {
    if (myPlayer.mediainfo.id === '4034552795001') {
      callback('https://pubads.g.doubleclick.net/.../url1');
    } else {
      callback('https://pubads.g.doubleclick.net/.../url2');
    }
  },
  requestMode: 'onload',
  debug: true,
  debugContribAds: true
});

timeout

Type: number Default Value: 4000

The maximum amount of time, in milliseconds, to wait for ads to play before an ad break is skipped.

This option is part of the ad framework is configured as follows:

player.ima3({
  timeout: 5000
});

In internal Brightcove testing it was found that four seconds seemed to be long enough to accommodate slow initialization in most cases, but still short enough that failures to initialize didn't look like failures of the player or content video.

useMediaCuePoints

Type: boolean Default Value: false

Enables the use of ad cue points (as defined in Studio) to trigger an ad to play.

For Video Cloud ad cuepoints to be used to trigger ads, the following is required in the plugin configuration:

  • useMediaCuePoints: true
  • requestMode: The string oncue
  • serverUrl: Must point to a valid VAST ad

If you are using Studio to setup advertising, when you select On cue point the useMediaCuePoints and requestMode options will be set correctly for you.

vpaidMode

Type: string Default Value: ENABLED

Specify VPAID 2 mode in the IMA HTML5 SDK.

There are three possible values for this option:

  • ENABLED: Play VPAID ads in an iframe with a different domain.
  • INSECURE: Play VPAID ads in an iframe with the same domain.
  • DISABLED: VPAID ads throw an error.

This option is configured as follows:

player.ima3({
  vpaidMode: 'DISABLED'
});

Ad macros and the serverUrl

There are ad macros available to make your job easier when creating the ad server URL. These macros enable you to use variables in the server URL for which the IMA3 plugin will substitute appropriate values. For instance, the following server URL contains some of the variables:

{"serverUrl": "//myadserver.com/ad?video={mediainfo.id}&duration={player.duration}"}

The IMA3 plugins would substitute in the appropriate values, and the server URL actually used would appear as follows:

{"serverUrl": "//myadserver.com/ad?video=12340001&duration=60"}

The following is the complete list of variables for which substituted values will be used:

Macro Description
{player.id} Player ID
{mediainfo.id} Video ID
{mediainfo.name} Video title
{mediainfo.description} Short description (250 chars max)
{mediainfo.tags} Tags (metadata) associated with the video
{mediainfo.referenceID} Reference ID
{mediainfo.duration} Duration of the video as reported by Video Cloud
{mediainfo.ad_keys} Free form text string that can be added and edited in the Media module of Studio; you should use the query parameter in the form
cust_params={mediainfo.ad_keys}
{player.duration} Duration of video as measured by player (possibly slightly different from mediainfo.duration and probably more accurate)
{document.referrer} Referring page URL
{window.location.href} Current page URL
{timestamp} Current local time in milliseconds since 1/1/70
{random} A random number 0-1 trillion (Used to create a unique impression. This prevents the ad from being cached in the browser and prevents impression discrepancies.)

Default values and ad macros

You can give ad macros default values. A default value can be provided within a macro, in which case this value will be used where a variable is undefined. The syntax is:

{macro=default}

For instance,

http://example.com/ad/{pageVariable.adConf=1234}

would resolve to the following if window.adConf is undefined:

http://example.com/ad/1234

Dynamic macros

Dynamic macros provide access to values in the following:

  • The video's customFields object through the mediainfo.customFields variable.
  • The DOM's window object through the pageVariable variable.

For example, you could use the following in your ad request:

//myadserver.com/ad?l={pageVariable.navigator.language}&category={mediainfo.customFields.type}

For the pageVariable values, only certain value types are allowed to be used, as shown in this table:

Type What Happens
String Use without changes
Number Converted to string automatically
Boolean Converted to string automatically
Null Returns the string null
Undefined Logs warning and returns empty string
Other Logs warning and returns empty string

Custom ad macros

Although the Dynamic macros technique described just above is the much preferred method to access specific information via macros, you may have defined custom values you use when requesting ads from your ad server that you cannot reach via dynamic macros. In this case, you can utilize your values by overriding the adMacroReplacement() method. When you override this method it allows you to pass your specialized values for the ad request.

The following is an example of overriding the adMacroReplacement() method. In this example, the custom values are defined as part of the page DOM, thus enabling ad requests to be customized on a per page basis. In this example, mySite.category is the location where the ad request information is stored.

brightcovePlayer.ima3.adMacroReplacement = function (url) {
    var parameters = {
    '{category}': mySite.category
  };
  for (var i in parameters) {
    url = url.split(i).join(encodeURIComponent(parameters[i]));
  }
  return url;
}

Using specific values will help clarify exactly what is happening. Assume your request URL to the ad server is the following:

//myadserver.com/myads?adWord={category}

And assume the value dynamically assigned to mySite.category in the page is the string fishing-pole. Then after your version of the adMacroReplacement() method is called your ad request URL would appear as:

//myadserver.com/myads?adWord=fishing-pole

To summarize, when you override the adMacroReplacement() method it allows you to use custom values as ad macros, and dynamically assign values to the URL ad request.

Methods

player.ima3.adrequest( )

Calling this method will create an on-demand adrequest immediately upon receiving an ad response. Invoking this method creates a new IMA adManager which means that any previous ad response information (for instance, a postroll ad returned in a previous VAST response) will be lost. Brightcove recommends that you only use this method in cases where up-front knowledge of ad timings isn't known or you will be making all ad calls on-demand. In all other cases, it makes sense to put all ad data in the initial VAST call on plugin initialization.

The following are two important points to consider when using player.ima3.adrequest( ):

  • The method is for use with the ondemand request mode only.
  • The method is not recommended for prerolls as content will play before the ad request completes, resulting in a flash of content.
Parameters
  • adRequestUrl String Path to a VAST ad tag. You can and should pass relative URLs. This parameter is optional and the configured serverUrl is used if no parameter is passed.
Returns:
  • Nothing

Example

player.ima3.adrequest('//pubads.g.doubleclick.net/gampad/ads?sz=640x360&iu=/6062/iab_vast_samples/skippable&ciu_szs=300x250,728x90&impl=s&gdfp_req=1&env=vp&output=xml_vast2&unviewed_position_start=1&url=[referrer_url]&correlator=[timestamp]');

player.ima3.setAdsRenderingSettings()

This method lets you set ads rendering settings for the IMA SDK for HTML5.

If there is no Ads Manager yet, this method saves your settings and when an Ads Manager is created it uses the settings you provided. If an Ads Manager already exists, it is updated to use your settings. In either case, any new Ads Managers created in the future will also use the most recent settings you provided. You can create an AdsRenderingSettings object by accessing the IMA SDK directly. A variety of settings are available.

Parameters
  • google.ima.AdsRenderingSettings object
Returns:
  • Nothing

Example:

var adsRenderingSettings = new google.ima.AdsRenderingSettings();
adsRenderingSettings.bitrate = 2500;
adsRenderingSettings.enablePreloading = true;
player.ima3.setAdsRenderingSettings(adsRenderingSettings);

Google's AdsManager

There are methods and properties available from Google's google.ima.AdsManager Interface. You can use the interface's properties/methods that retrieve information. It is not advised to use the methods that perform actions, like destroy, setAutoPlayAdBreaks and stop. For example, one method you can use is shown here:

AdsManager.getRemainingTime

Type: google.ima.AdsManager.getRemainingTime

Usage: myPlayer.ima3.adsManager.getRemainingTime()

Calling this method returns the amount of time remaining for the current ad. If an ad isn't available or has finished playing, it returns -1. For more information see Google's documentation on the method.

Accessing the IMA SDK directly

A number of IMA settings are available on the plugin object at runtime. For instance, to determine the ad ID you would use:

var adId = player.ima3.currentAd.getAdId();

Be careful interacting directly with these properties. Calling the wrong method can lead to unexpected results and failure of advertisements to play properly.

adsLoader

Type: google.ima.AdsLoader

The object used to create ads requests. See ima.AdsLoader. The Ads Loader may not be available until adsready has been fired by the plugin.

adsManager

Type: google.ima.AdsManager

The object responsible for playing ads. See ima.AdsManager. The Ads Manager is not available until adsready has been fired by the plugin.

adDisplayContainer

Type: google.ima.AdDisplayContainer

The object responsible for managing the display elements for ads. See ima.AdDisplayContainer. The Ads Display container may not be available until adsready has been fired by the plugin.

currentAd

Type: google.ima.Ad

When an ad is playing, an object that encapsulates information about the current ad. See ima.Ad.

Events

The plugin emits some custom event types during loading, initialization, and playback. You can listen for IMA3 and ad framework events just like you would any other event:

player.on('ima3error', function(event) {
  console.log('event', event);
});
Event Dispatched when:
ima3-ready The ima3 plugin code has loaded and is ready load the IMA SDK.
ima3error There was an error loading the IMA3 SDK from Google. If it occurs, no ads will be displayed.
ima3-ad-error An error has occurred in the IMA3 SDK. You should verify your ad configuration and settings to be sure your DoubleClick account is correctly configured. You can find common troubleshooting tasks at the DoubleClick support site or talk to your DoubleClick account representative.
ads-request Upon request ad data.
ads-load When ad data is available following an ad request.
ads-ad-started An ad has started playing.
ads-ad-ended An ad has finished playing.
ads-pause An ad is paused.
ads-play An ad is resumed from a pause.
ads-ad-skipped An ad is skipped.
ads-first-quartile The ad has played 25% of its total duration.
ads-midpoint The ad has played 50% of its total duration.
ads-third-quartile The ad has played 75% of its total duration.
ads-click A viewer clicked on the playing ad.
ads-volumechange The volume of the playing ad has been changed.
ads-pod-started The first ad in a linear ad pod (a sequenced group of ads) has started.
ads-pod-ended The last ad in a linear ad pod (a sequenced group of ads) has finished.
ads-allpods-completed All linear ads have finished playing.

Re-dispatched ima3- prefixed events

When the IMA3 plugin is used in HTML mode, all AdErrorEvents, AdEvents and AdsManagerLoadedEvents are re-dispatched onto the player. When the events are re-dispatched, they are prefixed with ima3-. The following table shows the re-dispatched events:

Re-Dispatched Event
ima3-ad-error
ima3-ads-manager-loaded
ima3-all-ads-completed
ima3-click
ima3-complete
ima3-content-pause-requested
ima3-first-quartile
ima3-hardtimeout
ima3-loaded
ima3-midpoint
ima3-paused
ima3-ready
ima3-resumed
ima3-started
ima3-third-quartile
ima3-volume-changed

Live video and IMA3

If you are using version 3.1.0+ of the IMA3 plugin, you can use pre-rolls with a live event. The pre-roll will play when each viewer begins to watch the live event, not the one time the live event begins. When configuring your event in the Live module, as shown in the Creating and Managing Live Events using the Live Module document, you are prompted to select a player. You will want to configure advertising for the player you select, as shown in the Quick Start: Implementing Advertising document.

Note the following details of the implementation:

  • Only pre-rolls will play. Mid-rolls and post-rolls are not supported.
  • The Request Ads type must be either On load or On play.
  • You must be using version 3.1.0 or later of the IMA3 plugin, as mentioned earlier.

Player Ad Libraries

The videojs/videojs-contrib-ads GitHub repository contains a plugin which provides common functionality needed by video advertisement libraries working with Brightcove Player. The plugin provides common functionality needed by video ad integrations and takes care of a number of concerns for ad integrators, reducing the code you have to write for your ad integration. The plugin is fully documented, with an index page as the best starting point.

There are methods, events and properties available for use from the plugin. Full details are provided in the videojs-contrib-ads API reference. A sampling of the tools available are provided here, starting with methods:

Method Description
isInAdMode() Returns true if the player is in ad mode.
isWaitingForAdBreak() This method returns true during ad mode if an ad break hasn’t started yet.
isContentResuming() This method returns true during ad mode after an ad break has ended but before content has resumed playing.

The plugin also dispatches numerous events, a few are listed here:

Event Description
adstart Fired directly as a consequence of calling startLinearAdMode().
adend fired directly as a consequence of calling endLinearAdMode().
readyforpreroll Indicates that your ad plugin may start a preroll ad break by calling startLinearAdMode().

The plugin also provides numerous properties, a few are listed here:

Name Data Type Description
ads.ad.id String Unique identifier for an ad that plays
ads.ad.index Number The index of the ad that plays at a specified time; the index would identify the ordinal value of an ad in an ad pod
ads.ad.duration Number The duration of the ad in seconds
ads.ad.type String Either PREROLL, MIDROLL or POSTROLL

The following code demonstrates the use of the properties:

var myPlayer,
  player = bc('myPlayerID');
player.ima3({
  serverUrl: '//solutions.brightcove.com/bcls/brightcove-player/vmap/simple-vmap.xml'
});
player.ready(function () {
  myPlayer = this;
  myPlayer.on('ads-ad-started', function (evt) {
    console.log('ads-ad-started event passed to event handler', evt);
    console.log('myPlayer.ads.ad.id', myPlayer.ads.ad.id);
    console.log('myPlayer.ads.ad.index', myPlayer.ads.ad.index);
    console.log('myPlayer.ads.ad.duration', myPlayer.ads.ad.duration);
    console.log('myPlayer.ads.ad.type', myPlayer.ads.ad.type);
  });
});

The output in the console from the above code is shown here:

console of contrib-ads properties

Implement using code

To implement the IMA3 Plugin the player needs to know the location of the plugin code, a stylesheet, the plugin name and plugin configuration options. The location of the plugin code and stylesheet are as follows:

https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.js
https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.css

The name of the plugin is ima3, and an example set of options is:

{
  "serverUrl": "//pubads.g.doubleclick.net/gampad/ads?sz=400x300&iu=%2F6062...",
  "timeout": 5000
}

The following example uses the In-Page Embed implementation of the player to associate the IMA Plugin with a single instance of a player.

  • Line 12: Uses a link tag to include the plugin's CSS in the head of the HTML page.
  • Line 15: Gives the video tag an id attribute, with some value, in this case myPlayerID.
  • Line 23: Uses a script tag to include the plugin's JavaScript in the body of the HTML page.
  • Lines 26-29: Initializes the player using the bc() method, and then calls the ima3() method.
  • Lines 30-33: On player ready, a reference to the player is created. The comment is shown to indicate where you can place code to add other player behaviors beyond IMA3 plugin setup and configuration.
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>IMA3 Plugin Code Example</title>
  <style>
    .video-js {
      height: 344px;
      width: 610px;
    }
  </style>
  <link href="https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.css" rel="stylesheet">
</head>
<body>
  <video-js id="myPlayerID"
    data-video-id="3851380732001"
    data-account="1752604059001"
    data-player="Hy3gDJHu"
    data-embed="default"
    class="video-js"
    controls></video-js>
  <script src="https://players.brightcove.net/1752604059001/Hy3gDJHu_default/index.min.js"></script>
  <script src="https://players.brightcove.net/videojs-ima3/3/videojs.ima3.min.js"></script>
  <script>
    var myPlayer;
    var player = bc('myPlayerID');
    player.ima3({
      serverUrl: '//solutions.brightcove.com/bcls/brightcove-player/vmap/simple-vmap.xml'
    });
    player.ready(function() {
      myPlayer = this;
      //Do something
    });
  </script>
</body>
</html>

Debugging assistance

There are two options for assistance when debugging ad playback issues. If you do nothing, in the console you will see only information on when ads started and finished:

debug output in console

The first option is mentioned earlier in this document in the Options section. This turns on debugging at the plugin level. You will see additional debugging information:

debug output in console

The second option utilizes a tool supplied by Google. You specify a sdkurl option with a value pointing to a JavaScript file supplied by Google. An example configuration is shown here:

var myPlayer = bc('myPlayerID');
myPlayer.ima3({
  "serverUrl": "//solutions.brightcove.com/bcls/brightcove-player/vmap/simple-vmap.xml",
  "debug": true,
  "sdkurl": "//imasdk.googleapis.com/js/sdkloader/ima3_debug.js"
});
myPlayer.ready(function() {
  myPlayer = this;
});

The expanded debugging information would appear similar to the following. (The yellow highlighted information is from the plugin's debugging and the blue highlighted information is generated by the Google tool.)

debug output in console

For more details on Google's IMA errors, see the Class google.ima.AdError section of Google's Google IMA HTML5 SDK APIs document.

Known issues

Setting autoplay in Studio

Do NOT set autoplay in Studio if you are using the IMA3 plugin to display advertisements. Setting autoplay in Studio could cause ad plaback failure. See the Autoplay Considerations document for further information.

Chrome on Android: Unmute pre-roll, video will not autoplay

When using Chrome (latest version) on Android and unmute the player while pre-roll is playing, player does not start playing a video automatically after pre-roll ends. If you unmute the ad, the volume persistence feature of Brightcove Player will also unmute the content since the intention of the viewer is to hear the audio. However, on newer versions of Chrome Android, unmuted content cannot be auto-played and the user-gesture requirement to begin playback has been added. This is an OS/Device-level setting and not something Brightcove can override.

Preroll's Current Time display may not be accurate

This problem has to do with a limitation in the way the IMA SDK reports the current time. There is no work around documented at this time.

Unmuted midrolls may not play on Safari 11 Desktop

Unmuted midrolls may not play on Safari 11 Desktop due to a change in Google's IMA SDK. A new behavior was introduced to trigger an error and cancel an ad when autoplay is rejected by Safari 11 (Desktop and possibly iOS). Midrolls impacted in this way will trigger an ad error 400, with error code 1205 indicating autoplay was prevented.

Pre-rolls not supported for live streaming

IMA3 pre-roll ads with live streaming, including Brightcove Live, are only supported when using cue points and oncue request mode.

Supported environments

To check for supported combinations of platforms, advertising standards and video media, see Google's Video Feature and SDK compatibility document. That document and the Video Suite Inspector will help you diagnose attempted IMA3 advertisement configurations that simply will not function.

Overlays and Fullscreen Transitions

video.js uses the fullscreen API where available. Different browsers implement the transition to fullscreen differently and that can produce discrepancies in appearance when transitioning into and out of fullscreen mode. In most implementations, the element that is being taken into fullscreen is geometrically scaled (i.e. zoomed) from its original to the target size. Most overlay advertisements are designed to be displayed at a fixed size, however, and so they may appear distorted until the animation completes.

Skippable ads on iOS devices

With the IMA3 plugin, skippable ads can be played on iPhones when the following conditions are met:

  • The playsinline attribute is present on the video element
  • The disableCustomPlaybackForIOS10Plus setting is passed to the plugin, and set to true

For the playsinline attribute, simply include it as an attribute in the video tag:

<video-js id="player"
  width="640"
  height="360"
  data-video-id="4524585416001"
  data-account="4360108595001"
  data-player="r12ukws9l"
  data-embed="default"
  class="video-js"
  playsinline
  controls></video-js>

For the disableCustomPlaybackForIOS10Plus setting, assign it as a property of ima3SdkSettings:

player.ima3({
  ima3SdkSettings: {
    "disableCustomPlaybackForIOS10Plus": true
  }
})

If you are using Studio and wish to use the setting there, add this to your IMA3 plugin configuration:

{
  "ima3SdkSettings": {
    "disableCustomPlaybackForIOS10Plus": true
  }
}

For full details of this setting, see the disableCustomPlaybackForIOS10Plus entry in the ima3SdkSettings section of this document.

Skippable ad limitations:

  • The Skip Ad button may be partially covered by the ad control bar on some mobile devices. This makes it difficult for end users to actually skip the ad. The user can pinch to zoom to make the Skip Ad button bigger on mobile devices to be able to click it.
  • iPhone without playsinline and disableCustomPlaybackForIOS10Plus - Skippable ads are not played.
  • iPhone with playsinline and disableCustomPlaybackForIOS10Plus - Ads are played inline, but if using fullscreen, ads do not show, but audio for the ad will play. In other words, skippable ads in fullscreen do not function correctly.
  • iPad - Ads are played inline but skip is not available in fullscreen mode

Conflict with gpt_proxy.js

If using the GPT proxy script with IMA3, and the adTechOder is HTML5 first, playback issues can occur. The IMA3 plugin will be affected when using any script that uses window.google or window.google.ima. It is suggested that you check if you're using Brightcove Player, and if so, don't load the proxy on those occasions.

Resize Skip Ad button

It is not possible to resize the Skip Ad button. The Brightcove Player API does not have methods or properties to specify the size of the Skip Ad button. At the developer level, if a publisher is using VPAID ads, the ads can implement their own Skip Ad button and logic to fit within the UI and element distribution of Brightcove Player.

Ads will not autoplay on iOS

Although not specific to the IMA3 plugin, know that autoplay is restricted iOS, so ads will not start until a user gesture is made.

Ad cue point issues

For issues specific to using ad cue points, see the Known issues section of the Displaying Ads Using Ad Cue Points document.

Changelog

24 Oct 2018

v3.2.2

  • Fixed bug to call adMacroReplacement when serverUrl is empty string
  • Fixed issue to allow IE/Edge control bar visibility on hover with overlay ads

18 Oct 2018

v3.2.1

  • Fixed issue where content didn't resume immediately following empty VAST response in a VMAP
  • Fixed an issue where analytics didn't send video_view events after ad errors and timeouts

13 Sep 2018

v3.2.0

  • New Video Cloud cuepoints implementation that addresses a variety of known bugs
  • Added support for content source change during ads
  • Bugfixes to handling reinstantiation of player after dispose
  • Destroy ads manager on player dispose
  • Fix issue related to volume persistence on iOS
  • Fix IE/Edge ad control bar visibility on hover
  • Fix case with playonselect:false where you are before preroll and you change source to an economics:ad_supported video and ad/content automatically plays
  • Remove dead Flash code
  • Updated to use videojs-contrib-ads 6.6.1
    • Improved support for stitched ad scenarios
    • Avoid multiple-registration warning messages by accepting only the first contrib-ads per context
    • Fix play event redispatch issue on IE
    • Improved player dispose handling

15 Aug 2018

v3.1.0

  • Fixed a bug where the progress bar wasn't updated and player.ima3.adPlayer.currentTime() returned 0 instead of current time of the ad
  • Added isVpaid convenience method to IMA plugin
  • Added IMA Live preroll support
  • Updated videojs-contrib-ads to 6.5.0 which includes 6.4.3 changes as well
    • Added liveCuePoints option
    • Restore all sources instead of single source on snapshot restore
    • Send pause event when autoplay blocked on Chrome to be consistent with Safari

6 Aug 2018

v3.0.3

  • Fixed a bug that results from plugin init order. Specifically, the value for the {player.url} macro has changed to remove a dependency on the Analytics plugin. This macro could be used to uniquely identify the player, but we recommend using the {player.id} macro instead.
  • Improved dispose handling
  • Code organization improvements
  • Updated videojs-contrib-ads to 6.4.2
    • Cleanup snapshot object after ads done
    • Improved dispose handling

11 Jun 2018

v3.0.2

  • Fixed a poster flash when restoring after preroll
  • player.ads.ad.currentTime used to be the time offset: now it is the current time
  • Added player.ads.ad.timeOffset
  • Bug fix to economics mediainfo handling related to initialization
  • Removed loadingSpinner option because it did not do anything
  • Updated videojs-contrib-ads to 6.4.1
    • Updated documentation link in initialization error message
    • Added contentIsLive setting, which can be used for live streams that do not report their duration as infinity
    • Fixed a bug where a loading spinner could appear at the end of the video if there was no postroll
    • Allow default values for macros

4 May 2018

v3.0.1

  • Fixed a bug where ad doesn't play when mediainfo.economics is set to undefined

1 May 2018

v3.0.0

  • Updated videojs-contrib-ads from 5.1.6 to 6.2.1
  • Initialization now uses middleware to reduce risk of content flash
  • The plugin's handling of source changes has been reworked, resulting in far greater reliability when used with playlists
  • The serverUrl option can now be a function, facilitating asynchronous workflows such as header bidding
  • Fixed a bug that could have led to a longer timeout than expected
  • Various other bug fixes and reliability improvements; see the videojs-contrib-ads changelog for more information

13 Apr 2018

v2.22.3

  • Fixed autoplay issue on iOS and adds support on iOS for IMA SDK setAdWillPlayMuted() and setAdWillAutoPlay()

28 Mar 2018

v2.22.2

  • Fixed a bug with a specific IMA3 configuration of autoplay and requestMode onplay

21 Mar 2018

v2.22.1

  • Fixed a bug with Internet Explorer 11 support that was introduced in 2.22.0

14 Mar 2018

v2.22.0

  • Added support to detect can autoplay and can autoplay muted
  • Implemented IMA SDK setAdWillPlayMuted and setAdWillAutoPlay

30 Jan 2018

v2.21.0

  • Added showVpaidControls option
  • Updated to use videojs-contrib-ads 5.1.6

27 Nov 2017

v2.20.3

  • Fixed bugs with subsequent content videos not being allowed to play
  • Fixed a bug with midrolls on iOS causing content to restart from the beginning
  • Fixed a bug where content is not seen but audio is heard on iOS

2 Nov 2017

v2.20.2

  • Compatibility with latest IMA SDK
  • Improved Safari 11 support
  • Hide custom controls for VPAID ads
  • Updated to use videojs-contrib-ads 5.1.1

10 Oct 2017

v2.20.1

  • Added compatibility with Video.js 6.3 and greater

4 Oct 2017

v2.20.0

  • Updated to use videojs-contrib-ads 5.1.0

16 Aug 2017

v2.19.4

  • Fix a bug that timed out on postrolls when an empty vast ad is seen
  • Remove redundant ads-request event trigger
  • Added logic to check the version of Chrome independently from the player version
  • Fixed a bug where the adtimeupdate event would fire during content
  • Fixed a bug with autoplay on Android devices
  • Fixed a bug with waiting for postroll ads after an ad error

28 Jul 2017

v2.19.3

  • Bugfixes for oncue mode and ID3 ad cancellation
  • Updated to use videojs-contrib-ads 5.0.3

21 Jul 2017

v2.19.2

  • Mobile autoplay support
  • Updated to use videojs-contrib-ads 5.0.2
    • Fixed dispatching of loadeddata and loadedmetadata events
    • Fixed bug with empty ad response when using ondemand mode

7 Jul 2017

v2.19.1

Note: This version includes fixes to support autoplay of HMTL5 ads on iOS 10 and Android devices.

  • Autoplay HTML5 ads in players that are not muted and/or do not include playsinline will correctly play when the user initiates playback via a tap or click on iOS 10 and Android devices
  • Autoplay HTML5 ads in players that include muted AND playsinline will correctly autoplay on iOS 10 and Android devices
  • Fixes the Mute button on iOS 10 and Android HTML5 ads
    • When the muted attribute is present, the mute button will display allowing the user to un-mute the ad
    • The mute button will no longer display on devices that do not support controlling the volume programmatically
    • The mute button will correctly mute/un-mute the ad when tapped or clicked
    • The mute/unmute setting will persist from the ad to main content

Additionally, the IMA HTML5 SDK released a feature to disable custom playback on iOS 10+ devices. This feature determines whether inline playback or native playback of ads is used, including adding support for TrueView skippable ads. More information on this setting can be found in the IMA HTML5 SDK documentation.

Information on how to apply this setting using the Brightcove IMA SDK plugin can be found in our Advertising with the IMA3 Plugin documentation under ima3SdkSettings.

28 Jun 2017

v2.19.0

For information see this post in the Brightcove Web Player Developer Forum. For general information testing players and plugins together, see the Player/Plugin Version Testing

Features in this release are:

  • Volume settings persist when skipping ads
  • Updated to use videojs-contrib-ads 5.0.1
    • Cross-compatibility between Video.js 5 and 6
    • Bug fix regarding Flash of content on iOS
    • Better cleanup when player is disposed
    • An error message is displayed in the Console when the plugin is initialized too late

4 Apr 2017

v2.18.0

  • Added player.ima3.setAdsRenderingSettings, which allows users to set ads rendering settings for the IMA SDK for HTML5
  • Updated for Video.js 5 and 6 cross-compatibility

23 Mar 2017

v2.17.0

  • Exposed adsLoader.contentComplete in Flash to allow resetting the IMA correlator

9 Mar 2017

v2.16.4

  • Adding back ES3 support
  • Updated to use videojs-contrib-ads 4.2.5
    • Added a way to estimate adType
    • Reverted "No longer take postroll snapshot when there will be no postroll" to fix a bug with missing ended events

3 Mar 2017

v2.16.3

  • Roll back to videojs-contrib-ads 4.2.3 to fix a bug with missing ended events

1 Mar 2017

v2.16.2

  • Don't allow cues without IDs to be used in oncue request mode
  • Updated to use videojs-contrib-ads 4.2.4
    • No longer take postroll snapshot when there will be no postroll
    • Video.js 5/6 cross-compatibility

2 Feb 2017

v2.16.1

This is a bugfix update.

  • Make HTML5 ads in iframes responsive when possible
  • Prevent erroneous admuted tracking in DFP
  • Localize ad control bar for both HTML5 and Flash
  • Allow right-clicking to enable Flash in Chrome
  • Updated to use videojs-contrib-ads 4.2.2
  • Re-fixes iOS content flash

27 Jan 2017

v2.16.0

  • Added support for cueTextTracks feature in videojs-contrib-ads so Video Cloud cue points can be used to trigger ads.

19 Jan 2017

v2.15.6

  • Updated to use videojs-contrib-ads 4.2.1
    • The update reverted the change that prevented ad clickthrough when clicking progress bar during ad. This fix will now be in single-video-template instead.

20 Dec 2016

v2.15.5

  • Updated to use videojs-contrib-ads 4.1.6
    • Fixed placeholder div on iOS 10 playsinline
    • No longer sends an undocumented adcontentplaying event, which was only sent to cancel an extra adplaying event; code has been refactored to not need this extra event

8 Dec 2016

v2.15.4

  • Updated to use videojs-contrib-ads 4.1.5
    • Hide captions and audio track buttons during ads (they were already hidden in IMA, so this update does not impact this project)
    • Plugin now prevents ad clickthrough when clicking progress bar during ad
    • Ended event now triggers correctly after the content ends additional times having ended once already

21 Nov 2016

v2.15.3

  • Updated to use videojs-contrib-ads 4.1.4
    • Fixed issue where blank div to prevent content flash covers ad on iPad
    • Fixed to snapshot test to avoid relying on track src
  • Fixed to show ad duration in Video.js 6
  • Fixed to initialize adDisplayContainer on touchend instead of touchstart

10 Nov 2016

v2.15.2

  • Updated to use videojs-contrib-ads 4.1.3
    • Added missing import of videojs
    • Fixed for content playing behind ad on Android
  • Fixed volume persistence bug when playing LIVE content

10 Nov 2016

v2.15.1

  • Updated to use videojs-contrib-ads 4.1.2
    • Fix bug with snapshot and text tracks

2 Nov 2016

v2.15.0

  • New page variable feature in ad macros
    • In IMA, ad macros are supported in the ad server URL
    • A URL with a page variable macro might look like this: http://example.com?foo={pageVariable.foo} (that macro would be replaced with the value of the variable foo in the browser's JavaScript context when the ad request is made)
    • When your ad request is made if the page variable isn't yet available, your macro will not work
    • You can learn technical details on the new ad macro feature here: https://github.com/videojs/videojs-contrib-ads#macros
  • Now use try/catch when destroying ads manager in case it isn't created yet
    • This is for extra safety in edge cases, you shouldn't expect to see any difference
  • Temporarily re-added contentplayback event
    • This event was part of the integration between the Brightcove IMA plugin and the open source videojs-contrib-ads project; Brightcove plans to remove it in the future
    • The playing event is probably what you would want to use instead

26 Oct 1016

v2.14.0

  • Updated to use videojs-contrib-ads 4.0.0
    • playing event no longer sent before preroll
    • contentplayback event removed
    • Fixed a flash of content introduced in Chrome 53 where ads-loading class was being removed too soon
    • Added player.ads.VERSION
    • Updated to use conventions put forward by generator-videojs-plugin
    • Created separate files for feature modules
  • Volume and Muted states now persist across ad breaks

18 Oct 2016

v2.13.0

  • Custom fields in ad macros
  • Avoid timeout-length delay before content if there is no preroll in flash ad tech
    • This can resolve additional issues that resulted from an unexpected delay, such as the player throwing an error on empty post-roll call
  • More accurate progress bar in Flash

3 Oct 2016

v2.12.0

  • Prevent extra playing event after a hard timeout
  • {player.id} macro now refers to the correct value
  • Smooth progress bar movement

23 Sep 2016

v2.11.6

  • Updated to videojs-contrib-ads 3.3.13
    • Fix check to reset snapshot on contentupdate

19 Sep 2016

v2.11.5

  • Set hardTimeouts setting default to true
  • Set timeout setting default to 4000 milliseconds
  • Fix bug where video would pause during overlay ads
  • Fix bug with display of flash tech control bar during overlay ads
  • Fix bug when playing an ad-supported video after a free one

6 Sep 2016

v2.11.4

  • Unified timeout settings

24 Aug 2016

v2.11.3

  • Updated to videojs-contrib-ads 3.3.12
    • Fix for metrics on empty ad
  • Make sure player is in started state on adstart
  • Ondemand adrequests no longer succeed with economics set to free

3 Aug 2016

v2.11.2

  • Fix for iOS in which a flash of video content is seen before a preroll
  • Fix a bug in which the ended event does not trigger after video content source is changed

27 Jul 2016

v2.11.1

  • Updated to videojs-contrib-ads 3.3.10
    • Fix a bug in which content would replay after postrolls under certain circumstances

22 Jul 2016

v2.11.0

  • Added player.ima3.adTech

18 Jul 2016

v2.10.3

  • Updated to videojs-contrib-ads 3.3.9
    • Fix a bug in which contentupdate is missed in postroll

14 Jul 2016

v2.10.2

  • Fix to account for adrequests made when requestmode is onplay and content is already playing
  • Fixed bug where ImaSdkSettings did not reflect locale setting
  • Fixed bug where IMA3 Plugin did not respect the setNumRedirects setting
  • Updated to videojs-contrib-ads 3.3.9
    • Fix a bug in which contentupdate is missed in postroll

21 Jun 2016

v2.10.1

  • Workaround for Chrome bug when removing poster
  • Updated to videojs-contrib-ads 3.3.8
    • Fix for issue resuming after ads on Android
    • Fix for issue requesting ads for subsequent videos

16 Jun 2016

v2.10.0

  • Hide poster and tech before preroll

13 Jun 2016

v2.9.1

  • Fixed a bug where content would replay after a postroll completed

6 Jun 2016

v2.9.0

  • Hard timeouts now work for VAST ads that do not use VMAP as well as with the Flash ad tech
  •  
  • Fixed bug that could cause a flash of content on source change
  • Fixed bug where first adrequest would fail with requestMode:ondemand + autoplay + preload:none + html5 ad tech

26 May 2016

v2.8.0

  • Add default postrollTimeout of 1000 milliseconds
  • Add missing logic for flash ad tech to destroy ads manager on adserror
  • No longer send nopreroll for VAST ads
  • No longer send adrequest for empty string content source
  • Cancel multiple ad requests for the same content source
  • No longer allow autoplay with onplay; it changes it to onload

10 May 2016

v2.7.1

  • Fix to live ads that was introduced in 2.7.0
  • Fix in live ads code that introduced intermittant errors on iOS8 (even in non-live scenarios)

28 Apr 2016

v2.7.0

  • Added ad_keys to ad macros
  • Code maintenance to enable vjsstandard
  • No longer plays ads when Economics flag is set to FREE

20 Apr 2016

v2.6.0

  • Ability to play and cancel ads in live streams based on ID3 metadata
  • Quicker load time when requestmode is set to ondemand or oncue
  • Fixed and restored nopostroll feature

31 Mar 2016

v2.5.2

  • Rollback nopostroll feature as it was preventing ended events

31 Mar 2016

v2.5.1

  • Minor bugfix to contrib-ads

28 Mar 2016

v2.5.0

Features
  • HTML5 hardTimeouts option. Will prevent "flash of content" when using VMAP for HTML5 ads by discarding overdue ads. Disabled by default; planned to be enabled by default in a later major version update.
  • Quicker load time when using IMA3 plugin with no preroll ads.
  • Expose player.ima3.currentAd.wrapperAdIds and player.ima3.currentAd.wrapperAdSystems when using Flash ad tech.
Bugfixes
  • Fix display of volume slider in graphite skin
  • Fix bug where progress slider would continue when paused in Flash
  • Fix bug where play/pause icon would not update correctly in Flash
  • Fix several situations where invalid adtimeout events would be sent

28 Mar 2016

v2.4.0

  • Added VPAID 2 support

28 Mar 2016

v2.3.0

  • Hide dock during ad playback
  • Fix bug where iPad overlay ads would not click-through
  • Use versioned URL for default adSwf value
  • Fix clickthroughs for HTML5 ads in IE10

20 Jan 2016

v1.14.x

  • Support multiple players

30 Mar 2015

v1.13.0

  • Update contrib-ads to pick up playlist support

27 Mar 2015

v1.12.0

  • Add adrequest method
  • Add ready method
  • Add loadingSpinner option
  • Fix timings in HTML controlbar
  • Add black background div to prevent content flashing issues with prerolls and midrolls (on desktop)

27 Jan 2015

v1.11.0

  • Add error handling
  • Bump videojs-contrib-ads to 1.0.0
  • Fix race condition where contentupdate can trigger twice

8 Jan 2015

v1.10.0

  • Bump videojs-contrib-ads to 0.6.0
  • Add no-op function stubs for text track API methods

21 Oct 2014

v1.8.0

  • Bump default preroll timeout to 1000ms
  • Always use a separate control bar for ad playback. Previously, ads on platforms that did not support Flash would re-use the content control bar for ad playback.
  • Move ad container offscreen during content playback because IMA steals touch events on Android Chrome.

16 Oct 2014

v1.7.0

  • VPAID 2.0 support for the Flash ad tech

1 Oct 2014

v1.6.0

  • Update videojs-ads
  • Pass updated plugin settings to the ad SWF

1 Oct 2014

v1.5.0

  • Set the default ad tech order to flash, html5

28 Aug 2014

v1.4.0

  • Post-roll support
  • Added the ability to use custom click tracking elements with IMA3/HTML5

20 Mar 2014

v1.3.0

  • Upgrade to video.js 4.4.3