(function() { aud = (typeof aud != 'undefined') ? aud : {}; aud.html5 = {}; /* Browser and Device Detection */ function isIPad() { return navigator.userAgent.match(/iPad/i) !== null; } function isIPhone() { return navigator.userAgent.match(/iPhone/i) !== null; } function isIOS() { return isIPhone() || isIPad(); } function isAndroid() { return navigator.userAgent.match(/Android/i) !== null; } var _eventMap = {}, _eventId = 0; aud.events = { init_complete : 'initComplete', init_failed : 'initFailed', break_begin : 'breakBegin', break_end : 'breakEnd', linear_ad_begin : 'linearAdBegin', linear_ad_end : 'linearAdEnd', non_linear_ad_begin : 'nonLinearAdBegin', non_linear_ad_end : 'nonLinearAdEnd', companion_banner_show : 'companionBannerShow', companion_banner_hide : 'companionBannerHide', pause_playback : 'pausePlayback', resume_playback : 'resumePlayback', ad_click : 'adClick', ad_progress : 'adProgress', vastXmlLoaded : 'vastXmlLoaded', vastXmlInvocationError : 'vastXmlInvocationError', network_load_complete : 'networkLoadComplete' }; aud.notifications = { break_begin : 'notifyBreakBegin', break_end : 'notifyBreakEnd', video_playback_started : 'notifyVideoPlaybackStarted', video_playback_paused : 'notifyVideoPlaybackPaused', video_playback_resumed : 'notifyVideoPlaybackResumed', video_playback_complete : 'notifyVideoPlaybackComplete', video_playhead_update : 'video_playhead_update', notify_event : 'notifyEvent', pauseAd : 'pauseAd', ad_click : 'notifyAdClick' }; var slice = Array.prototype.slice; aud.util = { handler : function(context, fn) { if (typeof fn == "string") { fn = context[fn]; } var args = slice.call(arguments, 2), cb = function() { return fn.apply(context, args.concat(slice.apply(arguments))); }; return cb; }, subscribe : function(name, fn) { if (!_eventMap[name]) { _eventMap[name] = []; } _eventMap[name].push(fn); }, publish : function(name) { var fns = _eventMap[name]; if (fns) { var l = fns.length; var i; for (i = 0; i < l; i++) { fns[i].apply(null, arguments); } } }, remove : function(nm, fn) { if (!fn) { _eventMap[nm] = []; } else {} }, addEvent : function(element, type, fn) { if (element.attachEvent) { element.attachEvent('on' + type, fn); } else { element.addEventListener(type, fn, false); } }, removeEvent: function(element, type, fn) { if (element.removeEventListener) { element.removeEventListener(type, fn, false); } else if (element.detachEvent) { element.detachEvent('on' + type, fn); } }, trigger : function(video, mtd) { if (video[mtd]) { video[mtd](); } if (video.fireEvent) { if (video[mtd]) { video[mtd](); } else { video.fireEvent('on' + mtd); } } return true; }, extend : function(to, from) { if (!to || !from) { return; } var k; for (k in from) { if(from[k]) { to[k] = from[k]; } } }, pingUrl : function(url, data, method) { if (!url) { //if (!data && !method) { (new Image()).src = type; } return; } if (method != 'post') { if (data) { if (url.indexOf('?') < 0) url += '?'; var k; for (k in data) { url += '&' + k + '=' + data[k]; } } (new Image()).src = this.replacePlaceHolder(url); } else { try { var xdr = new XMLHttpRequest(); xdr.open("POST", this.replacePlaceHolder(url)); xdr.setRequestHeader('Content-Type', 'text/plain'); xdr.send(data); } catch(e) {} } }, replacePlaceHolder : function (url) { var w,h; if (this._opts != null && this._opts.style != null) { w = this._opts.style.width; h = this._opts.style.height; } if (url != null && url != 'undefined') { var nUrl = url.replace('[random]', Math.round(Math.random()*10000000)); nUrl = nUrl.replace('[page_url]', encodeURIComponent(location.href) ); nUrl = nUrl.replace('[timestamp]', Math.round( (new Date()).getTime()/1000) ); nUrl = nUrl.replace('[localtime]', aud.util.getLocalTime()); if (w != null && w != 'undefined') { nUrl = nUrl.replace('[width]', w ); } if (h != null && h != 'undefined') { nUrl = nUrl.replace('[height]', h ); } if (this._videoIds && this._videoIds.length > 0) { nUrl = nUrl.replace('[mediaid]', this._videoIds[0] ); } if (this._zoneId && this._zoneId.length > 0) { nUrl = nUrl.replace('[aud:zone_id]', this._zoneId); } return nUrl; } else { return url; } }, setOpts : function (opts) { this._opts = opts; }, setVideoIds : function(videoIds) { this._videoIds = videoIds }, setZoneId : function (zoneId) { this._zoneId = zoneId; }, getNodeValue : function(node) { var nodeValue = ""; if (node.hasChildNodes) { for (var n = 0; n < node.childNodes.length; n++) { nodeValue += node.childNodes[n].nodeValue.replace(/^\s+|\s+$/g, '').replace(/(\r\n|\n|\r)/gm,""); } }else { nodeValue = node.firstChild.nodeValue; } return nodeValue; }, // return all driec child node group by tagName getChildNodes : function(parent) { var nodes = {}; for (var childIndex = 0; childIndex < parent.childNodes.length; childIndex ++) { var childNode = parent.childNodes[childIndex]; var tagName = childNode.tagName; if (nodes[tagName] == null){ nodes[tagName] = []; } nodes[tagName].push(childNode) } return nodes; }, consoleLog : function(text) { traceLog = false; if (this._opts.traceLog != null){traceLog = this._opts.traceLog;} if (traceLog && window.console) { console.log("[Auditude] " + text); } }, getLocalTime : function() { var now = new Date(); var yearStr = now.getFullYear(); var monthStr = (now.getMonth() + 1).toString(); while (monthStr.length < 2) { monthStr = '0' + monthStr; } var dateStr = now.getDate().toString(); while (dateStr.length < 2){ dateStr = '0' + dateStr; } var hourStr = now.getHours().toString(); while (hourStr.length < 2) { hourStr = '0' + hourStr; } var minuteStr = now.getMinutes().toString(); while (minuteStr.length < 2) { minuteStr = '0' + minuteStr; } var secondStr = now.getSeconds().toString(); while (secondStr.length < 2) { secondStr = '0' + secondStr; } return yearStr + monthStr + dateStr + hourStr + minuteStr + secondStr; } }, aud.AdServerClient = { idx: 0, pre: 'audxdrs', request: function(uids, domain, adRequestDomain, zid, geoString, userData, cb, cb_err) { var id = this.pre + (++this.idx), t = this; this[id] = function(resp) { t.handleResp(resp, cb); } var scr = this.script = document.createElement('script'); var us = "" for (var uidIndex=0; uidIndex < uids.length; uidIndex++) { us += '&u=' + aud.util.MD5(uids[uidIndex]); } aud.util.extend(scr, { id : id, async : true, src : 'http://' + (adRequestDomain != null ? adRequestDomain : ('ad.' + domain)) + '/adserver?tm=15&jcb=aud.AdServerClient.' + id + us + '&l=' + this.localTimeAsString() + '&z=' + zid + '&of=1.4' + '&g=' + this.groupId() + (geoString != null ? "&geo=" + geoString : "") + (userData ? '&k=' + userData : ''), onerror: cb_err }); document.body.appendChild(scr); }, handleResp: function(resp, cb) { cb((new DOMParser()).parseFromString(resp, "text/xml")); document.body.removeChild(this.script); delete this[this.script.id]; this.script = null; }, groupId : function() { if (isIOS()) { return "1000004"; } if (isAndroid()) { return "1000005"; } return "1000006"; }, localTimeAsString : function() { var dt = new Date(), y = dt.getFullYear(), mo = dt.getMonth() + 1, d = dt.getDate(), h = dt.getHours(), mi = dt.getMinutes(), s = dt.getSeconds(); if (mo < 10) mo = '0' + mo; if (d < 10) d = '0' + d; if (h < 10) h = '0' + h; if (mi < 10) mi = '0' + mi; if (s < 10) s = '0' + s; return "" + y + mo + d + h + mi + s; } } aud.html5.AdPlayer = function(video, container, ad_domain, zone_id, opts) { if (!(this instanceof aud.html5.AdPlayer)) { return new aud.html5.AdPlayer(video, container, ad_domain, zone_id, opts); } this.auditudeSDKVersion = "#{major}.#{minor}.#{revision} (inc: #{incremental}, date: #{date})"; this.VERSION = this.auditudeSDKVersion; this.bitrate = 0; this._mimeType = {"video/mp4":0, "application/x-mpegURL":1, "vnd.apple.mpegURL":2}; this._defaultServerTimeout = 10000; this._name = video; this._container = container; this._elem = null; this._overlay = null; this._adDomain = ad_domain; this._zoneId = zone_id; this._evtId = 'evtid_' + (++_eventId); this._opts = (opts || zone_id) || {}; this._serverTimeout = this._opts._serverTimeout || this._defaultServerTimeout; this._auditudeHandlesChapterBreaks = true; if (this._opts.auditudeHandlesChapterBreaks != null) { this._auditudeHandlesChapterBreaks = this._opts.auditudeHandlesChapterBreaks; } this._auditudeHandlesLinearAds = true; if (this._opts.auditudeHandlesLinearAds != null) { this._auditudeHandlesLinearAds = this._opts.auditudeHandlesLinearAds; } this._prefetchNetworkAds = false; if (this._opts.prefetchNetworkAds != null) { this._prefetchNetworkAds = this._opts.prefetchNetworkAds; } this._auditudeHandlesAdClick = false; if (this._opts.auditudeHandlesAdClick != null) { this._auditudeHandlesAdClick = this._opts.auditudeHandlesAdClick; } this._vastLoadTimeout = this._defaultServerTimeout; if (this._opts.vastLoadTimeout != null && this._opts.vastLoadTimeout > 0) { this._vastLoadTimeout = this._opts.vastLoadTimeout * 1000; } this._adRequestDomain = null; if(this._opts.adRequestDomain && this._opts.adRequestDomain != null) { this._adRequestDomain = this._opts.adRequestDomain; } this._countryCode = null; if (this._opts.countryCode && this._opts.countryCode != null) { this._countryCode = this._opts.countryCode.replace(/^\s+/,'').replace(/\s+$/,''); } this._zipCode = null; if (this._opts.zipCode && this._opts.zipCode != null) { this._zipCode = this._opts.zipCode.replace(/^\s+/,'').replace(/\s+$/,''); } aud.util.setOpts(opts); aud.util.setZoneId(this._zoneId); this._addListeners(); }; var ap_proto = aud.html5.AdPlayer.prototype; var utils = ['publish', 'subscribe', 'remove']; for (var i = 0; i < utils.length; i++) { var method = utils[i]; ap_proto[method] = (function (name) { return function() { var a = arguments; a[0] = a[0] + '.' + this._evtId; aud.util[name].apply(null, a); return this; } })(method); } aud.util.extend(ap_proto, { init : function(video_id, params) { this._audVideoPlayer = null; this._submissions = {}; this._globalSubmissionData = {}; this._breaks = []; this._chapters = []; this._ads = {}; this._breakIndex = 0; this._sequenceIndex = 0; this._currentChapter = null; this._currentGroup = null; this._currentSequence = null; this._currentChapterSequence = null; this._currentPar = null; this._parIndex = 0; this._refIndex = 0; this._playCount = 0; this._playDur = 0; this._chapterIndex = 0; this._initFailed = false; this._params = params || {}; this._initCompleted = false; this._breakStarted = false; this._chapterStarted = false; this._contentCompleted = false; this._maxWrapperCount = 0; if (isNaN(this._zoneId)) { this._failInit("invalide zone Id :" + this._zoneId + ", zoneId must be numeric"); return this; } if(typeof video_id == 'string'){ video_id = [video_id]; } aud.util.setVideoIds(video_id); //----- set GEO base on countryCode and zipCode var geoString = null; if ( (this._countryCode != null && this._countryCode.length > 0) || (this._zipCode != null && this._zipCode.length > 0) ) { geoString = encodeURIComponent(";" + (this._countryCode != null ? this._countryCode : "") + ";;;" + (this._zipCode != null ? this._zipCode : "") + ";;"); } aud.AdServerClient.request(video_id, this._adDomain, this._adRequestDomain, this._zoneId, geoString, this._params.userData, aud.util.handler(this, this._loadXml), aud.util.handler(this, this._failInit)); var t = this; setTimeout(function() { if (!t._initCompleted) { t._failInit("ad serer call timeout"); } }, this._serverTimeout); return this; }, _failInit : function(errorMessage) { if(this._initFailed || this._initCompleted) { return; } this.publish(aud.events.init_failed,this,errorMessage); this._initFailed = true; }, _startBreak : function(breakIndex) { //-- set index if passed in if (breakIndex != null && this._breakIndex != breakIndex) { this._breakIndex = breakIndex; this._breakStarted = false; } //-- do nothing if the break is already started if (this._breakStarted) { return; } //-- end chapter and dispatch Break Begin Event this._endChapter(); //reset break variables this._breakStarted = true; this._sequenceIndex = 0; this._currentSequence = null; if (this._prefetchNetworkAds) { var t = this; this.subscribe("breakPreloded", function(){t._onVastBreakPreloaded()}); this.preloadVastBreak(this._breakIndex, 0, 0); } else { this._onVastBreakPreloaded(); } }, _onVastBreakPreloaded : function() { this.remove("breakPreloded"); this._currentGroup = this._breaks[this._breakIndex]; this.publish(aud.events.break_begin, this, this._getGroupData(this._currentGroup)); if ( this._currentGroup == null || this._currentGroup.seqs.length <= 0) { this._endBreak(); } else { this._currentGroup.played = true; this._showNextSequence(); } }, _getGroupData : function(group) { var totalDuration = 0; var totalCount = 0; var banners ={}; if (group != null && group.seqs) { for(seqIndex = 0; seqIndex < group.seqs.length; seqIndex++) { var seq = group.seqs[seqIndex]; if (seq != null && seq.pars != null) { var seqDuration = 0; var seqCount = 0; var maxCount = parseInt(seq["max-count"] != null ? seq["max-count"] : seq.count); var maxDur = parseInt(seq["max-dur"] != null ? seq["max-dur"] : seq.dur); var creativemaxdur = parseInt(seq["creativemaxdur"] != null ? seq["creativemaxdur"] : -1); for(parIndex = 0; parIndex < seq.pars.length; parIndex++) { var par = seq.pars[parIndex]; if (par != null && par.refs != null) { for(refIndex = 0; refIndex < par.refs.length; refIndex++) { var ref = par.refs[refIndex]; if (ref != null && ref.primaryAsset != null) { if (seqDuration + parseInt(ref.primaryAsset.runtime) <= maxDur && seqCount+1 <= maxCount && (creativemaxdur < 0 || parseInt(ref.primaryAsset.runtime) <= creativemaxdur) && this.getBestVideoFormat(ref.primaryAsset.mediaFiles) != null) { seqDuration += parseInt(ref.primaryAsset.runtime); seqCount++; if (ref.companions && ref.companions.length > 0) for (var companionIndex = 0; companionIndex < ref.companions.length; companionIndex++) { var myCompanion = ref.companions[companionIndex]; if (myCompanion.mediaFiles && myCompanion.mediaFiles.length > 0) { for (var mediaFileIndex = 0; mediaFileIndex < myCompanion.mediaFiles.length; mediaFileIndex++) { var myMediaFile = myCompanion.mediaFiles[mediaFileIndex] banners["banner_" + myMediaFile.width + "x" + myMediaFile.height] = true; } } } } } } } } totalDuration += seqDuration; totalCount += seqCount; } } } return {breakCount:totalCount, breakDuration:totalDuration, breakIsEmpty:totalCount <= 0, banners:banners}; }, _endBreak : function(forced) { if (this._breakStarted) { if(!this._prefetchNetworkAds) { this._breakIndex++; } this._breakStarted = false; if (this._audVideoPlayer) { this._audVideoPlayer.destroy(); this._audVideoPlayer = null; } if (!forced) { this.publish(aud.events.break_end, this); this._startChapter(); } } }, _showNextSequence : function() { // ping sequence end for the current sequence if (this._currentSequence) { this._pingSequence(this._currentSequence, false, true); } var seqs = this._currentGroup.seqs; if (seqs && (this._sequenceIndex < seqs.length)) { this._currentSequence = seqs[this._sequenceIndex]; this._sequenceIndex++; this._playCount = 0; this._playDur = 0; if (!this._currentSequence) { this._showNextSequence(); return; } this._pingSequence(this._currentSequence, true, false); if(this._currentSequence.pars.length > 0) { this._parIndex = 0; this._showNextPar(); } else { this._showNextSequence(); return; } } else { this._endBreak(); } }, _showNextPar : function() { var pars = this._currentSequence.pars; if (pars && (this._parIndex < pars.length)) { this._currentPar = this._currentSequence.pars[this._parIndex]; this._parIndex++; if (this._currentPar) { this._refIndex = 0; if (this._currentPar.adSystem != null && this._currentPar.adSystem.toUpperCase() == "VAST") { if (!this._currentPar.resolved) { //-- load and parse vast var vastParser = new aud.html5.VastParser(this, this._vastLoadTimeout, null, null, this._currentPar.refs[this._refIndex].primaryAsset.contentType); var audAdID = this._currentPar.refs[this._refIndex].primaryAsset.adId; vastParser.loadVastXML(aud.util.replacePlaceHolder(this._currentPar.adTagURI), audAdID, audAdID, true); } else { this._showNextRef(); } } else { this._showNextRef(); } } } else { this._showNextSequence(); return; } }, onVastParserDone : function(vastRefs, errorData) { if (vastRefs && vastRefs.length > 0) { //**** merge submissions & traking if (this._currentPar.refs[this._refIndex] != null ) { this._mergeTrakings(this._currentPar.refs[this._refIndex], vastRefs); } this._currentPar.refs = vastRefs; } else { if (!errorData) { errorData = {errorid:"1108", message:""}; } if (this._currentPar && this._currentPar.refs && this._currentPar.refs[0] && this._currentPar.refs[0].primaryAsset) { errorData.a = this._currentPar.refs[this._refIndex].primaryAsset.adId; } aud.util.pingUrl(this._submissions["playererror"], errorData); this._currentPar.refs = []; } this._currentPar.resolved = true; this._showNextRef(); }, _mergeTrakings : function (wrapperRef, vastRefs) { var primaryClicksSubmissions = []; var primarySubmissions = {}; var companionsClicks = []; var companionsImpressions = []; //-- primary Asset if (wrapperRef.primaryAsset.clicks != null){ primaryClicksSubmissions = primaryClicksSubmissions.concat(wrapperRef.primaryAsset.clicks[0].submissions); } for (var subId in wrapperRef.primaryAsset.submissions) { if (primarySubmissions[subId] == null){ primarySubmissions[subId] = []; } primarySubmissions[subId] = primarySubmissions[subId].concat(wrapperRef.primaryAsset.submissions[subId]); } // get impression and click from companion for (var compIndex = 0; compIndex < wrapperRef.companions.length; compIndex++) { for (var clickIndex=0; clickIndex < wrapperRef.companions[compIndex].clicks.length; clickIndex++) { companionsClicks.push( {action:wrapperRef.companions[compIndex].clicks[clickIndex].href, method:'get', id:wrapperRef.companions[compIndex].clicks[clickIndex].id} ) for (var submission in wrapperRef.companions[compIndex].clicks[clickIndex].submissions) { companionsClicks.push( {action:wrapperRef.companions[compIndex].clicks[clickIndex].submissions[submission].action, method:'get', id:wrapperRef.companions[compIndex].clicks[clickIndex].id} ) } } for (var mIndex = 0; mIndex < wrapperRef.companions[compIndex].mediaFiles.length; mIndex++) { companionsImpressions.push({action:wrapperRef.companions[compIndex].mediaFiles[mIndex].src}); } } //-- add the wrapper info to vastRefs; for (var refIndex = 0; refIndex < vastRefs.length; refIndex++) { var ref = vastRefs[refIndex]; //-- add to primary Asset if (ref.primaryAsset != null) { //-- add submissions for (var subId in primarySubmissions) { if (ref.primaryAsset.submissions[subId] == null){ ref.primaryAsset.submissions[subId] = []; } ref.primaryAsset.submissions[subId] = ref.primaryAsset.submissions[subId].concat(primarySubmissions[subId]); } //-- add click submission to existing click if (primaryClicksSubmissions.length > 0 && ref.primaryAsset.clicks && ref.primaryAsset.clicks.length > 0) { if (!ref.primaryAsset.clicks[0].submissions){ ref.primaryAsset.clicks[0].submissions = [] } ref.primaryAsset.clicks[0].submissions = ref.primaryAsset.clicks[0].submissions.concat(primaryClicksSubmissions); } //--- merge trakings if (ref.primaryAsset.trackings == null){ ref.primaryAsset.trackings = {}; } for (var key in wrapperRef.primaryAsset.trackings) { if (ref.primaryAsset.trackings[key] == null) { ref.primaryAsset.trackings[key] = []; } ref.primaryAsset.trackings[key] = ref.primaryAsset.trackings[key].concat(wrapperRef.primaryAsset.trackings[key]); } } //-- add to Companions if (ref.companions != null) { for (var cIndex=0; cIndex < ref.companions.length; cIndex++) { //-- add tracking if (ref.companions[cIndex].trackings['impression'] == null){ ref.companions[cIndex].trackings['impression'] = []; } for (var impIndex = 0; impIndex < companionsImpressions.length; impIndex++) { ref.companions[cIndex].trackings["impression"].push(companionsImpressions[impIndex]); } ref.companions[cIndex].clicks[0].submissions = ref.companions[cIndex].clicks[0].submissions.concat(companionsClicks); } } } }, _showNextRef : function() { var t = this; var progressSent = []; var adStarted = false; var ref = this._currentPar.refs[this._refIndex]; this._refIndex ++; if (ref != null) { //-- play primary Asset if (ref.primaryAsset != null) { /// check count and duration for linear (move to next sequence if reach max duration and/or count) var seqCount = parseInt( this._currentSequence['max-count'] || parseInt(this._currentSequence.count)); var seqDur = parseInt(this._currentSequence['max-dur'] || parseInt(this._currentSequence.dur)); var creativemaxdur = parseInt(this._currentSequence['creativemaxdur'] || -1); if (this._playCount >= seqCount || parseInt(this._playDur) + parseInt(ref.primaryAsset.runtime) > seqDur || (creativemaxdur >= 0 && parseInt(ref.primaryAsset.runtime) > creativemaxdur) ) { this._showNextRef(); return; } var context = { banners:this._createBanners( ref.companions) }; context.session = this._createSession(this, context, ref.primaryAsset, this._currentSequence, this._currentPar); // pick best media file var media = this.getBestVideoFormat(ref.primaryAsset.mediaFiles); if (media == null) { this._showNextRef(); return; } switch (ref.primaryAsset.behavior.format.toLowerCase()) { case 'video': var opts = { w: media.width, h: media.height, handlers: { play: function() { this._done = false; //aud.util.consoleLog("--->> video play"); if (!context.session.isAdStarted()) { t._playCount++; t._playDur += parseInt(ref.primaryAsset.runtime); } context.session.notifyStart(true); }, ended: function(evt, player, video) { //aud.util.consoleLog("--->> video ended") if (!this._done) { this._done = true; t._internalVideoEnd(context); } }, timeupdate: function() { context.session.notifyPlayheadUpdate(this.currentTime, this.duration); if (!this._done && this.currentTime && this.duration && this.currentTime/this.duration >= 1) { this._done = true; t._internalVideoEnd(context); } }, pause: function() { context.session.notifyPause(); }, resume: function() { context.session.notifyResume(); }, click: function() { if (t._auditudeHandlesAdClick) { context.session.notifyAdClick(); } }, error: function() { //aud.util.consoleLog("--->> video error"); } }, customHandlers: this._opts.handlers || [], controls: this._opts.controls, style: this._opts.style || false }; if (t._auditudeHandlesLinearAds) { this._audVideoPlayer = AUD_Html5VideoPlayer.create(this._name, media.src, opts); this._elem = this._audVideoPlayer._elem; } else { if (t._currentSequence.ctype == "nonlinear") { t.publish(aud.events.non_linear_ad_begin, t, context); } else { t.publish(aud.events.linear_ad_begin, t, context); } } break; } } else { this._showNextPar(); return; } } else { this._showNextPar(); return; } }, _internalVideoEnd : function(context) { aud.util.consoleLog('_internalVideoEnd call') context.session.notifyComplete(); if (this._audVideoPlayer) { this._audVideoPlayer.destroy(); this._audVideoPlayer = null; this._showNextRef(); } }, getBestVideoFormat : function(mediaFiles) { if (mediaFiles == null) { return null; } var media = null; var mediaPriority = 100000; var bitrateDif = 1000000; for (var mediaIndex = 0; mediaIndex < mediaFiles.length; mediaIndex++) { var priority = this._mimeType[mediaFiles[mediaIndex].type] ; if (priority != 'undefined' && priority <= mediaPriority) { mediaBitrate = mediaFiles[mediaIndex].bitrate || 0; dif = Math.abs(this.bitrate - mediaBitrate); if (dif <= bitrateDif){ media = mediaFiles[mediaIndex]; mediaPriority = priority; bitrateDif = dif; } } } return media; }, _startChapter : function(chapterIndex) { // set index id passed in if (chapterIndex != null && chapterIndex != this._chapterIndex) { this._chapterIndex = chapterIndex; this._chapterStarted = false; } //-- do nothing if chapter started if (this._chapterStarted || this._contentCompleted) { return; } //-- set prerole as played if (this._breaks[0] != null && !this._breaks[0].played) { this._breaks[0].played = true; //-- set break index (skip preroll) if (this._breakIndex <= 0) { this._breakIndex = 1; } } this._currentChapter = this._chapters[this._chapterIndex]; t = this; // check that theire is a valid chapter to play if (!this._currentChapter || !this._currentChapter.seqs || this._currentChapter.seqs.length <= 0) { if (!this._auditudeHandlesLinearAds) { this.publish(aud.events.resume_playback, this); } return; } var seqs = this._currentChapter.seqs; for (var seqIndex = 0; seqIndex < seqs.length; seqIndex++) { this._currentChapterSequence = seqs[seqIndex]; this._pingSequence(this._currentChapterSequence, true, true); if (this._currentChapterSequence.pars.length > 0) { for (parIndex = 0; parIndex < this._currentChapterSequence.pars.length; parIndex++) { this._currentPar = this._currentChapterSequence.pars[parIndex]; if (this._currentPar.refs.length > 0) { for (var refIndex = 0; refIndex < par.refs.length; refIndex++) { var ref = this._currentPar.refs[refIndex]; var banners = []; if (this._currentPar.adSystem != "VAST") { banners = this._createBanners(ref.companions); } var context = { banners: banners }; context.session = this._createSession(this, context, ref.primarryAsset, this._currentChapterSequence, this._currentPar); context.session.notifyStart(true); } }else { return; } } } } this._chapterStarted = true; this.publish(aud.events.resume_playback, this); }, _createBanners : function(companions) { var resourcePriority = {'static':0, 'text/html':1, 'iframe':2 }; var groups = {}; //--- pick best media for each width and height group. for (var companionIndex = 0; companionIndex < companions.length; companionIndex++) { var companion = companions[companionIndex]; for (var mediaIndex = 0; mediaIndex < companion.mediaFiles.length; mediaIndex++) { var media = companion.mediaFiles[mediaIndex]; var width = media.width; var height = media.height; var resourceType = "static"; if (media && media.type) { resourceType = media.type.toLowerCase();// == 'text/html' ? 'iframe':'static'; } var html = ""; if (resourceType == 'iframe') { resourceType = 'text/html'; html = ""; } else if (resourceType == 'text/html') { html = media.src; } else // static { resourceType = 'text/html'; var d = new Date(); if (companion.clicks.length > 0 && companion.clicks[0].href != null && companion.clicks[0].href.length > 0 && companion.clicks[0].href.toLowerCase() != "http://") { var hRef = aud.util.replacePlaceHolder(companion.clicks[0].href); html = ''; }else { html = ''; } } html += this._getTrackingPixel(companion.trackings); if (groups[width+"_"+height] == null || resourcePriority[resourceType] > resourcePriority[groups[width+"_"+height].resourceType]) { groups[width+"_"+height] = {resourceType:resourceType, media:media, companion:companion, html:html}; } } } //-- create banners object from groups var banners = []; for (var wh in groups) { var id = null; var type = null; var width = null; var height = null; var adParameters = null; var customData = null; if (groups[wh].companion) { id = groups[wh].companion.id; if(groups[wh].companion.behavior) { type = groups[wh].companion.behavior.format; } adParameters = groups[wh].companion.parameters; customData = groups[wh].companion.customData; } if (groups[wh].media) { width = groups[wh].media.width; height = groups[wh].media.height; } var banner = { id : id, type : type, width : width, height : height, adParameters : adParameters, customData : customData, resourceType : groups[wh].resourceType, data:groups[wh].html } if (groups[wh].companion.clicks != null) { var click = groups[wh].companion.clicks[0]; if (click) { banner.click = {id:click.id, url:aud.util.replacePlaceHolder(click.href), title:click.title}; } } banners.push(banner); } return banners; }, _getClickTrackingJS : function(clicks) { var result = ""; for (var clickIndex=0; clickIndex < clicks.length; clickIndex++) { click = clicks[clickIndex]; if (click && click.submissions) { for (var subIndex=0; subIndex < click.submissions.length; subIndex++) { result = result + "(new Image()).src='" + (click.submissions[subIndex].action) + "';"; } } } return result; }, _getTrackingPixel : function(trackings) { var html =""; //--- add traking pixel for (var trackingKey in trackings) { for (var i=0; i< trackings[trackingKey].length; i++) { var trackingUrl = aud.util.replacePlaceHolder(trackings[trackingKey][i].action); var htmlTrakings = ""; html += htmlTrakings; } } return html; }, _endChapter : function() { if (this._overlay) { this._elem.removeChild(this._overlay); this._overlay = null; } if (this._currentChapterSequence) { this._pingSequence(this._currentChapterSequence, false, false); this._currentChapterSequence = null; this._chapterIndex++; this.publish(aud.events.non_linear_ad_end, this); } this.publish(aud.events.pause_playback, this); this._chapterStarted = false; }, _handleGenericEvent : function(context) { if (context) { switch (context.notificationType) { case 'sequenceBegin': this._pingSequence(context.sequence, context.begin, context.advancePattern); break; case 'sequenceEnd': this._pingSequence(context.sequence, context.begin, context.advancePattern); break; default: break; } } }, _createSession : function(context, sessionContext, asset, sequence, par) { var t = this; var progressSent = []; var adStarted = false; var adCompleted = false; if (asset) { var media = this.getBestVideoFormat(asset.mediaFiles); if (media) { sessionContext.asset = {url:media.src, duration:asset.runtime}; if (asset.clicks && asset.clicks.length > 0 && asset.clicks[0].href && asset.clicks[0].href.length > 0) { sessionContext.asset["clickUrl"] = asset.clicks[0].href; } } } session = { isAdStarted : function() { return adStarted; }, notifyStart : function(sendAdBegin) { if (!adStarted) { adStarted = true; if (sendAdBegin == true) { if (sequence.ctype == "nonlinear") { context.publish(aud.events.non_linear_ad_begin, t, sessionContext); } else { context.publish(aud.events.linear_ad_begin, t, sessionContext); } } if (!progressSent[0]) { progressSent[0] = true; if (asset != null) { //-- ping impression ( only once per ad ); var ad = context._ads[asset.adId]; if (ad != null && ad.submissions['impression'] != null && ad.submissions['impression'].sent == false) { context._pingAdSubmission(ad.submissions['impression'].submissions, sequence, par); ad.submissions['impression'].sent = true; } if (asset.trackings != null) { context._pingAdTracking(asset.trackings['creativeView']); context._pingAdTracking(asset.trackings['0%']); } if (asset.submissions != null) { context._pingAdSubmission(asset.submissions['creativeView'], sequence, par); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '0'); } } } } return this; }, notifyStop : function() { if (context._audVideoPlayer) { context._audVideoPlayer.trigger('stop'); } if (!adCompleted) { adCompleted = true; context.publish(aud.events.linear_ad_end, t, sessionContext); if (!context._auditudeHandlesLinearAds) { context._playCount++; context._playDur += parseInt(context._currentPar.refs[context._refIndex-1].primaryAsset.runtime); context._showNextRef(); } } return this; }, notifyComplete : function() { if (!adCompleted) { adCompleted = true; context.publish(aud.events.linear_ad_end, t, sessionContext); if (adStarted && !progressSent[100]) { progressSent[100] = true; context._pingAdTracking(asset.trackings['100%']); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '100'); } if (!context._auditudeHandlesLinearAds) { context._playCount++; context._playDur += parseInt(context._currentPar.refs[context._refIndex-1].primaryAsset.runtime); context._showNextRef(); } } return this; }, notifyPlayheadUpdate : function(currentTime, duration) { var progress = Math.round(currentTime.toFixed(1) / duration * 100); if (progress == 100 && !progressSent[100]) { progressSent[progress] = true; context._pingAdTracking(asset.trackings['100%']); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '100'); } else { if (progress > 25 && !progressSent[25]) { progressSent[25] = true; context._pingAdTracking(asset.trackings['25%']); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '25'); } else if (progress > 50 && !progressSent[50]) { progressSent[50] = true; context._pingAdTracking(asset.trackings['50%']); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '50'); } else if (progress > 75 && !progressSent[75]) { progressSent[75] = true; context._pingAdTracking(asset.trackings['75%']); context._pingAdSubmission(asset.submissions['creativeProgress'], sequence, par, '75'); } } }, notifyPause : function() { if (context._audVideoPlayer) { context._audVideoPlayer.trigger('pause'); } return this; }, notifyResume : function() { if (context._audVideoPlayer) { context._audVideoPlayer.trigger('play'); } return this; }, notifyAdClick : function() { if (asset != null && asset.clicks != null) { if (asset.clicks.length > 0 && asset.clicks[0].href && asset.clicks[0].href.length > 0) { context.publish(aud.events.ad_click, t, sessionContext); window.open( aud.util.replacePlaceHolder(asset.clicks[0].href)); }; for (var clickIndex = 0; clickIndex < asset.clicks.length; clickIndex++) { if (asset.clicks[clickIndex].href && asset.clicks[clickIndex].href.length > 0) { context._pingAdSubmission(asset.clicks[clickIndex].submissions, sequence, par); context._pingAdTracking(asset.clicks[clickIndex].trackings); } } } } }; return session; }, _sendSubmission : function(type, data, method) { aud.util.pingUrl(this._submissions[type], data, method); }, _pingSequence : function(sequence, isBegin, advancePattern) { if (sequence) { var data = {}; aud.util.extend(data, sequence.setvalues); data['advancepattern'] = (advancePattern ? '1' : '0'); data['event'] = (isBegin ? 'start' : 'complete'); this._sendSubmission('podprogress', data, 'get'); } }, _pingAdSubmission : function(submissions, sequence, par, progress) { if (submissions) { var i; for (i = 0; i < submissions.length; i++) { var data = {}; aud.util.extend(data, this._globalSubmissionData); aud.util.extend(data, sequence.setvalues); aud.util.extend(data, par.setvalues); if (progress) { var state = {}; state['progress'] = progress; state['unit'] = 'percent'; aud.util.extend(data, state); } aud.util.pingUrl(submissions[i]['action'], data, submissions[i]['method']); } } }, _pingAdTracking : function(trackings) { if (trackings) { var i; for (i = 0; i < trackings.length; i++) { aud.util.pingUrl(trackings[i]['action']); } } }, _addListeners : function() { var t = this; this.subscribe(aud.notifications.break_begin, function(name, index) { t._startBreak(index); }); this.subscribe(aud.notifications.break_end, function() { t.publish(aud.events.linear_ad_end, t, {asset:{}, banners:[], session:null}); t._endBreak(); }); this.subscribe(aud.notifications.video_playback_started, function(name, index) { t._contentCompleted = false; t._startChapter(index); }); this.subscribe(aud.notifications.video_playback_complete, function() { t._contentCompleted = true; t._endChapter(); /*if (t._auditudeHandlesChapterBreaks) { t._startBreak(); }*/ }); this.subscribe(aud.notifications.video_playback_paused, function(){ //if (t._chapterStarted) //{ // t._endChapter(); //} }); this.subscribe(aud.notifications.video_playback_resumed, function(name, index) { //t._startChapter(index); }); this.subscribe(aud.notifications.video_playhead_update, function(name, currentTime, duration) { if (t._auditudeHandlesChapterBreaks && !t._breakStarted && t._currentChapter != null && (currentTime < t._currentChapter.startTime || currentTime >= t._currentChapter.startTime + t._currentChapter.dur)) { //-- get current chaper index; var currentChapter = 0; var currentIndex = 0; for (var chapterIndex = 0; chapterIndex < t._chapters.length; chapterIndex++) { var chapter = t._chapters[chapterIndex]; if (currentTime > chapter.startTime && currentTime <= chapter.startTime + chapter.dur) { currentIndex = chapterIndex; break; } } //-- find break for this chapter for (var breakIndex = 0 ; breakIndex < t._breaks.length; breakIndex ++) { if (t._breaks[breakIndex].startTime == t._chapters[currentIndex].startTime) { if (!t._breaks[breakIndex].played && t._auditudeHandlesChapterBreaks) { //-- if there is a break, set chapter to last chapter playe ( index will be incress at the end of the break); t._chapterIndex = currentIndex - 1; t._currentChapter = t._chapters[t._chapterIndex]; t._startBreak(breakIndex); } else { //-- set current chapter t._chapterIndex = currentIndex; t._currentChapter = t._chapters[t._chapterIndex]; } break; } } } }); this.subscribe(aud.notifications.pauseAd, function(name, index) { if (this.session) { this.session.notifyPause(); } }); this.subscribe(aud.notifications.ad_click, function(name, context) { if (this.session) { this.session.notifyAdClick(); } }); this.subscribe(aud.notifications.notify_event, function(name, context) { t._handleGenericEvent(context); }); }, getBreakData : function() { //--- create breaks data myBreakData = []; for (var myBreakIndex = 0; myBreakIndex < this._breaks.length; myBreakIndex++) { var myBreak = this._breaks[myBreakIndex]; var breakStartTime = myBreak.startTime; var breakCount = 0; var breakDuration = 0; var breakIsEmpty = true; var banners = {}; var groupData = this._getGroupData(myBreak); myBreakData.push({breakIndex:myBreakIndex, breakStartTime:breakStartTime, breakCount:groupData.breakCount, breakDuration:groupData.breakDuration, breakIsEmpty:groupData.breakIsEmpty, banners:groupData.banners}); } return myBreakData; }, /****************************************************/ /****************** PDK Functions *******************/ /****************************************************/ getAdEventsInBreak : function(breakIndex) { var ads = []; var index = (typeof breakIndex != 'undefined') ? breakIndex : -1; var currentGroup = (index >= 0) ? this._breaks[index] : this._breaks[this._breakIndex]; if (currentGroup && currentGroup.seqs && !currentGroup.played) { var sequenceIndex = 0; var parIndex = 0; var currentSequence; var seqs = currentGroup.seqs; if (sequenceIndex < seqs.length) { currentSequence = seqs[sequenceIndex]; while (currentSequence) { sequenceIndex++; var maxCount = 10000; if (currentSequence["max-count"]) { maxCount = parseInt(currentSequence["max-count"]); } else if (currentSequence["count"]) { maxCount = parseInt(currentSequence["count"]); } var maxDur = 10000; if (currentSequence["max-dur"]) { maxDur = parseInt(currentSequence["max-dur"]); } else if (currentSequence["dur"]) { maxDur = parseInt(currentSequence["dur"]); } var creativemaxdur = parseInt(currentSequence["creativemaxdur"] != null ? currentSequence["creativemaxdur"] : -1); var totalDur = 0; var refCount = 0; // add the sequence ads.push({ type: "notify", notificationType: "sequenceBegin", sequence: currentSequence, begin: true, advancePattern: false }); if(currentSequence.pars.length > 0) { parIndex = 0; var currentPar; var pars = currentSequence.pars; var t = this; if (parIndex < pars.length) { currentPar = pars[parIndex]; while (currentPar) { parIndex++; if (currentPar.refs.length > 0) { var primaryAsset = null; var banners = []; for (var refIndex = 0; refIndex < currentPar.refs.length; refIndex++) { var ref = currentPar.refs[refIndex]; primaryAsset = ref.primaryAsset; banners = this._createBanners(ref.companions); //**** check mediaFile type. var media = this.getBestVideoFormat(primaryAsset.mediaFiles); primaryAsset.mediaFiles = []; if (media) { primaryAsset.mediaFiles.push(media)} if (primaryAsset && primaryAsset.mediaFiles && primaryAsset.mediaFiles.length > 0 && primaryAsset.behavior && primaryAsset.behavior.format == 'video' && parseInt(refCount) < parseInt(maxCount) && parseInt(totalDur) + parseInt(primaryAsset.runtime) <= parseInt(maxDur) && (creativemaxdur < 0 || parseInt(ref.primaryAsset.runtime) <= creativemaxdur)) { var context = { type: "ad", adType: "linear", format: "video", asset: primaryAsset, banners: banners, sequence: currentSequence, par: currentPar }; context.session = this._createSession(this, context, primaryAsset, currentSequence, currentPar); refCount ++; totalDur = parseFloat(totalDur) + parseFloat(primaryAsset.runtime); ads.push(context); } } currentPar = pars[parIndex]; } else { currentPar = pars[parIndex]; } } // add the sequence end notification ads.push({ type: "notify", notificationType: "sequenceEnd", sequence: currentSequence, begin: false, advancePattern: true }); currentSequence = seqs[sequenceIndex]; continue; } else { // add the sequence end notification ads.push({ type: "notify", notificationType: "sequenceEnd", sequence: currentSequence, begin: false, advancePattern: true }); currentSequence = seqs[sequenceIndex]; continue; } } else { // add the sequence end notification ads.push({ type: "notify", notificationType: "sequenceEnd", sequence: currentSequence, begin: false, advancePattern: true }); currentSequence = seqs[sequenceIndex]; continue; } } } } if (currentGroup != null) { currentGroup.played = true; } return ads; }, preloadVastBreak : function(breakIndex, seqIndex, parIndex) { breakIndex = (typeof breakIndex != 'undefined') ? breakIndex : this._breakIndex; seqIndex = (typeof seqIndex != 'undefined') ? seqIndex : 0; parIndex = (typeof parIndex != 'undefined') ? parIndex : 0; var currentBreak = this._breaks[breakIndex]; if (currentBreak != null && !currentBreak.played) { var currentSeq = currentBreak.seqs[seqIndex]; if ( currentSeq != null) { var currentPar = currentSeq.pars[parIndex]; if (currentPar != null) { if (currentPar.adSystem != null && currentPar.adSystem.toUpperCase() == "VAST") { //-- load and parse vast var t = this; var myDelegate = { onVastParserDone :function(vastRefs, errorData) { t._onVastXmlPreloadedHandler(vastRefs, errorData, breakIndex, seqIndex, parIndex) }, publish: function(evt, obj, data) { t.publish(evt, obj, data); } }; var vastParser = new aud.html5.VastParser(myDelegate, t._vastLoadTimeout, null, null, currentPar.refs[0].primaryAsset.contentType ); var audAdID = currentPar.refs[0].primaryAsset.adId; vastParser.loadVastXML(aud.util.replacePlaceHolder(currentPar.adTagURI), audAdID, audAdID, true); return; } parIndex ++; this.preloadVastBreak(breakIndex, seqIndex, parIndex); return; } else { parIndex = 0; seqIndex ++; this.preloadVastBreak(breakIndex, seqIndex, parIndex); return; } } } this.publish("breakPreloded", this); this._breakIndex = breakIndex; this._breakIndex ++; }, _onVastXmlPreloadedHandler : function(vastRefs, errorData, breakIndex, seqIndex, parIndex) { var currentPar = this._breaks[breakIndex].seqs[seqIndex].pars[parIndex]; if (vastRefs && vastRefs.length > 0 ) { //**** merge submissions & traking if (currentPar.refs[0] != null) { this._mergeTrakings(currentPar.refs[0], vastRefs); } currentPar.refs = vastRefs; } else { if (!errorData) { errorData = {errorid:"1108", message:""}; } if (currentPar && currentPar.refs && currentPar.refs[0] && currentPar.refs[0].primaryAsset) { errorData.a = currentPar.refs[this._refIndex].primaryAsset.adId; } aud.util.pingUrl(this._submissions["playererror"], errorData); currentPar.refs = []; } parIndex ++; currentPar.resolved = true; this.preloadVastBreak(breakIndex, seqIndex, parIndex); }, /****************************************************/ /****************** XML Parsing *********************/ /****************************************************/ _loadXml : function(xmlDoc) { if(this._initFailed) return; this._xmlDoc = xmlDoc; if (this._xmlDoc) { this._parseXml(this._xmlDoc); this._initCompleted = true; this.publish(aud.events.init_complete, this); } else { this._failInit("invalid xml doc"); } }, _parseXml : function(xml) { var head = xml.getElementsByTagName('head'); var body = xml.getElementsByTagName('body'); var ads = aud.util.getChildNodes(xml.childNodes[0]).ad; this._parseSubmissions(head); this._parseAds(ads); this._parseSmil(body[0].childNodes); }, _parseSubmissions : function(xml) { if (!xml) return; xml = xml[0]; var data = xml.getElementsByTagName('data'), submissions = xml.getElementsByTagName('submission'), parameters = data[0].childNodes; this._globalSubmissionData = {}; var i; for (i = 0; i < parameters.length; i++) { var p = parameters[i]; if (p.tagName) { this._globalSubmissionData[p.tagName] = p.firstChild.data; } } for (i = 0; i < submissions.length; i++) { var submission = submissions[i], id = submission.getAttribute('id'), url = submission.getAttribute('action'); if (url.indexOf('?') < 0) url += '?'; this._submissions[id] = url; var k; for (k in this._globalSubmissionData) { this._submissions[id] += '&' + k + '=' + this._globalSubmissionData[k]; } } }, _parseAds : function(ads) { if (!ads) { return; } for (var adIndex = 0; adIndex < ads.length; adIndex++) { /// get Ad info. var adNode = ads[adIndex]; var adChildNodes = aud.util.getChildNodes(adNode); var wrapperNodes = aud.util.getChildNodes(adNode).wrapper; var adId = adNode.attributes.getNamedItem('id').nodeValue; // get Ad Submissions var adSubmissionNodes = adChildNodes.submission; var adSubmissions = {}; for (var adSubmissionIndex = 0; adSubmissionIndex < adSubmissionNodes.length; adSubmissionIndex++) { var adSubmissionId = adSubmissionNodes[adSubmissionIndex].attributes.getNamedItem('id').nodeValue; if (adSubmissions[adSubmissionId] == null) { adSubmissions[adSubmissionId] = {sent:false, submissions:[]}; } var adSubmission = { action : adSubmissionNodes[adSubmissionIndex].attributes.getNamedItem('action').nodeValue, method : adSubmissionNodes[adSubmissionIndex].attributes.getNamedItem('method').nodeValue } adSubmissions[adSubmissionId].submissions.push(adSubmission); } // get behaviours var behaviorNodes = adNode.getElementsByTagName('Behavior'); var behaviors = {}; for (var behaviorIndex = 0; behaviorIndex < behaviorNodes.length; behaviorIndex++) { var bid = behaviorNodes[behaviorIndex].attributes.getNamedItem('type').nodeValue; behaviors[bid] = {}; var params = aud.util.getNodeValue(behaviorNodes[behaviorIndex]).split("&"); for (var paramIndex=0; paramIndex < params.length; paramIndex++) { var split = params[paramIndex].split("="); behaviors[bid][split[0]] = split[1]; } } //get custom data var customDataNodes = adNode.getElementsByTagName('CustomData'); var customData = {}; for (var customDataIndex = 0; customDataIndex < customDataNodes.length; customDataIndex++) { var cid = customDataNodes[customDataIndex].attributes.getNamedItem('type').nodeValue; customData[cid] = aud.util.getNodeValue(customDataNodes[customDataIndex]).split("&"); } // get assets var assets = {}; var assetNodes = adChildNodes.asset; for(var assetIndex = 0; assetIndex < assetNodes.length; assetIndex++) { // get asset info var assetNode = assetNodes[assetIndex]; var asset = { adId : adId, id : assetNode.attributes.getNamedItem('id').nodeValue, contentType : assetNode.attributes.getNamedItem('contentType').nodeValue, parameters : assetNode.attributes.getNamedItem('parameters').nodeValue, submissions:{}, mediaFiles:[], clicks:[], trackings:{} }; if ( assetNode.attributes.getNamedItem('runtime') != null) { asset.runtime = assetNode.attributes.getNamedItem('runtime').nodeValue } //-- attache behaviour to asset if (behaviors[asset.id] != null) { asset.behavior = behaviors[asset.id]; } //-- attache customData to asset asset.customData = customData var assetChildNodes = aud.util.getChildNodes(assetNode); //get asset submissions var assetSubmissionNodes = assetChildNodes.submission; if (assetSubmissionNodes != null) { for (var assetSubmissionIndex = 0; assetSubmissionIndex < assetSubmissionNodes.length; assetSubmissionIndex ++ ) { var submissionId = assetSubmissionNodes[assetSubmissionIndex].attributes.getNamedItem('id').nodeValue; if (asset.submissions[submissionId] == null) { asset.submissions[submissionId] = []; } var submission = { action : assetSubmissionNodes[assetSubmissionIndex].attributes.getNamedItem('action').nodeValue, method : assetSubmissionNodes[assetSubmissionIndex].attributes.getNamedItem('method').nodeValue } asset.submissions[submissionId].push(submission); } } //-- get media files var mediaNodes = assetChildNodes.mediaFile; if (mediaNodes != null) { for (var mediaIndex = 0; mediaIndex < mediaNodes.length; mediaIndex++) { var mediaFile = {}; if (mediaNodes[mediaIndex].attributes.getNamedItem('src') != null) { mediaFile.src = mediaNodes[mediaIndex].attributes.getNamedItem('src').nodeValue; } if (mediaNodes[mediaIndex].attributes.getNamedItem('type') != null) { mediaFile.type = mediaNodes[mediaIndex].attributes.getNamedItem('type').nodeValue; if (mediaFile.type.toLowerCase() == 'text/html') {mediaFile.type = 'iframe'} } if (mediaNodes[mediaIndex].attributes.getNamedItem('width') != null) { mediaFile.width = mediaNodes[mediaIndex].attributes.getNamedItem('width').nodeValue; } if (mediaNodes[mediaIndex].attributes.getNamedItem('height') != null) { mediaFile.height = mediaNodes[mediaIndex].attributes.getNamedItem('height').nodeValue; } if (wrapperNodes != null || (mediaFile.type != null && mediaFile.width != null && mediaFile.height != null)) { asset.mediaFiles.push(mediaFile); } } } //-- get asset click var clickNodes = assetChildNodes.click; if (clickNodes != null) { for (var clickIndex = 0; clickIndex < clickNodes.length; clickIndex ++) { var click = { id : clickNodes[clickIndex].attributes.getNamedItem('id').nodeValue, href : clickNodes[clickIndex].attributes.getNamedItem('href').nodeValue, title : clickNodes[clickIndex].attributes.getNamedItem('title').nodeValue, submissions : [], trackings : [] }; //-- get click Submission; var clikcSubmissionNodes = aud.util.getChildNodes(clickNodes[clickIndex]).submission; if (clikcSubmissionNodes != null) { for (var clickSubIndex = 0; clickSubIndex < clikcSubmissionNodes.length; clickSubIndex++) { clickSubmission = { id : clikcSubmissionNodes[clickSubIndex].attributes.getNamedItem('id').nodeValue, action : clikcSubmissionNodes[clickSubIndex].attributes.getNamedItem('action').nodeValue, method : clikcSubmissionNodes[clickSubIndex].attributes.getNamedItem('method').nodeValue }; click.submissions.push(clickSubmission); } } asset.clicks.push(click); } } //-- get asset trackings var trackingNodes = assetChildNodes.tracking; if (trackingNodes != null) { for (var trackingIndex = 0; trackingIndex < trackingNodes.length; trackingIndex++) { var actuate = 'impression' if (trackingNodes[trackingIndex].attributes.getNamedItem('actuate') != null) { actuate = trackingNodes[trackingIndex].attributes.getNamedItem('actuate').nodeValue; } if (asset.trackings[actuate] == null) { asset.trackings[actuate] = [] } if (actuate == "click") { if (asset.clicks.length == 0 ) {asset.clicks.push({trackings:[]})} asset.clicks[0].trackings.push({action:trackingNodes[trackingIndex].attributes.getNamedItem('action').nodeValue, method:'get', actuate:actuate}); } else { asset.trackings[actuate].push({action:trackingNodes[trackingIndex].attributes.getNamedItem('action').nodeValue, method:'get', actuate:actuate}); } } } assets[asset.id] = asset; } //*** get ad Pars var adPars = {}; var adParNodes = adNode.getElementsByTagName('par'); for (var adParIndex = 0; adParIndex < adParNodes.length; adParIndex++) { var adParRefNodes = adParNodes[adParIndex].getElementsByTagName('ref'); var adParId = adParNodes[adParIndex].attributes.getNamedItem('id').nodeValue; adPars[adParId] = {id:adParId, refs:[]}; for (var adParRefIndex = 0; adParRefIndex < adParRefNodes.length; adParRefIndex++ ) { var adParRefSplit = adParRefNodes[adParRefIndex].attributes.getNamedItem('asset').nodeValue.split("."); var adParRef = { adId:adParRefSplit[0], assetId:adParRefSplit[1] }; adPars[adParId].refs.push(adParRef); } } this._ads[adId] = { pars:adPars, assets:assets, submissions:adSubmissions }; //*** get wrapper info if (wrapperNodes != null) { var wrapperNode = wrapperNodes[0]; this._ads[adId].wrapper = { adSystem : wrapperNode.attributes.getNamedItem('adSystem').nodeValue, adTagURI : wrapperNode.attributes.getNamedItem('adTagURI').nodeValue }; } } }, _parseSmil : function(seqNodes) { var group = { played:false, dur:0, startTime:0, seqs:[] }; var lastType = null; var startTime = 0; for (var seqIndex = 0; seqIndex < seqNodes.length; seqIndex++) { var seq = {sends:[], setvalues:{}, pars:[]}; var segChildNodes = aud.util.getChildNodes(seqNodes[seqIndex]); // parse meta data var metaNodes = segChildNodes.meta; if (metaNodes != null) { for (var metaIndex = 0; metaIndex < metaNodes.length; metaIndex++) { var key = metaNodes[metaIndex].attributes.getNamedItem('name').nodeValue; seq[key] = metaNodes[metaIndex].attributes.getNamedItem('content').nodeValue; } } // parse setvalue var setValueNodes = segChildNodes.setvalue; if (setValueNodes != null) { for (var setValueIndex = 0; setValueIndex < setValueNodes.length; setValueIndex ++) { seq.setvalues[setValueNodes[setValueIndex].attributes.getNamedItem('ref').nodeValue] = setValueNodes[setValueIndex].attributes.getNamedItem('value').nodeValue; } } // parse sends var sendNodes = segChildNodes.send; if (sendNodes != null) { for (var sendIndex = 0; sendIndex < sendNodes.length; sendIndex++) { seq.sends.push(sendNodes[sendIndex].attributes.getNamedItem('submission').nodeValue); } } //- parse pars var parNodes = segChildNodes.par; if (parNodes != null) { for (var parIndex = 0; parIndex < parNodes.length; parIndex++) { seq.pars.push(this._parsePar(parNodes[parIndex], seq.ctype)); } } if (seq.ctype != lastType) { switch(lastType) { case "linear": this._breaks.push(group); break; case "nonlinear": startTime += parseInt(group.dur); this._chapters.push(group); //-- add an empty group to break if the first seq is a linear if (this._breaks.length <= 0) { this._breaks.push({ dur:0, startTime:0, seqs:[] } ); } break; } group = { played:false, dur:0, startTime:startTime, seqs:[] }; lastType = seq.ctype; } group.dur += parseInt(seq.dur); group.seqs.push(seq); } //-- ad the last group created switch(lastType) { case "linear": this._breaks.push(group); break; case "nonlinear": this._chapters.push(group); break; } }, _parsePar : function(parNode, contentType) { par = {setvalues:{}, refs:[]}; var parChildNodes = aud.util.getChildNodes(parNode); // parse meta data var metaNodes = parChildNodes.meta; if (metaNodes != null) { for (var metaIndex = 0; metaIndex < metaNodes.length; metaIndex++) { par[metaNodes[metaIndex].attributes.getNamedItem('name').nodeValue] = metaNodes[metaIndex].attributes.getNamedItem('content').nodeValue; } } // parse setvalue var setValueNodes = parChildNodes.setvalue; if (setValueNodes != null) { for (var setValueIndex = 0; setValueIndex < setValueNodes.length; setValueIndex ++) { par.setvalues[setValueNodes[setValueIndex].attributes.getNamedItem('ref').nodeValue] = setValueNodes[setValueIndex].attributes.getNamedItem('value').nodeValue; } } //-- parse pars var refNodes = parChildNodes.ref; if (refNodes != null) { for (var refIndex = 0; refIndex < refNodes.length; refIndex++) { var id = refNodes[refIndex].attributes.getNamedItem('src').nodeValue.split(':').pop(); if (id.lastIndexOf('#') > 0) { var params = id.split('#'); var ad = this._ads[params[0]]; if (ad != null) { par.refs.push( this._createRef(ad.pars[params[1]]) ); } if (ad.wrapper != null) { par.adSystem = ad.wrapper.adSystem; par.adTagURI = ad.wrapper.adTagURI; } } } } return par; }, _createRef : function(adPar) { var ref = {primaryAsset:{}, companions:[]}; for (var refIndex=0; refIndex < adPar.refs.length; refIndex++) { var adId = adPar.refs[refIndex].adId; var assetId = adPar.refs[refIndex].assetId; var asset = this._ads[adId].assets[assetId]; if (asset != null) { switch (asset.contentType) { case "linear": case "noneLinear": ref.primaryAsset = asset; break; case "companion": ref.companions.push(asset); break default: break; } } } return ref; } }); /****************************************************/ /****************** VAST XML *********************/ /****************************************************/ aud.html5.VastParser = function (delegate, timeout, parentWrapperRef, wrapperCount, type) { this.delegate = delegate; this.parentWrapperRef = parentWrapperRef; this.wrapperCount = 0; if (wrapperCount != undefined) { this.wrapperCount = wrapperCount; } aud.html5.AdPlayer._maxWrapperCount = this.wrapperCount; this.myUrl = null; this.refs = []; this.xmlAds = []; this._customParams = null; this.adIndex = 0; this.timeout = timeout ? timeout : 0; this.networkAdLoadMetrics = new aud.html5.VastParser.prototype.networkAdLoadMetrics(); this.networkAdLoadMetrics.type = type; this.networkAdLoadMetrics.depth = this.wrapperCount; if (window.XDomainRequest) { this._useXDomainRequest = true; this.invocation = new XDomainRequest(); } else { this._useXDomainRequest = false; this.invocation = new XMLHttpRequest(); } }; aud.html5.VastParser.prototype.networkAdLoadMetrics = function() { this.adID = null; this.networkAdID = null; this.URL = null; this.type = null; this.loadTime = 0; this.validAdCount = 0; this.success = false; this.adSystem = "VAST"; this.resolveTime = 0; this.depth = 0; this.children = []; this.failReason = -1; } aud.html5.VastParser.prototype.createNetworkAdLoadMetrics = function(t) { var result = new aud.html5.VastParser.prototype.networkAdLoadMetrics(); result.adID = t.adID; result.networkAdID = t.networkAdID; result.URL = t.URL; result.type = t.type; result.loadTime = t.loadTime; result.resolveTime = t.resolveTime; result.adSystem = t.adSystem; result.success = t.success; result.failReason = t.failReason; var validAdCount = 0; for(var i = 0; i < t.children.length; i++) { var child = t.children[i]; if(child.validAdCount == 1) { // inline if(child.success) { validAdCount += child.validAdCount; } child.validAdCount = 0; result.children.push(child); } else { // wrapper var childNetworkAdLoadMetrics = this.createNetworkAdLoadMetrics(child); result.children.push(childNetworkAdLoadMetrics); validAdCount += childNetworkAdLoadMetrics.validAdCount; } } result.validAdCount = validAdCount; result.depth = t.depth; //result.depth = aud.html5.AdPlayer._maxWrapperCount + 1 - t.depth; if(result.validAdCount == 0) { result.success = false; if(result.failReason == -1) { result.failReason = 3; } } return result; } aud.html5.VastParser.prototype.loadVastXML = function(url, adID, networkAdID, isRoot) { if (this.invocation) { this.myUrl = url; this._customParams = this.delegate._params; if (this._customParams) { for (var key in this._customParams) { var value = this._customParams[key]; url = url.replace(new RegExp("\\[" + key + "\\]","g"),value) } } var t = this; if (window.XDomainRequest ? true : false) { this.invocation.onload = function() { if(t.timeout > 0) { clearTimeout(timeoutID); } t.onVastXMLhandler() }; this.invocation.open('GET', url, true); } else { this.invocation.open('GET', url, true); this.invocation.onreadystatechange = function() { if(t.timeout > 0) { clearTimeout(timeoutID); } t.onVastXMLhandler(); } } if(isRoot) { this.networkAdLoadMetrics.isRoot = true; } this.networkAdLoadMetrics.URL = url; this.networkAdLoadMetrics.adID = adID; this.networkAdLoadMetrics.networkAdID = networkAdID; this.networkAdLoadMetrics.loadTime = new Date().getTime(); this.invocation.send(); // set timeout for vast xml load var delay = function() { t.networkAdLoadMetrics.failReason = 1; t.networkAdLoadMetrics.success = false; setNetworkAdLoadMetrics(t);} function setNetworkAdLoadMetrics(t) { t.invocation.abort();} var timeoutID; if(this.timeout > 0) { timeoutID = setTimeout(delay, this.timeout); } } }; aud.html5.VastParser.prototype.onVastXMLhandler = function() { //console.log("onVastXMLhandler:" + this.invocation.readyState + " , " + this.invocation.status); if ( (this.invocation.readyState == 4 && this.invocation.status == 200) || this._useXDomainRequest ) { this.networkAdLoadMetrics.loadTime = new Date().getTime() - this.networkAdLoadMetrics.loadTime; if (this.invocation.responseText || this.invocation.responseXML) { //--- see if we got responseXML ( most browser - not IE9 ) //-- if we do not have reponseXML try parsing responseText ( IE9 ) var xmlDoc = null; if (this.invocation.responseXML) { var xmlDoc = this.invocation.responseXML; } else //-- other boweser (mostly IE9) { parser=new DOMParser(); var xmlDoc = parser.parseFromString(this.invocation.responseText,"text/xml"); } //-- start parsing XML if (xmlDoc) { this.xmlAds = xmlDoc.getElementsByTagName("Ad"); } this.adIndex = 0; this.parseNextAd(); } else { if (this.wrapperCount == 0) { // invalid xml this.parseNextAd({errorid:"1109", message:""}); this.networkAdLoadMetrics.success = false; this.networkAdLoadMetrics.failReason = 4; } else { this.parseNextAd(); } } } else if (this.invocation.readyState == 4 && (this.invocation.status == 404 || this.invocation.status == 0)) { // invalid vast url this.networkAdLoadMetrics.success = false; if (this.networkAdLoadMetrics.failReason <= -1) { this.networkAdLoadMetrics.failReason = 2; } if (this.wrapperCount == 0) { this.parseNextAd({errorid:"1109", message:""}); } else { this.parseNextAd(); } } else if (this.invocation.readyState == 4 && this.invocation.status != 200) { if (this.wrapperCount == 0) { // invalid xml this.parseNextAd({errorid:"1109", message:""}); this.networkAdLoadMetrics.success = false; this.networkAdLoadMetrics.failReason = 4; } else { this.parseNextAd(); } } }; aud.html5.VastParser.prototype.parseNextAd = function(errorData) { if(this.xmlAds.length > 0) { this.networkAdLoadMetrics.success = true; } else if(this.xmlAds != '' && this.xmlAds != undefined) { this.networkAdLoadMetrics.success = false; this.networkAdLoadMetrics.failReason = 3; } else if(this.networkAdLoadMetrics.failReason != 2) { this.networkAdLoadMetrics.success = false; this.networkAdLoadMetrics.failReason = 1; this.networkAdLoadMetrics.loadTime = this.timeout; } if(this.networkAdLoadMetrics.resolveTime <= 0) { this.networkAdLoadMetrics.resolveTime = new Date().getTime(); } if (this.adIndex < this.xmlAds.length) { var networkAdID = this.xmlAds[this.adIndex].getAttribute('id'); var childNodes = this.xmlAds[this.adIndex].childNodes; for (var childIndex=0; childIndex < childNodes.length; childIndex++) { switch(childNodes[childIndex].tagName) { case "Wrapper": var adTagURI = aud.util.getNodeValue(childNodes[childIndex].getElementsByTagName('VASTAdTagURI')[0]); if (adTagURI && adTagURI.length > 0) { if (this.wrapperCount < 6) { var wRef = {companions:[]}; wRef = this.parseCreatives(childNodes[childIndex]); this.mergeTracking(wRef); var vastParser = new aud.html5.VastParser(this, this.timeout, wRef, this.wrapperCount + 1); vastParser.loadVastXML(aud.util.replacePlaceHolder(adTagURI), this.networkAdLoadMetrics.adID, networkAdID); this.networkAdLoadMetrics.children.push(vastParser.networkAdLoadMetrics); if (wRef != null && wRef.primaryAsset != null) { vastParser.networkAdLoadMetrics.type = wRef.primaryAsset.contentType; } else { vastParser.networkAdLoadMetrics.type = "nonlinear" } return; } else { this.adIndex ++; // reach max wrapper count this.networkAdLoadMetrics.success = false; this.networkAdLoadMetrics.failReason = 5; this.parseNextAd({errorid:"1110", message:""}); } } break; case "InLine": // create networkAdLoadMetrics for inline ad var inlineNetworkAdLoadMetrics = new aud.html5.VastParser.prototype.networkAdLoadMetrics(); inlineNetworkAdLoadMetrics.adID = this.networkAdLoadMetrics.adID; inlineNetworkAdLoadMetrics.networkAdID = networkAdID; inlineNetworkAdLoadMetrics.resolveTime = new Date().getTime(); inlineNetworkAdLoadMetrics.depth = this.networkAdLoadMetrics.depth + 1; var ref = {companions:[]}; ref = this.parseCreatives(childNodes[childIndex], inlineNetworkAdLoadMetrics);//console.log(ref); if (ref.primaryAsset != null) { inlineNetworkAdLoadMetrics.URL = ref.primaryAsset.mediaFiles[0].src; inlineNetworkAdLoadMetrics.resolveTime = new Date().getTime() - inlineNetworkAdLoadMetrics.resolveTime; if(ref.primaryAsset.runtime) { inlineNetworkAdLoadMetrics.success = true; inlineNetworkAdLoadMetrics.failReason = -1; } else { inlineNetworkAdLoadMetrics.success = false; inlineNetworkAdLoadMetrics.failReason = 4; } } else { inlineNetworkAdLoadMetrics.success = false; inlineNetworkAdLoadMetrics.failReason = 6; } inlineNetworkAdLoadMetrics.validAdCount = 1; inlineNetworkAdLoadMetrics.adSystem = null; this.networkAdLoadMetrics.children.push(inlineNetworkAdLoadMetrics); this.mergeTracking(ref); if(ref.primaryAsset != null && ref.primaryAsset.runtime) { this.refs.push(ref); } this.adIndex ++; this.parseNextAd(); break; } } } else { this.networkAdLoadMetrics.resolveTime = new Date().getTime() - this.networkAdLoadMetrics.resolveTime; this.delegate.onVastParserDone(this.refs, errorData); if(this.networkAdLoadMetrics.isRoot) { var t = this.createNetworkAdLoadMetrics(this.networkAdLoadMetrics); this.delegate.publish(aud.events.network_load_complete, this, t); } } }; aud.html5.VastParser.prototype.mergeTracking = function(ref) { if (this.parentWrapperRef != null && this.parentWrapperRef.primaryAsset != null && this.parentWrapperRef.primaryAsset.trackings != null && ref != null && ref.primaryAsset != null) { if (ref.primaryAsset.trackings == null){ ref.primaryAsset.trackings = {}; } for (var key in this.parentWrapperRef.primaryAsset.trackings) { if (ref.primaryAsset.trackings[key] == null) { ref.primaryAsset.trackings[key] = []; } ref.primaryAsset.trackings[key] = ref.primaryAsset.trackings[key].concat(this.parentWrapperRef.primaryAsset.trackings[key]); } //-- merge VideoClick Trackings if (this.parentWrapperRef.primaryAsset.clicks && this.parentWrapperRef.primaryAsset.clicks.length > 0) { //fred if (!ref.primaryAsset.clicks || ref.primaryAsset.clicks.length == 0 ) { ref.primaryAsset.clicks = []; ref.primaryAsset.clicks.push({}); } var firstClick = ref.primaryAsset.clicks[0]; if (!firstClick.hasOwnProperty('trackings')) { firstClick.trackings = []; } for (var clickIndex=0; clickIndex < this.parentWrapperRef.primaryAsset.clicks.length; clickIndex++) { firstClick.trackings = firstClick.trackings.concat( this.parentWrapperRef.primaryAsset.clicks[clickIndex].trackings ); } } //-- get wrapper companions click trackings. var companionClickSubmissions = []; if (this.parentWrapperRef.companions.length > 0 && this.parentWrapperRef.companions[0].clicks != null ) { for (var wClick in this.parentWrapperRef.companions[0].clicks) { for (var wSubmission in this.parentWrapperRef.companions[0].clicks[wClick].submissions) { companionClickSubmissions.push(this.parentWrapperRef.companions[0].clicks[wClick].submissions[wSubmission]); } } } //-- add wrappe submission to all companions clicks. for (var companion in ref.companions ) { for (var click in ref.companions[companion].clicks) { if (ref.companions[companion].clicks[click].submissions == null) {ref.companions[companion].clicks[click].submissions = [];} ref.companions[companion].clicks[click].submissions = ref.companions[companion].clicks[click].submissions.concat(companionClickSubmissions); } } } }; aud.html5.VastParser.prototype.onVastParserDone = function(vastRefs, errorData) { aud.util.remove(aud.events.vastXmlLoaded); this.refs = this.refs.concat(vastRefs); this.adIndex ++; this.parseNextAd(errorData); } aud.html5.VastParser.prototype.parseCreatives = function(vastInLineNode, creativeNetworkAdLoadMetrics) { var ref = {companions:[]}; //--- get all Impression to be added to primary asset trackings var impressions = []; var vastImpressionNodes = vastInLineNode.getElementsByTagName("Impression"); for (var impressionIndex = 0; impressionIndex < vastImpressionNodes.length; impressionIndex++) { impressions.push({action:aud.util.getNodeValue(vastImpressionNodes[impressionIndex]), actuate:'creativeView', method:'get'}); } //--- parse creative to asset var creativeNodes = vastInLineNode.getElementsByTagName("Creatives")[0].childNodes; for (var creativeIndex = 0; creativeIndex < creativeNodes.length; creativeIndex++) { if (creativeNodes[creativeIndex].nodeType == 1) { for (var childIndex = 0; childIndex < creativeNodes[creativeIndex].childNodes.length; childIndex ++) { switch (creativeNodes[creativeIndex].childNodes[childIndex].tagName) { case "Linear": if (creativeNetworkAdLoadMetrics != null) { creativeNetworkAdLoadMetrics.type = "linear"; } ref.primaryAsset = this.parseLinearAd(creativeNodes[creativeIndex].childNodes[childIndex], creativeIndex); for (var impIndex = 0; impIndex < impressions.length; impIndex++) { var actuate = impressions[impIndex].actuate; if (ref.primaryAsset.trackings[actuate] == null){ ref.primaryAsset.trackings[actuate] = []; } ref.primaryAsset.trackings[actuate].push(impressions[impIndex]) } break; case "NonLinearAds": if (creativeNetworkAdLoadMetrics != null) { creativeNetworkAdLoadMetrics.type = "nonlinear"; } break; case "CompanionAds": var CompanionAdsNode = creativeNodes[creativeIndex].getElementsByTagName("Companion"); for (var companionIndex = 0; companionIndex < CompanionAdsNode.length; companionIndex++) { var id = creativeIndex + "-" + companionIndex; ref.companions.push(this.parseCompanionAd(CompanionAdsNode[companionIndex], id)); } break; } } } } return ref; } aud.html5.VastParser.prototype.parseCompanionAd = function(CompanionNode, nodeId) { var asset = {behavior:{format:'onpage'}, contentType:'companion', id:nodeId, trackings:{}, mediaFiles:[], clicks:[]}; var width = CompanionNode.attributes.getNamedItem('width') ? CompanionNode.attributes.getNamedItem('width').nodeValue : 0; var height = CompanionNode.attributes.getNamedItem('height') ? CompanionNode.attributes.getNamedItem('height').nodeValue : 0; //--- parse CompanionClickTracking var clickSubmissions = []; var companionClickTrackings = CompanionNode.getElementsByTagName("CompanionClickTracking"); for (var clickTrackingIndex = 0; clickTrackingIndex < companionClickTrackings.length; clickTrackingIndex ++) { clickSubmissions.push({action:aud.util.getNodeValue(companionClickTrackings[clickTrackingIndex]), method:'get'}); } var companionClickThrough = CompanionNode.getElementsByTagName('CompanionClickThrough')[0]; if (companionClickThrough) { asset.clicks.push({ href:aud.util.getNodeValue(companionClickThrough), submissions:clickSubmissions, title:""}); }else{ asset.clicks.push({ href:"", submissions:clickSubmissions, title:""}); } //--get media for (var childIndex = 0; childIndex < CompanionNode.childNodes.length; childIndex ++) { switch(CompanionNode.childNodes[childIndex].tagName) { case "StaticResource": var creativeType = null; var cNode = CompanionNode.childNodes[childIndex].attributes.getNamedItem('creativeType'); if (cNode){ creativeType = CompanionNode.childNodes[childIndex].attributes.getNamedItem('creativeType').nodeValue; } if ( creativeType != null && creativeType.toLowerCase().indexOf('image') >= 0) { asset.mediaFiles.push({width:width, height:height, type:CompanionNode.childNodes[childIndex].attributes.getNamedItem('creativeType').nodeValue, src:aud.util.getNodeValue(CompanionNode.childNodes[childIndex]) }) } break; case "IFrameResource": asset.mediaFiles.push({width:width, height:height, type:'iframe', src:aud.util.getNodeValue(CompanionNode.childNodes[childIndex]) }) break; case "HTMLResource": asset.mediaFiles.push({width:width, height:height, type:'text/html', src:aud.util.getNodeValue(CompanionNode.childNodes[childIndex]) }) break; } } return asset; } aud.html5.VastParser.prototype.parseLinearAd = function(linearNode, nodeId) { var asset = { behavior:{format:'video'}, contentType:'linear', id:nodeId, trackings:{}, clicks:[], submissions:{} }; if (linearNode.getElementsByTagName("Duration").length > 0 && linearNode.getElementsByTagName("Duration")[0].firstChild != null){ asset.runtime = this.getSeconds(linearNode.getElementsByTagName("Duration")[0].firstChild.nodeValue); } var videoClicks = linearNode.getElementsByTagName("VideoClicks"); if (videoClicks.length > 0) { asset.clicks.push(this.parseVideoClicks(linearNode.getElementsByTagName("VideoClicks")[0]) ); } var trackingEvents = linearNode.getElementsByTagName("TrackingEvents"); if (trackingEvents.length > 0) { var trackings = this.parseTracking(trackingEvents[0].getElementsByTagName("Tracking")); for (var key in trackings) { if (asset.trackings[key] == null) { asset.trackings[key] = [] } asset.trackings[key] = asset.trackings[key].concat(trackings[key]); } } var mediaFiles = linearNode.getElementsByTagName("MediaFiles"); if (mediaFiles.length > 0){ asset.mediaFiles = this.parseMediaFiles(mediaFiles[0]); } return asset; } aud.html5.VastParser.prototype.parseTracking = function(trackingNodes) { var trackings = []; for (var trackingIndex = 0; trackingIndex < trackingNodes.length; trackingIndex++) { var type; switch( trackingNodes[trackingIndex].attributes.getNamedItem('event').nodeValue.toLowerCase() ) { case "start": type = "0%"; break; case "firstquartile": type = "25%"; break; case "midpoint": type = "50%"; break; case "thirdquartile": type = "75%"; break; case "complete": type = "100%"; break; case "creativeview": type = "creativeView"; break; default: type = trackingNodes[trackingIndex].attributes.getNamedItem('event').nodeValue.toLowerCase(); break; } if (type) { if (trackings[type] == null) { trackings[type] = [] } trackings[type].push({action: aud.util.getNodeValue(trackingNodes[trackingIndex]), actuate:type, method:'get'}); } } return trackings; } aud.html5.VastParser.prototype.parseMediaFiles = function(MediaFilesNode) { var mediaFiles = []; var mediaNodes = MediaFilesNode.getElementsByTagName("MediaFile"); for (var mediaIndex = 0; mediaIndex < mediaNodes.length; mediaIndex++) { var media = {}; for (var attIndex= 0; attIndex < mediaNodes[mediaIndex].attributes.length; attIndex++) { media[mediaNodes[mediaIndex].attributes[attIndex].name] = mediaNodes[mediaIndex].attributes[attIndex].nodeValue; } media.src = aud.util.getNodeValue(mediaNodes[mediaIndex]); mediaFiles.push(media); } return mediaFiles; } aud.html5.VastParser.prototype.parseVideoClicks = function(clickNodes) { click = {}; var clickThrough = clickNodes.getElementsByTagName("ClickThrough"); if (clickThrough.length > 0) { click.href = aud.util.getNodeValue(clickThrough[0]); } click.trackings = []; var ClickTrackings = clickNodes.getElementsByTagName("ClickTracking"); for (var clickTrackingIndex = 0; clickTrackingIndex < ClickTrackings.length; clickTrackingIndex++) { //var id = ClickTrackings[clickTrackingIndex].attributes.getNamedItem('id').nodeValue; var action = aud.util.getNodeValue(ClickTrackings[clickTrackingIndex]); click.trackings.push({id:clickTrackingIndex, action:action, method:'get'}); } click.title = ""; return click; } aud.html5.VastParser.prototype.getSeconds= function(str) { var list = str.split(':'); var sec = (parseInt(list[0]) * 3600) + (parseInt(list[1]) * 60) + parseInt(list[2]); return sec; } /****************************************************/ /****************** HTML5 Video *********************/ /****************************************************/ function AUD_Html5VideoPlayer(name, src, opts) { this._playerContainer = null; this._opts = opts || {}; this._src = [src]; this._handlers = this._opts.handlers || {}; this._customHandlers = {}; this._elem = typeof (name) == 'object' ? name : document.getElementById(name); this._video = (this._elem.tagName.toLowerCase() == 'video') ? this._elem : null; this._reusingExternalVideoObject = this._video ? true : false; //aud.util.consoleLog("reusing: " + this._reusingExternalVideoObject); if (src) { // create the video player if it doesn't exist already. this._createVideoPlayer(this._opts); //*** to caht bad media .. safarie does not dispatch and error but will dispatch a emptied and/or stalled /*this._video.addEventListener("emptied", onVideoError, false); this._video.addEventListener("error", onVideoError, false); this._video.addEventListener("stalled", onVideoError, false);*/ this._addHandlers(); this._setSrc(); } } AUD_Html5VideoPlayer.create = function(name, src, opts) { var player = new AUD_Html5VideoPlayer(name, src, opts); //aud.util.consoleLog("calling load and play"); player.load(); player.play(); return player; } aud.util.extend(AUD_Html5VideoPlayer.prototype, { opts : function(opts) { var k; for (k in opts) { this._opts[k] = opts[k]; } return this; }, src : function(src) { this._src = [src]; return this; }, play : function() { this.trigger('play'); return this; }, load : function() { this.trigger('load'); return this; }, trigger : function(method) { aud.util.trigger(this._video, method); return this; }, _createVideoPlayer : function(opts) { if (!this._video) { var players = this._elem.getElementsByTagName('video'); if (players && players.length) { this._video = players[0]; this._reusingExternalVideoObject = true; var divs = this._elem.getElementsByTagName('div'); for (var divIndex = 0; divIndex < divs.length; divIndex++ ) { if (divs[divIndex].getAttribute('id') == "_auditudePlayerContainer_") { this._playerContainer = divs[divIndex]; break; } } } else { var playerDiv = document.createElement('div'); playerDiv.setAttribute('id', '_auditudePlayerContainer_'); var player = document.createElement('video'); // set dimensions on the video object if (opts.style.width && opts.style.height) { aud.util.extend(player, { width : opts.style.width, height : opts.style.height }); } else { aud.util.extend(player, { width : '100%', height : '100%' }); } var style = playerDiv.style; style.width = '100%'; style.height = '100%'; playerDiv.appendChild(player); this._elem.appendChild(playerDiv); this._video = player; this._playerContainer = playerDiv; // show the parent element. this._elem.style.display = 'block'; } } }, _setSrc : function() { var vid = this._video; vid.controls = this._opts.controls; // remove existing 'src' attribute and 'source' child nodes vid.removeAttribute('src'); var sources = vid.getElementsByTagName('source'); if (sources) { var i; for (i = 0; i < sources.length; i++) { vid.removeChild(sources[i]); } } //aud.util.consoleLog("setting source on the video: " + this._src[0]); vid.src = this._src[0]; }, _addHandlers : function() { var handlers = this._handlers, vid = this._video; if (handlers) { var k; for (k in handlers) { this._handlers[k] = (function(context, fn) { return function(e) { fn.apply(context, [e]); return false; } })(vid, handlers[k]); } } handlers = this._handlers; if (handlers) { for (k in handlers) { aud.util.addEvent(vid, k, handlers[k]); } } //add custom handlers handlers = this._opts.customHandlers; if (handlers) { for (k in handlers) { this._customHandlers[k] = (function(context, v, fn, type) { return function(){ fn(type, context, v); return false; } })(this, vid, handlers[k], k); } } handlers = this._customHandlers; if (handlers) { for (k in handlers) { aud.util.addEvent(vid, k, handlers[k]); } } }, destroy : function() { var vid = this._video; // show the video element. if (!this._reusingExternalVideoObject) { vid.style.display = 'none'; } //remove handlers var handlers = this._handlers; var k; if (handlers) { for (k in handlers) { aud.util.removeEvent(vid, k, handlers[k]); } } //remove custom handlers handlers = this._customHandlers; if (handlers) { for (k in handlers) { aud.util.removeEvent(vid, k, handlers[k]); } } if (this._playerContainer) { this._elem.removeChild(this._playerContainer); this._video = null; // hide the parent element. this._elem.style.display = 'none'; } } }); /****************************************************/ /*************** UTILITY FUNCTIONS ******************/ /****************************************************/ if (typeof(DOMParser) == 'undefined') { //IE compat DOMParser = function() {} DOMParser.prototype.parseFromString = function(str, contentType) { if (typeof(ActiveXObject) != 'undefined') { var xmldata = new ActiveXObject('MSXML.DomDocument'); xmldata.async = false; xmldata.loadXML(str); return xmldata; } else if (typeof(XMLHttpRequest) != 'undefined') { xmldata = new XMLHttpRequest; if (!contentType) { contentType = 'application/xml'; } xmldata.open('GET', 'data:' + contentType + ';charset=utf-8,' + encodeURIComponent(str), false); if (xmldata.overrideMimeType) { xmldata.overrideMimeType(contentType); } xmldata.send(null); return xmldata.responseXML; } }; } /** * MD5 (Message-Digest Algorithm) * http://www.webtoolkit.info/ **/ aud.util.MD5 = function(string) { function RotateLeft(lValue, iShiftBits) { return (lValue<>>(32-iShiftBits)); } function AddUnsigned(lX,lY) { var lX4,lY4,lX8,lY8,lResult; lX8 = (lX & 0x80000000); lY8 = (lY & 0x80000000); lX4 = (lX & 0x40000000); lY4 = (lY & 0x40000000); lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF); if (lX4 & lY4) { return (lResult ^ 0x80000000 ^ lX8 ^ lY8); } if (lX4 | lY4) { if (lResult & 0x40000000) { return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); } else { return (lResult ^ 0x40000000 ^ lX8 ^ lY8); } } else { return (lResult ^ lX8 ^ lY8); } } function F(x,y,z) { return (x & y) | ((~x) & z); } function G(x,y,z) { return (x & z) | (y & (~z)); } function H(x,y,z) { return (x ^ y ^ z); } function I(x,y,z) { return (y ^ (x | (~z))); } function FF(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); } function GG(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); } function HH(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); } function II(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); } function ConvertToWordArray(string) { var lWordCount; var lMessageLength = string.length; var lNumberOfWords_temp1=lMessageLength + 8; var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64; var lNumberOfWords = (lNumberOfWords_temp2+1)*16; var lWordArray=Array(lNumberOfWords-1); var lBytePosition = 0; var lByteCount = 0; while ( lByteCount < lMessageLength ) { lWordCount = (lByteCount-(lByteCount % 4))/4; lBytePosition = (lByteCount % 4)*8; lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<>>29; return lWordArray; } function WordToHex(lValue) { var WordToHexValue="",WordToHexValue_temp="",lByte,lCount; for (lCount = 0;lCount<=3;lCount++) { lByte = (lValue>>>(lCount*8)) & 255; WordToHexValue_temp = "0" + lByte.toString(16); WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2); } return WordToHexValue; } function Utf8Encode(string) { string = string.replace(/\r\n/g,"\n"); var utftext = ""; var n; for (n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; } var x=Array(); var k,AA,BB,CC,DD,a,b,c,d; var S11=7, S12=12, S13=17, S14=22; var S21=5, S22=9 , S23=14, S24=20; var S31=4, S32=11, S33=16, S34=23; var S41=6, S42=10, S43=15, S44=21; string = Utf8Encode(string); x = ConvertToWordArray(string); a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476; for (k=0;k