Advertising with the Once UX Plugin

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

In this topic, you will learn about using Brightcove Player and the Once UX plugin to enable you to play any Brightcove Once video.

Overview

By default, the plugin enforces that all advertisements are watched and displays an ad count-down timer while they play. You can easily customize this plugin to use your own overlays and allow users to skip advertisements.

The player

This example enforces the playback of an advertisement before the main subject video. For this example, a pre-roll is used.

Implement using Players module

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

  1. Open the Players module and locate the player.
  2. Click the link for the player to open the player properties.
  3. Locate the Plugins section and click Edit.
  4. The JavaScript for the plugin is provided and will not change for different plugin implementations. For the JavaScript URL, enter:
          //players.brightcove.net/videojs-onceux/2/videojs-onceux.min.js
  5. The CSS for the plugin is provided and will not change for different plugin implementations. For the CSS URL, enter:
          //players.brightcove.net/videojs-onceux/2/videojs-onceux.min.css
  6. For the plugin name, enter onceux.
  7. The Options provided in the form specifies the URI to call to get your Once VMAP data. A stub example is shown here:
          {
            "metadataUri" : "http://onceux.unicornmedia.com/now/ads/vmap/od/auto/f1e8b045-e52e-4636-9459-818da5f90bab/3aaf99a3-57d7-4a8d-8dd9-2c6f671d77e1/825a2774-b49d-11e3-87e6-005056835b09/0a10b34f-85e7-44a8-a4fb-4a1b7c9e97ac/content.once"
          }
    onceux plugin configuration in Studio
  8. Click Save and then Publish the player.

Initialize options

When you add the OnceUX plugin to your player, as shown above, you must pass an options object to the plugin to initialize it. This object must contain a metadataUri string or a VMAP object, along with any of the other optional properties:

  • metadataUri
    • Required
    • Type: String
    • Default: undefined
    • Description: The URI to call for the VMAP data.
    • Example: "http://onceux.unicornmedia.com/now/ads/vmap/od/auto/1234"
  • vmap
    • Optional
    • Type: Object
    • Default: none
    • Description: If supplied, the plugin will use this VMAP object instead of calling the metadata URL to get the VMAP data.
    • Example: see this VMAP object
  • hideOverlay
    • Optional
    • Type: Boolean
    • Default: false
    • Description: If true, the countdown timer and the Learn More click through overlays will not be shown while ads are playing.
    • Example: true (hides default overlays)
  • timeout
    • Optional
    • Type: Number
    • Default: 45000
    • Description: The time in milliseconds to wait for the Once URI to respond.
    • Example: 10000 (wait 10 seconds)

Use iframe

It is a best practice to use the iframe player implementation.

Here is the complete code:

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Once UX Plugin</title>

    <!-- Page styles -->
    <style>
    /* set player size */
        iframe {
          width: 640px;
          height: 360px;
        }
    </style>
</head>

<body>

<iframe src='//players.brightcove.net/1752604059001/f12ef9e3-30bc-4edb-aa0a-ad767c99e807_default/index.html' allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>

</body>
</html>

Use embed_in_page

If you choose to use the embed_in_page implementation, you can add the OnceUX plugin right in the page code. Just remember that using the embed_in_page implementation only affects the player instance on the page, while the iframe implementation affects all instances of your player.

Here is the complete code:

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Once UX Plugin</title>
    <link href="//players.brightcove.net/videojs-onceux/2/videojs-onceux.min.css" rel="stylesheet">
</head>

<body>
    <video-js id="myPlayerID"
      style='width: 640px;height: 360px;'
      data-account="1752604059001"
      data-player="b4be1424-e1de-4413-8241-ba373272d2ca"
      data-embed="default"
      class="video-js" controls></video-js>
    <script src="//players.brightcove.net/1752604059001/b4be1424-e1de-4413-8241-ba373272d2ca_default/index.min.js"></script>

    <script src="//players.brightcove.net/videojs-onceux/2/videojs-onceux.min.js"></script>

    <!-- custom script -->
    <script type="text/JavaScript">
        videojs.getPlayer('myPlayerID').ready(function() {
            var myPlayer = this,
            options = { "metadataUri": "http://onceux.unicornmedia.com/now/ads/vmap/od/auto/9bb68221-9a65-4416-837c-2f5b0da311ca/3a6bd8b9-3d91-4ccf-a0bf-325f8aaeb07a/19c5e818-a4bc-4fb2-9c06-0fa04ebd0800/content.once"
        };
        myPlayer.onceux(options);
    });
    </script>
