The Extension API provides the ability to ‘extend’ the capability of the platform by creating your own custom annotation.
Steps to use Extension API
Located in the project editor view, click on the icon to open the widget library menu.
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.
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>
hapyak.context.player.play()
hapyak.context.player.pause()
hapyak.context.player.mute()
hapyak.context.player.pause()
hapyak.context.player.volume()
hapyak.context.player.volume(0.5)
addClass(classNames, selector) and removeClass(classNames, selector)
Set or remove CSS classes on the IFRAME annotation where:
classNames
(string or array) classNames
can be a single class e.g myAwesomeClass
or an array of classes ['class1', 'class2']
selector
(optional) 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.
examples:
hapyak.context.player.addClass('myClass', 'div#wrapper > h1)
hapyak.context.player.removeClass('myClass', 'div#wrapper > .exampleElement')
READ ONLY
var playerPaused = hapyak.context.player.paused
READ ONLY
var videoLength = hapyak.context.player.paused //duration in seconds
READ / WRITE
var currentTime = hapyak.context.player.currentTime //returns time in seconds
hapyak.context.player.currentTime = 20 //will jump to 20 seconds
READ ONLY
hapyak.context.player.isEditMode
READ ONLY
hapyak.context.player.isEditing
In order to set properties, the iFrame must be visible. The following example is one recommended way to ensure that the iframe is shown prior to attempting a resize.
hapyak.context.addEventListener('iframeshow', function () {
hapyak.context.width = document.body.querySelector('.hapyak-iframe-container').offsetWidth;
});
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 this screenshot:
READ ONLY
hapyak.context.annotationData
hapyak.context.addEventListener('annotationload', function(){
console.log("annotation Data", hapyak.context.annotationData)
});
READ / WRITE
hapyak.context.width = pixels
READ / WRITE
hapyak.context.height = pixels
Events are accessed through event listeners on the hapyak.context object:
hapyak.context.addEventListener("event", function () {
//do something here
});
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
}
hapyak.context.addEventListener("loadedmetadata", function (data) {
console.log(data)
});
hapyak.context.addEventListener("data", function (data) {
console.log(data);
});
{
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"
}
hapyak.context.addEventListener("iframeshow", function () {
console.log('Iframe has appeared');
});
hapyak.context.addEventListener("timeupdate", function () {
// prints current time of video to the console
console.log(hapyak.context.player.currentTime);
});
hapyak.context.addEventListener("resized", function () {
console.log('Player is becoming smaller');
});
hapyak.context.addEventListener("play", function () {
console.log("Video is currently playing");
});
hapyak.context.addEventListener("pause", function () {
console.log('Player has been paused');
});
hapyak.context.addEventListener("iframehide", function () {
console.log('Iframe annotation is no longer visible');
});
hapyak.context.addEventListener("editModeChange", function () {
console.log('Video is currently being edited');
});
hapyak.context.addEventListener("playerHover", function () {
console.log('Mouse is being hovered within the player');
});
hapyak.context.tracking.widgetAction(action, properties)
Allows partners to track custom analytics.
trackButton.addEventListener( "click", function () {
hapyak.context.tracking.widgetAction('Follow', {'username': 'foobar123'});
});
<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>
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
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)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:
The variable would resolve after the function is called:
hapyak.context.env.get('name')
Returns the value of the variable by name
.
set
sets data asynchronously, so if you call get
immediately after set
and before
the data
event fires, the values may be different.
To return annotation data in current project:
hapyak.context.addEventListener("data", function() { //wait for data event to fire
hapyak.context.env.get('projectAnnotations')
})
hapyak.context.env.clear('name')
name
.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
});