Brightcove Interactivity Extension API

The Extension API provides the ability to ‘extend’ the capability of the platform by creating your own custom annotation.

Extension API

The Extension API provides the ability to ‘extend’ the capability of the platform by creating your own custom annotation.

Steps to use Extension API

  1. Located in the project editor view, click on the alt text icon to open the widget library menu. alt text

  2. From here, click the HTML tab. This block of code contains all of the necessary scripts to get started. Editing the raw HTMLboiler-plate code gives you the freedom to build a custom extension or annotation tailored to your needs.
    alt text

This example represents a good starting point:

<!doctype html>
<html>
  <head>
      <title></title>
      <meta charset="utf-8"/>
      <style type="text/css">
          html, body { margin: 0; padding: 0 }
      </style>
  </head>
  <body>
      <!-- HTML code goes here -->

      <script type="text/javascript" src="//d2qrdklrsxowl2.cloudfront.net/js/hapyak-iframe.js"></script>
      <script type="text/javascript" src="//d2qrdklrsxowl2.cloudfront.net/js/hapyak.api.js"></script>
      <script type="text/javascript">
          (function () {
              /*
              Write your script code here
              */

              hapyak.context.addEventListener('data', function (variables) {
                  /*
                  Access Environment variables here
                  */
              });
          }());
      </script>
  </body>
</html>

Player object

Object: hapyak.context.player

Methods

play()

hapyak.context.player.play()

Plays the video.

pause()

hapyak.context.player.pause()

Pauses the video.

mute()

hapyak.context.player.mute()

Mutes the video.

unmute()

hapyak.context.player.unmute()

Unmutes the video.

volume()

hapyak.context.player.volume()

Passing no arguments to this function returns a number between 0 to 1 representing the current volume.

hapyak.context.player.volume(0.5)

Passing a number between 0-1 will set the volume of the player to that value.

addClass(classNames, selector)

hapyak.context.player.

Add CSS classes on the IFRAME annotation where:

  • classNames (string or array) can be a single class e.g myAwesomeClass or an array of classes ['class1', 'class2']
  • selector (optional) is used to target an existing class, id, or DOM element on the player element and add the class(es) to that element. If a selector is not passed in, the class will be added to the parent div within the iframe.