</body>

</html>
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Once UX Plugin</title>
    <link href="//players.brightcove.net/videojs-onceux/2/videojs-onceux.min.css" rel="stylesheet">
</head>

<body>
    <video-js id="myPlayerID"
      style='width: 640px;height: 360px;'
      data-account="3676484086001"
      data-player="0d52b995-92bb-4d5f-9059-e27479550e79"
      data-embed="default"
      class="video-js" controls></video-js>
    <script src="//players.brightcove.net/3676484086001/0d52b995-92bb-4d5f-9059-e27479550e79_default/index.min.js"></script>
    <script src="//players.brightcove.net/videojs-onceux/2/videojs-onceux.min.js"></script>

    <!-- custom script -->
    <script type="text/JavaScript">
        videojs.getPlayer('myPlayerID').ready(function() {
            var myPlayer = this,
                options = { "metadataUri": "http://onceux.unicornmedia.com/now/ads/vmap/od/auto/9bb68221-9a65-4416-837c-2f5b0da311ca/3a6bd8b9-3d91-4ccf-a0bf-325f8aaeb07a/19c5e818-a4bc-4fb2-9c06-0fa04ebd0800/content.once" };
            myPlayer.onceux(options); });
    </script>
</body>

</html>

Methods

The OnceUX plugin has the following methods:

  • player.onceux.absoluteTimeAt(timeInSeconds)
    • A function that takes the content time and returns the absolute time in the entire stream, including ads.
    • Parameters: A Number for the content time in seconds.
    • Returns: Number
    • Example: You can use the following code to seek 5 seconds into the video content.
            myPlayer.currentTime(myPlayer.onceux.absoluteTimeAt(5)))
  • player.onceux.currentTime()
    • A function that returns the current time within the playing ad or content.
    • Parameters: none
    • Returns: Number
  • player.onceux.duration()
    • A function that returns the current duration of the playing ad or content.
    • Parameters: none
    • Returns: Number
  • player.onceux.timeline.pathAtAbsoluteTime(timeInSeconds)
    • A function which takes a Number and provides a "path" into the timeline at any given point between 0 and the absoluteDuration of the stream.
    • Parameters: A Number for the absolute time in seconds to provide a "path" for.
    • Returns: A JSON object for the path representing the timeline. For details, see the path object properties.
  • player.onceux.seekAds(timeInSeconds)
    • A function that takes a time (in seconds) to seek to without the default seek handling behavior enforcing that ads are not skipped.
    • Parameters: A Number for the absolute time in seconds to seek to.
    • Returns: None

Events

The OnceUX plugin events are triggered when the timeupdate event occurs. Both the linearAd and adRoll objects are passed in these events.

Here is an example of an event object returned:

event = {
  adRoll: {},
  linearAd: {}
};

Here are the available events:

  • onceux-linearad-start : The linear ad starts playing.

  • onceux-linearad-impression : The linear ad impression URL has been pinged.

  • onceux-linearad-firstQuartile : The linear ad playhead crosses first quartile.

  • onceux-linearad-midpoint : The linear ad playhead crosses midpoint.

  • onceux-linearad-thirdQuartile : The linear ad playhead crosses third quartile.

  • onceux-linearad-complete : The linear ad completes playing. The playCount property of linear ad is incremented.

  • onceux-adroll-start : The ad roll starts playing.

  • onceux-adroll-complete : The ad roll completes playing. The playCount property of the ad roll is incremented.

  • onceux-ads-complete : All the ads have been played.

  • onceux-linearad-skipped : The linear ad is skipped by the user. Ads can be skipped only when multiple ad rolls are seeked over or by invoking the seekAds() function.

  • onceux-linearad-mute : The linear ad is muted by the user.

  • onceux-linearad-unmute : The linear ad is unmuted by the user.

  • onceux-linearad-pause : The linear ad is paused by the user.

  • onceux-linearad-resume : The linear ad is resumed by the user.

  • onceux-companionad-creativeView : The companion ad creative view event fired.

Properties

