stormcloud-video-player 0.8.72 → 0.8.74
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/README.md +10 -70
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/Player.d.cts +1 -0
- package/lib/StormcloudPlayer.cjs +992 -276
- package/lib/StormcloudPlayer.cjs.map +1 -1
- package/lib/StormcloudPlayer.d.cts +1 -0
- package/lib/index.cjs +1005 -281
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +40 -3
- package/lib/index.js +998 -282
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.cjs +772 -70
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +7 -9
- package/lib/player/AdConfigManager.cjs +314 -62
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/AdConfigManager.d.cts +7 -12
- package/lib/player/AdTimingService.cjs +37 -1
- package/lib/player/AdTimingService.cjs.map +1 -1
- package/lib/player/AdTimingService.d.cts +8 -1
- package/lib/player/EdgePodRequest.d.cts +1 -0
- package/lib/player/FloorLadder.d.cts +1 -0
- package/lib/player/HlsEngine.d.cts +1 -0
- package/lib/player/OptimizedPodRequest.cjs +719 -0
- package/lib/player/OptimizedPodRequest.cjs.map +1 -0
- package/lib/player/OptimizedPodRequest.d.cts +101 -0
- package/lib/player/PlayerControls.d.cts +1 -0
- package/lib/player/Scte35CueManager.d.cts +1 -0
- package/lib/player/Scte35Parser.d.cts +1 -0
- package/lib/player/StormcloudVideoPlayer.cjs +992 -276
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/player/playerTypes.d.cts +1 -0
- package/lib/players/HlsPlayer.cjs +992 -276
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -0
- package/lib/players/index.cjs +992 -276
- package/lib/players/index.cjs.map +1 -1
- package/lib/props.d.cts +1 -0
- package/lib/sdk/hlsAdPlayer.cjs +316 -51
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +3 -1
- package/lib/sdk/pal.cjs +108 -83
- package/lib/sdk/pal.cjs.map +1 -1
- package/lib/sdk/pal.d.cts +1 -0
- package/lib/types.d.cts +9 -2
- package/lib/ui/StormcloudVideoPlayer.cjs +997 -281
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/utils/ctvVastSignals.cjs +9 -7
- package/lib/utils/ctvVastSignals.cjs.map +1 -1
- package/lib/utils/tracking.cjs +17 -3
- package/lib/utils/tracking.cjs.map +1 -1
- package/lib/utils/tracking.d.cts +2 -1
- package/lib/utils/vastEnvironmentSignals.cjs +9 -7
- package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
- package/lib/utils/vastMacros.cjs +250 -10
- package/lib/utils/vastMacros.cjs.map +1 -1
- package/lib/utils/vastMacros.d.cts +13 -4
- package/package.json +5 -3
|
@@ -0,0 +1,719 @@
|
|
|
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
|
+
}
|
|
10
|
+
function _array_without_holes(arr) {
|
|
11
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
12
|
+
}
|
|
13
|
+
function _iterable_to_array(iter) {
|
|
14
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
|
|
15
|
+
return Array.from(iter);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function _iterable_to_array_limit(arr, i) {
|
|
19
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
20
|
+
if (_i == null) return;
|
|
21
|
+
var _arr = [];
|
|
22
|
+
var _n = true;
|
|
23
|
+
var _d = false;
|
|
24
|
+
var _s, _e;
|
|
25
|
+
try {
|
|
26
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
27
|
+
_arr.push(_s.value);
|
|
28
|
+
if (i && _arr.length === i) break;
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
_d = true;
|
|
32
|
+
_e = err;
|
|
33
|
+
} finally{
|
|
34
|
+
try {
|
|
35
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
36
|
+
} finally{
|
|
37
|
+
if (_d) throw _e;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return _arr;
|
|
41
|
+
}
|
|
42
|
+
function _non_iterable_rest() {
|
|
43
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
44
|
+
}
|
|
45
|
+
function _non_iterable_spread() {
|
|
46
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
47
|
+
}
|
|
48
|
+
function _sliced_to_array(arr, i) {
|
|
49
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
50
|
+
}
|
|
51
|
+
function _to_consumable_array(arr) {
|
|
52
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
53
|
+
}
|
|
54
|
+
function _type_of(obj) {
|
|
55
|
+
"@swc/helpers - typeof";
|
|
56
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
57
|
+
}
|
|
58
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
59
|
+
if (!o) return;
|
|
60
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
61
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
62
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
63
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
64
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
65
|
+
}
|
|
66
|
+
var __defProp = Object.defineProperty;
|
|
67
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
68
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
69
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
70
|
+
var __export = function __export(target, all) {
|
|
71
|
+
for(var name in all)__defProp(target, name, {
|
|
72
|
+
get: all[name],
|
|
73
|
+
enumerable: true
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
var __copyProps = function __copyProps(to, from, except, desc) {
|
|
77
|
+
if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
|
|
78
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
79
|
+
try {
|
|
80
|
+
var _loop = function() {
|
|
81
|
+
var key = _step.value;
|
|
82
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
83
|
+
get: function get() {
|
|
84
|
+
return from[key];
|
|
85
|
+
},
|
|
86
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
|
|
90
|
+
} catch (err) {
|
|
91
|
+
_didIteratorError = true;
|
|
92
|
+
_iteratorError = err;
|
|
93
|
+
} finally{
|
|
94
|
+
try {
|
|
95
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
96
|
+
_iterator.return();
|
|
97
|
+
}
|
|
98
|
+
} finally{
|
|
99
|
+
if (_didIteratorError) {
|
|
100
|
+
throw _iteratorError;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return to;
|
|
106
|
+
};
|
|
107
|
+
var __toCommonJS = function __toCommonJS(mod) {
|
|
108
|
+
return __copyProps(__defProp({}, "__esModule", {
|
|
109
|
+
value: true
|
|
110
|
+
}), mod);
|
|
111
|
+
};
|
|
112
|
+
// src/player/OptimizedPodRequest.ts
|
|
113
|
+
var OptimizedPodRequest_exports = {};
|
|
114
|
+
__export(OptimizedPodRequest_exports, {
|
|
115
|
+
DEFAULT_REQUEST_SAFETY_MS: function DEFAULT_REQUEST_SAFETY_MS1() {
|
|
116
|
+
return DEFAULT_REQUEST_SAFETY_MS;
|
|
117
|
+
},
|
|
118
|
+
GAM_AD_OPPORTUNITY_DURATION_MS: function GAM_AD_OPPORTUNITY_DURATION_MS1() {
|
|
119
|
+
return GAM_AD_OPPORTUNITY_DURATION_MS;
|
|
120
|
+
},
|
|
121
|
+
computePodResponseDiagnostics: function computePodResponseDiagnostics1() {
|
|
122
|
+
return computePodResponseDiagnostics;
|
|
123
|
+
},
|
|
124
|
+
finalizeGamRequestUrl: function finalizeGamRequestUrl1() {
|
|
125
|
+
return finalizeGamRequestUrl;
|
|
126
|
+
},
|
|
127
|
+
isOptimizedPodUrl: function isOptimizedPodUrl1() {
|
|
128
|
+
return isOptimizedPodUrl;
|
|
129
|
+
},
|
|
130
|
+
isPodRequestAbortedError: function isPodRequestAbortedError1() {
|
|
131
|
+
return isPodRequestAbortedError;
|
|
132
|
+
},
|
|
133
|
+
measureBreakCapacity: function measureBreakCapacity1() {
|
|
134
|
+
return measureBreakCapacity;
|
|
135
|
+
},
|
|
136
|
+
resolveAdPodConfig: function resolveAdPodConfig1() {
|
|
137
|
+
return resolveAdPodConfig;
|
|
138
|
+
},
|
|
139
|
+
resolvePodParams: function resolvePodParams1() {
|
|
140
|
+
return resolvePodParams;
|
|
141
|
+
},
|
|
142
|
+
validateGamRequestUrl: function validateGamRequestUrl1() {
|
|
143
|
+
return validateGamRequestUrl;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
module.exports = __toCommonJS(OptimizedPodRequest_exports);
|
|
147
|
+
// src/utils/vastEnvironmentSignals.ts
|
|
148
|
+
var DEVICE_TYPE_HINT = {
|
|
149
|
+
FEATURE_PHONE: 1,
|
|
150
|
+
SMARTPHONE: 2,
|
|
151
|
+
DESKTOP: 3,
|
|
152
|
+
TABLET: 4,
|
|
153
|
+
CONNECTED_TV: 5,
|
|
154
|
+
GAME_CONSOLE: 6,
|
|
155
|
+
SET_TOP_BOX: 7
|
|
156
|
+
};
|
|
157
|
+
var DEVICE_TYPE_HINT_ALIASES = {
|
|
158
|
+
featurephone: DEVICE_TYPE_HINT.FEATURE_PHONE,
|
|
159
|
+
smartphone: DEVICE_TYPE_HINT.SMARTPHONE,
|
|
160
|
+
mobile: DEVICE_TYPE_HINT.SMARTPHONE,
|
|
161
|
+
phone: DEVICE_TYPE_HINT.SMARTPHONE,
|
|
162
|
+
desktop: DEVICE_TYPE_HINT.DESKTOP,
|
|
163
|
+
pc: DEVICE_TYPE_HINT.DESKTOP,
|
|
164
|
+
tablet: DEVICE_TYPE_HINT.TABLET,
|
|
165
|
+
ctv: DEVICE_TYPE_HINT.CONNECTED_TV,
|
|
166
|
+
tv: DEVICE_TYPE_HINT.CONNECTED_TV,
|
|
167
|
+
connectedtv: DEVICE_TYPE_HINT.CONNECTED_TV,
|
|
168
|
+
smarttv: DEVICE_TYPE_HINT.CONNECTED_TV,
|
|
169
|
+
console: DEVICE_TYPE_HINT.GAME_CONSOLE,
|
|
170
|
+
gameconsole: DEVICE_TYPE_HINT.GAME_CONSOLE,
|
|
171
|
+
stb: DEVICE_TYPE_HINT.SET_TOP_BOX,
|
|
172
|
+
settopbox: DEVICE_TYPE_HINT.SET_TOP_BOX
|
|
173
|
+
};
|
|
174
|
+
var PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5;
|
|
175
|
+
// src/utils/vastMacros.ts
|
|
176
|
+
var INVALID_VAST_PARAM_KEY = /^\s|\s$/;
|
|
177
|
+
function removeBrokenAppNameOrphans(params, appName) {
|
|
178
|
+
var toDelete = [];
|
|
179
|
+
params.forEach(function(_value, key) {
|
|
180
|
+
if (!key || INVALID_VAST_PARAM_KEY.test(key)) {
|
|
181
|
+
toDelete.push(key);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
if (appName && appName.includes("&")) {
|
|
185
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
186
|
+
try {
|
|
187
|
+
for(var _iterator = appName.split("&").slice(1)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
188
|
+
var suffix = _step.value;
|
|
189
|
+
var trimmed = suffix.replace(/^\s+/, "");
|
|
190
|
+
if (!trimmed) continue;
|
|
191
|
+
toDelete.push(suffix, " ".concat(trimmed), trimmed);
|
|
192
|
+
}
|
|
193
|
+
} catch (err) {
|
|
194
|
+
_didIteratorError = true;
|
|
195
|
+
_iteratorError = err;
|
|
196
|
+
} finally{
|
|
197
|
+
try {
|
|
198
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
199
|
+
_iterator.return();
|
|
200
|
+
}
|
|
201
|
+
} finally{
|
|
202
|
+
if (_didIteratorError) {
|
|
203
|
+
throw _iteratorError;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
209
|
+
try {
|
|
210
|
+
for(var _iterator1 = new Set(toDelete)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
211
|
+
var key = _step1.value;
|
|
212
|
+
if (key) params.delete(key);
|
|
213
|
+
}
|
|
214
|
+
} catch (err) {
|
|
215
|
+
_didIteratorError1 = true;
|
|
216
|
+
_iteratorError1 = err;
|
|
217
|
+
} finally{
|
|
218
|
+
try {
|
|
219
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
220
|
+
_iterator1.return();
|
|
221
|
+
}
|
|
222
|
+
} finally{
|
|
223
|
+
if (_didIteratorError1) {
|
|
224
|
+
throw _iteratorError1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function normalizeVastTagUrl(raw) {
|
|
230
|
+
if (!raw) return raw;
|
|
231
|
+
try {
|
|
232
|
+
var url = new URL(raw);
|
|
233
|
+
var anValue = url.searchParams.get("an");
|
|
234
|
+
if (anValue !== null) {
|
|
235
|
+
var orphanFragments = [];
|
|
236
|
+
url.searchParams.forEach(function(_value, key) {
|
|
237
|
+
if (key && INVALID_VAST_PARAM_KEY.test(key)) {
|
|
238
|
+
orphanFragments.push(key.trim());
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
if (orphanFragments.length > 0) {
|
|
242
|
+
var reconstructed = [
|
|
243
|
+
anValue.replace(/\s+$/, "")
|
|
244
|
+
].concat(_to_consumable_array(orphanFragments)).filter(Boolean).join(" & ");
|
|
245
|
+
url.searchParams.forEach(function(_value, key) {
|
|
246
|
+
if (key && INVALID_VAST_PARAM_KEY.test(key)) {
|
|
247
|
+
url.searchParams.delete(key);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
url.searchParams.set("an", reconstructed);
|
|
251
|
+
return url.toString().replace(/([?&]an=)([^&]*)/, function(_match, prefix, val) {
|
|
252
|
+
return prefix + val.replace(/\+/g, "%20");
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
removeBrokenAppNameOrphans(url.searchParams);
|
|
257
|
+
return url.toString();
|
|
258
|
+
} catch (unused) {
|
|
259
|
+
return raw;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
|
|
263
|
+
var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
|
|
264
|
+
var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
|
|
265
|
+
var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
|
|
266
|
+
"cust_params"
|
|
267
|
+
]);
|
|
268
|
+
var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
|
|
269
|
+
"PMND",
|
|
270
|
+
"PMXD",
|
|
271
|
+
"PMAD"
|
|
272
|
+
]);
|
|
273
|
+
function safeDecode(value) {
|
|
274
|
+
try {
|
|
275
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
276
|
+
} catch (unused) {
|
|
277
|
+
return value;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function findScvpMacroNames(url) {
|
|
281
|
+
if (!url) return [];
|
|
282
|
+
var names = /* @__PURE__ */ new Set();
|
|
283
|
+
var text = url;
|
|
284
|
+
for(var pass = 0; pass < 3; pass++){
|
|
285
|
+
text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
|
|
286
|
+
names.add(String(bracketName || parenName).toUpperCase());
|
|
287
|
+
return "";
|
|
288
|
+
});
|
|
289
|
+
var decoded = safeDecode(text);
|
|
290
|
+
if (decoded === text) break;
|
|
291
|
+
text = decoded;
|
|
292
|
+
}
|
|
293
|
+
return Array.from(names);
|
|
294
|
+
}
|
|
295
|
+
var keepNone = function keepNone() {
|
|
296
|
+
return false;
|
|
297
|
+
};
|
|
298
|
+
function substituteScvpParams(params, values, unresolved, keep, nested) {
|
|
299
|
+
var out = [];
|
|
300
|
+
var replaceMacro = function replaceMacro(match, bracketName, parenName) {
|
|
301
|
+
var name = String(bracketName || parenName).toUpperCase();
|
|
302
|
+
var value = values.get(name);
|
|
303
|
+
if (value != null) return value;
|
|
304
|
+
if (keep(name)) return match;
|
|
305
|
+
unresolved.add(name);
|
|
306
|
+
return "";
|
|
307
|
+
};
|
|
308
|
+
params.forEach(function(value, key) {
|
|
309
|
+
var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
|
|
310
|
+
if (whole) {
|
|
311
|
+
var name = String(whole[1] || whole[2]).toUpperCase();
|
|
312
|
+
var resolved = values.get(name);
|
|
313
|
+
if (resolved != null) {
|
|
314
|
+
out.push([
|
|
315
|
+
key,
|
|
316
|
+
resolved
|
|
317
|
+
]);
|
|
318
|
+
} else if (keep(name)) {
|
|
319
|
+
out.push([
|
|
320
|
+
key,
|
|
321
|
+
value
|
|
322
|
+
]);
|
|
323
|
+
} else {
|
|
324
|
+
unresolved.add(name);
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (!SCVP_MACRO_DETECT.test(value)) {
|
|
329
|
+
out.push([
|
|
330
|
+
key,
|
|
331
|
+
value
|
|
332
|
+
]);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
|
|
336
|
+
var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
|
|
337
|
+
if (inner.length > 0) {
|
|
338
|
+
out.push([
|
|
339
|
+
key,
|
|
340
|
+
inner.map(function(param) {
|
|
341
|
+
var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
|
|
342
|
+
return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
|
|
343
|
+
}).join("&")
|
|
344
|
+
]);
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
out.push([
|
|
349
|
+
key,
|
|
350
|
+
value.replace(SCVP_MACRO_PATTERN, replaceMacro)
|
|
351
|
+
]);
|
|
352
|
+
});
|
|
353
|
+
return out;
|
|
354
|
+
}
|
|
355
|
+
function substituteScvpMacros(baseUrl, values) {
|
|
356
|
+
var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
|
|
357
|
+
var unresolved = /* @__PURE__ */ new Set();
|
|
358
|
+
var url;
|
|
359
|
+
try {
|
|
360
|
+
url = new URL(normalizeVastTagUrl(baseUrl));
|
|
361
|
+
} catch (unused) {
|
|
362
|
+
var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
|
|
363
|
+
var name = String(bracketName || parenName).toUpperCase();
|
|
364
|
+
var value = values.get(name);
|
|
365
|
+
if (value != null) return encodeURIComponent(value);
|
|
366
|
+
if (keep(name)) return match;
|
|
367
|
+
unresolved.add(name);
|
|
368
|
+
return "";
|
|
369
|
+
});
|
|
370
|
+
return {
|
|
371
|
+
url: replaced,
|
|
372
|
+
unresolved: Array.from(unresolved)
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
|
|
376
|
+
var search = new URLSearchParams();
|
|
377
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
378
|
+
try {
|
|
379
|
+
for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
380
|
+
var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
|
|
381
|
+
search.append(key, value);
|
|
382
|
+
}
|
|
383
|
+
} catch (err) {
|
|
384
|
+
_didIteratorError = true;
|
|
385
|
+
_iteratorError = err;
|
|
386
|
+
} finally{
|
|
387
|
+
try {
|
|
388
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
389
|
+
_iterator.return();
|
|
390
|
+
}
|
|
391
|
+
} finally{
|
|
392
|
+
if (_didIteratorError) {
|
|
393
|
+
throw _iteratorError;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
url.search = search.toString();
|
|
398
|
+
return {
|
|
399
|
+
url: url.toString(),
|
|
400
|
+
unresolved: Array.from(unresolved)
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
// src/player/OptimizedPodRequest.ts
|
|
404
|
+
var DEFAULT_REQUEST_SAFETY_MS = 1500;
|
|
405
|
+
var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
|
|
406
|
+
var POD_PARAM_KEYS = [
|
|
407
|
+
"pmnd",
|
|
408
|
+
"pmxd",
|
|
409
|
+
"pmad"
|
|
410
|
+
];
|
|
411
|
+
var POSITIVE_INT = /^[1-9]\d*$/;
|
|
412
|
+
var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
|
|
413
|
+
function nonNegativeInt(value) {
|
|
414
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
|
|
415
|
+
}
|
|
416
|
+
function positiveInt(value) {
|
|
417
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
|
|
418
|
+
}
|
|
419
|
+
function resolveAdPodConfig(config) {
|
|
420
|
+
var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
|
|
421
|
+
var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
|
|
422
|
+
return {
|
|
423
|
+
requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
|
|
424
|
+
minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
|
|
425
|
+
maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
|
|
426
|
+
maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
|
|
427
|
+
exactDuration: config.podExactDuration === true
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function measureBreakCapacity(timing, nowMonoMs) {
|
|
431
|
+
var _timing_breakEndMonoMs;
|
|
432
|
+
var scheduled = timing.scheduledBreakDurationMs;
|
|
433
|
+
if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
|
|
434
|
+
return void 0;
|
|
435
|
+
}
|
|
436
|
+
var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
|
|
437
|
+
var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
|
|
438
|
+
var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
|
|
439
|
+
return {
|
|
440
|
+
scheduledBreakDurationMs: scheduled,
|
|
441
|
+
elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
|
|
442
|
+
remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
function resolvePodParams(input) {
|
|
446
|
+
var capacity = input.capacity, config = input.config;
|
|
447
|
+
var pmxd;
|
|
448
|
+
var source;
|
|
449
|
+
if (capacity) {
|
|
450
|
+
pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
|
|
451
|
+
source = "break_remaining";
|
|
452
|
+
} else if (config.maxPodDurationMs != null) {
|
|
453
|
+
pmxd = config.maxPodDurationMs;
|
|
454
|
+
source = "configured_cap";
|
|
455
|
+
} else if (input.tagMaxDurationMs != null) {
|
|
456
|
+
pmxd = input.tagMaxDurationMs;
|
|
457
|
+
source = "tag_cap";
|
|
458
|
+
} else {
|
|
459
|
+
return {
|
|
460
|
+
kind: "omit"
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
|
|
464
|
+
if (!Number.isFinite(pmxd) || pmxd < minUsable) {
|
|
465
|
+
return {
|
|
466
|
+
kind: "abort",
|
|
467
|
+
reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
|
|
468
|
+
pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
|
|
472
|
+
return {
|
|
473
|
+
kind: "send",
|
|
474
|
+
params: {
|
|
475
|
+
pmnd: pmnd,
|
|
476
|
+
pmxd: pmxd,
|
|
477
|
+
pmad: config.maxAdsPerBreak
|
|
478
|
+
},
|
|
479
|
+
source: source
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
function podRequestAborted(reason, message, diagnostics) {
|
|
483
|
+
var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
|
|
484
|
+
error.podRequestAborted = true;
|
|
485
|
+
error.reason = reason;
|
|
486
|
+
error.diagnostics = diagnostics;
|
|
487
|
+
return error;
|
|
488
|
+
}
|
|
489
|
+
function isPodRequestAbortedError(error) {
|
|
490
|
+
return !!error && error.podRequestAborted === true;
|
|
491
|
+
}
|
|
492
|
+
function firstPositiveIntParam(params, key) {
|
|
493
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
494
|
+
try {
|
|
495
|
+
for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
496
|
+
var value = _step.value;
|
|
497
|
+
if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
|
|
498
|
+
}
|
|
499
|
+
} catch (err) {
|
|
500
|
+
_didIteratorError = true;
|
|
501
|
+
_iteratorError = err;
|
|
502
|
+
} finally{
|
|
503
|
+
try {
|
|
504
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
505
|
+
_iterator.return();
|
|
506
|
+
}
|
|
507
|
+
} finally{
|
|
508
|
+
if (_didIteratorError) {
|
|
509
|
+
throw _iteratorError;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return void 0;
|
|
514
|
+
}
|
|
515
|
+
function isOptimizedPodUrl(url) {
|
|
516
|
+
if (findScvpMacroNames(url).some(function(name) {
|
|
517
|
+
return SCVP_POD_MACROS.has(name);
|
|
518
|
+
})) return true;
|
|
519
|
+
try {
|
|
520
|
+
var params = new URL(url).searchParams;
|
|
521
|
+
return POD_PARAM_KEYS.some(function(key) {
|
|
522
|
+
return params.has(key);
|
|
523
|
+
});
|
|
524
|
+
} catch (unused) {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function finalizeGamRequestUrl(rawUrl, ctx) {
|
|
529
|
+
var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
|
|
530
|
+
var optimizedPod = isOptimizedPodUrl(rawUrl);
|
|
531
|
+
var capacity = ctx.capacity;
|
|
532
|
+
var base = {
|
|
533
|
+
breakId: ctx.breakId,
|
|
534
|
+
optimizedPod: optimizedPod,
|
|
535
|
+
scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
|
|
536
|
+
elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
|
|
537
|
+
remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
|
|
538
|
+
safetyReserveMs: ctx.config.requestSafetyMs
|
|
539
|
+
};
|
|
540
|
+
var decision = {
|
|
541
|
+
kind: "omit"
|
|
542
|
+
};
|
|
543
|
+
if (optimizedPod) {
|
|
544
|
+
var tagMaxDurationMs;
|
|
545
|
+
try {
|
|
546
|
+
tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
|
|
547
|
+
} catch (unused) {}
|
|
548
|
+
decision = resolvePodParams({
|
|
549
|
+
capacity: capacity,
|
|
550
|
+
config: ctx.config,
|
|
551
|
+
minUsablePmxdMs: ctx.minUsablePmxdMs,
|
|
552
|
+
tagMaxDurationMs: tagMaxDurationMs
|
|
553
|
+
});
|
|
554
|
+
if (decision.kind === "abort") {
|
|
555
|
+
throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
var pod = decision.kind === "send" ? decision.params : void 0;
|
|
559
|
+
var values = /* @__PURE__ */ new Map();
|
|
560
|
+
if (pod) {
|
|
561
|
+
values.set("PMND", String(pod.pmnd));
|
|
562
|
+
values.set("PMXD", String(pod.pmxd));
|
|
563
|
+
if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
|
|
564
|
+
}
|
|
565
|
+
var substituted = substituteScvpMacros(rawUrl, values);
|
|
566
|
+
var finalUrl;
|
|
567
|
+
try {
|
|
568
|
+
var url = new URL(normalizeVastTagUrl(substituted.url));
|
|
569
|
+
if (pod) {
|
|
570
|
+
url.searchParams.set("pmnd", String(pod.pmnd));
|
|
571
|
+
url.searchParams.set("pmxd", String(pod.pmxd));
|
|
572
|
+
if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
|
|
573
|
+
else url.searchParams.delete("pmad");
|
|
574
|
+
} else {
|
|
575
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
576
|
+
try {
|
|
577
|
+
for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
578
|
+
var key = _step.value;
|
|
579
|
+
url.searchParams.delete(key);
|
|
580
|
+
}
|
|
581
|
+
} catch (err) {
|
|
582
|
+
_didIteratorError = true;
|
|
583
|
+
_iteratorError = err;
|
|
584
|
+
} finally{
|
|
585
|
+
try {
|
|
586
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
587
|
+
_iterator.return();
|
|
588
|
+
}
|
|
589
|
+
} finally{
|
|
590
|
+
if (_didIteratorError) {
|
|
591
|
+
throw _iteratorError;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
finalUrl = url.toString();
|
|
597
|
+
} catch (unused) {
|
|
598
|
+
throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
|
|
599
|
+
}
|
|
600
|
+
var problems = validateGamRequestUrl(finalUrl, {
|
|
601
|
+
optimizedPod: !!pod,
|
|
602
|
+
remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
|
|
603
|
+
});
|
|
604
|
+
if (problems.length > 0) {
|
|
605
|
+
throw podRequestAborted("invalid_url", problems.join("; "), base);
|
|
606
|
+
}
|
|
607
|
+
var givn = null;
|
|
608
|
+
try {
|
|
609
|
+
givn = new URL(finalUrl).searchParams.get("givn");
|
|
610
|
+
} catch (unused) {}
|
|
611
|
+
return {
|
|
612
|
+
url: finalUrl,
|
|
613
|
+
diagnostics: {
|
|
614
|
+
breakId: ctx.breakId,
|
|
615
|
+
optimizedPod: !!pod,
|
|
616
|
+
pmxdSource: decision.kind === "send" ? decision.source : void 0,
|
|
617
|
+
scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
|
|
618
|
+
elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
|
|
619
|
+
remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
|
|
620
|
+
safetyReserveMs: ctx.config.requestSafetyMs,
|
|
621
|
+
pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
|
|
622
|
+
pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
|
|
623
|
+
pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
|
|
624
|
+
palNoncePresent: !!givn,
|
|
625
|
+
gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
|
|
626
|
+
strippedMacros: substituted.unresolved.filter(function(name) {
|
|
627
|
+
return !SCVP_POD_MACROS.has(name);
|
|
628
|
+
})
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function validateGamRequestUrl(url, expect) {
|
|
633
|
+
var problems = [];
|
|
634
|
+
var leftover = findScvpMacroNames(url);
|
|
635
|
+
if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
|
|
636
|
+
var params;
|
|
637
|
+
try {
|
|
638
|
+
params = new URL(url).searchParams;
|
|
639
|
+
} catch (unused) {
|
|
640
|
+
return problems.concat("URL could not be parsed");
|
|
641
|
+
}
|
|
642
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
643
|
+
try {
|
|
644
|
+
for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
645
|
+
var key = _step.value;
|
|
646
|
+
if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
|
|
647
|
+
}
|
|
648
|
+
} catch (err) {
|
|
649
|
+
_didIteratorError = true;
|
|
650
|
+
_iteratorError = err;
|
|
651
|
+
} finally{
|
|
652
|
+
try {
|
|
653
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
654
|
+
_iterator.return();
|
|
655
|
+
}
|
|
656
|
+
} finally{
|
|
657
|
+
if (_didIteratorError) {
|
|
658
|
+
throw _iteratorError;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (!expect.optimizedPod) {
|
|
663
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
664
|
+
try {
|
|
665
|
+
for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
666
|
+
var key1 = _step1.value;
|
|
667
|
+
if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
|
|
668
|
+
}
|
|
669
|
+
} catch (err) {
|
|
670
|
+
_didIteratorError1 = true;
|
|
671
|
+
_iteratorError1 = err;
|
|
672
|
+
} finally{
|
|
673
|
+
try {
|
|
674
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
675
|
+
_iterator1.return();
|
|
676
|
+
}
|
|
677
|
+
} finally{
|
|
678
|
+
if (_didIteratorError1) {
|
|
679
|
+
throw _iteratorError1;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return problems;
|
|
684
|
+
}
|
|
685
|
+
var pmxd = params.get("pmxd");
|
|
686
|
+
var pmnd = params.get("pmnd");
|
|
687
|
+
var pmad = params.get("pmad");
|
|
688
|
+
if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
|
|
689
|
+
if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
|
|
690
|
+
if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
|
|
691
|
+
if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
|
|
692
|
+
if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
|
|
693
|
+
problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
|
|
694
|
+
}
|
|
695
|
+
return problems;
|
|
696
|
+
}
|
|
697
|
+
function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
|
|
698
|
+
var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
|
|
699
|
+
return {
|
|
700
|
+
vastAdCount: vastAdCount,
|
|
701
|
+
totalVastCreativeDurationMs: totalVastCreativeDurationMs,
|
|
702
|
+
estimatedUnusedPodMs: estimatedUnusedPodMs,
|
|
703
|
+
estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
707
|
+
0 && (module.exports = {
|
|
708
|
+
DEFAULT_REQUEST_SAFETY_MS: DEFAULT_REQUEST_SAFETY_MS,
|
|
709
|
+
GAM_AD_OPPORTUNITY_DURATION_MS: GAM_AD_OPPORTUNITY_DURATION_MS,
|
|
710
|
+
computePodResponseDiagnostics: computePodResponseDiagnostics,
|
|
711
|
+
finalizeGamRequestUrl: finalizeGamRequestUrl,
|
|
712
|
+
isOptimizedPodUrl: isOptimizedPodUrl,
|
|
713
|
+
isPodRequestAbortedError: isPodRequestAbortedError,
|
|
714
|
+
measureBreakCapacity: measureBreakCapacity,
|
|
715
|
+
resolveAdPodConfig: resolveAdPodConfig,
|
|
716
|
+
resolvePodParams: resolvePodParams,
|
|
717
|
+
validateGamRequestUrl: validateGamRequestUrl
|
|
718
|
+
});
|
|
719
|
+
//# sourceMappingURL=OptimizedPodRequest.cjs.map
|