1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | (function (global, factory) {
|
8 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
9 | typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
10 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.snowplowYouTubeTracking = {}));
|
11 | }(this, (function (exports) { 'use strict';
|
12 |
|
13 | |
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | var __assign = function() {
|
29 | __assign = Object.assign || function __assign(t) {
|
30 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
31 | s = arguments[i];
|
32 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
33 | }
|
34 | return t;
|
35 | };
|
36 | return __assign.apply(this, arguments);
|
37 | };
|
38 |
|
39 | function __spreadArray(to, from, pack) {
|
40 | if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
41 | if (ar || !(i in from)) {
|
42 | if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
43 | ar[i] = from[i];
|
44 | }
|
45 | }
|
46 | return to.concat(ar || from);
|
47 | }
|
48 |
|
49 | var SnowplowEvent;
|
50 | (function (SnowplowEvent) {
|
51 | SnowplowEvent["PERCENTPROGRESS"] = "percentprogress";
|
52 | SnowplowEvent["SEEK"] = "seek";
|
53 | SnowplowEvent["VOLUMECHANGE"] = "volumechange";
|
54 | })(SnowplowEvent || (SnowplowEvent = {}));
|
55 |
|
56 | var YouTubeIFrameAPIURL = 'https://www.youtube.com/iframe_api';
|
57 |
|
58 |
|
59 |
|
60 | var YTPlayerEvent;
|
61 | (function (YTPlayerEvent) {
|
62 | YTPlayerEvent["ONSTATECHANGE"] = "onStateChange";
|
63 | YTPlayerEvent["ONPLAYBACKQUALITYCHANGE"] = "onPlaybackQualityChange";
|
64 | YTPlayerEvent["ONERROR"] = "onError";
|
65 | YTPlayerEvent["ONAPICHANGE"] = "onApiChange";
|
66 | YTPlayerEvent["ONPLAYBACKRATECHANGE"] = "onPlaybackRateChange";
|
67 | YTPlayerEvent["ONREADY"] = "onReady";
|
68 | })(YTPlayerEvent || (YTPlayerEvent = {}));
|
69 | var YTStateEvent = {
|
70 | '-1': 'unstarted',
|
71 | '0': 'ended',
|
72 | '1': 'play',
|
73 | '2': 'pause',
|
74 | '3': 'buffering',
|
75 | '5': 'cued'
|
76 | };
|
77 | var CaptureEventToYouTubeEvent = {
|
78 | ready: YTPlayerEvent.ONREADY,
|
79 | playbackratechange: YTPlayerEvent.ONPLAYBACKRATECHANGE,
|
80 | playbackqualitychange: YTPlayerEvent.ONPLAYBACKQUALITYCHANGE,
|
81 | error: YTPlayerEvent.ONERROR,
|
82 | apichange: YTPlayerEvent.ONAPICHANGE
|
83 | };
|
84 |
|
85 |
|
86 | Object.keys(YTStateEvent).forEach(function (k) { return (CaptureEventToYouTubeEvent[YTStateEvent[k]] = YTPlayerEvent.ONSTATECHANGE); });
|
87 | var YTState;
|
88 | (function (YTState) {
|
89 | YTState["UNSTARTED"] = "unstarted";
|
90 | YTState["ENDED"] = "ended";
|
91 | YTState["PLAYING"] = "play";
|
92 | YTState["PAUSED"] = "pause";
|
93 | YTState["BUFFERING"] = "buffering";
|
94 | YTState["CUED"] = "cued";
|
95 | })(YTState || (YTState = {}));
|
96 | var YTError = {
|
97 | 2: 'INVALID_URL',
|
98 | 5: 'HTML5_ERROR',
|
99 | 100: 'VIDEO_NOT_FOUND',
|
100 | 101: 'MISSING_EMBED_PERMISSION',
|
101 | 150: 'MISSING_EMBED_PERMISSION'
|
102 | };
|
103 |
|
104 | var YTEvent;
|
105 | (function (YTEvent) {
|
106 | YTEvent["STATECHANGE"] = "statechange";
|
107 | YTEvent["PLAYBACKQUALITYCHANGE"] = "playbackqualitychange";
|
108 | YTEvent["ERROR"] = "error";
|
109 | YTEvent["APICHANGE"] = "apichange";
|
110 | YTEvent["PLAYBACKRATECHANGE"] = "playbackratechange";
|
111 | YTEvent["READY"] = "ready";
|
112 | })(YTEvent || (YTEvent = {}));
|
113 | [
|
114 | YTState.BUFFERING,
|
115 | YTState.CUED,
|
116 | YTState.ENDED,
|
117 | YTState.PAUSED,
|
118 | YTState.PLAYING,
|
119 | YTState.UNSTARTED,
|
120 | ];
|
121 |
|
122 | var AllEvents = __spreadArray(__spreadArray(__spreadArray([], Object.keys(YTEvent).map(function (k) { return YTEvent[k]; })), Object.keys(SnowplowEvent).map(function (k) { return SnowplowEvent[k]; })), Object.keys(YTState).map(function (k) { return YTState[k]; }));
|
123 | var DefaultEvents = [
|
124 | YTState.PAUSED,
|
125 | YTState.PLAYING,
|
126 | YTState.ENDED,
|
127 | SnowplowEvent.SEEK,
|
128 | SnowplowEvent.VOLUMECHANGE,
|
129 | YTPlayerEvent.ONPLAYBACKQUALITYCHANGE,
|
130 | YTPlayerEvent.ONPLAYBACKRATECHANGE,
|
131 | SnowplowEvent.PERCENTPROGRESS,
|
132 | ];
|
133 | var EventGroups = {
|
134 | AllEvents: AllEvents,
|
135 | DefaultEvents: DefaultEvents
|
136 | };
|
137 |
|
138 | function trackingOptionsParser(mediaId, conf) {
|
139 | var defaults = {
|
140 | mediaId: mediaId,
|
141 | captureEvents: DefaultEvents,
|
142 | youtubeEvents: [
|
143 | YTPlayerEvent.ONSTATECHANGE,
|
144 | YTPlayerEvent.ONPLAYBACKQUALITYCHANGE,
|
145 | YTPlayerEvent.ONERROR,
|
146 | YTPlayerEvent.ONPLAYBACKRATECHANGE,
|
147 | ],
|
148 | updateRate: 500,
|
149 | progress: {
|
150 | boundaries: [10, 25, 50, 75],
|
151 | boundaryTimeoutIds: []
|
152 | }
|
153 | };
|
154 | if (!conf)
|
155 | return defaults;
|
156 | if (conf.updateRate)
|
157 | defaults.updateRate = conf.updateRate;
|
158 | if (conf.captureEvents) {
|
159 | var parsedEvents = [];
|
160 | var _loop_1 = function (ev) {
|
161 |
|
162 | if (EventGroups.hasOwnProperty(ev)) {
|
163 | parsedEvents = parsedEvents.concat(EventGroups[ev]);
|
164 | }
|
165 | else if (!Object.keys(AllEvents).filter(function (k) { return k === ev; })) {
|
166 | console.warn("'" + ev + "' is not a valid event.");
|
167 | }
|
168 | else {
|
169 | parsedEvents.push(ev);
|
170 | }
|
171 | };
|
172 | for (var _i = 0, _a = conf.captureEvents; _i < _a.length; _i++) {
|
173 | var ev = _a[_i];
|
174 | _loop_1(ev);
|
175 | }
|
176 | conf.captureEvents = parsedEvents;
|
177 | for (var _b = 0, _c = conf.captureEvents; _b < _c.length; _b++) {
|
178 | var ev = _c[_b];
|
179 | var youtubeEvent = CaptureEventToYouTubeEvent[ev];
|
180 | if (CaptureEventToYouTubeEvent.hasOwnProperty(ev) && defaults.youtubeEvents.indexOf(youtubeEvent) === -1) {
|
181 | defaults.youtubeEvents.push(youtubeEvent);
|
182 | }
|
183 | }
|
184 | if (conf.captureEvents.indexOf(SnowplowEvent.PERCENTPROGRESS) !== -1) {
|
185 | defaults.progress = {
|
186 | boundaries: (conf === null || conf === void 0 ? void 0 : conf.boundaries) || defaults.progress.boundaries,
|
187 | boundaryTimeoutIds: []
|
188 | };
|
189 | }
|
190 | }
|
191 | return __assign(__assign({}, defaults), conf);
|
192 | }
|
193 |
|
194 |
|
195 | function addUrlParam(url, key, value) {
|
196 | var urlParams = parseUrlParams(url);
|
197 | urlParams[key] = value;
|
198 | return url + "?" + urlParamsToString(urlParams);
|
199 | }
|
200 | function parseUrlParams(url) {
|
201 | var params = {};
|
202 | var urlParams = url.split('?')[1];
|
203 | if (!urlParams)
|
204 | return params;
|
205 | urlParams.split('&').forEach(function (p) {
|
206 | var param = p.split('=');
|
207 | params[param[0]] = param[1];
|
208 | });
|
209 | return params;
|
210 | }
|
211 | function urlParamsToString(urlParams) {
|
212 |
|
213 | var params = '';
|
214 | Object.keys(urlParams).forEach(function (p) {
|
215 | params += p + "=" + urlParams[p] + "&";
|
216 | });
|
217 | return params.slice(0, -1);
|
218 | }
|
219 |
|
220 | |
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 | function payloadBuilder() {
|
256 | var dict = {}, allJson = [], jsonForProcessing = [];
|
257 | var processor;
|
258 | var add = function (key, value) {
|
259 | if (value != null && value !== '') {
|
260 |
|
261 | dict[key] = value;
|
262 | }
|
263 | };
|
264 | var addDict = function (dict) {
|
265 | for (var key in dict) {
|
266 | if (Object.prototype.hasOwnProperty.call(dict, key)) {
|
267 | add(key, dict[key]);
|
268 | }
|
269 | }
|
270 | };
|
271 | var addJson = function (keyIfEncoded, keyIfNotEncoded, json) {
|
272 | if (json && isNonEmptyJson(json)) {
|
273 | var jsonWithKeys = { keyIfEncoded: keyIfEncoded, keyIfNotEncoded: keyIfNotEncoded, json: json };
|
274 | jsonForProcessing.push(jsonWithKeys);
|
275 | allJson.push(jsonWithKeys);
|
276 | }
|
277 | };
|
278 | return {
|
279 | add: add,
|
280 | addDict: addDict,
|
281 | addJson: addJson,
|
282 | getPayload: function () { return dict; },
|
283 | getJson: function () { return allJson; },
|
284 | withJsonProcessor: function (jsonProcessor) {
|
285 | processor = jsonProcessor;
|
286 | },
|
287 | build: function () {
|
288 | processor === null || processor === void 0 ? void 0 : processor(this, jsonForProcessing);
|
289 | return dict;
|
290 | }
|
291 | };
|
292 | }
|
293 | |
294 |
|
295 |
|
296 |
|
297 | function isNonEmptyJson(property) {
|
298 | if (!isJson(property)) {
|
299 | return false;
|
300 | }
|
301 | for (var key in property) {
|
302 | if (Object.prototype.hasOwnProperty.call(property, key)) {
|
303 | return true;
|
304 | }
|
305 | }
|
306 | return false;
|
307 | }
|
308 | |
309 |
|
310 |
|
311 |
|
312 | function isJson(property) {
|
313 | return (typeof property !== 'undefined' &&
|
314 | property !== null &&
|
315 | (property.constructor === {}.constructor || property.constructor === [].constructor));
|
316 | }
|
317 |
|
318 | |
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 | var label = 'Snowplow: ';
|
348 | var LOG_LEVEL;
|
349 | (function (LOG_LEVEL) {
|
350 | LOG_LEVEL[LOG_LEVEL["none"] = 0] = "none";
|
351 | LOG_LEVEL[LOG_LEVEL["error"] = 1] = "error";
|
352 | LOG_LEVEL[LOG_LEVEL["warn"] = 2] = "warn";
|
353 | LOG_LEVEL[LOG_LEVEL["debug"] = 3] = "debug";
|
354 | LOG_LEVEL[LOG_LEVEL["info"] = 4] = "info";
|
355 | })(LOG_LEVEL || (LOG_LEVEL = {}));
|
356 | var LOG$1 = logger();
|
357 | function logger(logLevel) {
|
358 | if (logLevel === void 0) { logLevel = LOG_LEVEL.warn; }
|
359 | function setLogLevel(level) {
|
360 | if (LOG_LEVEL[level]) {
|
361 | logLevel = level;
|
362 | }
|
363 | else {
|
364 | logLevel = LOG_LEVEL.warn;
|
365 | }
|
366 | }
|
367 | |
368 |
|
369 |
|
370 | function error(message, error) {
|
371 | var extraParams = [];
|
372 | for (var _i = 2; _i < arguments.length; _i++) {
|
373 | extraParams[_i - 2] = arguments[_i];
|
374 | }
|
375 | if (logLevel >= LOG_LEVEL.error && typeof console !== 'undefined') {
|
376 | var logMsg = label + message + '\n';
|
377 | if (error) {
|
378 | console.error.apply(console, __spreadArray([logMsg + '\n', error], extraParams));
|
379 | }
|
380 | else {
|
381 | console.error.apply(console, __spreadArray([logMsg], extraParams));
|
382 | }
|
383 | }
|
384 | }
|
385 | |
386 |
|
387 |
|
388 | function warn(message, error) {
|
389 | var extraParams = [];
|
390 | for (var _i = 2; _i < arguments.length; _i++) {
|
391 | extraParams[_i - 2] = arguments[_i];
|
392 | }
|
393 | if (logLevel >= LOG_LEVEL.warn && typeof console !== 'undefined') {
|
394 | var logMsg = label + message;
|
395 | if (error) {
|
396 | console.warn.apply(console, __spreadArray([logMsg + '\n', error], extraParams));
|
397 | }
|
398 | else {
|
399 | console.warn.apply(console, __spreadArray([logMsg], extraParams));
|
400 | }
|
401 | }
|
402 | }
|
403 | |
404 |
|
405 |
|
406 | function debug(message) {
|
407 | var extraParams = [];
|
408 | for (var _i = 1; _i < arguments.length; _i++) {
|
409 | extraParams[_i - 1] = arguments[_i];
|
410 | }
|
411 | if (logLevel >= LOG_LEVEL.debug && typeof console !== 'undefined') {
|
412 | console.debug.apply(console, __spreadArray([label + message], extraParams));
|
413 | }
|
414 | }
|
415 | |
416 |
|
417 |
|
418 | function info(message) {
|
419 | var extraParams = [];
|
420 | for (var _i = 1; _i < arguments.length; _i++) {
|
421 | extraParams[_i - 1] = arguments[_i];
|
422 | }
|
423 | if (logLevel >= LOG_LEVEL.info && typeof console !== 'undefined') {
|
424 | console.info.apply(console, __spreadArray([label + message], extraParams));
|
425 | }
|
426 | }
|
427 | return { setLogLevel: setLogLevel, warn: warn, error: error, debug: debug, info: info };
|
428 | }
|
429 | |
430 |
|
431 |
|
432 |
|
433 |
|
434 |
|
435 |
|
436 |
|
437 | function buildSelfDescribingEvent(event) {
|
438 | var _a = event.event, schema = _a.schema, data = _a.data, pb = payloadBuilder();
|
439 | var ueJson = {
|
440 | schema: 'iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0',
|
441 | data: { schema: schema, data: data }
|
442 | };
|
443 | pb.add('e', 'ue');
|
444 | pb.addJson('ue_px', 'ue_pr', ueJson);
|
445 | return pb;
|
446 | }
|
447 |
|
448 | |
449 |
|
450 |
|
451 |
|
452 |
|
453 | |
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 | function dispatchToTrackersInCollection(trackers, trackerCollection, fn) {
|
461 | try {
|
462 | getTrackersFromCollection(trackers !== null && trackers !== void 0 ? trackers : Object.keys(trackerCollection), trackerCollection).forEach(fn);
|
463 | }
|
464 | catch (ex) {
|
465 | LOG$1.error('Function failed', ex);
|
466 | }
|
467 | }
|
468 | function getTrackersFromCollection(trackerIds, trackerCollection) {
|
469 | var trackers = [];
|
470 | for (var _i = 0, trackerIds_1 = trackerIds; _i < trackerIds_1.length; _i++) {
|
471 | var id = trackerIds_1[_i];
|
472 | if (trackerCollection.hasOwnProperty(id)) {
|
473 | trackers.push(trackerCollection[id]);
|
474 | }
|
475 | else {
|
476 | LOG$1.warn(id + ' not configured');
|
477 | }
|
478 | }
|
479 | return trackers;
|
480 | }
|
481 |
|
482 | function buildYouTubeEvent(player, eventName, conf, eventData) {
|
483 | var data = { type: eventName };
|
484 | if (conf.hasOwnProperty('label'))
|
485 | data.label = conf.label;
|
486 | var context = [
|
487 | getYouTubeEntities(player, conf.urlParameters, eventData),
|
488 | getMediaPlayerEntities(eventName, player, conf.urlParameters, eventData),
|
489 | ];
|
490 | return {
|
491 | schema: 'iglu:com.snowplowanalytics.snowplow/media_player_event/jsonschema/1-0-0',
|
492 | data: data,
|
493 | context: context
|
494 | };
|
495 | }
|
496 | function getYouTubeEntities(player, urlParameters, eventData) {
|
497 | var spherical = player.getSphericalProperties();
|
498 | var playerStates = {
|
499 | buffering: false,
|
500 | cued: false,
|
501 | unstarted: false
|
502 | };
|
503 | var state = player.getPlayerState();
|
504 | if (playerStates.hasOwnProperty(YTStateEvent[state])) {
|
505 | playerStates[YTStateEvent[state]] = true;
|
506 | }
|
507 | var data = {
|
508 | autoPlay: urlParameters.autoplay === '1',
|
509 | avaliablePlaybackRates: player.getAvailablePlaybackRates(),
|
510 | buffering: playerStates.buffering,
|
511 | controls: urlParameters.controls !== '0',
|
512 | cued: playerStates.cued,
|
513 | loaded: parseInt(String(player.getVideoLoadedFraction() * 100)),
|
514 | playbackQuality: player.getPlaybackQuality(),
|
515 | playerId: player.getIframe().id,
|
516 | unstarted: playerStates.unstarted,
|
517 | url: player.getVideoUrl()
|
518 | };
|
519 | if (spherical)
|
520 | data = __assign(__assign({}, data), spherical);
|
521 | if (eventData === null || eventData === void 0 ? void 0 : eventData.error)
|
522 | data.error = eventData.error;
|
523 | var playlistIndex = player.getPlaylistIndex();
|
524 | if (playlistIndex !== -1)
|
525 | data.playlistIndex = playlistIndex;
|
526 | var playlist = player.getPlaylist();
|
527 | if (playlist) {
|
528 | data.playlist = playlist.map(function (item) { return parseInt(item); });
|
529 | }
|
530 | var qualityLevels = player.getAvailableQualityLevels();
|
531 | if (qualityLevels)
|
532 | data.avaliableQualityLevels = qualityLevels;
|
533 | return {
|
534 | schema: 'iglu:com.youtube/youtube/jsonschema/1-0-0',
|
535 | data: data
|
536 | };
|
537 | }
|
538 | function getMediaPlayerEntities(e, player, urlParameters, eventData) {
|
539 | var playerStates = {
|
540 | ended: false,
|
541 | paused: false
|
542 | };
|
543 | var state = player.getPlayerState();
|
544 | if (playerStates.hasOwnProperty(YTStateEvent[state])) {
|
545 | playerStates[YTStateEvent[state]] = true;
|
546 | }
|
547 | var data = {
|
548 | currentTime: player.getCurrentTime(),
|
549 | duration: player.getDuration(),
|
550 | ended: playerStates.ended,
|
551 | loop: urlParameters.loop === '1',
|
552 | muted: player.isMuted(),
|
553 | paused: playerStates.paused,
|
554 | playbackRate: player.getPlaybackRate(),
|
555 | volume: player.getVolume()
|
556 | };
|
557 | if (e === SnowplowEvent.PERCENTPROGRESS) {
|
558 | data.percentProgress = eventData.percentThrough;
|
559 | }
|
560 | return {
|
561 | schema: 'iglu:com.snowplowanalytics.snowplow/media_player/jsonschema/1-0-0',
|
562 | data: data
|
563 | };
|
564 | }
|
565 |
|
566 | var _trackers = {};
|
567 | var trackedPlayers = {};
|
568 | var trackingQueue = [];
|
569 | var LOG;
|
570 | function YouTubeTrackingPlugin() {
|
571 | return {
|
572 | activateBrowserPlugin: function (tracker) {
|
573 | _trackers[tracker.id] = tracker;
|
574 | },
|
575 | logger: function (logger) {
|
576 | LOG = logger;
|
577 | }
|
578 | };
|
579 | }
|
580 | function trackEvent(event, trackers) {
|
581 | if (trackers === void 0) { trackers = Object.keys(_trackers); }
|
582 | dispatchToTrackersInCollection(trackers, _trackers, function (t) {
|
583 | t.core.track(buildSelfDescribingEvent({ event: event }), event.context, event.timestamp);
|
584 | });
|
585 | }
|
586 | function enableYouTubeTracking(args) {
|
587 | var conf = trackingOptionsParser(args.id, args.options);
|
588 | var el = document.getElementById(args.id);
|
589 | if (!el) {
|
590 | LOG.error('Cannot find YouTube iframe');
|
591 | return;
|
592 | }
|
593 |
|
594 | if (el.src.indexOf('enablejsapi') === -1) {
|
595 | el.src = addUrlParam(el.src, 'enablejsapi', '1');
|
596 | }
|
597 | conf.urlParameters = parseUrlParams(el.src);
|
598 |
|
599 | if (typeof YT !== 'undefined' && typeof YT.Player !== 'undefined') {
|
600 | addListeners(conf);
|
601 | }
|
602 | else {
|
603 |
|
604 |
|
605 | trackingQueue.push(conf);
|
606 | handleYouTubeIframeAPI();
|
607 | }
|
608 | }
|
609 | var iframeAPIRetryWait = 100;
|
610 | function handleYouTubeIframeAPI() {
|
611 |
|
612 | var scriptTags = Array.prototype.slice.call(document.getElementsByTagName('script'));
|
613 | if (!scriptTags.some(function (s) { return s.src === YouTubeIFrameAPIURL; })) {
|
614 |
|
615 |
|
616 | var tag = document.createElement('script');
|
617 | tag.src = YouTubeIFrameAPIURL;
|
618 | var firstScriptTag = document.getElementsByTagName('script')[0];
|
619 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
620 | }
|
621 |
|
622 |
|
623 |
|
624 | if (typeof YT === 'undefined' || typeof YT.Player === 'undefined') {
|
625 | if (iframeAPIRetryWait <= 6400) {
|
626 | setTimeout(handleYouTubeIframeAPI, iframeAPIRetryWait);
|
627 | iframeAPIRetryWait *= 2;
|
628 | }
|
629 | else {
|
630 | LOG.error('YouTube iframe API failed to load.');
|
631 | }
|
632 | }
|
633 | else {
|
634 |
|
635 | while (trackingQueue.length) {
|
636 | addListeners(trackingQueue.pop());
|
637 | }
|
638 | }
|
639 | }
|
640 | function addListeners(conf) {
|
641 | var _a;
|
642 | var builtInEvents = (_a = {},
|
643 | _a[YTPlayerEvent.ONREADY] = function () { return youtubeEvent(trackedPlayers[conf.mediaId].player, YTEvent.READY, conf); },
|
644 | _a[YTPlayerEvent.ONSTATECHANGE] = function (e) {
|
645 | if (conf.captureEvents.indexOf(YTStateEvent[e.data.toString()]) !== -1) {
|
646 | youtubeEvent(trackedPlayers[conf.mediaId].player, YTStateEvent[e.data], conf);
|
647 | }
|
648 | },
|
649 | _a[YTPlayerEvent.ONPLAYBACKQUALITYCHANGE] = function () {
|
650 | return youtubeEvent(trackedPlayers[conf.mediaId].player, YTEvent.PLAYBACKQUALITYCHANGE, conf);
|
651 | },
|
652 | _a[YTPlayerEvent.ONAPICHANGE] = function () { return youtubeEvent(trackedPlayers[conf.mediaId].player, YTEvent.APICHANGE, conf); },
|
653 | _a[YTPlayerEvent.ONERROR] = function (e) {
|
654 | return youtubeEvent(trackedPlayers[conf.mediaId].player, YTEvent.ERROR, conf, { error: YTError[e.data] });
|
655 | },
|
656 | _a[YTPlayerEvent.ONPLAYBACKRATECHANGE] = function () {
|
657 | return youtubeEvent(trackedPlayers[conf.mediaId].player, YTEvent.PLAYBACKRATECHANGE, conf);
|
658 | },
|
659 | _a);
|
660 | var playerEvents = {};
|
661 | conf.youtubeEvents.forEach(function (e) {
|
662 | playerEvents[e] = builtInEvents[e];
|
663 | });
|
664 | trackedPlayers[conf.mediaId] = {
|
665 | player: new YT.Player(conf.mediaId, { events: __assign({}, playerEvents) }),
|
666 | conf: conf,
|
667 | seekTracking: {
|
668 | prevTime: 0,
|
669 | enabled: false
|
670 | },
|
671 | volumeTracking: {
|
672 | prevVolume: 0,
|
673 | enabled: false
|
674 | }
|
675 | };
|
676 | }
|
677 | function youtubeEvent(player, eventName, conf, eventData) {
|
678 | var playerInstance = trackedPlayers[conf.mediaId];
|
679 | if (!playerInstance.seekTracking.enabled && conf.captureEvents.indexOf('seek') !== 1) {
|
680 | enableSeekTracking(player, conf, eventData);
|
681 | }
|
682 | if (!playerInstance.volumeTracking.enabled && conf.captureEvents.indexOf('volume') !== 1) {
|
683 | enableVolumeTracking(player, conf, eventData);
|
684 | }
|
685 | if (conf.hasOwnProperty('boundaries')) {
|
686 | progressHandler(player, eventName, conf);
|
687 | }
|
688 | var event = buildYouTubeEvent(player, eventName, conf, eventData);
|
689 | trackEvent(event);
|
690 | }
|
691 |
|
692 | function progressHandler(player, eventName, conf) {
|
693 | var timeoutIds = conf.progress.boundaryTimeoutIds;
|
694 | if (eventName === YTState.PAUSED) {
|
695 | timeoutIds.forEach(function (id) { return clearTimeout(id); });
|
696 | timeoutIds.length = 0;
|
697 | }
|
698 | if (eventName === YTState.PLAYING) {
|
699 | setPercentageBoundTimeouts(player, conf);
|
700 | }
|
701 | }
|
702 | function setPercentageBoundTimeouts(player, conf) {
|
703 | var _a;
|
704 | var currentTime = player.getCurrentTime();
|
705 | (_a = conf.progress) === null || _a === void 0 ? void 0 : _a.boundaries.forEach(function (p) {
|
706 | var _a;
|
707 | var percentTime = player.getDuration() * 1000 * (p / 100);
|
708 | if (currentTime !== 0) {
|
709 | percentTime -= currentTime * 1000;
|
710 | }
|
711 | if (p < percentTime) {
|
712 | (_a = conf.progress) === null || _a === void 0 ? void 0 : _a.boundaryTimeoutIds.push(setTimeout(function () { return waitAnyRemainingTimeAfterTimeout(player, conf, percentTime, p); }, percentTime));
|
713 | }
|
714 | });
|
715 | }
|
716 |
|
717 |
|
718 | function waitAnyRemainingTimeAfterTimeout(player, conf, percentTime, p) {
|
719 | if (player.getCurrentTime() * 1000 < percentTime) {
|
720 | setTimeout(function () { return waitAnyRemainingTimeAfterTimeout(player, conf, percentTime, p); }, 10);
|
721 | }
|
722 | else {
|
723 | youtubeEvent(player, SnowplowEvent.PERCENTPROGRESS, conf, {
|
724 | percentThrough: p
|
725 | });
|
726 | }
|
727 | }
|
728 |
|
729 | function enableSeekTracking(player, conf, eventData) {
|
730 | trackedPlayers[conf.mediaId].seekTracking.enabled = true;
|
731 | setInterval(function () { return seekEventTracker(player, conf, eventData); }, conf.updateRate);
|
732 | }
|
733 | function seekEventTracker(player, conf, eventData) {
|
734 | var playerInstance = trackedPlayers[conf.mediaId];
|
735 | var playerTime = player.getCurrentTime();
|
736 | if (Math.abs(playerTime - (playerInstance.seekTracking.prevTime + 0.5)) > 1) {
|
737 | youtubeEvent(player, SnowplowEvent.SEEK, conf, eventData);
|
738 | }
|
739 | playerInstance.seekTracking.prevTime = playerTime;
|
740 | }
|
741 |
|
742 | function enableVolumeTracking(player, conf, eventData) {
|
743 | trackedPlayers[conf.mediaId].volumeTracking.enabled = true;
|
744 | trackedPlayers[conf.mediaId].volumeTracking.prevVolume = player.getVolume();
|
745 | setInterval(function () { return volumeEventTracker(player, conf, eventData); }, conf.updateRate);
|
746 | }
|
747 | function volumeEventTracker(player, conf, eventData) {
|
748 | var playerVolumeTracking = trackedPlayers[conf.mediaId].volumeTracking;
|
749 | var playerVolume = player.getVolume();
|
750 | if (playerVolume !== playerVolumeTracking.prevVolume) {
|
751 | youtubeEvent(player, SnowplowEvent.VOLUMECHANGE, conf, eventData);
|
752 | }
|
753 | playerVolumeTracking.prevVolume = playerVolume;
|
754 | }
|
755 |
|
756 | exports.YouTubeTrackingPlugin = YouTubeTrackingPlugin;
|
757 | exports.enableYouTubeTracking = enableYouTubeTracking;
|
758 |
|
759 | Object.defineProperty(exports, '__esModule', { value: true });
|
760 |
|
761 | })));
|
762 |
|