You can view the values of runtime properties for the onceux object. Not all properties are currently parsed from the VMAP. See the properties example for the current objects that are returned.

Once object properties

Here are the properties included in the onceux object:

  • player.onceux.timeline
    • Type: Object
    • Description: An object providing the essential parsed "absolute" timeline information from the VMAP.
    • Example:
            {
              contenturi: "",
              adRolls: [],
              absoluteDuration: 0,
              contentDuration: 0,
              pathAtAbsoluteTime: function() {
                return {};
              }
            }
  • player.onceux.timeline.contenturi
    • Type: String
    • Description: The content URI parsed from the VMAP.
  • player.onceux.timeline.absoluteDuration
    • Type: Number
    • Description: The total duration of the content including all Linear advertisements.
  • player.onceux.timeline.contentDuration
    • Type: Number
    • Description: The duration of the content excluding all Linear advertisements.
  • player.onceux.timeline.adRolls
    • Type: Array
    • Description: An Array of JSON objects representing the unmodified VAST 'AdBreak' info parsed from the Once VMAP XML file.

Ad roll properties

Here are the properties included in the adRoll object:

  • adRoll.absoluteBeginTime : Indicates the absolute time at which the adRoll will begin.

  • adRoll.absoluteEndTime : Indicates the absolute time at which the adRoll will end.

  • adRoll.index : Indicates the position of the adRoll with respect to the other adRollsIndicates the absolute time at which the adRoll will end.

  • adRoll.playCount : Indicates the number of times the adRoll has completed. Value 0 means that it has not been played.

Linear ad properties

Here are the properties included in the linearAd object:

  • linearAd.absoluteBeginTime : Indicates the absolute time at which the linear ad will begin.

  • linearAd.absoluteEndTime : Indicates the absolute time at which the linear ad will end.

  • linearAd.index : Indicates the position of the linear ad within the adRoll.

  • linearAd.playCount : Indicates the number of times the linear ad has been played. Value 0 means that it has not been played.

  • linearAd.skipOffset : Indicates the time after which the linear ad can be skipped. Value 0 means that the linear ad is not skippable.

  • linearAd.companionAd : An object representing the unmodified VAST companionAd info.

  • linearAd.companionAds : An array that holds a number of companionAd objects. An example usage appears as follows:

    "companionAds": [{
      "id": "54061052904921234300x250",
      "width": "300",
      "height": "250",
      "CompanionClickThrough": "http: //www.bluebucks.com/static/images/global/logo.png",
      "TrackingEvents": {
        "Tracking": [{
          "event": "creativeView",
          "url": "http: //companiontrack.demo.url.com/companion/bluebuckstwo"
        }]
      },
      "StaticResource": {
        "creativeType": "image/jpeg",
        "url": "http: //demo.umedia.com/jes/ads/bluebuckstwo300.jpg"
      }
    }]

Path properties

Here are the properties included in the path object:

  • path.absoluteTime : This is the time in the stream relative to the absolute total time. This will always match what is passed into the function and provided just for convenience.

  • path.contentTime : This is the time in the stream relative to the currently playing linear advertisement or content.

  • path.adRoll : This value is null if no ad should be playing at the passed absolute time or if an ad should be playing, a JSON Object with the linear advertisement absolute begin/end time info from the timeline.

  • path.linearAd : This value is null if no ad should be playing at the passed absolute time or if an ad should be playing, a JSON Object with the linear advertisement AdBreak info from the timeline.

Here is an example of a path object without an ad.

{
  "absoluteTime": 3,
  "contentTime": 3,
  "adRoll": null,
  "linearAd": null
}

Here is an example of a path object with an ad.

