stormcloud-video-player 0.8.59 → 0.8.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +1369 -1369
- package/dist/stormcloud-vp.min.js +3 -1
- package/lib/Player.cjs +548 -0
- package/lib/Player.cjs.map +1 -0
- package/lib/Player.d.cts +146 -0
- package/lib/{index.js → StormcloudPlayer.cjs} +1193 -1908
- package/lib/StormcloudPlayer.cjs.map +1 -0
- package/lib/{index.d.ts → StormcloudPlayer.d.cts} +7 -400
- package/lib/index.cjs +1064 -280
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +18 -4032
- package/lib/patterns.cjs +111 -0
- package/lib/patterns.cjs.map +1 -0
- package/lib/patterns.d.cts +14 -0
- package/lib/player/AdBreakOrchestrator.cjs +51 -16
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +3 -1
- package/lib/player/AdConfigManager.cjs +206 -26
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/AdConfigManager.d.cts +1 -1
- package/lib/player/AdTimingService.cjs.map +1 -1
- package/lib/player/AdTimingService.d.cts +1 -1
- package/lib/player/HlsEngine.cjs.map +1 -1
- package/lib/player/HlsEngine.d.cts +1 -1
- package/lib/player/PlaceholderLayer.cjs.map +1 -1
- package/lib/player/PlayerControls.cjs.map +1 -1
- package/lib/player/PlayerControls.d.cts +1 -1
- package/lib/player/Scte35CueManager.cjs.map +1 -1
- package/lib/player/Scte35CueManager.d.cts +1 -1
- package/lib/player/Scte35Parser.cjs.map +1 -1
- package/lib/player/Scte35Parser.d.cts +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +1060 -278
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/player/playerTypes.cjs.map +1 -1
- package/lib/player/playerTypes.d.cts +1 -1
- package/lib/players/FilePlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +1060 -278
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +1060 -278
- package/lib/players/index.cjs.map +1 -1
- package/lib/props.cjs +186 -0
- package/lib/props.cjs.map +1 -0
- package/lib/props.d.cts +62 -0
- package/lib/sdk/hlsAdPlayer.cjs +884 -234
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/sdk/pal.cjs +9 -5
- package/lib/sdk/pal.cjs.map +1 -1
- package/lib/sdk/pal.d.cts +1 -0
- package/lib/types.cjs +49 -0
- package/lib/types.cjs.map +1 -0
- package/lib/{types-52ASml2N.d.cts → types.d.cts} +48 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +1064 -280
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/browserCompat.cjs.map +1 -1
- package/lib/utils/ctvVastSignals.cjs +178 -19
- package/lib/utils/ctvVastSignals.cjs.map +1 -1
- package/lib/utils/devUrl.cjs.map +1 -1
- package/lib/utils/polyfills.cjs.map +1 -1
- package/lib/utils/tracking.cjs +45 -16
- package/lib/utils/tracking.cjs.map +1 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/lib/utils/trackingIngest.cjs.map +1 -1
- package/lib/utils/vastEnvironmentSignals.cjs +192 -20
- package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
- package/lib/utils/vastEnvironmentSignals.d.cts +13 -2
- package/lib/utils/vastMacros.cjs +50 -4
- package/lib/utils/vastMacros.cjs.map +1 -1
- package/lib/utils/vastMacros.d.cts +2 -0
- package/lib/utils/vastTrackingMacros.cjs +5 -0
- package/lib/utils/vastTrackingMacros.cjs.map +1 -1
- package/lib/utils/vastTrackingMacros.d.cts +2 -0
- package/lib/utils.cjs +292 -0
- package/lib/utils.cjs.map +1 -0
- package/lib/utils.d.cts +17 -0
- package/package.json +91 -91
- package/rollup.config.js +90 -90
- package/lib/index.js.map +0 -1
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
function _array_like_to_array(arr, len) {
|
|
3
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
4
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
5
|
+
return arr2;
|
|
6
|
+
}
|
|
7
|
+
function _array_with_holes(arr) {
|
|
8
|
+
if (Array.isArray(arr)) return arr;
|
|
9
|
+
}
|
|
2
10
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
3
11
|
try {
|
|
4
12
|
var info = gen[key](arg);
|
|
@@ -25,6 +33,62 @@ function _async_to_generator(fn) {
|
|
|
25
33
|
});
|
|
26
34
|
};
|
|
27
35
|
}
|
|
36
|
+
function _define_property(obj, key, value) {
|
|
37
|
+
if (key in obj) {
|
|
38
|
+
Object.defineProperty(obj, key, {
|
|
39
|
+
value: value,
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true
|
|
43
|
+
});
|
|
44
|
+
} else obj[key] = value;
|
|
45
|
+
return obj;
|
|
46
|
+
}
|
|
47
|
+
function _iterable_to_array_limit(arr, i) {
|
|
48
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
49
|
+
if (_i == null) return;
|
|
50
|
+
var _arr = [];
|
|
51
|
+
var _n = true;
|
|
52
|
+
var _d = false;
|
|
53
|
+
var _s, _e;
|
|
54
|
+
try {
|
|
55
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
56
|
+
_arr.push(_s.value);
|
|
57
|
+
if (i && _arr.length === i) break;
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
_d = true;
|
|
61
|
+
_e = err;
|
|
62
|
+
} finally{
|
|
63
|
+
try {
|
|
64
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
65
|
+
} finally{
|
|
66
|
+
if (_d) throw _e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return _arr;
|
|
70
|
+
}
|
|
71
|
+
function _non_iterable_rest() {
|
|
72
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
73
|
+
}
|
|
74
|
+
function _object_spread(target) {
|
|
75
|
+
for(var i = 1; i < arguments.length; i++){
|
|
76
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
77
|
+
var ownKeys = Object.keys(source);
|
|
78
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
79
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
80
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
ownKeys.forEach(function(key) {
|
|
84
|
+
_define_property(target, key, source[key]);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return target;
|
|
88
|
+
}
|
|
89
|
+
function _sliced_to_array(arr, i) {
|
|
90
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
91
|
+
}
|
|
28
92
|
function _ts_generator(thisArg, body) {
|
|
29
93
|
var f, y, t, _ = {
|
|
30
94
|
label: 0,
|
|
@@ -128,6 +192,14 @@ function _type_of(obj) {
|
|
|
128
192
|
"@swc/helpers - typeof";
|
|
129
193
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
130
194
|
}
|
|
195
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
196
|
+
if (!o) return;
|
|
197
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
198
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
199
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
200
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
201
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
202
|
+
}
|
|
131
203
|
var __create = Object.create;
|
|
132
204
|
var __defProp = Object.defineProperty;
|
|
133
205
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -383,6 +455,7 @@ var KNOWN_VAST_MACROS = /* @__PURE__ */ new Set([
|
|
|
383
455
|
"PLAYERSIZE",
|
|
384
456
|
"PLAYERSTATE",
|
|
385
457
|
"PODSEQUENCE",
|
|
458
|
+
"REASON",
|
|
386
459
|
"REGULATIONS",
|
|
387
460
|
"SERVERSIDE",
|
|
388
461
|
"SERVERUA",
|
|
@@ -441,6 +514,10 @@ function resolveMacroValues(ctx) {
|
|
|
441
514
|
if (ctx.podSequence != null) {
|
|
442
515
|
set("PODSEQUENCE", String(ctx.podSequence));
|
|
443
516
|
}
|
|
517
|
+
set("ADSERVINGID", ctx.adServingId);
|
|
518
|
+
if (ctx.reason != null && ctx.reason !== "") {
|
|
519
|
+
set("REASON", String(ctx.reason));
|
|
520
|
+
}
|
|
444
521
|
return values;
|
|
445
522
|
}
|
|
446
523
|
function substituteVastTrackingMacros(url) {
|
|
@@ -457,10 +534,72 @@ function substituteVastTrackingMacros(url) {
|
|
|
457
534
|
});
|
|
458
535
|
}
|
|
459
536
|
// src/sdk/hlsAdPlayer.ts
|
|
537
|
+
var LINEAR_TRACKING_EVENTS = [
|
|
538
|
+
"creativeView",
|
|
539
|
+
"loaded",
|
|
540
|
+
"start",
|
|
541
|
+
"firstQuartile",
|
|
542
|
+
"midpoint",
|
|
543
|
+
"thirdQuartile",
|
|
544
|
+
"complete",
|
|
545
|
+
"mute",
|
|
546
|
+
"unmute",
|
|
547
|
+
"pause",
|
|
548
|
+
"resume",
|
|
549
|
+
"fullscreen",
|
|
550
|
+
"exitFullscreen",
|
|
551
|
+
"playerExpand",
|
|
552
|
+
"playerCollapse",
|
|
553
|
+
"notUsed"
|
|
554
|
+
];
|
|
555
|
+
function textOf(el) {
|
|
556
|
+
var _el_textContent;
|
|
557
|
+
var value = el === null || el === void 0 ? void 0 : (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
558
|
+
return value ? value : void 0;
|
|
559
|
+
}
|
|
560
|
+
function parseVastTime(value) {
|
|
561
|
+
if (!value) return void 0;
|
|
562
|
+
var parts = value.trim().split(":");
|
|
563
|
+
if (parts.length !== 3) return void 0;
|
|
564
|
+
var _parts_map = _sliced_to_array(parts.map(function(p) {
|
|
565
|
+
return parseFloat(p);
|
|
566
|
+
}), 3), h = _parts_map[0], m = _parts_map[1], s = _parts_map[2];
|
|
567
|
+
if (![
|
|
568
|
+
h,
|
|
569
|
+
m,
|
|
570
|
+
s
|
|
571
|
+
].every(function(n) {
|
|
572
|
+
return n !== void 0 && Number.isFinite(n);
|
|
573
|
+
})) {
|
|
574
|
+
return void 0;
|
|
575
|
+
}
|
|
576
|
+
return h * 3600 + m * 60 + s;
|
|
577
|
+
}
|
|
578
|
+
function parseProgressOffset(offset) {
|
|
579
|
+
if (!offset) return void 0;
|
|
580
|
+
var trimmed = offset.trim();
|
|
581
|
+
if (trimmed.endsWith("%")) {
|
|
582
|
+
var percent = parseFloat(trimmed);
|
|
583
|
+
return Number.isFinite(percent) ? {
|
|
584
|
+
offsetPercent: percent
|
|
585
|
+
} : void 0;
|
|
586
|
+
}
|
|
587
|
+
var seconds = parseVastTime(trimmed);
|
|
588
|
+
return seconds !== void 0 ? {
|
|
589
|
+
offsetSeconds: seconds
|
|
590
|
+
} : void 0;
|
|
591
|
+
}
|
|
460
592
|
var MAX_VAST_WRAPPER_DEPTH = 5;
|
|
461
593
|
var BEACON_TIMEOUT_MS = 3e4;
|
|
462
594
|
var inFlightBeacons = /* @__PURE__ */ new Set();
|
|
463
595
|
var VAST_ERROR_MEDIA_DISPLAY = 405;
|
|
596
|
+
var VAST_ERROR_WRAPPER_TIMEOUT = 301;
|
|
597
|
+
var VAST_ERROR_WRAPPER_LIMIT = 302;
|
|
598
|
+
var VAST_ERROR_WRAPPER_NO_ADS = 303;
|
|
599
|
+
var VAST_ERROR_NO_SUPPORTED_MEDIA = 403;
|
|
600
|
+
var VERIFICATION_NOT_SUPPORTED_REASON = 2;
|
|
601
|
+
var VIEWABLE_MIN_VISIBLE_RATIO = 0.5;
|
|
602
|
+
var VIEWABLE_MIN_CONTINUOUS_S = 2;
|
|
464
603
|
function toVastMediaErrorCode(error) {
|
|
465
604
|
switch(error === null || error === void 0 ? void 0 : error.code){
|
|
466
605
|
case 1:
|
|
@@ -488,6 +627,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
488
627
|
var adHls;
|
|
489
628
|
var adContainerEl = (_contentVideo_AD_CONTAINER_PROP = contentVideo[AD_CONTAINER_PROP]) !== null && _contentVideo_AD_CONTAINER_PROP !== void 0 ? _contentVideo_AD_CONTAINER_PROP : void 0;
|
|
490
629
|
var adEventHandlers = [];
|
|
630
|
+
var containerHandlers = [];
|
|
491
631
|
var currentAd;
|
|
492
632
|
var currentAdMediaFile;
|
|
493
633
|
var podAds = [];
|
|
@@ -505,14 +645,28 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
505
645
|
var sawDecodedVideoFrame = false;
|
|
506
646
|
var videoFrameCallbackHandle;
|
|
507
647
|
var pendingPlayPromise;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
648
|
+
function createTrackingState() {
|
|
649
|
+
return {
|
|
650
|
+
impression: false,
|
|
651
|
+
loaded: false,
|
|
652
|
+
start: false,
|
|
653
|
+
firstQuartile: false,
|
|
654
|
+
midpoint: false,
|
|
655
|
+
thirdQuartile: false,
|
|
656
|
+
complete: false,
|
|
657
|
+
viewabilitySettled: false,
|
|
658
|
+
lastMuted: void 0,
|
|
659
|
+
progressFired: /* @__PURE__ */ new Set()
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
var trackingFired = createTrackingState();
|
|
663
|
+
var resolvedAds = /* @__PURE__ */ new Set();
|
|
664
|
+
var viewObserver;
|
|
665
|
+
var visibleRatio = 0;
|
|
666
|
+
var continuousVisibleS = 0;
|
|
667
|
+
var lastViewSampleTime;
|
|
668
|
+
var lastPlayerExpanded = false;
|
|
669
|
+
var documentHandlers = [];
|
|
516
670
|
function emit(event, payload) {
|
|
517
671
|
var set = listeners.get(event);
|
|
518
672
|
if (!set) return;
|
|
@@ -541,7 +695,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
541
695
|
}
|
|
542
696
|
}
|
|
543
697
|
}
|
|
544
|
-
function buildTrackingMacroContext(
|
|
698
|
+
function buildTrackingMacroContext() {
|
|
699
|
+
var options2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
700
|
+
var _options2_ad;
|
|
701
|
+
var errorCode = options2.errorCode, reason = options2.reason;
|
|
702
|
+
var ad = (_options2_ad = options2.ad) !== null && _options2_ad !== void 0 ? _options2_ad : currentAd;
|
|
545
703
|
var context = {
|
|
546
704
|
adPlayheadSeconds: adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.currentTime,
|
|
547
705
|
contentPlayheadSeconds: contentVideo.currentTime,
|
|
@@ -562,11 +720,17 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
562
720
|
if (podAds.length > 0) {
|
|
563
721
|
context.podSequence = podIndex + 1;
|
|
564
722
|
}
|
|
723
|
+
if (ad === null || ad === void 0 ? void 0 : ad.adServingId) {
|
|
724
|
+
context.adServingId = ad.adServingId;
|
|
725
|
+
}
|
|
726
|
+
if (reason != null) {
|
|
727
|
+
context.reason = reason;
|
|
728
|
+
}
|
|
565
729
|
return context;
|
|
566
730
|
}
|
|
567
731
|
function fireTrackingPixels(urls, options2) {
|
|
568
732
|
if (!urls || urls.length === 0) return;
|
|
569
|
-
var macroContext = buildTrackingMacroContext(options2
|
|
733
|
+
var macroContext = buildTrackingMacroContext(options2);
|
|
570
734
|
urls.forEach(function(url) {
|
|
571
735
|
try {
|
|
572
736
|
var trackingUrl = substituteVastTrackingMacros(url, macroContext);
|
|
@@ -677,8 +841,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
677
841
|
var url = (mediaFile.url.toLowerCase().split("?")[0] || "").trim();
|
|
678
842
|
return type.startsWith("audio/") || url.endsWith(".mp3") || url.endsWith(".aac") || url.endsWith(".m4a") || url.endsWith(".ogg") || url.endsWith(".oga") || url.endsWith(".opus") || url.endsWith(".wav") || url.endsWith(".weba");
|
|
679
843
|
}
|
|
680
|
-
function collectVideoMediaFiles(
|
|
681
|
-
var mediaFileElements =
|
|
844
|
+
function collectVideoMediaFiles(linear, verbose) {
|
|
845
|
+
var mediaFileElements = linear.querySelectorAll(":scope > MediaFiles > MediaFile");
|
|
682
846
|
var mediaFiles = [];
|
|
683
847
|
if (verbose) {
|
|
684
848
|
console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
|
|
@@ -698,6 +862,13 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
698
862
|
}
|
|
699
863
|
return;
|
|
700
864
|
}
|
|
865
|
+
var apiFramework = (mf.getAttribute("apiFramework") || "").toUpperCase();
|
|
866
|
+
if (apiFramework === "VPAID") {
|
|
867
|
+
if (verbose) {
|
|
868
|
+
console.log("[HlsAdPlayer] MediaFile ".concat(index, " ignored (VPAID creatives are not supported)"));
|
|
869
|
+
}
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
701
872
|
var bitrateAttr = mf.getAttribute("bitrate");
|
|
702
873
|
var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
703
874
|
var mediaFile = {
|
|
@@ -728,114 +899,144 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
728
899
|
return mediaFiles;
|
|
729
900
|
}
|
|
730
901
|
function createEmptyTrackingUrls() {
|
|
731
|
-
|
|
902
|
+
var urls = {
|
|
732
903
|
impression: [],
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
pause: [],
|
|
741
|
-
resume: [],
|
|
742
|
-
fullscreen: [],
|
|
743
|
-
exitFullscreen: [],
|
|
744
|
-
skip: [],
|
|
745
|
-
error: []
|
|
904
|
+
clickTracking: [],
|
|
905
|
+
error: [],
|
|
906
|
+
viewable: [],
|
|
907
|
+
notViewable: [],
|
|
908
|
+
viewUndetermined: [],
|
|
909
|
+
verificationNotExecuted: [],
|
|
910
|
+
progress: []
|
|
746
911
|
};
|
|
912
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
913
|
+
try {
|
|
914
|
+
for(var _iterator = LINEAR_TRACKING_EVENTS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
915
|
+
var event = _step.value;
|
|
916
|
+
urls[event] = [];
|
|
917
|
+
}
|
|
918
|
+
} catch (err) {
|
|
919
|
+
_didIteratorError = true;
|
|
920
|
+
_iteratorError = err;
|
|
921
|
+
} finally{
|
|
922
|
+
try {
|
|
923
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
924
|
+
_iterator.return();
|
|
925
|
+
}
|
|
926
|
+
} finally{
|
|
927
|
+
if (_didIteratorError) {
|
|
928
|
+
throw _iteratorError;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return urls;
|
|
747
933
|
}
|
|
748
|
-
function
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
753
|
-
if (url) trackingUrls.impression.push(url);
|
|
934
|
+
function pushUrls(target, elements) {
|
|
935
|
+
elements.forEach(function(el) {
|
|
936
|
+
var url = textOf(el);
|
|
937
|
+
if (url) target.push(url);
|
|
754
938
|
});
|
|
755
|
-
|
|
756
|
-
|
|
939
|
+
}
|
|
940
|
+
function collectLinearTracking(linear, into) {
|
|
941
|
+
linear.querySelectorAll(":scope > TrackingEvents > Tracking").forEach(function(el) {
|
|
757
942
|
var event = el.getAttribute("event");
|
|
758
|
-
var url = (
|
|
759
|
-
if (event
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
943
|
+
var url = textOf(el);
|
|
944
|
+
if (!event || !url) return;
|
|
945
|
+
if (event === "progress") {
|
|
946
|
+
var offset = parseProgressOffset(el.getAttribute("offset"));
|
|
947
|
+
if (offset) into.progress.push(_object_spread({
|
|
948
|
+
url: url
|
|
949
|
+
}, offset));
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
if (LINEAR_TRACKING_EVENTS.indexOf(event) !== -1) {
|
|
953
|
+
into[event].push(url);
|
|
764
954
|
}
|
|
765
955
|
});
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
956
|
+
pushUrls(into.clickTracking, linear.querySelectorAll(":scope > VideoClicks > ClickTracking"));
|
|
957
|
+
}
|
|
958
|
+
function collectAdLevelTracking(adBody, into) {
|
|
959
|
+
pushUrls(into.impression, adBody.querySelectorAll(":scope > Impression"));
|
|
960
|
+
pushUrls(into.error, adBody.querySelectorAll(":scope > Error"));
|
|
961
|
+
pushUrls(into.viewable, adBody.querySelectorAll(":scope > ViewableImpression > Viewable"));
|
|
962
|
+
pushUrls(into.notViewable, adBody.querySelectorAll(":scope > ViewableImpression > NotViewable"));
|
|
963
|
+
pushUrls(into.viewUndetermined, adBody.querySelectorAll(":scope > ViewableImpression > ViewUndetermined"));
|
|
964
|
+
adBody.querySelectorAll(':scope > AdVerifications > Verification, :scope > Extensions > Extension[type="AdVerifications"] > AdVerifications > Verification').forEach(function(verification) {
|
|
965
|
+
pushUrls(into.verificationNotExecuted, verification.querySelectorAll(':scope > TrackingEvents > Tracking[event="verificationNotExecuted"]'));
|
|
770
966
|
});
|
|
771
|
-
return trackingUrls;
|
|
772
967
|
}
|
|
773
968
|
function mergeTrackingUrls(target, source) {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
969
|
+
var targetLists = target;
|
|
970
|
+
var sourceLists = source;
|
|
971
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
972
|
+
try {
|
|
973
|
+
for(var _iterator = Object.keys(targetLists)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
974
|
+
var key = _step.value;
|
|
975
|
+
var incoming = sourceLists[key];
|
|
976
|
+
if (incoming && incoming.length > 0) {
|
|
977
|
+
targetLists[key] = targetLists[key].concat(incoming);
|
|
978
|
+
}
|
|
777
979
|
}
|
|
778
|
-
})
|
|
980
|
+
} catch (err) {
|
|
981
|
+
_didIteratorError = true;
|
|
982
|
+
_iteratorError = err;
|
|
983
|
+
} finally{
|
|
984
|
+
try {
|
|
985
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
986
|
+
_iterator.return();
|
|
987
|
+
}
|
|
988
|
+
} finally{
|
|
989
|
+
if (_didIteratorError) {
|
|
990
|
+
throw _iteratorError;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
779
994
|
return target;
|
|
780
995
|
}
|
|
996
|
+
function parseXml(xmlString) {
|
|
997
|
+
var xmlDoc = new DOMParser().parseFromString(xmlString, "text/xml");
|
|
998
|
+
var parserError = xmlDoc.querySelector("parsererror");
|
|
999
|
+
if (parserError) {
|
|
1000
|
+
console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
|
|
1001
|
+
return null;
|
|
1002
|
+
}
|
|
1003
|
+
return xmlDoc;
|
|
1004
|
+
}
|
|
1005
|
+
function getAdSequence(adElement) {
|
|
1006
|
+
var sequence = parseInt(adElement.getAttribute("sequence") || "", 10);
|
|
1007
|
+
return Number.isFinite(sequence) ? sequence : void 0;
|
|
1008
|
+
}
|
|
1009
|
+
function emptyVastResult(root) {
|
|
1010
|
+
var errorUrls = [];
|
|
1011
|
+
pushUrls(errorUrls, root.querySelectorAll(":scope > Error"));
|
|
1012
|
+
return {
|
|
1013
|
+
type: "empty",
|
|
1014
|
+
errorUrls: errorUrls,
|
|
1015
|
+
errorCode: VAST_ERROR_WRAPPER_NO_ADS
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
781
1018
|
function parseVastXml(xmlString) {
|
|
782
1019
|
try {
|
|
783
|
-
var
|
|
784
|
-
var
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
}
|
|
793
|
-
var adElement = xmlDoc.querySelector("Ad");
|
|
1020
|
+
var _adElements_find;
|
|
1021
|
+
var xmlDoc = parseXml(xmlString);
|
|
1022
|
+
if (!xmlDoc) return {
|
|
1023
|
+
type: "empty"
|
|
1024
|
+
};
|
|
1025
|
+
var root = xmlDoc.documentElement;
|
|
1026
|
+
var adElements = Array.from(root.querySelectorAll(":scope > Ad"));
|
|
1027
|
+
var adElement = (_adElements_find = adElements.find(function(el) {
|
|
1028
|
+
return getAdSequence(el) === void 0;
|
|
1029
|
+
})) !== null && _adElements_find !== void 0 ? _adElements_find : adElements[0];
|
|
794
1030
|
if (!adElement) {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
var adId = adElement.getAttribute("id") || "unknown";
|
|
801
|
-
var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
|
|
802
|
-
var clickThrough = (_xmlDoc_querySelector1 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector1.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
|
|
803
|
-
var wrapperUri = (_xmlDoc_querySelector2 = xmlDoc.querySelector("VASTAdTagURI")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent1 = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent1 === void 0 ? void 0 : _xmlDoc_querySelector_textContent1.trim();
|
|
804
|
-
if (wrapperUri) {
|
|
805
|
-
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
|
|
806
|
-
return {
|
|
807
|
-
type: "wrapper",
|
|
808
|
-
vastAdTagUri: wrapperUri,
|
|
809
|
-
trackingUrls: extractTrackingUrls(xmlDoc),
|
|
810
|
-
clickThrough: clickThrough
|
|
811
|
-
};
|
|
1031
|
+
var _root_getAttribute;
|
|
1032
|
+
console.warn("[HlsAdPlayer] No Ad element found in VAST ".concat((_root_getAttribute = root.getAttribute("version")) !== null && _root_getAttribute !== void 0 ? _root_getAttribute : "", " response"));
|
|
1033
|
+
return emptyVastResult(root);
|
|
812
1034
|
}
|
|
813
|
-
var
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
817
|
-
var mediaFiles = collectVideoMediaFiles(xmlDoc, true);
|
|
818
|
-
if (mediaFiles.length === 0) {
|
|
819
|
-
if (isNoAdAvailable) {
|
|
820
|
-
console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
|
|
821
|
-
} else {
|
|
822
|
-
console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
|
|
823
|
-
}
|
|
824
|
-
return {
|
|
825
|
-
type: "empty"
|
|
826
|
-
};
|
|
1035
|
+
var parsed = parseAdElement(adElement, true);
|
|
1036
|
+
if (parsed.type === "wrapper") {
|
|
1037
|
+
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
|
|
827
1038
|
}
|
|
828
|
-
return
|
|
829
|
-
type: "inline",
|
|
830
|
-
ad: {
|
|
831
|
-
id: adId,
|
|
832
|
-
title: title,
|
|
833
|
-
duration: duration,
|
|
834
|
-
mediaFiles: mediaFiles,
|
|
835
|
-
trackingUrls: extractTrackingUrls(xmlDoc),
|
|
836
|
-
clickThrough: clickThrough
|
|
837
|
-
}
|
|
838
|
-
};
|
|
1039
|
+
return parsed;
|
|
839
1040
|
} catch (error) {
|
|
840
1041
|
console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
|
|
841
1042
|
return {
|
|
@@ -844,48 +1045,101 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
844
1045
|
}
|
|
845
1046
|
}
|
|
846
1047
|
function parseAdElement(adElement) {
|
|
1048
|
+
var verbose = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
|
|
847
1049
|
try {
|
|
848
|
-
var
|
|
849
|
-
var
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1050
|
+
var _parseVastTime;
|
|
1051
|
+
var wrapper = adElement.querySelector(":scope > Wrapper");
|
|
1052
|
+
if (wrapper) {
|
|
1053
|
+
var vastAdTagUri = textOf(wrapper.querySelector(":scope > VASTAdTagURI"));
|
|
1054
|
+
if (!vastAdTagUri) {
|
|
1055
|
+
console.warn("[HlsAdPlayer] <Wrapper> has no VASTAdTagURI");
|
|
1056
|
+
return {
|
|
1057
|
+
type: "empty"
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
var trackingUrls2 = createEmptyTrackingUrls();
|
|
1061
|
+
collectAdLevelTracking(wrapper, trackingUrls2);
|
|
1062
|
+
wrapper.querySelectorAll(":scope > Creatives > Creative > Linear").forEach(function(linear2) {
|
|
1063
|
+
return collectLinearTracking(linear2, trackingUrls2);
|
|
1064
|
+
});
|
|
854
1065
|
return {
|
|
855
1066
|
type: "wrapper",
|
|
856
|
-
vastAdTagUri:
|
|
857
|
-
trackingUrls:
|
|
858
|
-
|
|
1067
|
+
vastAdTagUri: vastAdTagUri,
|
|
1068
|
+
trackingUrls: trackingUrls2,
|
|
1069
|
+
rules: {
|
|
1070
|
+
followAdditionalWrappers: wrapper.getAttribute("followAdditionalWrappers") !== "false"
|
|
1071
|
+
}
|
|
859
1072
|
};
|
|
860
1073
|
}
|
|
861
|
-
var
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
865
|
-
var mediaFiles = collectVideoMediaFiles(adElement, false);
|
|
866
|
-
if (mediaFiles.length === 0) {
|
|
867
|
-
if (isNoAdAvailable) {
|
|
868
|
-
console.warn("[HlsAdPlayer] Pod <Ad> indicates no ad available");
|
|
869
|
-
} else {
|
|
870
|
-
console.warn("[HlsAdPlayer] No supported media files in pod <Ad>");
|
|
871
|
-
}
|
|
1074
|
+
var inLine = adElement.querySelector(":scope > InLine");
|
|
1075
|
+
if (!inLine) {
|
|
1076
|
+
console.warn("[HlsAdPlayer] <Ad> has neither <InLine> nor <Wrapper>");
|
|
872
1077
|
return {
|
|
873
1078
|
type: "empty"
|
|
874
1079
|
};
|
|
875
1080
|
}
|
|
1081
|
+
var errorUrls = [];
|
|
1082
|
+
pushUrls(errorUrls, inLine.querySelectorAll(":scope > Error"));
|
|
1083
|
+
if (adElement.getAttribute("conditionalAd") === "true") {
|
|
1084
|
+
console.warn("[HlsAdPlayer] Skipping conditional <Ad> (VPAID-only)");
|
|
1085
|
+
return {
|
|
1086
|
+
type: "empty",
|
|
1087
|
+
errorUrls: errorUrls,
|
|
1088
|
+
errorCode: VAST_ERROR_NO_SUPPORTED_MEDIA
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
var linear;
|
|
1092
|
+
var mediaFiles = [];
|
|
1093
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1094
|
+
try {
|
|
1095
|
+
for(var _iterator = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear"))[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1096
|
+
var candidate = _step.value;
|
|
1097
|
+
var files = collectVideoMediaFiles(candidate, verbose);
|
|
1098
|
+
if (files.length > 0) {
|
|
1099
|
+
linear = candidate;
|
|
1100
|
+
mediaFiles = files;
|
|
1101
|
+
break;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
} catch (err) {
|
|
1105
|
+
_didIteratorError = true;
|
|
1106
|
+
_iteratorError = err;
|
|
1107
|
+
} finally{
|
|
1108
|
+
try {
|
|
1109
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1110
|
+
_iterator.return();
|
|
1111
|
+
}
|
|
1112
|
+
} finally{
|
|
1113
|
+
if (_didIteratorError) {
|
|
1114
|
+
throw _iteratorError;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if (!linear) {
|
|
1119
|
+
console.warn("[HlsAdPlayer] No supported linear media files in <Ad>");
|
|
1120
|
+
return {
|
|
1121
|
+
type: "empty",
|
|
1122
|
+
errorUrls: errorUrls,
|
|
1123
|
+
errorCode: VAST_ERROR_NO_SUPPORTED_MEDIA
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
var trackingUrls = createEmptyTrackingUrls();
|
|
1127
|
+
collectAdLevelTracking(inLine, trackingUrls);
|
|
1128
|
+
collectLinearTracking(linear, trackingUrls);
|
|
876
1129
|
return {
|
|
877
1130
|
type: "inline",
|
|
878
1131
|
ad: {
|
|
879
|
-
id:
|
|
880
|
-
title:
|
|
881
|
-
duration:
|
|
1132
|
+
id: adElement.getAttribute("id") || "unknown",
|
|
1133
|
+
title: textOf(inLine.querySelector(":scope > AdTitle")) || "Ad",
|
|
1134
|
+
duration: (_parseVastTime = parseVastTime(textOf(linear.querySelector(":scope > Duration")))) !== null && _parseVastTime !== void 0 ? _parseVastTime : 30,
|
|
882
1135
|
mediaFiles: mediaFiles,
|
|
883
|
-
trackingUrls:
|
|
884
|
-
clickThrough:
|
|
1136
|
+
trackingUrls: trackingUrls,
|
|
1137
|
+
clickThrough: textOf(linear.querySelector(":scope > VideoClicks > ClickThrough")),
|
|
1138
|
+
adServingId: textOf(inLine.querySelector(":scope > AdServingId"))
|
|
885
1139
|
}
|
|
886
1140
|
};
|
|
887
1141
|
} catch (error) {
|
|
888
|
-
console.error("[HlsAdPlayer] Error parsing
|
|
1142
|
+
console.error("[HlsAdPlayer] Error parsing <Ad> element:", error);
|
|
889
1143
|
return {
|
|
890
1144
|
type: "empty"
|
|
891
1145
|
};
|
|
@@ -964,30 +1218,63 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
964
1218
|
}
|
|
965
1219
|
function fetchAndParseVastAd(_0) {
|
|
966
1220
|
return _async_to_generator(function(vastTagUrl) {
|
|
967
|
-
var depth, accumulatedTracking, vastXml, parsed;
|
|
1221
|
+
var depth, accumulatedTracking, rules, vastXml, error, parsed, _parsed_errorUrls, _parsed_errorCode;
|
|
968
1222
|
var _arguments = arguments;
|
|
969
1223
|
return _ts_generator(this, function(_state) {
|
|
970
1224
|
switch(_state.label){
|
|
971
1225
|
case 0:
|
|
972
|
-
depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls()
|
|
1226
|
+
depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls(), rules = _arguments.length > 3 && _arguments[3] !== void 0 ? _arguments[3] : {
|
|
1227
|
+
followAdditionalWrappers: true
|
|
1228
|
+
};
|
|
1229
|
+
_state.label = 1;
|
|
1230
|
+
case 1:
|
|
1231
|
+
_state.trys.push([
|
|
1232
|
+
1,
|
|
1233
|
+
3,
|
|
1234
|
+
,
|
|
1235
|
+
4
|
|
1236
|
+
]);
|
|
973
1237
|
return [
|
|
974
1238
|
4,
|
|
975
1239
|
fetchVastXml(vastTagUrl, depth === 0 ? "include" : "omit")
|
|
976
1240
|
];
|
|
977
|
-
case
|
|
1241
|
+
case 2:
|
|
978
1242
|
vastXml = _state.sent();
|
|
1243
|
+
return [
|
|
1244
|
+
3,
|
|
1245
|
+
4
|
|
1246
|
+
];
|
|
1247
|
+
case 3:
|
|
1248
|
+
error = _state.sent();
|
|
1249
|
+
if (depth === 0) throw error;
|
|
1250
|
+
console.warn("[HlsAdPlayer] Wrapped VAST request failed:", error);
|
|
1251
|
+
fireTrackingPixels(accumulatedTracking.error, {
|
|
1252
|
+
errorCode: VAST_ERROR_WRAPPER_TIMEOUT
|
|
1253
|
+
});
|
|
1254
|
+
return [
|
|
1255
|
+
2,
|
|
1256
|
+
null
|
|
1257
|
+
];
|
|
1258
|
+
case 4:
|
|
979
1259
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
980
1260
|
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
981
1261
|
parsed = parseVastXml(vastXml);
|
|
982
1262
|
if (parsed.type === "empty") {
|
|
1263
|
+
;
|
|
1264
|
+
fireTrackingPixels(((_parsed_errorUrls = parsed.errorUrls) !== null && _parsed_errorUrls !== void 0 ? _parsed_errorUrls : []).concat(accumulatedTracking.error), {
|
|
1265
|
+
errorCode: (_parsed_errorCode = parsed.errorCode) !== null && _parsed_errorCode !== void 0 ? _parsed_errorCode : VAST_ERROR_WRAPPER_NO_ADS
|
|
1266
|
+
});
|
|
983
1267
|
return [
|
|
984
1268
|
2,
|
|
985
1269
|
null
|
|
986
1270
|
];
|
|
987
1271
|
}
|
|
988
1272
|
if (parsed.type === "wrapper") {
|
|
989
|
-
if (depth >= MAX_VAST_WRAPPER_DEPTH) {
|
|
990
|
-
console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
|
|
1273
|
+
if (depth >= MAX_VAST_WRAPPER_DEPTH || !rules.followAdditionalWrappers) {
|
|
1274
|
+
console.warn(rules.followAdditionalWrappers ? "[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain") : '[HlsAdPlayer] Parent wrapper set followAdditionalWrappers="false"; rejecting nested wrapper');
|
|
1275
|
+
fireTrackingPixels(accumulatedTracking.error.concat(parsed.trackingUrls.error), {
|
|
1276
|
+
errorCode: VAST_ERROR_WRAPPER_LIMIT
|
|
1277
|
+
});
|
|
991
1278
|
return [
|
|
992
1279
|
2,
|
|
993
1280
|
null
|
|
@@ -996,7 +1283,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
996
1283
|
mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
|
|
997
1284
|
return [
|
|
998
1285
|
2,
|
|
999
|
-
fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
|
|
1286
|
+
fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking, parsed.rules)
|
|
1000
1287
|
];
|
|
1001
1288
|
}
|
|
1002
1289
|
mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
|
|
@@ -1010,7 +1297,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1010
1297
|
}
|
|
1011
1298
|
function fetchAndParsePod(vastTagUrl) {
|
|
1012
1299
|
return _async_to_generator(function() {
|
|
1013
|
-
var vastXml, trimmedXml,
|
|
1300
|
+
var _root_getAttribute, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute1, _empty_errorUrls, empty, _empty_errorCode, resolveAd, podElements, buffet, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, adElement, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, adElement1, ad1, err;
|
|
1014
1301
|
return _ts_generator(this, function(_state) {
|
|
1015
1302
|
switch(_state.label){
|
|
1016
1303
|
case 0:
|
|
@@ -1029,125 +1316,212 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1029
1316
|
[]
|
|
1030
1317
|
];
|
|
1031
1318
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
console.error("[HlsAdPlayer] Pod VAST XML parsing error (malformed). Content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
1319
|
+
xmlDoc = parseXml(vastXml);
|
|
1320
|
+
if (!xmlDoc) {
|
|
1321
|
+
console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
1036
1322
|
return [
|
|
1037
1323
|
2,
|
|
1038
1324
|
[]
|
|
1039
1325
|
];
|
|
1040
1326
|
}
|
|
1041
|
-
|
|
1327
|
+
root = xmlDoc.documentElement;
|
|
1328
|
+
adElements = Array.from(root.querySelectorAll(":scope > Ad"));
|
|
1042
1329
|
if (adElements.length === 0) {
|
|
1043
|
-
|
|
1330
|
+
;
|
|
1331
|
+
;
|
|
1332
|
+
console.warn("[HlsAdPlayer] No <Ad> elements in VAST ".concat((_root_getAttribute1 = root.getAttribute("version")) !== null && _root_getAttribute1 !== void 0 ? _root_getAttribute1 : "", " pod response (no fill)"));
|
|
1333
|
+
empty = emptyVastResult(root);
|
|
1334
|
+
if (empty.type === "empty" && ((_empty_errorUrls = empty.errorUrls) === null || _empty_errorUrls === void 0 ? void 0 : _empty_errorUrls.length)) {
|
|
1335
|
+
;
|
|
1336
|
+
fireTrackingPixels(empty.errorUrls, {
|
|
1337
|
+
errorCode: (_empty_errorCode = empty.errorCode) !== null && _empty_errorCode !== void 0 ? _empty_errorCode : VAST_ERROR_WRAPPER_NO_ADS
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1044
1340
|
return [
|
|
1045
1341
|
2,
|
|
1046
1342
|
[]
|
|
1047
1343
|
];
|
|
1048
1344
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1345
|
+
resolveAd = function resolveAd(adElement) {
|
|
1346
|
+
return _async_to_generator(function() {
|
|
1347
|
+
var _parsed_errorUrls, parsed, _parsed_errorCode;
|
|
1348
|
+
return _ts_generator(this, function(_state) {
|
|
1349
|
+
parsed = parseAdElement(adElement);
|
|
1350
|
+
if (parsed.type === "inline") return [
|
|
1351
|
+
2,
|
|
1352
|
+
parsed.ad
|
|
1353
|
+
];
|
|
1354
|
+
if (parsed.type === "wrapper") {
|
|
1355
|
+
return [
|
|
1356
|
+
2,
|
|
1357
|
+
fetchAndParseVastAd(parsed.vastAdTagUri, 1, parsed.trackingUrls, parsed.rules)
|
|
1358
|
+
];
|
|
1359
|
+
}
|
|
1360
|
+
if ((_parsed_errorUrls = parsed.errorUrls) === null || _parsed_errorUrls === void 0 ? void 0 : _parsed_errorUrls.length) {
|
|
1361
|
+
;
|
|
1362
|
+
fireTrackingPixels(parsed.errorUrls, {
|
|
1363
|
+
errorCode: (_parsed_errorCode = parsed.errorCode) !== null && _parsed_errorCode !== void 0 ? _parsed_errorCode : VAST_ERROR_NO_SUPPORTED_MEDIA
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
return [
|
|
1367
|
+
2,
|
|
1368
|
+
null
|
|
1369
|
+
];
|
|
1370
|
+
});
|
|
1371
|
+
})();
|
|
1372
|
+
};
|
|
1373
|
+
podElements = adElements.filter(function(el) {
|
|
1374
|
+
return getAdSequence(el) !== void 0;
|
|
1375
|
+
}).sort(function(a, b) {
|
|
1376
|
+
return getAdSequence(a) - getAdSequence(b);
|
|
1377
|
+
});
|
|
1378
|
+
buffet = adElements.filter(function(el) {
|
|
1379
|
+
return getAdSequence(el) === void 0;
|
|
1055
1380
|
});
|
|
1056
1381
|
ads = [];
|
|
1382
|
+
if (!(podElements.length === 0)) return [
|
|
1383
|
+
3,
|
|
1384
|
+
10
|
|
1385
|
+
];
|
|
1057
1386
|
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1058
1387
|
_state.label = 2;
|
|
1059
1388
|
case 2:
|
|
1060
1389
|
_state.trys.push([
|
|
1061
1390
|
2,
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1391
|
+
7,
|
|
1392
|
+
8,
|
|
1393
|
+
9
|
|
1065
1394
|
]);
|
|
1066
|
-
_iterator =
|
|
1395
|
+
_iterator = buffet[Symbol.iterator]();
|
|
1067
1396
|
_state.label = 3;
|
|
1068
1397
|
case 3:
|
|
1069
1398
|
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
1070
1399
|
3,
|
|
1071
|
-
|
|
1400
|
+
6
|
|
1072
1401
|
];
|
|
1073
1402
|
adElement = _step.value;
|
|
1074
|
-
parsed = parseAdElement(adElement);
|
|
1075
|
-
if (!(parsed.type === "inline")) return [
|
|
1076
|
-
3,
|
|
1077
|
-
4
|
|
1078
|
-
];
|
|
1079
|
-
ads.push(parsed.ad);
|
|
1080
1403
|
return [
|
|
1081
|
-
|
|
1082
|
-
|
|
1404
|
+
4,
|
|
1405
|
+
resolveAd(adElement)
|
|
1083
1406
|
];
|
|
1084
1407
|
case 4:
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
8
|
|
1088
|
-
];
|
|
1408
|
+
ad = _state.sent();
|
|
1409
|
+
if (ad) ads.push(ad);
|
|
1089
1410
|
_state.label = 5;
|
|
1090
1411
|
case 5:
|
|
1091
|
-
|
|
1092
|
-
5,
|
|
1093
|
-
7,
|
|
1094
|
-
,
|
|
1095
|
-
8
|
|
1096
|
-
]);
|
|
1412
|
+
_iteratorNormalCompletion = true;
|
|
1097
1413
|
return [
|
|
1098
|
-
|
|
1099
|
-
|
|
1414
|
+
3,
|
|
1415
|
+
3
|
|
1100
1416
|
];
|
|
1101
1417
|
case 6:
|
|
1102
|
-
resolved = _state.sent();
|
|
1103
|
-
if (resolved) {
|
|
1104
|
-
ads.push(resolved);
|
|
1105
|
-
}
|
|
1106
1418
|
return [
|
|
1107
1419
|
3,
|
|
1108
|
-
|
|
1420
|
+
9
|
|
1109
1421
|
];
|
|
1110
1422
|
case 7:
|
|
1111
|
-
|
|
1112
|
-
|
|
1423
|
+
err = _state.sent();
|
|
1424
|
+
_didIteratorError = true;
|
|
1425
|
+
_iteratorError = err;
|
|
1113
1426
|
return [
|
|
1114
1427
|
3,
|
|
1115
|
-
|
|
1428
|
+
9
|
|
1116
1429
|
];
|
|
1117
1430
|
case 8:
|
|
1118
|
-
|
|
1431
|
+
try {
|
|
1432
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1433
|
+
_iterator.return();
|
|
1434
|
+
}
|
|
1435
|
+
} finally{
|
|
1436
|
+
if (_didIteratorError) {
|
|
1437
|
+
throw _iteratorError;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1119
1440
|
return [
|
|
1120
|
-
|
|
1121
|
-
3
|
|
1441
|
+
7
|
|
1122
1442
|
];
|
|
1123
1443
|
case 9:
|
|
1124
1444
|
return [
|
|
1125
1445
|
3,
|
|
1126
|
-
|
|
1446
|
+
21
|
|
1127
1447
|
];
|
|
1128
1448
|
case 10:
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1449
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
1450
|
+
_state.label = 11;
|
|
1451
|
+
case 11:
|
|
1452
|
+
_state.trys.push([
|
|
1453
|
+
11,
|
|
1454
|
+
19,
|
|
1455
|
+
20,
|
|
1456
|
+
21
|
|
1457
|
+
]);
|
|
1458
|
+
_iterator1 = podElements[Symbol.iterator]();
|
|
1459
|
+
_state.label = 12;
|
|
1460
|
+
case 12:
|
|
1461
|
+
if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
|
|
1462
|
+
3,
|
|
1463
|
+
18
|
|
1464
|
+
];
|
|
1465
|
+
adElement1 = _step1.value;
|
|
1466
|
+
return [
|
|
1467
|
+
4,
|
|
1468
|
+
resolveAd(adElement1)
|
|
1469
|
+
];
|
|
1470
|
+
case 13:
|
|
1471
|
+
ad1 = _state.sent();
|
|
1472
|
+
_state.label = 14;
|
|
1473
|
+
case 14:
|
|
1474
|
+
if (!(!ad1 && buffet.length > 0)) return [
|
|
1475
|
+
3,
|
|
1476
|
+
16
|
|
1477
|
+
];
|
|
1478
|
+
return [
|
|
1479
|
+
4,
|
|
1480
|
+
resolveAd(buffet.shift())
|
|
1481
|
+
];
|
|
1482
|
+
case 15:
|
|
1483
|
+
ad1 = _state.sent();
|
|
1484
|
+
return [
|
|
1485
|
+
3,
|
|
1486
|
+
14
|
|
1487
|
+
];
|
|
1488
|
+
case 16:
|
|
1489
|
+
if (ad1) ads.push(ad1);
|
|
1490
|
+
_state.label = 17;
|
|
1491
|
+
case 17:
|
|
1492
|
+
_iteratorNormalCompletion1 = true;
|
|
1132
1493
|
return [
|
|
1133
1494
|
3,
|
|
1134
1495
|
12
|
|
1135
1496
|
];
|
|
1136
|
-
case
|
|
1497
|
+
case 18:
|
|
1498
|
+
return [
|
|
1499
|
+
3,
|
|
1500
|
+
21
|
|
1501
|
+
];
|
|
1502
|
+
case 19:
|
|
1503
|
+
err = _state.sent();
|
|
1504
|
+
_didIteratorError1 = true;
|
|
1505
|
+
_iteratorError1 = err;
|
|
1506
|
+
return [
|
|
1507
|
+
3,
|
|
1508
|
+
21
|
|
1509
|
+
];
|
|
1510
|
+
case 20:
|
|
1137
1511
|
try {
|
|
1138
|
-
if (!
|
|
1139
|
-
|
|
1512
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
1513
|
+
_iterator1.return();
|
|
1140
1514
|
}
|
|
1141
1515
|
} finally{
|
|
1142
|
-
if (
|
|
1143
|
-
throw
|
|
1516
|
+
if (_didIteratorError1) {
|
|
1517
|
+
throw _iteratorError1;
|
|
1144
1518
|
}
|
|
1145
1519
|
}
|
|
1146
1520
|
return [
|
|
1147
1521
|
7
|
|
1148
1522
|
];
|
|
1149
|
-
case
|
|
1150
|
-
console.log("[HlsAdPlayer] Parsed ".concat(ads.length, " ad(s) from pod
|
|
1523
|
+
case 21:
|
|
1524
|
+
console.log("[HlsAdPlayer] Parsed ".concat(ads.length, " ad(s) from VAST ").concat((_root_getAttribute = root.getAttribute("version")) !== null && _root_getAttribute !== void 0 ? _root_getAttribute : "", " pod response"));
|
|
1151
1525
|
return [
|
|
1152
1526
|
2,
|
|
1153
1527
|
ads
|
|
@@ -1177,7 +1551,40 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1177
1551
|
var onTimeUpdate = function onTimeUpdate() {
|
|
1178
1552
|
if (!currentAd || !adVideoElement) return;
|
|
1179
1553
|
noteAdProgress();
|
|
1180
|
-
|
|
1554
|
+
sampleViewability();
|
|
1555
|
+
var currentTime = adVideoElement.currentTime;
|
|
1556
|
+
if (trackingFired.start) {
|
|
1557
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1558
|
+
try {
|
|
1559
|
+
for(var _iterator = currentAd.trackingUrls.progress[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1560
|
+
var event = _step.value;
|
|
1561
|
+
var _event_offsetSeconds, _event_offsetPercent;
|
|
1562
|
+
if (trackingFired.progressFired.has(event)) continue;
|
|
1563
|
+
var threshold = (_event_offsetSeconds = event.offsetSeconds) !== null && _event_offsetSeconds !== void 0 ? _event_offsetSeconds : ((_event_offsetPercent = event.offsetPercent) !== null && _event_offsetPercent !== void 0 ? _event_offsetPercent : 0) / 100 * currentAd.duration;
|
|
1564
|
+
if (currentTime >= threshold) {
|
|
1565
|
+
trackingFired.progressFired.add(event);
|
|
1566
|
+
fireTrackingPixels([
|
|
1567
|
+
event.url
|
|
1568
|
+
]);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
} catch (err) {
|
|
1572
|
+
_didIteratorError = true;
|
|
1573
|
+
_iteratorError = err;
|
|
1574
|
+
} finally{
|
|
1575
|
+
try {
|
|
1576
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1577
|
+
_iterator.return();
|
|
1578
|
+
}
|
|
1579
|
+
} finally{
|
|
1580
|
+
if (_didIteratorError) {
|
|
1581
|
+
throw _iteratorError;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
if (!(currentAd.duration > 0)) return;
|
|
1587
|
+
var progress = currentTime / currentAd.duration;
|
|
1181
1588
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
1182
1589
|
trackingFired.firstQuartile = true;
|
|
1183
1590
|
fireTrackingPixels(currentAd.trackingUrls.firstQuartile);
|
|
@@ -1199,15 +1606,38 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1199
1606
|
handleVideoDecodeFailure();
|
|
1200
1607
|
}
|
|
1201
1608
|
};
|
|
1609
|
+
var onCanPlay = function onCanPlay() {
|
|
1610
|
+
if (!currentAd || trackingFired.loaded) return;
|
|
1611
|
+
trackingFired.loaded = true;
|
|
1612
|
+
fireTrackingPixels(currentAd.trackingUrls.loaded);
|
|
1613
|
+
};
|
|
1202
1614
|
var onPlaying = function onPlaying() {
|
|
1203
1615
|
startStallWatchdog();
|
|
1204
|
-
if (!currentAd ||
|
|
1616
|
+
if (!currentAd || !adVideoElement) return;
|
|
1617
|
+
if (!trackingFired.impression) {
|
|
1618
|
+
trackingFired.impression = true;
|
|
1619
|
+
resolvedAds.add(currentAd);
|
|
1620
|
+
fireTrackingPixels(currentAd.trackingUrls.impression);
|
|
1621
|
+
fireTrackingPixels(currentAd.trackingUrls.creativeView);
|
|
1622
|
+
fireTrackingPixels(currentAd.trackingUrls.verificationNotExecuted, {
|
|
1623
|
+
reason: VERIFICATION_NOT_SUPPORTED_REASON
|
|
1624
|
+
});
|
|
1625
|
+
emit("ad_impression", {
|
|
1626
|
+
adId: currentAd.id,
|
|
1627
|
+
index: podIndex,
|
|
1628
|
+
total: podAds.length || 1
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
if (trackingFired.start) return;
|
|
1205
1632
|
trackingFired.start = true;
|
|
1633
|
+
trackingFired.lastMuted = adVideoElement.muted || adVideoElement.volume === 0;
|
|
1206
1634
|
fireTrackingPixels(currentAd.trackingUrls.start);
|
|
1207
1635
|
console.log("[HlsAdPlayer] Ad started playing");
|
|
1208
1636
|
};
|
|
1209
1637
|
var onEnded = function onEnded() {
|
|
1210
1638
|
if (!currentAd || trackingFired.complete) return;
|
|
1639
|
+
sampleViewability();
|
|
1640
|
+
settleViewability();
|
|
1211
1641
|
trackingFired.complete = true;
|
|
1212
1642
|
fireTrackingPixels(currentAd.trackingUrls.complete);
|
|
1213
1643
|
console.log("[HlsAdPlayer] Ad completed");
|
|
@@ -1219,11 +1649,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1219
1649
|
var onError = function onError(e) {
|
|
1220
1650
|
if (!adPlaying) return;
|
|
1221
1651
|
console.error("[HlsAdPlayer] Ad video error:", e);
|
|
1222
|
-
|
|
1223
|
-
fireTrackingPixels(currentAd.trackingUrls.error, {
|
|
1224
|
-
errorCode: toVastMediaErrorCode(adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.error)
|
|
1225
|
-
});
|
|
1226
|
-
}
|
|
1652
|
+
reportCurrentAdError(toVastMediaErrorCode(adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.error));
|
|
1227
1653
|
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1228
1654
|
return;
|
|
1229
1655
|
}
|
|
@@ -1231,19 +1657,26 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1231
1657
|
};
|
|
1232
1658
|
var onVolumeChange = function onVolumeChange() {
|
|
1233
1659
|
if (!currentAd || !adVideoElement) return;
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1660
|
+
var muted = adVideoElement.muted || adVideoElement.volume === 0;
|
|
1661
|
+
if (!trackingFired.start) {
|
|
1662
|
+
trackingFired.lastMuted = muted;
|
|
1663
|
+
return;
|
|
1238
1664
|
}
|
|
1665
|
+
if (muted === trackingFired.lastMuted) return;
|
|
1666
|
+
trackingFired.lastMuted = muted;
|
|
1667
|
+
fireTrackingPixels(muted ? currentAd.trackingUrls.mute : currentAd.trackingUrls.unmute);
|
|
1668
|
+
};
|
|
1669
|
+
var isTrackablePlayback = function isTrackablePlayback() {
|
|
1670
|
+
return adPlaying && !!currentAd && !!adVideoElement && trackingFired.start && !trackingFired.complete && !adVideoElement.ended;
|
|
1239
1671
|
};
|
|
1240
1672
|
var onPause = function onPause() {
|
|
1241
|
-
|
|
1673
|
+
continuousVisibleS = 0;
|
|
1674
|
+
if (isTrackablePlayback()) {
|
|
1242
1675
|
fireTrackingPixels(currentAd.trackingUrls.pause);
|
|
1243
1676
|
}
|
|
1244
1677
|
};
|
|
1245
1678
|
var onPlay = function onPlay() {
|
|
1246
|
-
if (
|
|
1679
|
+
if (isTrackablePlayback()) {
|
|
1247
1680
|
fireTrackingPixels(currentAd.trackingUrls.resume);
|
|
1248
1681
|
}
|
|
1249
1682
|
};
|
|
@@ -1256,6 +1689,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1256
1689
|
type: "loadedmetadata",
|
|
1257
1690
|
handler: onLoadedMetadata
|
|
1258
1691
|
},
|
|
1692
|
+
{
|
|
1693
|
+
type: "canplay",
|
|
1694
|
+
handler: onCanPlay
|
|
1695
|
+
},
|
|
1259
1696
|
{
|
|
1260
1697
|
type: "playing",
|
|
1261
1698
|
handler: onPlaying
|
|
@@ -1327,6 +1764,229 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1327
1764
|
}
|
|
1328
1765
|
adEventHandlers = [];
|
|
1329
1766
|
}
|
|
1767
|
+
function handleAdClick() {
|
|
1768
|
+
if (!adPlaying || !currentAd) return;
|
|
1769
|
+
fireTrackingPixels(currentAd.trackingUrls.clickTracking);
|
|
1770
|
+
emit("ad_click", {
|
|
1771
|
+
adId: currentAd.id,
|
|
1772
|
+
clickThrough: currentAd.clickThrough
|
|
1773
|
+
});
|
|
1774
|
+
if (currentAd.clickThrough) {
|
|
1775
|
+
try {
|
|
1776
|
+
window.open(currentAd.clickThrough, "_blank", "noopener");
|
|
1777
|
+
} catch (error) {
|
|
1778
|
+
console.warn("[HlsAdPlayer] Failed to open ClickThrough URL:", error);
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
function reportCurrentAdError(errorCode) {
|
|
1783
|
+
if (!currentAd) return;
|
|
1784
|
+
resolvedAds.add(currentAd);
|
|
1785
|
+
fireTrackingPixels(currentAd.trackingUrls.error, {
|
|
1786
|
+
errorCode: errorCode
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
function fireNotUsedForUnplayedAds() {
|
|
1790
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1791
|
+
try {
|
|
1792
|
+
for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1793
|
+
var ad = _step.value;
|
|
1794
|
+
if (resolvedAds.has(ad)) continue;
|
|
1795
|
+
resolvedAds.add(ad);
|
|
1796
|
+
fireTrackingPixels(ad.trackingUrls.notUsed, {
|
|
1797
|
+
ad: ad
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
} catch (err) {
|
|
1801
|
+
_didIteratorError = true;
|
|
1802
|
+
_iteratorError = err;
|
|
1803
|
+
} finally{
|
|
1804
|
+
try {
|
|
1805
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1806
|
+
_iterator.return();
|
|
1807
|
+
}
|
|
1808
|
+
} finally{
|
|
1809
|
+
if (_didIteratorError) {
|
|
1810
|
+
throw _iteratorError;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
function sampleViewability() {
|
|
1816
|
+
if (!currentAd || !adVideoElement || !viewObserver || !trackingFired.impression || trackingFired.viewabilitySettled) {
|
|
1817
|
+
return;
|
|
1818
|
+
}
|
|
1819
|
+
var now = adVideoElement.currentTime;
|
|
1820
|
+
var inView = visibleRatio >= VIEWABLE_MIN_VISIBLE_RATIO && document.visibilityState === "visible" && !adVideoElement.paused;
|
|
1821
|
+
if (!inView) {
|
|
1822
|
+
continuousVisibleS = 0;
|
|
1823
|
+
} else if (lastViewSampleTime !== void 0 && now >= lastViewSampleTime) {
|
|
1824
|
+
continuousVisibleS += now - lastViewSampleTime;
|
|
1825
|
+
}
|
|
1826
|
+
lastViewSampleTime = now;
|
|
1827
|
+
if (continuousVisibleS >= VIEWABLE_MIN_CONTINUOUS_S) {
|
|
1828
|
+
trackingFired.viewabilitySettled = true;
|
|
1829
|
+
fireTrackingPixels(currentAd.trackingUrls.viewable);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
function settleViewability() {
|
|
1833
|
+
if (!currentAd || !trackingFired.impression || trackingFired.viewabilitySettled) {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
trackingFired.viewabilitySettled = true;
|
|
1837
|
+
fireTrackingPixels(viewObserver ? currentAd.trackingUrls.notViewable : currentAd.trackingUrls.viewUndetermined);
|
|
1838
|
+
}
|
|
1839
|
+
function handleFullscreenChange() {
|
|
1840
|
+
var _document_fullscreenElement;
|
|
1841
|
+
if (!adPlaying || !currentAd || !adContainerEl || !trackingFired.start) return;
|
|
1842
|
+
var fullscreenEl = (_document_fullscreenElement = document.fullscreenElement) !== null && _document_fullscreenElement !== void 0 ? _document_fullscreenElement : document.webkitFullscreenElement;
|
|
1843
|
+
var expanded = !!fullscreenEl && fullscreenEl.contains(adContainerEl);
|
|
1844
|
+
if (expanded === lastPlayerExpanded) return;
|
|
1845
|
+
lastPlayerExpanded = expanded;
|
|
1846
|
+
var urls = currentAd.trackingUrls;
|
|
1847
|
+
fireTrackingPixels(expanded ? urls.fullscreen.concat(urls.playerExpand) : urls.exitFullscreen.concat(urls.playerCollapse));
|
|
1848
|
+
}
|
|
1849
|
+
function attachContainerHandlers() {
|
|
1850
|
+
if (!adContainerEl || containerHandlers.length > 0) return;
|
|
1851
|
+
var onClick = function onClick() {
|
|
1852
|
+
return handleAdClick();
|
|
1853
|
+
};
|
|
1854
|
+
var onInteraction = function onInteraction(event) {
|
|
1855
|
+
if (adPlaying) emit("ad_interaction", event);
|
|
1856
|
+
};
|
|
1857
|
+
containerHandlers = [
|
|
1858
|
+
{
|
|
1859
|
+
type: "click",
|
|
1860
|
+
handler: onClick
|
|
1861
|
+
},
|
|
1862
|
+
{
|
|
1863
|
+
type: "mousedown",
|
|
1864
|
+
handler: onInteraction
|
|
1865
|
+
},
|
|
1866
|
+
{
|
|
1867
|
+
type: "touchstart",
|
|
1868
|
+
handler: onInteraction
|
|
1869
|
+
}
|
|
1870
|
+
];
|
|
1871
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1872
|
+
try {
|
|
1873
|
+
for(var _iterator = containerHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1874
|
+
var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
|
|
1875
|
+
adContainerEl.addEventListener(type, handler);
|
|
1876
|
+
}
|
|
1877
|
+
} catch (err) {
|
|
1878
|
+
_didIteratorError = true;
|
|
1879
|
+
_iteratorError = err;
|
|
1880
|
+
} finally{
|
|
1881
|
+
try {
|
|
1882
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1883
|
+
_iterator.return();
|
|
1884
|
+
}
|
|
1885
|
+
} finally{
|
|
1886
|
+
if (_didIteratorError) {
|
|
1887
|
+
throw _iteratorError;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
var onFullscreenChange = function onFullscreenChange() {
|
|
1892
|
+
return handleFullscreenChange();
|
|
1893
|
+
};
|
|
1894
|
+
documentHandlers = [
|
|
1895
|
+
{
|
|
1896
|
+
type: "fullscreenchange",
|
|
1897
|
+
handler: onFullscreenChange
|
|
1898
|
+
},
|
|
1899
|
+
{
|
|
1900
|
+
type: "webkitfullscreenchange",
|
|
1901
|
+
handler: onFullscreenChange
|
|
1902
|
+
}
|
|
1903
|
+
];
|
|
1904
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
1905
|
+
try {
|
|
1906
|
+
for(var _iterator1 = documentHandlers[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
1907
|
+
var _step_value1 = _step1.value, type1 = _step_value1.type, handler1 = _step_value1.handler;
|
|
1908
|
+
document.addEventListener(type1, handler1);
|
|
1909
|
+
}
|
|
1910
|
+
} catch (err) {
|
|
1911
|
+
_didIteratorError1 = true;
|
|
1912
|
+
_iteratorError1 = err;
|
|
1913
|
+
} finally{
|
|
1914
|
+
try {
|
|
1915
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
1916
|
+
_iterator1.return();
|
|
1917
|
+
}
|
|
1918
|
+
} finally{
|
|
1919
|
+
if (_didIteratorError1) {
|
|
1920
|
+
throw _iteratorError1;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
1925
|
+
viewObserver = new IntersectionObserver(function(entries) {
|
|
1926
|
+
var entry = entries[entries.length - 1];
|
|
1927
|
+
if (entry) {
|
|
1928
|
+
visibleRatio = entry.isIntersecting ? entry.intersectionRatio : 0;
|
|
1929
|
+
}
|
|
1930
|
+
}, {
|
|
1931
|
+
threshold: [
|
|
1932
|
+
0,
|
|
1933
|
+
0.25,
|
|
1934
|
+
0.5,
|
|
1935
|
+
0.75,
|
|
1936
|
+
1
|
|
1937
|
+
]
|
|
1938
|
+
});
|
|
1939
|
+
viewObserver.observe(adContainerEl);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
function detachContainerHandlers() {
|
|
1943
|
+
if (adContainerEl) {
|
|
1944
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1945
|
+
try {
|
|
1946
|
+
for(var _iterator = containerHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1947
|
+
var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
|
|
1948
|
+
adContainerEl.removeEventListener(type, handler);
|
|
1949
|
+
}
|
|
1950
|
+
} catch (err) {
|
|
1951
|
+
_didIteratorError = true;
|
|
1952
|
+
_iteratorError = err;
|
|
1953
|
+
} finally{
|
|
1954
|
+
try {
|
|
1955
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1956
|
+
_iterator.return();
|
|
1957
|
+
}
|
|
1958
|
+
} finally{
|
|
1959
|
+
if (_didIteratorError) {
|
|
1960
|
+
throw _iteratorError;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
containerHandlers = [];
|
|
1966
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
1967
|
+
try {
|
|
1968
|
+
for(var _iterator1 = documentHandlers[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
1969
|
+
var _step_value1 = _step1.value, type1 = _step_value1.type, handler1 = _step_value1.handler;
|
|
1970
|
+
document.removeEventListener(type1, handler1);
|
|
1971
|
+
}
|
|
1972
|
+
} catch (err) {
|
|
1973
|
+
_didIteratorError1 = true;
|
|
1974
|
+
_iteratorError1 = err;
|
|
1975
|
+
} finally{
|
|
1976
|
+
try {
|
|
1977
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
1978
|
+
_iterator1.return();
|
|
1979
|
+
}
|
|
1980
|
+
} finally{
|
|
1981
|
+
if (_didIteratorError1) {
|
|
1982
|
+
throw _iteratorError1;
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
documentHandlers = [];
|
|
1987
|
+
viewObserver === null || viewObserver === void 0 ? void 0 : viewObserver.disconnect();
|
|
1988
|
+
viewObserver = void 0;
|
|
1989
|
+
}
|
|
1330
1990
|
function setAdPlayingFlag(isPlaying) {
|
|
1331
1991
|
if (isPlaying) {
|
|
1332
1992
|
contentVideo.dataset.stormcloudAdPlaying = "true";
|
|
@@ -1334,15 +1994,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1334
1994
|
delete contentVideo.dataset.stormcloudAdPlaying;
|
|
1335
1995
|
}
|
|
1336
1996
|
}
|
|
1337
|
-
function
|
|
1338
|
-
trackingFired =
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
firstQuartile: false,
|
|
1342
|
-
midpoint: false,
|
|
1343
|
-
thirdQuartile: false,
|
|
1344
|
-
complete: false
|
|
1345
|
-
};
|
|
1997
|
+
function resetAdTracking() {
|
|
1998
|
+
trackingFired = createTrackingState();
|
|
1999
|
+
continuousVisibleS = 0;
|
|
2000
|
+
lastViewSampleTime = void 0;
|
|
1346
2001
|
}
|
|
1347
2002
|
function isRvfcSupported(video) {
|
|
1348
2003
|
return typeof video.requestVideoFrameCallback === "function";
|
|
@@ -1448,13 +2103,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1448
2103
|
if (podIndex >= podAds.length - 1) {
|
|
1449
2104
|
return false;
|
|
1450
2105
|
}
|
|
2106
|
+
settleViewability();
|
|
1451
2107
|
podIndex++;
|
|
1452
2108
|
currentAd = podAds[podIndex];
|
|
1453
2109
|
currentAdMediaFile = void 0;
|
|
1454
|
-
|
|
2110
|
+
resetAdTracking();
|
|
1455
2111
|
if (currentAd) {
|
|
1456
|
-
fireTrackingPixels(currentAd.trackingUrls.impression);
|
|
1457
|
-
trackingFired.impression = true;
|
|
1458
2112
|
console.log("[HlsAdPlayer] Advancing to next pod ad (".concat(podIndex + 1, "/").concat(podAds.length, "): ").concat(currentAd.title, ", duration: ").concat(currentAd.duration, "s"));
|
|
1459
2113
|
}
|
|
1460
2114
|
clearStallWatchdog();
|
|
@@ -1492,11 +2146,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1492
2146
|
function handleAdStall() {
|
|
1493
2147
|
console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
|
|
1494
2148
|
clearStallWatchdog();
|
|
1495
|
-
|
|
1496
|
-
fireTrackingPixels(currentAd.trackingUrls.error, {
|
|
1497
|
-
errorCode: VAST_ERROR_MEDIA_DISPLAY
|
|
1498
|
-
});
|
|
1499
|
-
}
|
|
2149
|
+
reportCurrentAdError(VAST_ERROR_MEDIA_DISPLAY);
|
|
1500
2150
|
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1501
2151
|
return;
|
|
1502
2152
|
}
|
|
@@ -1562,11 +2212,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1562
2212
|
function handleVideoDecodeFailure() {
|
|
1563
2213
|
console.warn("[HlsAdPlayer] Ad audio is advancing but no video frames decoded (black screen) - skipping this creative");
|
|
1564
2214
|
clearStallWatchdog();
|
|
1565
|
-
|
|
1566
|
-
fireTrackingPixels(currentAd.trackingUrls.error, {
|
|
1567
|
-
errorCode: VAST_ERROR_MEDIA_DISPLAY
|
|
1568
|
-
});
|
|
1569
|
-
}
|
|
2215
|
+
reportCurrentAdError(VAST_ERROR_MEDIA_DISPLAY);
|
|
1570
2216
|
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1571
2217
|
return;
|
|
1572
2218
|
}
|
|
@@ -1621,6 +2267,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1621
2267
|
}
|
|
1622
2268
|
function handleAdComplete() {
|
|
1623
2269
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
2270
|
+
settleViewability();
|
|
1624
2271
|
clearStallWatchdog();
|
|
1625
2272
|
adPlaying = false;
|
|
1626
2273
|
setAdPlayingFlag(false);
|
|
@@ -1644,6 +2291,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1644
2291
|
}
|
|
1645
2292
|
function handleAdError() {
|
|
1646
2293
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
2294
|
+
settleViewability();
|
|
1647
2295
|
clearStallWatchdog();
|
|
1648
2296
|
adPlaying = false;
|
|
1649
2297
|
setAdPlayingFlag(false);
|
|
@@ -1676,6 +2324,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1676
2324
|
adContainerEl = container;
|
|
1677
2325
|
}
|
|
1678
2326
|
contentVideo[AD_CONTAINER_PROP] = adContainerEl;
|
|
2327
|
+
attachContainerHandlers();
|
|
1679
2328
|
},
|
|
1680
2329
|
requestAds: function requestAds(vastTagUrl) {
|
|
1681
2330
|
return _async_to_generator(function() {
|
|
@@ -1738,10 +2387,6 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1738
2387
|
currentAd = ads[0];
|
|
1739
2388
|
currentAdMediaFile = void 0;
|
|
1740
2389
|
console.log("[HlsAdPlayer] Pod parsed: ".concat(ads.length, ' ad(s), first="').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.title, '", duration=').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.duration, "s"));
|
|
1741
|
-
if (currentAd) {
|
|
1742
|
-
fireTrackingPixels(currentAd.trackingUrls.impression);
|
|
1743
|
-
trackingFired.impression = true;
|
|
1744
|
-
}
|
|
1745
2390
|
return [
|
|
1746
2391
|
2,
|
|
1747
2392
|
Promise.resolve()
|
|
@@ -1781,7 +2426,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1781
2426
|
contentVideo[AD_VIDEO_PROP] = adVideoElement;
|
|
1782
2427
|
}
|
|
1783
2428
|
setupAdEventListeners();
|
|
1784
|
-
|
|
2429
|
+
resetAdTracking();
|
|
1785
2430
|
contentVolume = contentVideo.volume;
|
|
1786
2431
|
originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
|
|
1787
2432
|
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
@@ -1852,6 +2497,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1852
2497
|
var previousMutedState;
|
|
1853
2498
|
return _ts_generator(this, function(_state) {
|
|
1854
2499
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
2500
|
+
settleViewability();
|
|
2501
|
+
fireNotUsedForUnplayedAds();
|
|
1855
2502
|
clearStallWatchdog();
|
|
1856
2503
|
adPlaying = false;
|
|
1857
2504
|
setAdPlayingFlag(false);
|
|
@@ -1882,6 +2529,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1882
2529
|
},
|
|
1883
2530
|
destroy: function destroy() {
|
|
1884
2531
|
console.log("[HlsAdPlayer] Destroying");
|
|
2532
|
+
settleViewability();
|
|
2533
|
+
fireNotUsedForUnplayedAds();
|
|
1885
2534
|
destroyed = true;
|
|
1886
2535
|
clearStallWatchdog();
|
|
1887
2536
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
@@ -1910,6 +2559,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1910
2559
|
contentVideo.muted = originalMutedState;
|
|
1911
2560
|
contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
|
|
1912
2561
|
teardownAdEventListeners();
|
|
2562
|
+
detachContainerHandlers();
|
|
1913
2563
|
releaseAdDecoder();
|
|
1914
2564
|
currentAd = void 0;
|
|
1915
2565
|
currentAdMediaFile = void 0;
|