1var _l10iq = _l10iq || []; 2 3// load YouTube javascript API 4var tag = document.createElement('script'); 5tag.src = "https://www.youtube.com/iframe_api"; 6var firstScriptTag = document.getElementsByTagName('script')[0]; 7firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 8 9function L10iYouTube(_ioq) { 10 var ioq = _ioq; 11 var io = _ioq.io; 12 this.playerState = {}; 13 this.players = {}; 14 this.playerEvents = {}; 15 this.playerObjSettings = {}; 16 this.domReady = false; 17 this.apiReady = false; 18 this.ready = false; 19 20 this.init = function init() { 21 22 this.domReady = true; 23 if (!this.ready && this.apiReady) { 24 this.trackYouTube(); 25 this.ready = true; 26 } 27 }; 28 29 this.apiInit = function () { 30 this.apiReady = true; 31 if (!this.ready && this.domReady) { 32 this.trackYouTube(); 33 this.ready = true; 34 } 35 }; 36 37 this.trackPlayer = function (player, videoId, objSettings) { 38 player.addEventListener('onReady', function (event) { io('youtube:onPlayerReady', event); }); 39 player.addEventListener('onStateChange', function (event) { io('youtube:onPlayerStateChange', event); }); 40 this.players[videoId] = player; 41 this.playerState[videoId] = { 42 state: -1, 43 paused: true 44 }; 45 this.playerEvents[videoId] = { 46 play: 0, 47 consumed: 0 48 }; 49 this.playerObjSettings[videoId] = objSettings || {}; 50 }; 51 52 this.trackYouTube = function () { 53 //ioq.log('YouTube:trackYouTube()');// 54 jQuery('iframe').each(function() { 55 var video = jQuery(this); 56 if(video.attr('src') !== undefined){ 57 var vidSrc = video.attr('src'); 58 var regex = /h?t?t?p?s?\:?\/\/www\.youtube\.com\/embed\/([\w-]{11})(?:\?.*)?/; 59 var matches = vidSrc.match(regex); 60 if(matches && matches.length > 1){ 61 // add a anchor link to support report links 62 video.before('<a name="video-' + matches[1] + '"></a>'); 63//console.log(ioq.getObjSettings(video)); 64 video.attr('id', matches[1]); 65 var width = video.width(); 66 var height = video.height(); 67 jQuery('iframe#' + matches[1]).replaceWith('<div id="' + matches[1] + '"></div>'); 68 69 var player = new YT.Player(matches[1], { 70 videoId: matches[1], 71 height: height, 72 width: width 73 /* 74 events: { 75 'onReady': this.onPlayerReady, 76 'onStateChange': this.onPlayerStateChange 77 } 78 */ 79 }); 80 81 io('youtube:trackPlayer', player, matches[1], ioq.getObjSettings(video)); 82 83 if (ioq.location.params['io-admin'] && ioq.hasPlugin('admin')) { 84 $target = jQuery('iframe#' + matches[1]); 85 io('admin:setBindTarget', $target); 86 } 87 88 //ths.trackPlayer(player, matches[1]); 89 } 90 } 91 }); 92 }; 93 94 this.onPlayerReady = function (event) { 95 96 }; 97 98 this.onPlayerStateChange = function (event) { 99//console.log('onPlayerStateChange'); 100//console.log(event); 101 // check if YouTube API event data struc is correct 102 if (event.target == undefined) { 103 return; 104 } 105 var videoData = {}; 106 // getVideoData was the method for getting data. But stopped working on 11/9/17 107 if (event.target.getVideoData) { 108 videoData = event.target.getVideoData(); 109 } 110 // on 11/9/17 data was available on .j element. Not sure if this is permanent 111 else if (event.target.j && event.target.j.videoData) { 112 videoData = event.target.j.videoData; 113 } 114//console.log(videoData); 115 116 if (!videoData.video_id) { 117 return; 118 } 119 120 var id = videoData.video_id; 121 //var title = (videoData.author) ? videoData.author : '(not set)'; 122 //title += ': ' + ((videoData.title) ? videoData.title : '(not set)'); 123 var title = ((videoData.title) ? videoData.title : '(not set)'); 124 125 var player = this.players[id]; 126 var playerEvents = this.playerEvents[id]; 127 //var objSettings = this.playerObjSettings[id]; 128 var ga_event = { 129 eventCategory: "Video event", 130 eventAction: "YouTube: " + title, 131 //'eventLabel': "::youtube:" + id, 132 eventLabel: ":youtube:" + id, 133 eventValue: 0, 134 nonInteraction: false, 135 objSettings: this.playerObjSettings[id]|| {} 136 }; 137 ga_event.oa = { 138 rs: 'youtube', 139 rc: 'video', 140 rk: id, 141 domi: id 142 }; 143//console.log(ga_event); 144 var $target_obj = jQuery(event.target); 145 var duration = player.getDuration(); 146 var playTime = player.getCurrentTime(); 147 var positionPer = Math.round(100 * playTime / duration); 148 if (event.data == YT.PlayerState.PLAYING){ 149 ga_event.eventCategory = 'Video play'; 150 ga_event.eventValue = 0; 151 // only value play on first occurance for video 152 if (!playerEvents.play) { 153 ga_event.eventCategory += '!' 154 ga_event.eventValue = io('get', 'c.scorings.events.youtube_video_play', 0); 155 } 156 ga_event.eid = 'videoPlay'; 157 158 event.type = 'play'; 159 ioq.defEventHandler(ga_event, $target_obj, event); 160 //io('event', ga_event); 161 162 this.playerEvents[id].play++; 163 this.playerState[id].paused = false;
164 } 165 else if (event.data == YT.PlayerState.ENDED && !this.playerState[id].paused) { 166 ga_event.eventCategory = 'Video scroll'; 167 ga_event.eventValue = 100; 168 ga_event.eid = 'videoScroll'; 169 170 var ga_event3 = {}; 171 172 // only fire consumed event once per video 173 if (!playerEvents.consumed) { 174 ga_event3 = jQuery.extend({}, ga_event); 175 ga_event3.eventCategory = 'Video consumed!'; 176 ga_event3.eventValue = ioq.get('c.scorings.events.youtube_video_consumed', 0); 177 ga_event3.eid = 'videoConsumed'; 178 } 179 180 ga_event.metric8 = 1; 181 ga_event.metric9 = Math.round(duration); 182 ga_event.metric10 = Math.round(duration); 183 ga_event.metric11 = 100; 184 ga_event.metric12 = 0; 185 186 event.type = 'scroll'; 187 ioq.defEventHandler(ga_event, $target_obj, event); 188 //io('event', ga_event); 189 if (ga_event3.eid) { 190 event.type = 'consumed'; 191 ioq.defEventHandler(ga_event3, $target_obj, event); 192 //io('event', ga_event3); 193 this.playerEvents[id].consumed++; 194 } 195 } 196 else if (event.data == YT.PlayerState.PAUSED && !this.playerState[id].paused){ 197 ga_event.eventCategory = 'Video stop'; 198 ga_event.eid = 'videoStop'; 199 200 // copy object for Video watched 201 var ga_event2 = jQuery.extend({}, ga_event); 202 ga_event2.eventCategory = 'Video scroll'; 203 ga_event2.eventValue = positionPer; 204 205 var ga_event3 = {}; 206 207 // only fire consumed event once per video and only if over 90% watched 208 if (!playerEvents.consumed && positionPer >= 90) { 209 ga_event3 = jQuery.extend({}, ga_event); 210 ga_event3.eventCategory = 'Video consumed!'; 211 ga_event3.eventValue = ioq.get('c.scorings.events.youtube_video_consumed', 0); 212 ga_event3.eid = 'videoConsumed'; 213 } 214 215 ga_event2.eid = 'videoScroll'; 216 ga_event2.metric8 = 1; 217 ga_event2.metric9 = Math.round(positionPer); 218 ga_event2.metric10 = Math.round(duration); 219 ga_event2.metric11 = Math.round(positionPer); 220 ga_event2.metric12 = 0; 221 222 223 event.type = 'stop'; 224 ioq.defEventHandler(ga_event, $target_obj, event); 225 event.type = 'scroll'; 226 ioq.defEventHandler(ga_event2, $target_obj, event); 227 //io('event', ga_event); 228 //io('event', ga_event2); 229 if (ga_event3.eid) { 230 //io('event', ga_event3); 231 event.type = 'consumed'; 232 ioq.defEventHandler(ga_event3, $target_obj, event); 233 this.playerEvents[id].consumed++; 234 } 235 236 this.playerState[id].paused = true; 237 } 238 }; 239 _l10iq.push(['addCallback', 'domReady', this.init, this]); 240} 241 242_l10iq.push(['providePlugin', 'youtube', L10iYouTube, {}]); 243 244// function called by YouTube API when ready 245function onYouTubeIframeAPIReady() { 246 _l10iq.push(['youtube:apiInit']); 247 //this.apiInit(); 248}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.