{
  "absoluteTime": 3,
  "contentTime": 3,
  "adRoll": {
    "absoluteBeginTime": 0,
    "absoluteEndTime": 60,
    "index": 0,
    "playCount": 0,
    "linearAdCount": 1
  },
  "linearAd": {
    "absoluteBeginTime": 0,
    "absoluteEndTime": 30,
    "breakType": "linear",
    "breakId": "PreRoll_0_0",
    "timeOffset": "start",
    "index": 0,
    "playCount": 0,
    "skipOffset": 0,
    "companionAds": [{
      "id": "54061052904921234300x250",
      "width": "300",
      "height": "250",
      "CompanionClickThrough": "http: //www.bluebucks.com/static/images/global/logo.png",
      "TrackingEvents": {
        "Tracking": [{
          "event": "creativeView",
          "url": "http: //companiontrack.demo.url.com/companion/bluebuckstwo"
        }]
      },
      "StaticResource": {
        "creativeType": "image/jpeg",
        "url": "http: //demo.umedia.com/jes/ads/bluebuckstwo300.jpg"
      }
    }],
    "AdSource": {
      "id": "1",
      "VASTData": {
        "VAST": {
          "Ad": {
            "id": "UmAds",
            "Inline": {
              "AdSystem": "UnicornInternal",
              "AdTitle": "videoadvertisement",
              "Description": "video ad",
              "Impression": "http://impressionurl1.demo.url.com/impression/demoAdstwo",
              "Creatives": {
                "Creative": [{
                  "Linear": {
                    "Duration": "00:00:30.0666666+00:00",
                    "TrackingEvents": {
                      "Tracking": [{
                        "event": "start",
                        "offset": "0",
                        "text": "http://trackingurl.demo.url.com/start/demoAdstwo"
                      }, {
                        "event": "firstQuartile",
                        "offset": "7",
                        "text": "http://trackingurl.demo.url.com/firstQuartile/demoAdstwo"
                      }, {
                        "event": "midpoint",
                        "offset": "15",
                        "text": "http://trackingurl.demo.url.com/midpoint/demoAdstwo"
                      }, {
                        "event": "thirdQuartile",
                        "offset": "22",
                        "text": "http://trackingurl.demo.url.com/thirdQuartile/demoAdstwo"
                      }, {
                        "event": "complete",
                        "offset": "30",
                        "text": "http://trackingurl.demo.url.com/complete/demoAdstwo"
                      }]
                    },
                    "VideoClicks": {
                      "ClickThrough": {
                        "id": "abc",
                        "text": "http://www.demoAds.com/static/images/global/logo.png"
                      },
                      "ClickTracking": {
                        "id": "",
                        "text": "http://www.clicktracking.com/test?click"
                      }
                    },
                    "MediaFiles": {}
                  }
                }]
              }
            }
          }
        }
      }
    }
  }
}

Seek handling

By default, the plugin enforces a "must-watch" ad policy. All advertisements must be watched in their entirety and adRolls cannot be skipped over or into part way. The only exception is when a seek is performed over multiple adRolls, where the plugin enforces that only the last adRoll that was seeked over is watched.

Here are some examples:

  • Seek out of an ad : Returns the user to where they seeked from.

  • Seek into an ad break : Returns the user to the start of the adRoll containing the adBreak.

  • Seek over an ad : Returns the user to the start of the adRoll seeked over. When the ad finishes playing, the user is returned to the point they initially requested.

  • Seek over multiple ad rolls : Returns the user to the start of the last adRoll seeked over. When the ad finishes playing, the user is returned to the point they initially requested.

  • Seek backwards : No default handling

Skippable ads