Example
hapyak.context.player.addClass('myClass', 'div#wrapper > h1)

removeClass(classNames, selector)

hapyak.context.player.

Remove CSS classes on the IFRAME annotation where:

  • classNames (string or array) can be a single class e.g myAwesomeClass or an array of classes ['class1', 'class2']
  • selector (optional) is used to target an existing class, id, or DOM element on the player element and add the class(es) to that element. If a selector is not passed in, the class will be added to the parent div within the iframe.
Example
hapyak.context.player.removeClass('myClass', 'div#wrapper > .video-title')

Properties

paused

READ ONLY

let playerPaused = hapyak.context.player.paused

Get whether video is paused or not.

duration

READ ONLY

const videoLength = hapyak.context.player.duration //duration in seconds

Returns video duration (unit: seconds).

currentTime

READ / WRITE

let currentTime = hapyak.context.player.currentTime //returns time in seconds

Can be used to Get current video time (unit: seconds).

hapyak.context.player.currentTime = 20 //will jump to 20 seconds

Can also be used to set the current time of the video (jump to time).

isEditMode

READ ONLY

hapyak.context.player.isEditMode

Returns true if the IFRAME is being displayed inside a Brightcove Interactivity editor.

isEditing

READ ONLY

hapyak.context.player.isEditing

Returns true if the IFRAME is currently being edited.

Annotation object

Methods

hapyak.context.releaseGate()

A gate restricts the progress of a viewer in the video, requiring that they interact with an annotation prior to continuing on. In the extension api, you must explicitly state when a gate is to be relased. To set a gate, toggle the respective option in the edit tab on the annotation to y as seen in these screenshots:

edit
gate
  • If the IFRAME is set to be gated, calling this method will release that gate.

Properties

annotationData

READ ONLY

hapyak.context.annotationData

Returns list of current annotation's properties. From here we can gain access to group and project configuration elements, including group and project level css. It is good practice to maintain styling by adding your group and project level CSS to the extension. In order to return this object, you must wait for the annotation to load:

hapyak.context.addEventListener('annotationload', function(){
  console.log("annotation Data", hapyak.context.annotationData)
});

width

READ / WRITE

hapyak.context.width = pixels

Sets or gets the width of the IFRAME element.

height

READ / WRITE

hapyak.context.height = pixels

Sets or gets the height of the IFRAME element.

Events

Events are accessed through event listeners on the hapyak.context object:

hapyak.context.addEventListener("event", function () {
  //do something here
});

annotationload

hapyak.context.addEventListener("annotationload", function (data) {
  console.log(data)
});
  • Emitted when the current annotation loads.

  • The object emitted by this event contains data related to the annotation, as well as group, and project configuration data.

{
  top: "19.999999999999993%",
  left: "20%",
  width: "60%",
  height: "60%",
  duration: 3,
  durationFormat: "seconds"
  durationValue: 3
  end: 6.2256
  groupConfig: {gates: true, minWidth: "0", iframeTimeout: 30000}
  height: "60%"
  id: "iframe1560519550307"
  left: "20%"
  projectConfig: {css: "", title: "Extension API example"},
  projectId: 284539
  projectTrackId: 575497
  start: 3.2256
  startTimeFormat: "seconds"
  startTimeValue: 3.2256
}

loadedmetadata

hapyak.context.addEventListener("loadedmetadata", function (data) {
    console.log(data)
});

Emitted when the Brightcove Interactivity metadata has finished loading.

data

hapyak.context.addEventListener("data", function (data) {
  console.log(data);
});

The 'data' event will fire anytime there is a change in the environment variables. This happens often. Below is an example of the object that is returned.

{
  annotationIds: {1457229: true, 1457445: true, 1457474: true, 1457475: true}
  annotationsLoaded: true
  configuration: {gates: true, minWidth: "0", iframeTimeout: 30000,}
  projectAnnotations: {1457229: {}, 1457445: {}, 1457474: {}, 1457475: {}}
  projectConfig: {css: "", title: "Extension API example"}
  projectId: 284539
  projectName: "Extension API example"
}

iframeshow

hapyak.context.addEventListener("iframeshow", function () {
  console.log('Iframe has appeared');
});

Emitted when the IFRAME annotation enters its start time and is shown.

iframehide

hapyak.context.addEventListener("iframehide", function () {
  console.log('Iframe annotation is no longer visible');
});

Emitted when the IFRAME annotation passes its end time and is hidden.

timeupdate

hapyak.context.addEventListener("timeupdate", function () {
  // prints current time of video to the console
  console.log(hapyak.context.player.currentTime);
});

Emitted when the current video time changes, and at a regular interval while the video is playing.

resized

hapyak.context.addEventListener("resized", function () {
  console.log('Player is becoming smaller');
});

Emitted when the player is resized relative to the window.

play

hapyak.context.addEventListener("play", function () {
  console.log("Video is currently playing");
});

Emitted when the video begins playing.

pause

hapyak.context.addEventListener("pause", function () {
  console.log("Player has been paused");
});

Emitted when the video becomes paused.

editModeChange

hapyak.context.addEventListener("pause", function () {
  console.log('Player has been paused');
});

Emitted when the edit mode is changed within the Brightcove Interactivity editor.

playerHover

hapyak.context.addEventListener("playerHover", function () {
  console.log('Mouse is being hovered within the player');
});

Emitted when a hover event occurs over the player. This event as a returned value of true or false for hovering or not hovering respectively.

Tracking object

hapyak.context.tracking.widgetAction(action, properties)

Allows partners to track custom analytics.

trackButton.addEventListener( "click", function () {
  hapyak.context.tracking.widgetAction('Follow', {'username': 'foobar123'});
});
  • Action: The name of the action being tracked. This can be any string.
  • Properties: Object of properties you wish to attach to this tracked action. The properties you wish to track is entirely up to you, but must be in true JSON format.
  • using the VideoJS4 Embed type provided in the share modal, you can add options to the viewer object that will allow you to see, and track your own analytics as seen below:
<video id="hapyak-player-157199-8825"  class="video-js vjs-default-skin" width="720" height="405" playsinline="playsinline">
  <source src="https://sample.hapyak-hosted.com/group_uploads/23/16673/videos/862f7e32a9b94974b98f004ae49fa9ef/Sample-Video-with-sound.mp4" type="video/mp4"/>
</video>
<link rel="stylesheet" href="//vjs.zencdn.net/4.8/video-js.css">
<script type="text/javascript" src="//vjs.zencdn.net/4.8/video.js"></script>

<script type="text/javascript" src="//d2qrdklrsxowl2.cloudfront.net/js/hapyak.js"></script>
<script type="text/javascript">
  (function () {
      var vjs = videojs('hapyak-player-157199-8825');

      hapyak.viewer({
          apiKey: "12345678910111213",
          projectId: 286041,
          resetVariables: true,
          player: vjs,
          videoType: "html5",
          playerType: "videojs4",
          autoplay: false,
          oncustomtrackingevent: function(data) {
            console.log("custom Data", data)
          }
      });
  })();
</script>

Session variables

These variables only exists during the session. Setting variables via the Extension API is functionally equivalent to passing in a "variables" object on the Viewer.

OBJECT: hapyak.context.env

Methods

set(name, value, temp, scope)

hapyak.context.env.set('obj', {name: "Andrew", anotherName: "Homer J Simpson"}, false, 'track');

Sets the value of the variable by name.

  • temp if true, the value will not be captured to the browser local storage. (default: false)
  • scope should be set to track to make the data available to other annotations. (default: annotation scope)
  • Variables where scope is annotation scope, there is no limitation to the data types that can be used.

Based on the example above, if we wanted to access the data from the the variable obj we could do so in a text annotation like this:

alt text

The variable would resolve after the function is called: alt text

get(name)

hapyak.context.env.get('name')

Returns the value of the variable by name.

To return annotation data in current project:

hapyak.context.addEventListener("data", function() { //wait for data event to fire
  hapyak.context.env.get('projectAnnotations')
})

Clears the value of a single variable by name.

NOTES:

Any variables set with env.set are changed asynchronously because they need time to be communicated to the parent window. The new value will not be returned by env.get until the next "data" event fires, which should occur within a few milliseconds.

console.log(hapyak.context.env.get('myData')); //foo
  hapyak.context.env.set('myData', 'bar');
  console.log(hapyak.context.env.get('myData')); //foo
  hapyak.context.addEventListener('data', function () {
      console.log(hapyak.context.env.get('myData')); //bar
  });