var fluidPlayerScriptLocation = function() {
var currentSrc = '';
if (document.currentScript) {
currentSrc = document.currentScript.src;
} else {
//IE
currentSrc = (function() {
var scripts = document.getElementsByTagName('script'),
script = scripts[scripts.length - 1];
if (script.getAttribute.length !== undefined) {
return script.src;
}
return script.getAttribute('src', -1)
}());
}
if (currentSrc) {
return currentSrc.substring(0, currentSrc.lastIndexOf('/') + 1);
}
return '';
}();
//Object.assign polyfill
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
//CustomEvent polyfill
(function () {
if ( typeof window.CustomEvent === "function" ) return false;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
fluidPlayer = function(idVideoPlayer, options) {
var inArray = function(needle, haystack) {
var length = haystack.length;
for (var i = 0; i < length; i++) {
if (haystack[i] == needle) {
return true;
}
}
return false;
};
var copy = fluidPlayerClass.constructor();
for (var attr in fluidPlayerClass) {
if (fluidPlayerClass.hasOwnProperty(attr) && !inArray(attr, fluidPlayerClass.notCloned)) {
copy[attr] = fluidPlayerClass[attr];
}
}
fluidPlayerClass.instances.push(copy);
copy.init(idVideoPlayer, options);
return copy;
};
var fluidPlayerClass = {
vttParserScript: '/scripts/webvtt.js',
instances: [],
notCloned: ['notCloned', 'vttParserScript', 'instances', 'getInstanceById',
'requestStylesheet', 'reqiestScript', 'isTouchDevice', 'vastOptions',
'displayOptions', 'getEventOffsetX', 'getEventOffsetY', 'getTranslateX',
'toggleElementText', 'getMobileOs', 'findClosestParent', 'activeVideoPlayerId',
'getInstanceIdByWrapperId', 'timer', 'timerPool', 'adList', 'adPool',
'isUserActive', 'isCurrentlyPlayingAd', 'initialAnimationSet'],
version: '2.2.2',
homepage: 'https://www.fluidplayer.com/',
activeVideoPlayerId: null,
getInstanceById: function(playerId) {
for (var i = 0; i < this.instances.length; i++) {
if (this.instances[i].videoPlayerId === playerId) {
return this.instances[i];
}
}
return null;
},
getInstanceIdByWrapperId: function(wrapperId) {
return typeof wrapperId != "undefined" ? wrapperId.replace('fluid_video_wrapper_', '') : null;
},
requestStylesheet: function(cssId, url) {
if (!document.getElementById(cssId)) {
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.id = cssId;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
link.media = 'all';
head.appendChild(link);
}
},
requestScript: function(url, callback) {
// Adding the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
},
isTouchDevice: function() {
return !!('ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints); // works on IE10/11 and Surface
},
/**
* Distinguises iOS from Android devices and the OS version.
*
* @returns object
*/
getMobileOs: function() {
var ua = navigator.userAgent;
var uaindex;
var result = {device: false, userOs: false, userOsVer: false, userOsMajor: false};
// determine OS
if (ua.match(/iPad/i)) {
result.device = 'iPad';
result.userOs = 'iOS';
uaindex = ua.indexOf('OS ');
} else if (ua.match(/iPhone/i)) {
result.device = 'iPhone';
result.userOs = 'iOS';
uaindex = ua.indexOf('OS ');
} else if (ua.match(/Android/i)) {
result.userOs = 'Android';
uaindex = ua.indexOf('Android ');
} else {
result.userOs = false;
}
// determine version
if (result.userOs === 'iOS' && (uaindex > -1)) {
var userOsTemp = ua.substr(uaindex + 3);
var indexOfEndOfVersion = userOsTemp.indexOf(' ');
if (indexOfEndOfVersion !== -1) {
result.userOsVer = userOsTemp.substring(0, userOsTemp.indexOf(' ')).replace(/_/g, '.');
result.userOsMajor = parseInt(result.userOsVer);
}
} else if (result.userOs === 'Android' && (uaindex > -1)) {
result.userOsVer = ua.substr(uaindex + 8, 3);
} else {
result.userOsVer = false;
}
return result;
},
/**
* Browser detection
*
* @returns object
*/
getBrowserVersion: function() {
var ua = navigator.userAgent;
var result = {browserName: false, fullVersion: false, majorVersion: false, userOsMajor: false};
var idx, uaindex;
try {
result.browserName = navigator.appName;
if ((idx = ua.indexOf("OPR/")) != -1) {
result.browserName = "Opera";
result.fullVersion = ua.substring(idx + 4);
}
else if ((idx = ua.indexOf("Opera")) != -1) {
result.browserName = "Opera";
result.fullVersion = ua.substring(idx + 6);
if ((idx = ua.indexOf("Version")) != -1)
result.fullVersion = ua.substring(idx + 8);
}
else if ((idx = ua.indexOf("MSIE")) != -1) {
result.browserName = "Microsoft Internet Explorer";
result.fullVersion = ua.substring(idx + 5);
}
else if ((idx = ua.indexOf("Chrome")) != -1) {
result.browserName = "Google Chrome";
result.fullVersion = ua.substring(idx + 7);
}
else if ((idx = ua.indexOf("Safari")) != -1) {
result.browserName = "Safari";
result.fullVersion = ua.substring(idx + 7);
if ((idx = ua.indexOf("Version")) != -1)
result.fullVersion = ua.substring(idx + 8);
}
else if ((idx = ua.indexOf("Firefox")) != -1) {
result.browserName = "Mozilla Firefox";
result.fullVersion = ua.substring(idx + 8);
}
// Others "name/version" is at the end of userAgent
else if ((uaindex = ua.lastIndexOf(' ') + 1) < (idx = ua.lastIndexOf('/'))) {
result.browserName = ua.substring(uaindex, idx);
result.fullVersion = ua.substring(idx + 1);
if (result.browserName.toLowerCase() == result.browserName.toUpperCase()) {
result.browserName = navigator.appName;
}
}
// trim the fullVersion string at semicolon/space if present
if ((uaindex = result.fullVersion.indexOf(';')) != -1) {
result.fullVersion = result.fullVersion.substring(0, uaindex);
}
if ((uaindex = result.fullVersion.indexOf(' ')) != -1) {
result.fullVersion = result.fullVersion.substring(0, uaindex);
}
result.majorVersion = parseInt('' + result.fullVersion, 10);
if (isNaN(result.majorVersion)) {
result.fullVersion = '' + parseFloat(navigator.appVersion);
result.majorVersion = parseInt(navigator.appVersion, 10);
}
} catch (e) {
//Return default obj.
}
return result;
},
getCurrentVideoDuration: function() {
var videoPlayerTag = document.getElementById(this.videoPlayerId);
if (videoPlayerTag) {
return videoPlayerTag.duration;
}
return 0;
},
getClickThroughUrlFromLinear: function(linear) {
var videoClicks = linear.getElementsByTagName('VideoClicks');
if (videoClicks.length) {//There should be exactly 1 node
var clickThroughs = videoClicks[0].getElementsByTagName('ClickThrough');
if (clickThroughs.length) {
return this.extractNodeData(clickThroughs[0]);
}
}
return false;
},
getVastAdTagUriFromWrapper: function(xmlResponse) {
var wrapper = xmlResponse.getElementsByTagName('Wrapper');
if (typeof wrapper !== 'undefined' && wrapper.length) {
var vastAdTagURI = wrapper[0].getElementsByTagName('VASTAdTagURI');
if (vastAdTagURI.length) {
return this.extractNodeData(vastAdTagURI[0]);
}
}
return false;
},
hasInLine: function (xmlResponse) {
var inLine = xmlResponse.getElementsByTagName('InLine');
return ((typeof inLine !== 'undefined') && inLine.length);
},
hasVastAdTagUri: function (xmlResponse) {
var vastAdTagURI = xmlResponse.getElementsByTagName('VASTAdTagURI');
return ((typeof vastAdTagURI !== 'undefined') && vastAdTagURI.length);
},
hasVastAdTagUriFromWrapper: function(creative) {
var player = this;
if ((typeof creative !== 'undefined') && creative.length) {
var arrayCreativeLinears = creative[0].getElementsByTagName('Linear');
if ((typeof arrayCreativeLinears !== 'undefined') && (arrayCreativeLinears !== null) && arrayCreativeLinears.length) {
return player.getMediaFileFromLinear(arrayCreativeLinears[0]);
}
}
return false;
},
getClickThroughUrlFromNonLinear: function (nonLinear) {
var result = '';
var nonLinears = nonLinear.getElementsByTagName('NonLinear');
if (nonLinears.length) {//There should be exactly 1 node
var nonLinearClickThrough = nonLinear.getElementsByTagName('NonLinearClickThrough');
if (nonLinearClickThrough.length) {
result = this.extractNodeData(nonLinearClickThrough[0]);
}
}
return result;
},
getTrackingFromLinear: function(linear) {
var trackingEvents = linear.getElementsByTagName('TrackingEvents');
if (trackingEvents.length) {//There should be no more than one node
return trackingEvents[0].getElementsByTagName('Tracking');
}
return [];
},
getDurationFromLinear: function(linear) {
var duration = linear.getElementsByTagName('Duration');
if (duration.length && (typeof duration[0].childNodes[0] !== 'undefined')) {
var nodeDuration = this.extractNodeData(duration[0]);
return this.convertTimeStringToSeconds(nodeDuration);
}
return false;
},
getDurationFromNonLinear: function(tag) {
var result = 0;
var nonLinear = tag.getElementsByTagName('NonLinear');
if (nonLinear.length && (typeof nonLinear[0].getAttribute('minSuggestedDuration') !== 'undefined')) {
result = this.convertTimeStringToSeconds(nonLinear[0].getAttribute('minSuggestedDuration'));
}
return result;
},
getDimensionFromNonLinear: function (tag) {
var result = {'width': null, 'height': null};
var nonLinear = tag.getElementsByTagName('NonLinear');
if (nonLinear.length) {
if (typeof nonLinear[0].getAttribute('width') !== 'undefined') {
result.width = nonLinear[0].getAttribute('width');
}
if (typeof nonLinear[0].getAttribute('height') !== 'undefined') {
result.height = nonLinear[0].getAttribute('height');
}
}
return result;
},
getCreativeTypeFromStaticResources: function (tag) {
var result = '';
var nonLinears = tag.getElementsByTagName('NonLinear');
if (nonLinears.length && (typeof nonLinears[0].childNodes[0] !== 'undefined')) {//There should be exactly 1 StaticResource node
result = nonLinears[0].getElementsByTagName('StaticResource')[0].getAttribute('creativeType');
}
return result.toLowerCase();
},
getMediaFilesFromLinear: function(linear) {
var mediaFiles = linear.getElementsByTagName('MediaFiles');
if (mediaFiles.length) {//There should be exactly 1 MediaFiles node
return mediaFiles[0].getElementsByTagName('MediaFile');
}
return [];
},
getStaticResourcesFromNonLinear: function(linear) {
var result = [];
var nonLinears = linear.getElementsByTagName('NonLinear');
if (nonLinears.length) {//There should be exactly 1 StaticResource node
result = nonLinears[0].getElementsByTagName('StaticResource');
}
return result;
},
extractNodeData: function(parentNode) {
var contentAsString = "";
for(var n = 0; n < parentNode.childNodes.length; n ++)
{
var child = parentNode.childNodes[n];
if (child.nodeType === 8 || (child.nodeType === 3 && /^\s*$/.test(child.nodeValue))) {
// Comments or text with no content
} else {
contentAsString += child.nodeValue;
}
}
var tidyString = contentAsString.replace(/(^\s+|\s+$)/g,'');
return tidyString;
},
getMediaFileFromLinear: function(linear) {
var mediaFile;
var mediaFiles = this.getMediaFilesFromLinear(linear);
if (mediaFiles.length) {
mediaFile = this.extractNodeData(mediaFiles[0]);
}
return mediaFile;
},
getIconClickThroughFromLinear: function (linear) {
var iconClickThrough = linear.getElementsByTagName('IconClickThrough');
if (iconClickThrough.length) {
return this.extractNodeData(iconClickThrough[0]);
} else {
this.displayOptions.vastOptions.adCTAText = false;
}
return '';
},
getStaticResourceFromNonLinear: function(linear) {
var fallbackStaticResource;
var staticResources = this.getStaticResourcesFromNonLinear(linear);
for (var i = 0; i < staticResources.length; i++) {
if (!staticResources[i].getAttribute('type')) {
fallbackStaticResource = this.extractNodeData(staticResources[i]);
}
if (staticResources[i].getAttribute('type') === this.displayOptions.staticResource) {
return this.extractNodeData(staticResources[i]);
}
}
return fallbackStaticResource;
},
registerTrackingEvents: function(creativeLinear, tmpOptions) {
var trackingEvents = this.getTrackingFromLinear(creativeLinear);
var eventType = '';
var oneEventOffset = 0;
for (var i = 0; i < trackingEvents.length; i++) {
eventType = trackingEvents[i].getAttribute('event');
switch (eventType) {
case 'start':
case 'firstQuartile':
case 'midpoint':
case 'thirdQuartile':
case 'complete':
if (typeof tmpOptions.tracking[eventType] === 'undefined') {
tmpOptions.tracking[eventType] = [];
}
if (typeof tmpOptions.stopTracking[eventType] === 'undefined') {
tmpOptions.stopTracking[eventType] = [];
}
tmpOptions.tracking[eventType].push(trackingEvents[i].childNodes[0].nodeValue);
tmpOptions.stopTracking[eventType] = false;
break;
case 'progress':
if (typeof tmpOptions.tracking[eventType] === 'undefined') {
tmpOptions.tracking[eventType] = [];
}
oneEventOffset = this.convertTimeStringToSeconds(trackingEvents[i].getAttribute('offset'));
if (typeof tmpOptions.tracking[eventType][oneEventOffset] === 'undefined') {
tmpOptions.tracking[eventType][oneEventOffset] = {
elements: [],
stopTracking: false
};
}
tmpOptions.tracking[eventType][oneEventOffset].elements.push(trackingEvents[i].childNodes[0].nodeValue);
break;
default:
break;
}
}
},
registerClickTracking: function(clickTrackingTag, tmpOptions) {
if(clickTrackingTag.length) {
for (var i = 0; i < clickTrackingTag.length; i++) {
if(clickTrackingTag[i] != ''){
tmpOptions.clicktracking.push(clickTrackingTag[i]);
}
}
}
},
registerImpressionEvents: function(impressionTags, tmpOptions) {
if (impressionTags.length) {
for (var i = 0; i < impressionTags.length; i++) {
var impressionEvent = this.extractNodeData(impressionTags[i]);
tmpOptions.impression.push(impressionEvent);
}
}
},
registerErrorEvents: function(errorTags, tmpOptions) {
if (
(typeof errorTags !== 'undefined') &&
(errorTags !== null) &&
(errorTags.length === 1) && //Only 1 Error tag is expected
(errorTags[0].childNodes.length === 1)
) {
tmpOptions.errorUrl = errorTags[0].childNodes[0].nodeValue;
}
},
announceError: function(code) {
if (
(typeof this.vastOptions.errorUrl === 'undefined') ||
!this.vastOptions.errorUrl
) {
return;
}
if (typeof(code) !== 'undefined') {
code = parseInt(code);
} else {
//Set a default code (900 Unidentified error)
code = 900;
}
var errorUrl = this.vastOptions.errorUrl.replace('[ERRORCODE]' , code);
//Send the error request
this.callUris([errorUrl]);
},
announceLocalError: function (code, msg) {
if (typeof(code) !== 'undefined') {
code = parseInt(code);
} else {
//Set a default code (900 Unidentified error)
code = 900;
}
message = '[Error] (' + code + '): ';
message += (!msg) ? 'Failed to load Vast' : msg;
console.log(message);
},
getClickTrackingEvents: function(linear) {
var result = [];
var videoClicks = linear.getElementsByTagName('VideoClicks');
if (videoClicks.length) {//There should be exactly 1 node
var clickTracking = videoClicks[0].getElementsByTagName('ClickTracking');
if (clickTracking.length) {
for (var i = 0; i < clickTracking.length; i++) {
var clickTrackingEvent = this.extractNodeData(clickTracking[i]);
result.push(clickTrackingEvent);
}
}
}
return result;
},
getNonLinearClickTrackingEvents: function (nonLinear) {
var result = [];
var nonLinears = nonLinear.getElementsByTagName('NonLinear');
if (nonLinears.length) {
var clickTracking = nonLinear.getElementsByTagName('NonLinearClickTracking');
if (clickTracking.length) {
for (var i = 0; i < clickTracking.length; i++) {
var NonLinearClickTracking = this.extractNodeData(clickTracking[i]);
result.push(NonLinearClickTracking);
}
}
}
return result;
},
callUris: function(uris) {
for (var i = 0; i < uris.length; i++) {
new Image().src = uris[i];
}
},
recalculateAdDimensions: function(idVideoPlayer) {
if ((!idVideoPlayer) && (typeof this.videoPlayerId !== 'undefined')) {
var idVideoPlayer = this.videoPlayerId;
}
var videoPlayer = document.getElementById(idVideoPlayer);
var divClickThrough = document.getElementById('vast_clickthrough_layer_' + idVideoPlayer);
if (divClickThrough) {
divClickThrough.style.width = videoPlayer.offsetWidth + 'px';
divClickThrough.style.height = videoPlayer.offsetHeight + 'px';
}
var requestFullscreenFunctionNames = this.checkFullscreenSupport('fluid_video_wrapper_' + idVideoPlayer);
var fullscreenButton = document.getElementById(idVideoPlayer + '_fluid_control_fullscreen');
var menuOptionFullscreen = document.getElementById(idVideoPlayer + 'context_option_fullscreen');
if (requestFullscreenFunctionNames) {
// this will go other way around because we alredy exited full screen
if (document[requestFullscreenFunctionNames.isFullscreen] === null) {
// Exit fullscreen
this.fullscreenOff(fullscreenButton, menuOptionFullscreen);
} else {
// Go fullscreen
this.fullscreenOn(fullscreenButton, menuOptionFullscreen);
}
} else {
//The browser does not support the Fullscreen API, so a pseudo-fullscreen implementation is used
if (fullscreenTag.className.search(/\bpseudo_fullscreen\b/g) !== -1) {
fullscreenTag.className += ' pseudo_fullscreen';
this.fullscreenOn(fullscreenButton, menuOptionFullscreen);
} else {
fullscreenTag.className = fullscreenTag.className.replace(/\bpseudo_fullscreen\b/g, '');
this.fullscreenOff(fullscreenButton, menuOptionFullscreen);
}
}
},
prepareVast: function (roll) {
var player = this;
var videoPlayerTag = document.getElementById(this.videoPlayerId);
var list = [];
list.length = 0;
list = player.findRoll(roll);
for (var i = 0; i < list.length; i++) {
var adListId = list[i];
if (player.adList[adListId].vastLoaded !== true && player.adList[adListId].error !== true) {
player.processUrl(player.adList[adListId].vastTag, adListId);
videoPlayerTag.addEventListener('adId_' + adListId, player[roll]);
}
}
},
toggleLoader: function(showLoader) {
if (this.displayOptions.layoutControls.layout=== 'browser') {
//The browser handles all the layout of the video tag
return;
}
var loaderDiv = document.getElementById('vast_video_loading_' + this.videoPlayerId);
if (showLoader) {
loaderDiv.style.display = 'table';
} else {
loaderDiv.style.display = 'none';
}
},
sendRequest: function(url, withCredentials, timeout, functionReadyStateChange) {
var xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.onreadystatechange = functionReadyStateChange;
xmlHttpReq.open('GET', url, true);
xmlHttpReq.withCredentials = withCredentials;
xmlHttpReq.timeout = timeout;
xmlHttpReq.send();
},
playMainVideoWhenVastFails: function(errorCode) {
var player = this;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
videoPlayerTag.removeEventListener('loadedmetadata', player.switchPlayerToVastMode);
videoPlayerTag.pause();
player.toggleLoader(false);
player.displayOptions.vastOptions.vastAdvanced.noVastVideoCallback();
if (!player.vastOptions || typeof this.vastOptions.errorUrl === 'undefined') {
player.announceLocalError(errorCode);
} else {
player.announceError(errorCode);
}
player.switchToMainVideo();
},
switchPlayerToVastMode: function() {},
/**
* Process the XML response
*
* @param xmlResponse
* @param adListId
* @param tmpOptions
*/
processVastXml: function (xmlResponse, adListId, tmpOptions) {
var player = this;
if (!xmlResponse) {
player.stopProcessAndReportError(adListId);
return;
}
//Get impression tag
var impression = xmlResponse.getElementsByTagName('Impression');
if (impression !== null) {
player.registerImpressionEvents(impression, tmpOptions);
}
//Get the error tag, if any
var errorTags = xmlResponse.getElementsByTagName('Error');
if (errorTags !== null) {
player.registerErrorEvents(errorTags, tmpOptions);
}
//Get Creative
var creative = xmlResponse.getElementsByTagName('Creative');
//Currently only 1 creative and 1 linear is supported
if ((typeof creative !== 'undefined') && creative.length) {
var arrayCreativeLinears = creative[0].getElementsByTagName('Linear');
if ((typeof arrayCreativeLinears !== 'undefined') && (arrayCreativeLinears !== null) && arrayCreativeLinears.length) {
var creativeLinear = arrayCreativeLinears[0];
player.registerTrackingEvents(creativeLinear, tmpOptions);
var clickTracks = player.getClickTrackingEvents(creativeLinear);
player.registerClickTracking(clickTracks, tmpOptions);
//Extract the Ad data if it is actually the Ad (!wrapper)
if (!player.hasVastAdTagUri(xmlResponse) && player.hasInLine(xmlResponse)) {
//Set initial values
tmpOptions.adFinished = false;
tmpOptions.adType = 'linear';
//Extract the necessary data from the Linear node
tmpOptions.skipoffset = player.convertTimeStringToSeconds(creativeLinear.getAttribute('skipoffset'));
tmpOptions.clickthroughUrl = player.getClickThroughUrlFromLinear(creativeLinear);
tmpOptions.duration = player.getDurationFromLinear(creativeLinear);
tmpOptions.mediaFile = player.getMediaFileFromLinear(creativeLinear);
tmpOptions.iconClick = player.getIconClickThroughFromLinear(creativeLinear);
}
}
if ((typeof tmpOptions.iconClick !== 'undefined') && (tmpOptions.iconClick !== null) && tmpOptions.iconClick.length) {
player.adList[adListId].landingPage = tmpOptions.iconClick;
}
var arrayCreativeNonLinears = creative[0].getElementsByTagName('NonLinearAds');
if ((typeof arrayCreativeNonLinears !== 'undefined') && (arrayCreativeNonLinears !== null) && arrayCreativeNonLinears.length) {
var creativeNonLinear = arrayCreativeNonLinears[0];
player.registerTrackingEvents(creativeNonLinear, tmpOptions);
var clickTracks = player.getNonLinearClickTrackingEvents(creativeNonLinear);
player.registerClickTracking(clickTracks, tmpOptions);
//Extract the Ad data if it is actually the Ad (!wrapper)
if (!player.hasVastAdTagUri(xmlResponse) && player.hasInLine(xmlResponse)) {
//Set initial values
tmpOptions.adType = 'nonLinear';
//Extract the necessary data from the NonLinear node
tmpOptions.clickthroughUrl = player.getClickThroughUrlFromNonLinear(creativeNonLinear);
tmpOptions.duration = player.getDurationFromNonLinear(creativeNonLinear); // VAST version < 4.0
tmpOptions.dimension = player.getDimensionFromNonLinear(creativeNonLinear); // VAST version < 4.0
tmpOptions.staticResource = player.getStaticResourceFromNonLinear(creativeNonLinear);
tmpOptions.creativeType = player.getCreativeTypeFromStaticResources(creativeNonLinear);
}
}
//Extract the Ad data if it is actually the Ad (!wrapper)
if (!player.hasVastAdTagUri(xmlResponse) && player.hasInLine(xmlResponse)) {
player.adList[adListId].adType = tmpOptions.adType ? tmpOptions.adType : 'unknown';
if (typeof tmpOptions.mediaFile !== 'undefined' || typeof tmpOptions.staticResource !== 'undefined') {
player.adList[adListId].vastLoaded = true;
player.adPool[adListId] = Object.assign({}, tmpOptions);
var event = document.createEvent('Event');
event.initEvent('adId_' + adListId, false, true);
document.getElementById(player.videoPlayerId).dispatchEvent(event);
player.displayOptions.vastOptions.vastAdvanced.vastLoadedCallback();
} else {
player.stopProcessAndReportError(adListId);
}
}
} else {
player.stopProcessAndReportError(adListId);
}
},
/**
* Parse the VAST Tag
*
* @param vastTag
* @param adListId
*/
processUrl: function (vastTag, adListId) {
var player = this;
var numberOfRedirects = 0;
var tmpOptions = {
tracking: [],
stopTracking: [],
impression: [],
clicktracking: [],
vastLoaded: false
};
player.resolveVastTag(
vastTag,
numberOfRedirects,
adListId,
tmpOptions
);
},
resolveVastTag: function (vastTag, numberOfRedirects, adListId, tmpOptions) {
var player = this;
if(!vastTag || vastTag == '') {
player.stopProcessAndReportError(adListId);
return;
}
var handleXmlHttpReq = function () {
var xmlHttpReq = this;
if (xmlHttpReq.readyState === 4 && xmlHttpReq.status === 404) {
player.stopProcessAndReportError(adListId);
return;
}
if (!((xmlHttpReq.readyState === 4) && (xmlHttpReq.status === 200))) {
return;
}
if ((xmlHttpReq.readyState === 4) && (xmlHttpReq.status !== 200)) {
player.stopProcessAndReportError(adListId);
return;
}
try {
var xmlResponse = xmlHttpReq.responseXML;
} catch (e) {
player.stopProcessAndReportError(adListId);
return;
}
if (!xmlResponse) {
player.stopProcessAndReportError(adListId);
return;
}
player.inLineFound = player.hasInLine(xmlResponse);
if (!player.inLineFound && player.hasVastAdTagUri(xmlResponse)) {
var vastAdTagUri = player.getVastAdTagUriFromWrapper(xmlResponse);
if (vastAdTagUri) {
player.resolveVastTag(vastAdTagUri, numberOfRedirects, adListId, tmpOptions);
} else {
player.stopProcessAndReportError(adListId);
return;
}
}
if (numberOfRedirects > player.displayOptions.vastOptions.maxAllowedVastTagRedirects && !player.inLineFound) {
player.stopProcessAndReportError(adListId);
return;
}
player.processVastXml(xmlResponse, adListId, tmpOptions);
};
if (numberOfRedirects <= player.displayOptions.vastOptions.maxAllowedVastTagRedirects) {
player.sendRequest(
vastTag,
true,
player.displayOptions.vastOptions.vastTimeout,
handleXmlHttpReq
);
}
numberOfRedirects++;
},
/**
* Helper function to stop processing
*
* @param adListId
*/
stopProcessAndReportError: function(adListId) {
var player = this;
//Set the error flag for the Ad
player.adList[adListId].error = true;
//The response returned an error. Proceeding with the main video.
//Try to switch main video only if it is a preRoll scenario
if (typeof adListId !== 'undefined' && player.adList[adListId]['roll'] == 'preRoll') {
player.playMainVideoWhenVastFails(900);
} else {
player.announceLocalError(101);
}
},
playRoll: function(adListId) {
var player = this;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
if (!player.adPool.hasOwnProperty(adListId)) {
player.announceLocalError(101);
return;
}
var roll = player.adList[adListId].roll;
//get the proper ad
player.vastOptions = player.adPool[adListId];
//spec configs by roll
switch (roll) {
case 'midRoll':
videoPlayerTag.mainVideoCurrentTime = videoPlayerTag.currentTime - 1;
break;
case 'postRoll':
videoPlayerTag.mainVideoCurrentTime = 0;
player.autoplayAfterAd = false;
videoPlayerTag.currentTime = player.mainVideoDuration;
break;
}
var playVideoPlayer = function(adListId) {
player.switchPlayerToVastMode = function() {
//Get the actual duration from the video file if it is not present in the VAST XML
if (!player.vastOptions.duration) {
player.vastOptions.duration = videoPlayerTag.duration;
}
player.addClickthroughLayer(player.videoPlayerId);
if (player.vastOptions.skipoffset !== false) {
player.addSkipButton();
}
player.addCTAButton(player.adList[adListId].landingPage);
player.addAdCountdown();
videoPlayerTag.removeAttribute('controls'); //Remove the default Controls
player.vastLogoBehaviour(true);
if (player.displayOptions.layoutControls.layout!== 'browser') {
var progressbarContainer = document.getElementById(player.videoPlayerId + '_fluid_controls_progress_container');
if (progressbarContainer !== null) {
document.getElementById(player.videoPlayerId + '_vast_control_currentprogress').style.backgroundColor = player.displayOptions.layoutControls.adProgressColor;
}
}
if (player.displayOptions.vastOptions.adText) {
player.addAdPlayingText(player.displayOptions.vastOptions.adText);
}
player.positionTextElements();
player.toggleLoader(false);
player.adList[adListId].played = true;
player.adFinished = false;
videoPlayerTag.play();
//Announce the impressions
player.trackSingleEvent('impression');
videoPlayerTag.removeEventListener('loadedmetadata', player.switchPlayerToVastMode);
};
videoPlayerTag.pause();
videoPlayerTag.addEventListener('loadedmetadata', player.switchPlayerToVastMode);
//Store the current time of the main video
player.mainVideoCurrentTime = videoPlayerTag.currentTime;
// Remove the streaming objects to prevent errors on the VAST content
player.detachStreamers();
videoPlayerTag.src = player.vastOptions.mediaFile;
player.isCurrentlyPlayingAd = true;
if (player.displayOptions.vastOptions.showProgressbarMarkers) {
player.hideAdMarkers();
}
videoPlayerTag.load();
//Handle the ending of the Pre-Roll ad
videoPlayerTag.addEventListener('ended', player.onVastAdEnded);
};
/**
* Sends requests to the tracking URIs
*/
var videoPlayerTimeUpdate = function() {
if (player.adFinished) {
videoPlayerTag.removeEventListener('timeupdate', videoPlayerTimeUpdate);
return;
}
var currentTime = Math.floor(videoPlayerTag.currentTime);
if (player.vastOptions.duration != 0) {
player.scheduleTrackingEvent(currentTime, player.vastOptions.duration);
}
if (currentTime >= (player.vastOptions.duration - 1 ) && player.vastOptions.duration != 0) {
videoPlayerTag.removeEventListener('timeupdate', videoPlayerTimeUpdate);
player.adFinished = true;
}
};
playVideoPlayer(adListId);
videoPlayerTag.addEventListener('timeupdate', videoPlayerTimeUpdate);
},
scheduleTrackingEvent : function(currentTime, duration) {
var player = this;
if (currentTime == 0) {
player.trackSingleEvent('start');
}
if (
(typeof player.vastOptions.tracking['progress'] !== 'undefined') &&
(player.vastOptions.tracking['progress'].length) &&
(typeof player.vastOptions.tracking['progress'][currentTime] !== 'undefined')
) {
player.trackSingleEvent('progress', currentTime);
}
if (currentTime == (Math.floor(duration / 4))) {
player.trackSingleEvent('firstQuartile');
}
if (currentTime == (Math.floor(duration / 2))) {
player.trackSingleEvent('midpoint');
}
if (currentTime == (Math.floor(duration * 3 / 4))) {
player.trackSingleEvent('thirdQuartile');
}
if (currentTime >= (duration - 1 )) {
player.trackSingleEvent('complete');
}
},
trackSingleEvent : function(eventType, eventSubType) {
var player = this;
var trackingUris = [];
trackingUris.length = 0;
switch (eventType) {
case 'start':
case 'firstQuartile':
case 'midpoint':
case 'thirdQuartile':
case 'complete':
if (player.vastOptions.stopTracking[eventType] === false) {
if (player.vastOptions.tracking[eventType] !== null) {
trackingUris = player.vastOptions.tracking[eventType];
}
player.vastOptions.stopTracking[eventType] = true;
}
break;
case 'progress':
player.vastOptions.tracking['progress'][eventSubType].elements.forEach(function(currentValue, index) {
if (
(player.vastOptions.tracking['progress'][eventSubType].stopTracking === false) &&
(player.vastOptions.tracking['progress'][eventSubType].elements.length)
) {
trackingUris = player.vastOptions.tracking['progress'][eventSubType].elements;
}
player.vastOptions.tracking['progress'][eventSubType].stopTracking = true;
});
break;
case 'impression':
if (
(typeof player.vastOptions.impression !== 'undefined') &&
(player.vastOptions.impression !== null) &&
(typeof player.vastOptions.impression.length !== 'unknown')
) {
trackingUris = player.vastOptions.impression;
}
break;
default:
break;
}
player.callUris(trackingUris);
},
completeNonLinearStatic: function (adListId) {
var player = this;
player.closeNonLinear(adListId);
if(player.adFinished == false) {
player.adFinished = true;
player.trackSingleEvent('complete');
}
clearInterval(player.nonLinearTracking);
},
/**
* Show up a nonLinear static creative
*/
createNonLinearStatic: function (adListId) {
var player = this;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
if (!player.adPool.hasOwnProperty(adListId) || player.adPool[adListId].error === true) {
player.announceLocalError(101);
return;
}
//get the proper ad
player.vastOptions = player.adPool[adListId];
player.createBoard(adListId);
player.adFinished = false;
player.trackSingleEvent('start');
var duration = (player.adList[adListId].nonLinearDuration) ? player.adList[adListId].nonLinearDuration : player.vastOptions.duration;
player.nonLinearTracking = setInterval(function () {
if (player.adFinished !== true) {
var currentTime = Math.floor(videoPlayerTag.currentTime);
player.scheduleTrackingEvent(currentTime, duration);
if (currentTime >= (duration - 1 )) {
player.adFinished = true;
}
}
}, 400);
time = parseInt(player.getCurrentTime()) + parseInt(duration);
player.scheduleTask({time: time, closeStaticAd: adListId});
},
/**
* Adds a nonLinear static Image banner
*
* currently only image/gif, image/jpeg, image/png supported
*/
createBoard: function (adListId) {
var player = this;
var vastSettings = player.adPool[adListId];
if (typeof vastSettings.staticResource === 'undefined'
|| player.supportedStaticTypes.indexOf(vastSettings.creativeType) === -1) {
player.adList[adListId].error = true;
return;
}
player.adList[adListId].played = true;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
var playerWidth = videoPlayerTag.clientWidth;
var playerHeight = videoPlayerTag.clientHeight;
var board = document.createElement('div');
var vAlign = (player.adList[adListId].vAlign) ? player.adList[adListId].vAlign : player.nonLinearVerticalAlign;
var creative = new Image();
creative.src = vastSettings.staticResource;
creative.id = 'fluid_nonLinear_imgCreative_' + adListId + '_' + player.videoPlayerId;
creative.onload = function () {
//Set banner size based on the below priority
// 1. adList -> roll -> size
// 2. VAST XML width/height attriubute (VAST 3.)
// 3. VAST XML static resource dimension
if(typeof player.adList[adListId].size !== 'undefined') {
origWidth = player.adList[adListId].size.split('x')[0];
origHeight = player.adList[adListId].size.split('x')[1];
} else if(vastSettings.dimension.width && vastSettings.dimension.height) {
origWidth = vastSettings.dimension.width;
origHeight = vastSettings.dimension.height;
} else {
origWidth = creative.width;
origHeight = creative.height;
}
if (origWidth > playerWidth) {
newBannerWidth = playerWidth - 5;
newBannerHeight = origHeight * newBannerWidth / origWidth;
} else {
newBannerWidth = origWidth;
newBannerHeight = origHeight;
}
img = document.getElementById(creative.id);
img.width = newBannerWidth;
img.height = newBannerHeight;
};
board.id = 'fluid_nonLinear_' + adListId;
board.className = 'fluid_nonLinear_' + vAlign;
board.innerHTML = creative.outerHTML;
//Bind the Onclick event
board.onclick = function () {
if (typeof vastSettings.clickthroughUrl !== 'undefined') {
window.open(vastSettings.clickthroughUrl);
}
//Tracking the NonLinearClickTracking events
if (typeof vastSettings.clicktracking !== 'undefined') {
player.callUris([vastSettings.clicktracking]);
}
};
if (typeof vastSettings.clickthroughUrl !== 'undefined') {
board.style.cursor = 'pointer';
}
var closeBtn = document.createElement('div');
closeBtn.id = 'close_button_' + player.videoPlayerId;
closeBtn.className = 'close_button';
closeBtn.innerHTML = '';
closeBtn.title = player.displayOptions.layoutControls.closeButtonCaption;
closeBtn.onclick = function (event) {
this.parentElement.remove(player);
if (typeof event.stopImmediatePropagation !== 'undefined') {
event.stopImmediatePropagation();
}
player.adFinished = true;
clearInterval(player.nonLinearTracking);
return false;
};
board.appendChild(closeBtn);
videoPlayerTag.parentNode.insertBefore(board, videoPlayerTag.nextSibling);
},
closeNonLinear: function (adListId) {
var element = document.getElementById('fluid_nonLinear_' + adListId);
if(element) {
element.remove();
}
},
preRoll: function (event) {
var player = fluidPlayerClass.getInstanceById(this.id);
var videoPlayerTag = document.getElementById(this.getAttribute('id'));
videoPlayerTag.removeEventListener(event.type, player.preRoll);
player.firstPlayLaunched = true;
var adListId = event.type.replace('adId_', '');
if (player.adList[adListId].played === true) {
return;
}
if (player.adList[adListId].adType == 'linear') {
player.toggleLoader(true);
player.playRoll(adListId);
}
if (player.adList[adListId].adType == 'nonLinear') {
videoPlayerTag.play();
player.createNonLinearStatic(adListId);
}
},
createAdMarker: function (adListId, time) {
var player = this;
var markersHolder = document.getElementById(player.videoPlayerId + '_ad_markers_holder');
var adMarker = document.createElement('div');
adMarker.id = 'ad_marker_' + player.videoPlayerId + "_" + adListId;
adMarker.className = 'fluid_controls_ad_marker';
adMarker.style.left = (time / player.mainVideoDuration * 100) + '%';
if (player.isCurrentlyPlayingAd) {
adMarker.style.display = 'none';
}
markersHolder.appendChild(adMarker);
},
hideAdMarker: function (adListId) {
var player = this;
var element = document.getElementById('ad_marker_' + player.videoPlayerId + "_" + adListId);
if (element) {
element.style.display = 'none';
}
},
showAdMarkers: function () {
var player = this;
var markersHolder = document.getElementById(player.videoPlayerId + '_ad_markers_holder');
var adMarkers = markersHolder.getElementsByClassName('fluid_controls_ad_marker');
var idPrefix = 'ad_marker_' + player.videoPlayerId + "_";
for (var i = 0; i < adMarkers.length; ++i) {
var item = adMarkers[i];
var adListId = item.id.replace(idPrefix, '');
if (player.adList[adListId].played === false) {
item.style.display = '';
}
}
},
hideAdMarkers: function () {
var player = this;
var markersHolder = document.getElementById(player.videoPlayerId + '_ad_markers_holder');
var adMarkers = markersHolder.getElementsByClassName('fluid_controls_ad_marker');
for (var i = 0; i < adMarkers.length; ++i) {
var item = adMarkers[i];
item.style.display = 'none';
}
},
midRoll: function (event) {
var player = fluidPlayerClass.getInstanceById(this.id);
var videoPlayerTag = document.getElementById(this.getAttribute('id'));
videoPlayerTag.removeEventListener(event.type, player.midRoll); //todo pass id?!
var adListId = event.type.replace('adId_', '');
if(player.adList[adListId].played === true){
return;
}
var time = parseInt(player.adList[adListId].timer);
if(typeof time == 'string' && time.indexOf("%") !== -1) {
time = time.replace('%', '');
time = Math.floor(player.mainVideoDuration / 100 * time);
}
if (player.displayOptions.vastOptions.showProgressbarMarkers &&
player.adList[adListId].adType === "nonLinear") {
player.createAdMarker(adListId, time);
}
player.scheduleTask({time: time, playRoll: 'midRoll', adListId: adListId});
},
postRoll: function (event) {
var player = fluidPlayerClass.getInstanceById(this.id);
var videoPlayerTag = document.getElementById(this.getAttribute('id'));
videoPlayerTag.removeEventListener(event.type, player.postRoll);
var adListId = event.type.replace('adId_', '');
player.scheduleTask({time: Math.floor(player.mainVideoDuration), playRoll: 'postRoll', adListId: adListId});
},
onPauseRoll: function (event) {
var player = fluidPlayerClass.getInstanceById(this.id);
var videoPlayerTag = document.getElementById(this.getAttribute('id'));
videoPlayerTag.removeEventListener(event.type, player.onPauseRoll);
var adListId = event.type.replace('adId_', '');
if (player.adList[adListId].adType == 'nonLinear') {
if (!player.adPool.hasOwnProperty(adListId) || player.adPool[adListId].error === true) {
player.announceLocalError(101);
return;
}
player.createBoard(adListId);
onPauseAd = document.getElementById('fluid_nonLinear_' + adListId);
onPauseAd.style.display = 'none';
}
},
/**
* Check if player has a valid nonLinear onPause Ad
*/
hasValidOnPauseAd: function() {
var player = this;
var onPauseAd = player.findRoll('onPauseRoll'); //should be only one. todo add validator to allow only one onPause roll
return (onPauseAd.length != 0 && player.adList[onPauseAd[0]] && player.adList[onPauseAd[0]].error === false);
},
/**
* Hide/show nonLinear onPause Ad
*/
toggleOnPauseAd: function() {
var player = this;
var videoPlayerTag = document.getElementById(this.videoPlayerId);
if (player.hasValidOnPauseAd() && !player.isCurrentlyPlayingAd) {
onPauseRoll = player.findRoll('onPauseRoll');
adListId = onPauseRoll[0];
player.vastOptions = player.adPool[adListId];
onPauseAd = document.getElementById('fluid_nonLinear_' + adListId);
if (onPauseAd && videoPlayerTag.paused) {
onPauseAd.style.display = 'flex';
player.adList[adListId].played = false;
player.trackingOnPauseNonLinearAd(adListId, 'start');
} else if (onPauseAd && !videoPlayerTag.paused) {
onPauseAd.style.display = 'none';
player.adFinished = true;
player.trackingOnPauseNonLinearAd(adListId, 'complete');
}
}
},
/**
* Helper function for tracking onPause Ads
*/
trackingOnPauseNonLinearAd: function (adListId, status) {
var player = this;
if (!player.adPool.hasOwnProperty(adListId) || player.adPool[adListId].error === true) {
player.announceLocalError(101);
return;
}
player.vastOptions = player.adPool[adListId];
player.trackSingleEvent(status);
},
adTimer: function() {
var player = this;
if (player.isTimer == true) {
return;
}
player.isTimer = !player.isTimer;
player.timer = setInterval(function () {
for (var keyTime in player.timerPool) {
time = Math.floor(player.getCurrentTime());
if(time != keyTime || player.isCurrentlyPlayingAd) {
continue;
}
//Task: playRoll
if (player.timerPool[keyTime] && player.timerPool[keyTime].hasOwnProperty('playRoll')) {
var adIdToCheck = player.timerPool[keyTime].adListId;
var playRoll = player.timerPool[keyTime].playRoll;
if(player.adList[adIdToCheck].played == false) {
player.vastOptions = player.adPool[adIdToCheck];
if(player.vastOptions.adType == 'linear'){
player.toggleLoader(true);
player.playRoll(adIdToCheck);
}
if(player.vastOptions.adType == 'nonLinear'){
player.createNonLinearStatic(adIdToCheck);
if (player.displayOptions.vastOptions.showProgressbarMarkers) {
player.hideAdMarker(adIdToCheck);
}
}
//Remove ad from the play list
delete player.timerPool[keyTime];
}
}
//Task: close nonLinear ads
if (player.timerPool[keyTime] && player.timerPool[keyTime].hasOwnProperty('closeStaticAd')) {
var adListId = player.timerPool[keyTime].closeStaticAd;
if(player.adList[adListId].played == true) {
player.completeNonLinearStatic(adListId);
//Remove ad from the play list
delete player.timerPool[keyTime];
}
}
}
}, 800);
},
scheduleTask: function (task) {
this.timerPool[task.time] = task;
},
switchToMainVideo: function() {
var player = this;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
videoPlayerTag.src = player.originalSrc;
player.initialiseStreamers();
var newCurrentTime = (typeof videoPlayerTag.mainVideoCurrentTime !== 'undefined')
? videoPlayerTag.mainVideoCurrentTime : 0;
if(videoPlayerTag.hasOwnProperty('currentTime')) {
videoPlayerTag.currentTime = newCurrentTime;
}
player.setCurrentTimeAndPlay(newCurrentTime, player.autoplayAfterAd);
player.isCurrentlyPlayingAd = false;
player.removeClickthrough();
player.removeSkipButton();
player.removeAdCountdown();
player.removeAdPlayingText();
player.removeCTAButton();
player.vastLogoBehaviour(false);
player.adFinished = true;
player.displayOptions.vastOptions.vastAdvanced.vastVideoEndedCallback();
player.vastOptions = null;
if (player.displayOptions.layoutControls.layout!== 'browser') {
player.setBuffering();
var progressbarContainer = document.getElementById(player.videoPlayerId + '_fluid_controls_progress_container');
if (progressbarContainer !== null) {
backgroundColor = (player.displayOptions.layoutControls.primaryColor) ? player.displayOptions.layoutControls.primaryColor : "white";
document.getElementById(player.videoPlayerId + '_vast_control_currentprogress').style.backgroundColor = backgroundColor;
}
}
videoPlayerTag.removeEventListener('ended', player.onVastAdEnded);
if (player.displayOptions.layoutControls.layout=== 'browser') {
videoPlayerTag.setAttribute('controls', 'controls');
}
if (player.displayOptions.vastOptions.showProgressbarMarkers) {
player.showAdMarkers();
}
},
vastLogoBehaviour: function (vastPlaying) {
if (!this.displayOptions.layoutControls.logo.showOverAds) {
var logoHolder = document.getElementById(this.videoPlayerId + '_logo');
var logoImage = document.getElementById(this.videoPlayerId + '_logo_image');
if (!logoHolder || !logoImage) {
return;
}
var logoDisplay = (vastPlaying) ? 'none' : 'inline';
logoHolder.style.display = logoDisplay;
}
},
onVastAdEnded: function() {
//"this" is the HTML5 video tag, because it disptches the "ended" event
var player = fluidPlayerClass.getInstanceById(this.id);
player.switchToMainVideo();
player.vastOptions = null;
player.adFinished = true;
},
onMainVideoEnded: function () {
var player = fluidPlayerClass.getInstanceById(this.id);
if (player.isCurrentlyPlayingAd && player.autoplayAfterAd) { // It may be in-stream ending, and if it's not postroll then we don't execute anything
return;
}
//we can remove timer as no more ad will be shown
if (Math.floor(player.getCurrentTime()) >= Math.floor(player.mainVideoDuration)) {
clearInterval(player.timer);
}
},
getCurrentTime: function() {
var player = this;
if(player.isCurrentlyPlayingAd) {
return player.mainVideoCurrentTime;
} else {
var videoPlayerTag = document.getElementById(this.videoPlayerId);
return videoPlayerTag.currentTime;
}
},
/**
* Adds a Skip Button
*/
addSkipButton: function() {
var videoPlayerTag = document.getElementById(this.videoPlayerId);
var divSkipButton = document.createElement('div');
divSkipButton.id = 'skip_button_' + this.videoPlayerId;
divSkipButton.className = 'skip_button skip_button_disabled';
divSkipButton.innerHTML = this.displayOptions.vastOptions.skipButtonCaption.replace('[seconds]', this.vastOptions.skipoffset);
document.getElementById('fluid_video_wrapper_' + this.videoPlayerId).appendChild(divSkipButton);
videoPlayerTag.addEventListener('timeupdate', this.decreaseSkipOffset, false);
},
/**
* Ad Countdown
*/
addAdCountdown: function() {
var videoPlayerTag = document.getElementById(this.videoPlayerId);
var videoWrapper = document.getElementById('fluid_video_wrapper_' + this.videoPlayerId);
var clickthrough = document.getElementById('vast_clickthrough_layer_' + this.videoPlayerId);
var divAdCountdown = document.createElement('div');
// Create element
var adCountdown = this.pad(parseInt(this.currentVideoDuration / 60)) + ':' + this.pad(parseInt(this.currentVideoDuration % 60));
var durationText = parseInt(adCountdown);
divAdCountdown.id = 'ad_countdown' + this.videoPlayerId;
divAdCountdown.className = 'ad_countdown';
divAdCountdown.innerHTML = "Ad - " + durationText;
videoWrapper.appendChild(divAdCountdown);
videoPlayerTag.addEventListener('timeupdate', this.decreaseAdCountdown, false);
clickthrough.addEventListener('mouseover', function() { divAdCountdown.style.display = 'none'; }, false);
},
decreaseAdCountdown: function decreaseAdCountdown() {
var videoPlayerTag = this;
var player = fluidPlayerClass.getInstanceById(videoPlayerTag.id);
var sec = parseInt(player.currentVideoDuration) - parseInt(videoPlayerTag.currentTime);
var btn = document.getElementById('ad_countdown' + player.videoPlayerId);
if (btn) {
btn.innerHTML = "Ad - " + player.pad(parseInt(sec / 60)) + ':' + player.pad(parseInt(sec % 60));
} else {
videoPlayerTag.removeEventListener('timeupdate', player.decreaseAdCountdown);
}
},
removeAdCountdown: function() {
var btn = document.getElementById('ad_countdown' + this.videoPlayerId);
if (btn) {
btn.parentElement.removeChild(btn);
}
},
toggleAdCountdown: function(showing) {
var btn = document.getElementById('ad_countdown' + this.videoPlayerId);
if (btn) {
if (showing){
btn.style.display = 'inline-block';
} else {
btn.style.display = 'none';
}
}
},
addAdPlayingText: function() {
var player = this;
var text = this.displayOptions.vastOptions.adText;
var adPlayingDiv = document.createElement('div');
adPlayingDiv.id = this.videoPlayerId + '_fluid_ad_playing';
if (player.displayOptions.layoutControls.primaryColor) {
adPlayingDiv.style.backgroundColor = player.displayOptions.layoutControls.primaryColor;
adPlayingDiv.style.opacity = 1;
}
adPlayingDiv.className = 'fluid_ad_playing';
adPlayingDiv.innerText = text;
document.getElementById('fluid_video_wrapper_' + this.videoPlayerId).appendChild(adPlayingDiv);
},
positionTextElements: function() {
var player = this;
var allowedPosition = ['top left', 'top right', 'bottom left', 'bottom right'];
var skipButton = document.getElementById('skip_button_' + player.videoPlayerId);
var adPlayingDiv = document.getElementById(player.videoPlayerId + '_fluid_ad_playing');
var ctaButton = document.getElementById(player.videoPlayerId + '_fluid_cta');
var ctaButtonHeightWithSpacing = 0;
var adPlayingDivHeightWithSpacing = 0;
var pixelSpacing = 8;
var isBottom = false;
var skipButtonHeightWithSpacing = 0;
var positionsCTA = [];
var defaultPositions = {
"top": {
"left": {"h": 34, "v": 34 },
"right": {"h": 0, "v": 34 }
},
"bottom": {
"left": {"h": 34, "v": 50 },
"right": {"h": 0, "v": 50 }
}
};
if (skipButton !== null) {
skipButtonHeightWithSpacing = skipButton.offsetHeight + pixelSpacing;
var wrapperElement = document.getElementById('fluid_video_wrapper_' + player.videoPlayerId);
if (wrapperElement.classList.contains('mobile')) {
defaultPositions.bottom.left.v = 75;
defaultPositions.bottom.right.v = 75;
}
}
if (ctaButton !== null) {
var CTATextPosition = player.displayOptions.vastOptions.adCTATextPosition.toLowerCase();
if (allowedPosition.indexOf(CTATextPosition) == -1) {
console.log('[FP Error] Invalid position for CTAText. Reverting to "bottom right"');
CTATextPosition = 'bottom right';
}
positionsCTA = CTATextPosition.split(' ');
isBottom = positionsCTA[0] == 'bottom';
ctaButton.style[positionsCTA[0]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].v;
ctaButton.style[positionsCTA[1]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].h;
if (isBottom && positionsCTA[1] == 'right') {
ctaButton.style[positionsCTA[0]] = defaultPositions[positionsCTA[0]][positionsCTA[1]].v + skipButtonHeightWithSpacing;
}
ctaButtonHeightWithSpacing = ctaButton.offsetHeight + pixelSpacing;
}
if (adPlayingDiv !== null) {
var adPlayingDivPosition = this.displayOptions.vastOptions.adTextPosition.toLowerCase();
if (allowedPosition.indexOf(adPlayingDivPosition) == -1) {
console.log('[FP Error] Invalid position for adText. Reverting to "top left"');
adPlayingDivPosition = 'top left';
}
var positionsAdText = adPlayingDivPosition.split(' ');
adPlayingDiv.style[positionsAdText[0]] = defaultPositions[positionsAdText[0]][positionsAdText[1]].v;
adPlayingDiv.style[positionsAdText[1]] = defaultPositions[positionsAdText[0]][positionsAdText[1]].h;
adPlayingDivHeightWithSpacing = adPlayingDiv.offsetHeight + pixelSpacing;
}
if (ctaButtonHeightWithSpacing > 0 && adPlayingDivHeightWithSpacing > 0 && CTATextPosition == adPlayingDivPosition) {
if (isBottom) {
if (positionsCTA[1] == 'right') {
adPlayingDiv.style.bottom = defaultPositions[positionsAdText[0]][positionsAdText[1]].v + skipButtonHeightWithSpacing + ctaButtonHeightWithSpacing;
} else {
adPlayingDiv.style.bottom = defaultPositions[positionsAdText[0]][positionsAdText[1]].v + ctaButtonHeightWithSpacing;
}
} else {
ctaButton.style.top = defaultPositions[positionsCTA[0]][positionsCTA[1]].v + adPlayingDivHeightWithSpacing;
}
}
},
removeAdPlayingText: function() {
var div = document.getElementById(this.videoPlayerId + '_fluid_ad_playing');
if (div) {
div.parentElement.removeChild(div);
}
},
addCTAButton: function(landingPage) {
if (!this.displayOptions.vastOptions.adCTAText) {
return;
}
var player = this;
var videoPlayerTag = document.getElementById(this.videoPlayerId);
var ctaButton = document.createElement('div');
ctaButton.id = this.videoPlayerId + '_fluid_cta';
ctaButton.className = 'fluid_ad_cta';
var link = document.createElement('a');
link.href = player.vastOptions.clickthroughUrl;
link.target = '_blank';
link.innerHTML = this.displayOptions.vastOptions.adCTAText + "
" + landingPage + "";
link.onclick = function() {
if (!videoPlayerTag.paused) {
videoPlayerTag.pause();
}
return true;
};
ctaButton.appendChild(link);
document.getElementById('fluid_video_wrapper_' + this.videoPlayerId).appendChild(ctaButton);
},
removeCTAButton: function() {
var btn = document.getElementById(this.videoPlayerId + '_fluid_cta');
if (btn) {
btn.parentElement.removeChild(btn);
}
},
decreaseSkipOffset: function decreaseSkipOffset() {
//"this" is the HTML5 video tag, because it disptches the "ended" event
var videoPlayerTag = this;
var player = fluidPlayerClass.getInstanceById(videoPlayerTag.id);
var sec = player.vastOptions.skipoffset - Math.floor(videoPlayerTag.currentTime);
var btn = document.getElementById('skip_button_' + player.videoPlayerId);
if (btn) {
if (sec >= 1) {
//set the button label with the remaining seconds
btn.innerHTML = player.displayOptions.vastOptions.skipButtonCaption.replace('[seconds]', sec);
} else {
//make the button clickable
btn.innerHTML = ''
+ player.displayOptions.vastOptions.skipButtonClickCaption
+ '';
//removes the CSS class for a disabled button
btn.className = btn.className.replace(/\bskip_button_disabled\b/,'');
videoPlayerTag.removeEventListener('timeupdate', player.decreaseSkipOffset);
}
} else {
sec = 0;
videoPlayerTag.removeEventListener('timeupdate', videoPlayerTag.decreaseSkipOffset);
}
},
pressSkipButton: function() {
this.removeSkipButton();
this.removeAdPlayingText();
this.removeCTAButton();
this.displayOptions.vastOptions.vastAdvanced.vastVideoSkippedCallback();
var event = document.createEvent('Event');
event.initEvent('ended', false, true);
document.getElementById(this.videoPlayerId).dispatchEvent(event);
},
removeSkipButton: function() {
btn = document.getElementById('skip_button_' + this.videoPlayerId);
if (btn) {
btn.parentElement.removeChild(btn);
}
},
/**
* Makes the player open the ad URL on clicking
*/
addClickthroughLayer: function() {
var player = this;
var videoPlayerTag = document.getElementById(player.videoPlayerId);
var divWrapper = document.getElementById('fluid_video_wrapper_' + player.videoPlayerId);
var divClickThrough = document.createElement('div');
divClickThrough.className = 'vast_clickthrough_layer';
divClickThrough.id = 'vast_clickthrough_layer_' + player.videoPlayerId;
divClickThrough.setAttribute(
'style',
'position: absolute; cursor: pointer; top: 0; left: 0; width: ' +
videoPlayerTag.offsetWidth + 'px; height: ' +
(videoPlayerTag.offsetHeight) + 'px;'
);
divWrapper.appendChild(divClickThrough);
//Bind the Onclick event
var openClickthrough = function() {
window.open(player.vastOptions.clickthroughUrl);
//Tracking the Clickthorugh events
if (typeof player.vastOptions.clicktracking !== 'undefined') {
player.callUris(player.vastOptions.clicktracking);
}
};
var clickthroughLayer = document.getElementById('vast_clickthrough_layer_' + player.videoPlayerId);
var deviceInfo = fluidPlayerClass.getMobileOs();
var isIos9orLower = (deviceInfo.device === 'iPhone') && (deviceInfo.userOsMajor !== false) && (deviceInfo.userOsMajor <= 9);
clickthroughLayer.onclick = function() {
if (videoPlayerTag.paused) {
//On Mobile Safari on iPhones with iOS 9 or lower open the clickthrough only once
if (isIos9orLower && !player.suppressClickthrough) {
openClickthrough();
player.suppressClickthrough = true;
} else {
videoPlayerTag.play();
}
} else {
openClickthrough();
videoPlayerTag.pause();
}
};
},
/**
* Remove the Clickthrough layer
*/
removeClickthrough: function() {
var clickthroughLayer = document.getElementById('vast_clickthrough_layer_' + this.videoPlayerId);
if (clickthroughLayer) {
clickthroughLayer.parentNode.removeChild(clickthroughLayer);
}
},
/**
* Gets the src value of the first source element of the video tag.
*
* @returns string|null
*/
getCurrentSrc: function() {
var sources = document.getElementById(this.videoPlayerId).getElementsByTagName('source');
if (sources.length) {
return sources[0].getAttribute('src');
}
return null;
},
/**
* Src types required for streaming elements
*/
getCurrentSrcType: function() {
var sources = document.getElementById(this.videoPlayerId).getElementsByTagName('source');
if (sources.length) {
for (var i = 0; i < sources.length; i++) {
if (sources[i].getAttribute('src') == this.originalSrc) {
return sources[i].getAttribute('type');
}
}
}
return null;
},
convertTimeStringToSeconds: function(str) {
if (str && str.match(/^(\d){2}(:[0-5][0-9]){2}(.(\d){1,3})?$/)) {
var timeParts = str.split(':');
return ((parseInt(timeParts[0], 10)) * 3600) + ((parseInt(timeParts[1], 10)) * 60) + (parseInt(timeParts[2], 10));
}
return false;
},
onRecentWaiting: function() {
//"this" is the HTML5 video tag, because it disptches the "ended" event
var player = fluidPlayerClass.getInstanceById(this.id);
player.recentWaiting = true;
setTimeout(function () {
player.recentWaiting = false;
}, 1000);
},
/**
* Dispatches a custom pause event which is not present when seeking.
*/
onFluidPlayerPause: function() {
//"this" is the HTML5 video tag, because it disptches the "ended" event
var videoPlayerTag = this;
setTimeout(function () {
var player = fluidPlayerClass.getInstanceById(videoPlayerTag.id);
if (!player.recentWaiting) {
var event = document.createEvent('CustomEvent');
event.initEvent('fluidplayerpause', false, true);
videoPlayerTag.dispatchEvent(event);
}
}, 100);
},
checkShouldDisplayVolumeBar: function() {
var deviceType = fluidPlayerClass.getMobileOs();
if (deviceType.userOs === 'iOS') {
return false;
}
return true;
},
generateCustomControlTags: function() {
return '