You can implement skippable ads in two ways. They are:

  • Using the skipoffset attribute in the VMAP/VAST ad definition. The applicable fragment from the VMAP XML is shown here:
          <Creatives>
            <Creative id="57860459056">
              <Linear skipoffset="00:00:05">
  • Using the linearAd.skipOffset property in your options. The applicable fragment from the JSON formatted options is shown here:
      "linearAd": {
        "absoluteBeginTime": 0,
        "absoluteEndTime": 30,
        "breakType":"linear",
        "breakId":"PreRoll_0_0",
        "timeOffset":"start",
        "index": 0,
        "playCount": 0,
        "skipOffset": 5,

Glossary

This plugin distinguishes the concepts of absolute and content time within a OnceUX stream. Traditional video players only have a concept of content time; times between start and end of the URI it is currently playing. Because a OnceUX stream is essentially a number of content streams stitched together we've introduced the concept of absolute time which takes into account the complete stitched stream including the video advertisements.

When you see the prefix absolute on a property or method, the times expected/returned are relative to the entire stitched stream. When you see the prefix content, the times expected/returned are relative only to a particular piece of content that was stitched into the stream (the main content or single linear advertisement).

  • timeline : A JSON representation of the information in the Once VMAP XML. The timeline describes the stream and is referenced during playback constantly to ensure the UI is adapting to the currently playing content.

  • path : A snapshot of the timeline at any given second with information that is relavant only to that point in time within the stream.

  • absoluteDuration : The total duration of the stream including the linear ads.

  • contentDuration : The total duration of the stream excluding the linear ads.

  • absoluteTime : The time within the stream relative to absolute time.

  • contentTime : The time within the stream relative to the stitched content segement.

  • absoluteStartTime : The start time for stitched content in absolute time.

  • absoluteEndTime : The end time for stitched content in absolute time.

  • adRoll : A collection of one or more linear ads and non-linear ads.

  • linearAd : An adBreak which replaces the main video content. For example, video ads.

  • companionAd : An adBreak accompanying the linear ad or nonlinear ad which will be displayed outside the player screen. For example, ad banners.

  • nonLinerAd : An adBreak which will not replace the main video content. For example, overlay ads. These are not yet supported.

Changelog

3 Oct 2017

v2.3.3

  • Fix an incompatibility between OnceUX and Video.js 6.3

2 Oct 2017

v2.3.2

  • Fix an incompatibility between OnceUX and Video.js 6 on mobile devices

1 Sep 2017

v2.3.1

  • Fixed support for click tracking coming from the Learn More overlay link

23 Aug 2017

v2.3.0

  • Added support for ClickTracking elements in the VMAP/VAST response

24 Jul 2017

v2.2.1

  • No longer block player UI while loading a source from Video Cloud

17 Jul 2017

v2.2.0

  • Added support for multiple companion ads

16 May 2017

v2.1.0

  • Added player.ads.ad.id while ad is playing
  • Added player.ads.ad.index while ad is playing
  • Added player.ads.ad.duration while ad is playing

27 Apr 2017

v2.0.0

  • Added support for macros in VMAP URLs
  • Added support for Video.js v6
  • playing events are now triggered in a way that is consistent with other Brightcove ad plugins
  • contentplayback event has been removed

22 Mar 2017

v1.4.0

  • Added support for standard ad events

22 Mar 2017

v1.3.0

  • Added support for Widevine / Playready DRM with Dash and Dynamic Delivery

19 Dec 2016

v1.2.0

  • Video Cloud support via player.onceux.loadSourcesFromCatalog

22 Nov 2016

v1.1.0

  • Volume now persists between content and ads

Dates not recorded from v1.0.1 and earlier

v1.0.1

  • Support switching between OnceUX sources

v1.0.0

  • Updated to use contrib-ads 3.3.8
  • Do not show captions if none exist
  • Update for Video.js 5
  • Share button moved from control bar to dock
  • Only play ad if we weren't playing previously
  • Don't play preroll if we seeked from before playback started
  • Prevent replay after postroll
  • Make mouse time display work with OnceUX control bar

v0.9.0

  • Make client tracking beacons optional

v0.8.1

  • Add social button on control bar if enabled
  • Support multiple Once players

v0.8.0

  • Set contentHeaders=true by default to serve HLS on desktop
  • Only send contentHeaders when we are adding in HLS support

v0.7.3

  • Fix bug in build script

v0.7.2

  • Disable clickthrough if hideOverlay is true
  • Set cursor to default when hideOverlay is true

v0.7.1

  • Namespaced the CSS

v0.7.0

  • Provide method for converting content time to absolute time

v0.6.0

  • Fix bug regarding skipping midrolls
  • Correct overlay alignment and skip ad styles

v0.5.1

  • Fix bug regarding calculating currentTime without a timeline

v0.5.0

  • Update contrib-ads dependency to 0.7.0
  • Captions on Once stream
  • Add multiple language captions support
  • Fix bug where control bar play button requires two clicks on load

v0.4.2

  • Add clickthrough handler when ads are playing
  • Upgrade video.js dependency to 4.10.1

v0.4.1

  • Trigger play and playing events for analytics

v0.4.0

  • Fix Brightcove player control bar

v0.3.0

  • Add support for OnceUX controls

v0.2.2

  • Make sure replay event tracking works
  • Make sure companions are shown on seek whenever the linear ad changes
  • Use an img tag to avoid crossdomain issues with tracking
  • Make seek handling better on iOS

v0.2.0

  • Add companion ad support for linear ads
  • Fix contenturi when setting vmap to object
  • Support for skippable ads

v0.1.1

  • Initial release