stormcloud-video-player 0.8.69 → 0.8.71
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/dist/stormcloud-vp.min.js +2 -2
- package/lib/StormcloudPlayer.cjs +547 -40
- package/lib/StormcloudPlayer.cjs.map +1 -1
- package/lib/index.cjs +577 -42
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +18 -2
- package/lib/index.js +577 -42
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.cjs +355 -18
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +18 -0
- package/lib/player/EdgePodRequest.cjs +148 -0
- package/lib/player/EdgePodRequest.cjs.map +1 -0
- package/lib/player/EdgePodRequest.d.cts +14 -0
- package/lib/player/StormcloudVideoPlayer.cjs +547 -40
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +9 -0
- package/lib/players/HlsPlayer.cjs +547 -40
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +547 -40
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +120 -19
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/types.d.cts +10 -3
- package/lib/ui/StormcloudVideoPlayer.cjs +577 -42
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2487,7 +2487,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2487
2487
|
img.onload = null;
|
|
2488
2488
|
img.onerror = null;
|
|
2489
2489
|
inFlightBeacons.delete(img);
|
|
2490
|
-
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(
|
|
2490
|
+
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingHost));
|
|
2491
2491
|
if (outcome !== "load") {
|
|
2492
2492
|
logFunnel("tracking_request_settled", {
|
|
2493
2493
|
reason: outcome,
|
|
@@ -2505,7 +2505,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2505
2505
|
return release("timeout");
|
|
2506
2506
|
}, BEACON_TIMEOUT_MS);
|
|
2507
2507
|
img.src = trackingUrl;
|
|
2508
|
-
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(
|
|
2508
|
+
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingHost));
|
|
2509
2509
|
logFunnel("tracking_request_created", {
|
|
2510
2510
|
trackingHost: trackingHost,
|
|
2511
2511
|
errorCode: options2 === null || options2 === void 0 ? void 0 : options2.errorCode
|
|
@@ -2959,7 +2959,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2959
2959
|
});
|
|
2960
2960
|
}
|
|
2961
2961
|
if (parsed.type === "wrapper") {
|
|
2962
|
-
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
|
|
2962
|
+
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(redactUrl(parsed.vastAdTagUri)));
|
|
2963
2963
|
}
|
|
2964
2964
|
return parsed;
|
|
2965
2965
|
}
|
|
@@ -3151,8 +3151,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3151
3151
|
switch(_state.label){
|
|
3152
3152
|
case 0:
|
|
3153
3153
|
attempt++;
|
|
3154
|
-
if (kind
|
|
3155
|
-
logFunnel("
|
|
3154
|
+
if (kind !== "wrapper") {
|
|
3155
|
+
logFunnel("".concat(kind, "_http_request_sent"), {
|
|
3156
3156
|
attempt: attempt,
|
|
3157
3157
|
credentials: creds
|
|
3158
3158
|
});
|
|
@@ -3172,8 +3172,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3172
3172
|
];
|
|
3173
3173
|
case 1:
|
|
3174
3174
|
response = _state.sent();
|
|
3175
|
-
if (kind
|
|
3176
|
-
logFunnel("
|
|
3175
|
+
if (kind !== "wrapper") {
|
|
3176
|
+
logFunnel("".concat(kind, "_response_received"), {
|
|
3177
3177
|
attempt: attempt,
|
|
3178
3178
|
httpStatus: response.status,
|
|
3179
3179
|
ok: response.ok,
|
|
@@ -3343,8 +3343,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3343
3343
|
elapsedMs: Date.now() - fetchStartedAt
|
|
3344
3344
|
});
|
|
3345
3345
|
}
|
|
3346
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
3347
|
-
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3346
|
+
console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
|
|
3348
3347
|
parsed = parseVastXml(vastXml);
|
|
3349
3348
|
if (parsed.type === "empty") {
|
|
3350
3349
|
;
|
|
@@ -3385,16 +3384,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3385
3384
|
});
|
|
3386
3385
|
}).apply(this, arguments);
|
|
3387
3386
|
}
|
|
3387
|
+
function isEdgeEmptySentinelAd(adElement) {
|
|
3388
|
+
var _textOf;
|
|
3389
|
+
if ((adElement.getAttribute("id") || "").trim().toLowerCase() === "empty") {
|
|
3390
|
+
return true;
|
|
3391
|
+
}
|
|
3392
|
+
var inLine = adElement.querySelector(":scope > InLine");
|
|
3393
|
+
if (!inLine) return false;
|
|
3394
|
+
if (/^no ad available$/i.test((_textOf = textOf(inLine.querySelector(":scope > AdTitle"))) !== null && _textOf !== void 0 ? _textOf : "")) {
|
|
3395
|
+
return true;
|
|
3396
|
+
}
|
|
3397
|
+
var durations = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear > Duration")).map(function(el) {
|
|
3398
|
+
return parseVastTime(textOf(el));
|
|
3399
|
+
});
|
|
3400
|
+
return durations.length > 0 && durations.every(function(seconds) {
|
|
3401
|
+
return seconds === 0;
|
|
3402
|
+
});
|
|
3403
|
+
}
|
|
3388
3404
|
function fetchAndParsePod(vastTagUrl) {
|
|
3405
|
+
var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
|
|
3389
3406
|
return _async_to_generator(function() {
|
|
3390
|
-
var _root_getAttribute, _root_getAttribute1, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
|
|
3407
|
+
var _root_getAttribute, _root_getAttribute1, isEdge, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, candidates, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
|
|
3391
3408
|
return _ts_generator(this, function(_state) {
|
|
3392
3409
|
switch(_state.label){
|
|
3393
3410
|
case 0:
|
|
3394
3411
|
lastPodAdElementCount = 0;
|
|
3412
|
+
isEdge = source === "edge";
|
|
3395
3413
|
return [
|
|
3396
3414
|
4,
|
|
3397
|
-
fetchVastXml(vastTagUrl)
|
|
3415
|
+
fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
|
|
3398
3416
|
];
|
|
3399
3417
|
case 1:
|
|
3400
3418
|
vastXml = _state.sent();
|
|
@@ -3417,7 +3435,6 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3417
3435
|
}
|
|
3418
3436
|
xmlDoc = parseXml(vastXml);
|
|
3419
3437
|
if (!xmlDoc) {
|
|
3420
|
-
console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3421
3438
|
logFunnel("vast_parsed", {
|
|
3422
3439
|
adElementCount: 0,
|
|
3423
3440
|
reason: "xml_parse_error"
|
|
@@ -3489,12 +3506,24 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3489
3506
|
});
|
|
3490
3507
|
})();
|
|
3491
3508
|
};
|
|
3492
|
-
|
|
3509
|
+
candidates = adElements;
|
|
3510
|
+
if (isEdge) {
|
|
3511
|
+
candidates = adElements.filter(function(el) {
|
|
3512
|
+
return !isEdgeEmptySentinelAd(el);
|
|
3513
|
+
});
|
|
3514
|
+
if (candidates.length < adElements.length) {
|
|
3515
|
+
logFunnel("edge_empty_sentinel", {
|
|
3516
|
+
sentinelCount: adElements.length - candidates.length,
|
|
3517
|
+
adElementCount: adElements.length
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
podElements = candidates.filter(function(el) {
|
|
3493
3522
|
return getAdSequence(el) !== void 0;
|
|
3494
3523
|
}).sort(function(a, b) {
|
|
3495
3524
|
return getAdSequence(a) - getAdSequence(b);
|
|
3496
3525
|
});
|
|
3497
|
-
buffet =
|
|
3526
|
+
buffet = candidates.filter(function(el) {
|
|
3498
3527
|
return getAdSequence(el) === void 0;
|
|
3499
3528
|
});
|
|
3500
3529
|
resolveAll = function resolveAll(elements) {
|
|
@@ -3651,7 +3680,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3651
3680
|
lastPodAdElementCount = adElements.length;
|
|
3652
3681
|
return [
|
|
3653
3682
|
2,
|
|
3654
|
-
ads
|
|
3683
|
+
isEdge ? ads.filter(function(ad) {
|
|
3684
|
+
return ad.duration > 0;
|
|
3685
|
+
}) : ads
|
|
3655
3686
|
];
|
|
3656
3687
|
}
|
|
3657
3688
|
});
|
|
@@ -4652,13 +4683,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4652
4683
|
contentVideo[AD_CONTAINER_PROP] = adContainerEl;
|
|
4653
4684
|
attachContainerHandlers();
|
|
4654
4685
|
},
|
|
4655
|
-
requestAds: function requestAds(vastTagUrl) {
|
|
4686
|
+
requestAds: function requestAds(vastTagUrl, requestOptions) {
|
|
4656
4687
|
return _async_to_generator(function() {
|
|
4657
|
-
var ads, preloaded, error;
|
|
4688
|
+
var _ref, source, ads, preloaded, error;
|
|
4658
4689
|
return _ts_generator(this, function(_state) {
|
|
4659
4690
|
switch(_state.label){
|
|
4660
4691
|
case 0:
|
|
4661
|
-
|
|
4692
|
+
source = (_ref = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.source) !== null && _ref !== void 0 ? _ref : "gam";
|
|
4693
|
+
console.log("[HlsAdPlayer] Requesting ads (".concat(source, "):"), redactUrl(vastTagUrl));
|
|
4662
4694
|
if (adPlaying) {
|
|
4663
4695
|
console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
|
|
4664
4696
|
return [
|
|
@@ -4703,7 +4735,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4703
4735
|
case 2:
|
|
4704
4736
|
return [
|
|
4705
4737
|
4,
|
|
4706
|
-
fetchAndParsePod(vastTagUrl)
|
|
4738
|
+
fetchAndParsePod(vastTagUrl, source)
|
|
4707
4739
|
];
|
|
4708
4740
|
case 3:
|
|
4709
4741
|
ads = _state.sent();
|
|
@@ -5113,6 +5145,75 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
5113
5145
|
return podAds.reduce(function(total, ad) {
|
|
5114
5146
|
return total + (ad.duration > 0 ? ad.duration * 1e3 : 0);
|
|
5115
5147
|
}, 0);
|
|
5148
|
+
},
|
|
5149
|
+
limitPodToBudget: function limitPodToBudget(maxDurationMs, maxAds) {
|
|
5150
|
+
if (adPlaying) return podAds.length;
|
|
5151
|
+
var kept = [];
|
|
5152
|
+
var dropped = [];
|
|
5153
|
+
var totalMs = 0;
|
|
5154
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
5155
|
+
try {
|
|
5156
|
+
for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
5157
|
+
var ad = _step.value;
|
|
5158
|
+
var durationMs = Math.round(ad.duration * 1e3);
|
|
5159
|
+
if (kept.length < maxAds && totalMs + durationMs <= maxDurationMs) {
|
|
5160
|
+
kept.push(ad);
|
|
5161
|
+
totalMs += durationMs;
|
|
5162
|
+
} else {
|
|
5163
|
+
dropped.push(ad);
|
|
5164
|
+
}
|
|
5165
|
+
}
|
|
5166
|
+
} catch (err) {
|
|
5167
|
+
_didIteratorError = true;
|
|
5168
|
+
_iteratorError = err;
|
|
5169
|
+
} finally{
|
|
5170
|
+
try {
|
|
5171
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
5172
|
+
_iterator.return();
|
|
5173
|
+
}
|
|
5174
|
+
} finally{
|
|
5175
|
+
if (_didIteratorError) {
|
|
5176
|
+
throw _iteratorError;
|
|
5177
|
+
}
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
if (dropped.length > 0) {
|
|
5181
|
+
logFunnel("pod_trimmed_to_budget", {
|
|
5182
|
+
keptCount: kept.length,
|
|
5183
|
+
droppedCount: dropped.length,
|
|
5184
|
+
keptDurationMs: totalMs,
|
|
5185
|
+
maxDurationMs: maxDurationMs,
|
|
5186
|
+
maxAds: maxAds
|
|
5187
|
+
});
|
|
5188
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
5189
|
+
try {
|
|
5190
|
+
for(var _iterator1 = dropped[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
5191
|
+
var ad1 = _step1.value;
|
|
5192
|
+
resolvedAds.add(ad1);
|
|
5193
|
+
fireTrackingPixels(ad1.trackingUrls.notUsed, {
|
|
5194
|
+
ad: ad1
|
|
5195
|
+
});
|
|
5196
|
+
}
|
|
5197
|
+
} catch (err) {
|
|
5198
|
+
_didIteratorError1 = true;
|
|
5199
|
+
_iteratorError1 = err;
|
|
5200
|
+
} finally{
|
|
5201
|
+
try {
|
|
5202
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
5203
|
+
_iterator1.return();
|
|
5204
|
+
}
|
|
5205
|
+
} finally{
|
|
5206
|
+
if (_didIteratorError1) {
|
|
5207
|
+
throw _iteratorError1;
|
|
5208
|
+
}
|
|
5209
|
+
}
|
|
5210
|
+
}
|
|
5211
|
+
}
|
|
5212
|
+
podAds = kept;
|
|
5213
|
+
podIndex = 0;
|
|
5214
|
+
currentAd = kept[0];
|
|
5215
|
+
currentAdMediaFile = void 0;
|
|
5216
|
+
return kept.length;
|
|
5116
5217
|
}
|
|
5117
5218
|
};
|
|
5118
5219
|
}
|
|
@@ -9125,6 +9226,71 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
9125
9226
|
]);
|
|
9126
9227
|
return HlsEngine;
|
|
9127
9228
|
}();
|
|
9229
|
+
// src/player/EdgePodRequest.ts
|
|
9230
|
+
var EDGE_POD_MAX_ADS = 10;
|
|
9231
|
+
var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
|
|
9232
|
+
var LICENSE_KEY_PLACEHOLDER = /\{licenseKey\}|%7BlicenseKey%7D/gi;
|
|
9233
|
+
function resolveEdgePodBaseUrl(config) {
|
|
9234
|
+
var _config_edgePodUrl, _config_licenseKey;
|
|
9235
|
+
if (config.enableEdgePodRequest !== true) return void 0;
|
|
9236
|
+
var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
|
|
9237
|
+
if (!raw) {
|
|
9238
|
+
console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
|
|
9239
|
+
return void 0;
|
|
9240
|
+
}
|
|
9241
|
+
var licenseKey = (_config_licenseKey = config.licenseKey) === null || _config_licenseKey === void 0 ? void 0 : _config_licenseKey.trim();
|
|
9242
|
+
if (!licenseKey) {
|
|
9243
|
+
console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but licenseKey is missing; using GAM only");
|
|
9244
|
+
return void 0;
|
|
9245
|
+
}
|
|
9246
|
+
var encodedKey = encodeURIComponent(licenseKey);
|
|
9247
|
+
try {
|
|
9248
|
+
var hasPlaceholder = raw.search(LICENSE_KEY_PLACEHOLDER) !== -1;
|
|
9249
|
+
var url = new URL(hasPlaceholder ? raw.replace(LICENSE_KEY_PLACEHOLDER, encodedKey) : raw);
|
|
9250
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
9251
|
+
throw new Error("unsupported protocol ".concat(url.protocol));
|
|
9252
|
+
}
|
|
9253
|
+
if (!hasPlaceholder) {
|
|
9254
|
+
var path = url.pathname.replace(/\/+$/, "");
|
|
9255
|
+
url.pathname = /\/[^/]+\/pod$/.test(path) ? path.replace(/\/[^/]+\/pod$/, "/".concat(encodedKey, "/pod")) : "".concat(path, "/").concat(encodedKey, "/pod");
|
|
9256
|
+
}
|
|
9257
|
+
return url.toString();
|
|
9258
|
+
} catch (unused) {
|
|
9259
|
+
console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
|
|
9260
|
+
return void 0;
|
|
9261
|
+
}
|
|
9262
|
+
}
|
|
9263
|
+
function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
|
|
9264
|
+
var url = new URL(baseUrl);
|
|
9265
|
+
var maxMs = Math.max(0, Math.floor(remainingMs));
|
|
9266
|
+
var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
|
|
9267
|
+
url.searchParams.set("pmxd", String(maxMs));
|
|
9268
|
+
url.searchParams.set("pmad", String(maxAds));
|
|
9269
|
+
url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
|
|
9270
|
+
url.searchParams.set("count", String(maxAds));
|
|
9271
|
+
return url.toString();
|
|
9272
|
+
}
|
|
9273
|
+
function classifyEdgeVastResponse(result) {
|
|
9274
|
+
var _ref;
|
|
9275
|
+
var _result_error;
|
|
9276
|
+
if (result.error == null) {
|
|
9277
|
+
return result.podAdCount > 0 ? "fill" : "no_fill";
|
|
9278
|
+
}
|
|
9279
|
+
var message = (_ref = (_result_error = result.error) === null || _result_error === void 0 ? void 0 : _result_error.message) !== null && _ref !== void 0 ? _ref : String(result.error);
|
|
9280
|
+
if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
|
|
9281
|
+
return "no_fill";
|
|
9282
|
+
}
|
|
9283
|
+
return "invalid";
|
|
9284
|
+
}
|
|
9285
|
+
function describeEdgeUrl(url) {
|
|
9286
|
+
try {
|
|
9287
|
+
var parsed = new URL(url);
|
|
9288
|
+
return "".concat(parsed.origin).concat(parsed.pathname);
|
|
9289
|
+
} catch (unused) {
|
|
9290
|
+
var _url_split_;
|
|
9291
|
+
return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9128
9294
|
// src/player/PlayerControls.ts
|
|
9129
9295
|
function getAdAudioVolume(adPlayer) {
|
|
9130
9296
|
return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
|
|
@@ -9284,6 +9450,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9284
9450
|
this.controllerCallInFlight = false;
|
|
9285
9451
|
this.playbackStartedForCurrentRequest = false;
|
|
9286
9452
|
this.opportunityEpoch = -1;
|
|
9453
|
+
this.edgeExhaustedForBreak = false;
|
|
9454
|
+
this.edgeRequestsInBreak = 0;
|
|
9287
9455
|
this.adPodQueue = [];
|
|
9288
9456
|
this.defaultMinRemainingMsToRequestAd = 1e4;
|
|
9289
9457
|
this.defaultMaxNoFillsPerBreak = 2;
|
|
@@ -9434,7 +9602,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9434
9602
|
_this.timing.clearAdRequestWatchdog();
|
|
9435
9603
|
_this.timing.activeAdRequestToken = null;
|
|
9436
9604
|
_this.showAds = true;
|
|
9437
|
-
_this.
|
|
9605
|
+
if (_this.currentPodSource !== "edge") {
|
|
9606
|
+
_this.timing.resetGamNoFillCounter();
|
|
9607
|
+
}
|
|
9438
9608
|
if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
|
|
9439
9609
|
_this.timing.scheduleAdStopAtBreakBoundary();
|
|
9440
9610
|
if (_this.debug) {
|
|
@@ -9566,6 +9736,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9566
9736
|
key: "beginVmapBreak",
|
|
9567
9737
|
value: function beginVmapBreak(breakKey, position) {
|
|
9568
9738
|
this.breakSource = "vmap";
|
|
9739
|
+
this.resetEdgeStateForBreak();
|
|
9569
9740
|
this.followUpBaseVastUrl = void 0;
|
|
9570
9741
|
this.unusableResponsesInBreak = 0;
|
|
9571
9742
|
this.timing.totalAdRequestsInBreak = 0;
|
|
@@ -9577,7 +9748,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9577
9748
|
key: "handleAdStart",
|
|
9578
9749
|
value: function handleAdStart(marker) {
|
|
9579
9750
|
return _async_to_generator(function() {
|
|
9580
|
-
var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
|
|
9751
|
+
var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
|
|
9581
9752
|
return _ts_generator(this, function(_state) {
|
|
9582
9753
|
switch(_state.label){
|
|
9583
9754
|
case 0:
|
|
@@ -9591,7 +9762,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9591
9762
|
];
|
|
9592
9763
|
}
|
|
9593
9764
|
baseVastUrl = this.adConfig.apiVastTagUrl;
|
|
9594
|
-
|
|
9765
|
+
edgeConfigured = !!this.host.getEdgePodBaseUrl();
|
|
9766
|
+
if (!baseVastUrl && !edgeConfigured) {
|
|
9595
9767
|
console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
|
|
9596
9768
|
this.clearPendingAdBreak();
|
|
9597
9769
|
return [
|
|
@@ -9607,6 +9779,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9607
9779
|
this.breakSource = "scte35";
|
|
9608
9780
|
this.followUpBaseVastUrl = baseVastUrl;
|
|
9609
9781
|
this.unusableResponsesInBreak = 0;
|
|
9782
|
+
this.resetEdgeStateForBreak();
|
|
9610
9783
|
this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
|
|
9611
9784
|
if (this.adConfig.podAssignedByPrefetch) {
|
|
9612
9785
|
this.adConfig.podAssignedByPrefetch = false;
|
|
@@ -9628,7 +9801,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9628
9801
|
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
|
|
9629
9802
|
epoch = this.timing.adBreakEpoch;
|
|
9630
9803
|
hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
|
|
9631
|
-
if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
|
|
9804
|
+
if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
|
|
9632
9805
|
3,
|
|
9633
9806
|
2
|
|
9634
9807
|
];
|
|
@@ -9647,11 +9820,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9647
9820
|
mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
|
|
9648
9821
|
console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
|
|
9649
9822
|
}
|
|
9823
|
+
if (!edgeConfigured) return [
|
|
9824
|
+
3,
|
|
9825
|
+
5
|
|
9826
|
+
];
|
|
9827
|
+
edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
|
|
9828
|
+
if (!edgeUrl) return [
|
|
9829
|
+
3,
|
|
9830
|
+
4
|
|
9831
|
+
];
|
|
9832
|
+
this.clearPendingAdBreak();
|
|
9650
9833
|
return [
|
|
9651
9834
|
4,
|
|
9652
|
-
this.
|
|
9835
|
+
this.runEdgePod(edgeUrl, "edge_break_start")
|
|
9653
9836
|
];
|
|
9654
9837
|
case 3:
|
|
9838
|
+
outcome = _state.sent();
|
|
9839
|
+
this.continueAfterEdgeOutcome(outcome, epoch);
|
|
9840
|
+
return [
|
|
9841
|
+
2
|
|
9842
|
+
];
|
|
9843
|
+
case 4:
|
|
9844
|
+
if (!this.edgeExhaustedForBreak) {
|
|
9845
|
+
this.markEdgeExhausted("not_eligible_at_break_start", {
|
|
9846
|
+
isLive: this.isLiveBreak(),
|
|
9847
|
+
durationMs: this.timing.expectedAdBreakDurationMs
|
|
9848
|
+
});
|
|
9849
|
+
}
|
|
9850
|
+
_state.label = 5;
|
|
9851
|
+
case 5:
|
|
9852
|
+
if (!baseVastUrl) {
|
|
9853
|
+
this.requestNextAd("no_gam_source");
|
|
9854
|
+
return [
|
|
9855
|
+
2
|
|
9856
|
+
];
|
|
9857
|
+
}
|
|
9858
|
+
return [
|
|
9859
|
+
4,
|
|
9860
|
+
this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
|
|
9861
|
+
];
|
|
9862
|
+
case 6:
|
|
9655
9863
|
podPlayed = _state.sent();
|
|
9656
9864
|
if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
|
|
9657
9865
|
this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
|
|
@@ -9743,6 +9951,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9743
9951
|
adPlayer = this.host.getAdPlayer();
|
|
9744
9952
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
9745
9953
|
this.timing.activeAdRequestToken = requestToken;
|
|
9954
|
+
this.currentPodSource = "gam";
|
|
9746
9955
|
this.setSlotState("REQUESTING", "initial_pod");
|
|
9747
9956
|
this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
|
|
9748
9957
|
requestUrl = this.applyOpportunityFloor(podUrl);
|
|
@@ -9859,6 +10068,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9859
10068
|
}).call(this);
|
|
9860
10069
|
}
|
|
9861
10070
|
},
|
|
10071
|
+
{
|
|
10072
|
+
// ───────────────────────────────────────────────────────────────
|
|
10073
|
+
// Edge-first pods (live SCTE-35 only, GAM fallback)
|
|
10074
|
+
// ───────────────────────────────────────────────────────────────
|
|
10075
|
+
key: "resetEdgeStateForBreak",
|
|
10076
|
+
value: function resetEdgeStateForBreak() {
|
|
10077
|
+
this.edgeExhaustedForBreak = false;
|
|
10078
|
+
this.edgeRequestsInBreak = 0;
|
|
10079
|
+
this.currentPodSource = void 0;
|
|
10080
|
+
}
|
|
10081
|
+
},
|
|
10082
|
+
{
|
|
10083
|
+
key: "isLiveBreak",
|
|
10084
|
+
value: function isLiveBreak() {
|
|
10085
|
+
return this.host.isLiveStream() || this.host.config.isLiveStream === true;
|
|
10086
|
+
}
|
|
10087
|
+
},
|
|
10088
|
+
{
|
|
10089
|
+
key: "canRequestEdge",
|
|
10090
|
+
value: function canRequestEdge() {
|
|
10091
|
+
return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
|
|
10092
|
+
}
|
|
10093
|
+
},
|
|
10094
|
+
{
|
|
10095
|
+
key: "markEdgeExhausted",
|
|
10096
|
+
value: function markEdgeExhausted(reason) {
|
|
10097
|
+
var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
10098
|
+
this.edgeExhaustedForBreak = true;
|
|
10099
|
+
this.countFunnelStage("edge_fallback:".concat(reason));
|
|
10100
|
+
this.logOrchestratorFunnel("edge_exhausted", _object_spread({
|
|
10101
|
+
reason: reason,
|
|
10102
|
+
edgeRequests: this.edgeRequestsInBreak,
|
|
10103
|
+
remainingMs: this.timing.getRemainingAdMs()
|
|
10104
|
+
}, extra));
|
|
10105
|
+
}
|
|
10106
|
+
},
|
|
10107
|
+
{
|
|
10108
|
+
/**
|
|
10109
|
+
* Builds the next Edge request from the budget left right now, or marks Edge
|
|
10110
|
+
* exhausted for this break. Synchronous on purpose: callers must reach the
|
|
10111
|
+
* REQUESTING state in the same tick so a second completion event cannot race
|
|
10112
|
+
* in a parallel request.
|
|
10113
|
+
*/ key: "prepareEdgePodRequest",
|
|
10114
|
+
value: function prepareEdgePodRequest() {
|
|
10115
|
+
var baseUrl = this.host.getEdgePodBaseUrl();
|
|
10116
|
+
if (!baseUrl) return void 0;
|
|
10117
|
+
var remainingMs = this.timing.getRemainingAdMs();
|
|
10118
|
+
var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
|
|
10119
|
+
if (remainingAds < 1) {
|
|
10120
|
+
this.markEdgeExhausted("ad_capacity_reached", {
|
|
10121
|
+
adsInBreak: this.timing.totalAdsInBreak
|
|
10122
|
+
});
|
|
10123
|
+
return void 0;
|
|
10124
|
+
}
|
|
10125
|
+
if (remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
10126
|
+
this.markEdgeExhausted("insufficient_break_time", {
|
|
10127
|
+
remainingMs: remainingMs
|
|
10128
|
+
});
|
|
10129
|
+
return void 0;
|
|
10130
|
+
}
|
|
10131
|
+
try {
|
|
10132
|
+
return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
|
|
10133
|
+
} catch (unused) {
|
|
10134
|
+
this.markEdgeExhausted("invalid_edge_url");
|
|
10135
|
+
return void 0;
|
|
10136
|
+
}
|
|
10137
|
+
}
|
|
10138
|
+
},
|
|
10139
|
+
{
|
|
10140
|
+
key: "runEdgePod",
|
|
10141
|
+
value: function runEdgePod(requestUrl, trigger) {
|
|
10142
|
+
return _async_to_generator(function() {
|
|
10143
|
+
var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
|
|
10144
|
+
return _ts_generator(this, function(_state) {
|
|
10145
|
+
switch(_state.label){
|
|
10146
|
+
case 0:
|
|
10147
|
+
epoch = this.timing.adBreakEpoch;
|
|
10148
|
+
this.recreateAdController("new_request");
|
|
10149
|
+
generation = this.controllerGeneration;
|
|
10150
|
+
adPlayer = this.host.getAdPlayer();
|
|
10151
|
+
requestToken = ++this.timing.adRequestTokenCounter;
|
|
10152
|
+
this.timing.activeAdRequestToken = requestToken;
|
|
10153
|
+
this.currentPodSource = "edge";
|
|
10154
|
+
this.edgeRequestsInBreak++;
|
|
10155
|
+
this.setSlotState("REQUESTING", trigger);
|
|
10156
|
+
this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
|
|
10157
|
+
this.currentVastUrl = requestUrl;
|
|
10158
|
+
params = new URL(requestUrl).searchParams;
|
|
10159
|
+
this.logOrchestratorFunnel("edge_request_sent", {
|
|
10160
|
+
trigger: trigger,
|
|
10161
|
+
attempt: this.edgeRequestsInBreak,
|
|
10162
|
+
endpoint: describeEdgeUrl(requestUrl),
|
|
10163
|
+
pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
|
|
10164
|
+
pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
|
|
10165
|
+
});
|
|
10166
|
+
_state.label = 1;
|
|
10167
|
+
case 1:
|
|
10168
|
+
_state.trys.push([
|
|
10169
|
+
1,
|
|
10170
|
+
4,
|
|
10171
|
+
,
|
|
10172
|
+
5
|
|
10173
|
+
]);
|
|
10174
|
+
this.timing.startAdRequestWatchdog(requestToken);
|
|
10175
|
+
return [
|
|
10176
|
+
4,
|
|
10177
|
+
this.callController(function() {
|
|
10178
|
+
return adPlayer.requestAds(requestUrl, {
|
|
10179
|
+
source: "edge"
|
|
10180
|
+
});
|
|
10181
|
+
})
|
|
10182
|
+
];
|
|
10183
|
+
case 2:
|
|
10184
|
+
_state.sent();
|
|
10185
|
+
this.timing.clearAdRequestWatchdog();
|
|
10186
|
+
if (this.isStale(epoch, generation)) {
|
|
10187
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10188
|
+
requestId: requestToken,
|
|
10189
|
+
source: "edge"
|
|
10190
|
+
});
|
|
10191
|
+
return [
|
|
10192
|
+
2,
|
|
10193
|
+
"stale"
|
|
10194
|
+
];
|
|
10195
|
+
}
|
|
10196
|
+
remainingMs = this.timing.getRemainingAdMs();
|
|
10197
|
+
remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
|
|
10198
|
+
podCount = adPlayer.limitPodToBudget ? adPlayer.limitPodToBudget(remainingMs, remainingAds) : (_ref = (_adPlayer_getPodAdCount = adPlayer.getPodAdCount) === null || _adPlayer_getPodAdCount === void 0 ? void 0 : _adPlayer_getPodAdCount.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0;
|
|
10199
|
+
if (classifyEdgeVastResponse({
|
|
10200
|
+
podAdCount: podCount
|
|
10201
|
+
}) !== "fill") {
|
|
10202
|
+
throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
|
|
10203
|
+
}
|
|
10204
|
+
this.setSlotState("READY", "edge_vast_ready");
|
|
10205
|
+
this.logOrchestratorFunnel("edge_fill", {
|
|
10206
|
+
podAdCount: podCount,
|
|
10207
|
+
podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
|
|
10208
|
+
remainingMs: remainingMs
|
|
10209
|
+
});
|
|
10210
|
+
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
10211
|
+
source: "hls",
|
|
10212
|
+
vastUrl: requestUrl,
|
|
10213
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10214
|
+
}, this.analyticsContext).catch(function() {});
|
|
10215
|
+
this.timing.startAdFailsafeTimer(requestToken);
|
|
10216
|
+
return [
|
|
10217
|
+
4,
|
|
10218
|
+
this.callController(function() {
|
|
10219
|
+
return adPlayer.play();
|
|
10220
|
+
})
|
|
10221
|
+
];
|
|
10222
|
+
case 3:
|
|
10223
|
+
_state.sent();
|
|
10224
|
+
if (this.isStale(epoch, generation)) return [
|
|
10225
|
+
2,
|
|
10226
|
+
"stale"
|
|
10227
|
+
];
|
|
10228
|
+
if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
|
|
10229
|
+
this.timing.scheduleAdStopAtBreakBoundary();
|
|
10230
|
+
}
|
|
10231
|
+
adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
|
|
10232
|
+
return [
|
|
10233
|
+
2,
|
|
10234
|
+
"fill"
|
|
10235
|
+
];
|
|
10236
|
+
case 4:
|
|
10237
|
+
error = _state.sent();
|
|
10238
|
+
this.timing.clearAdRequestWatchdog();
|
|
10239
|
+
this.timing.clearAdFailsafeTimer();
|
|
10240
|
+
if (this.timing.activeAdRequestToken === requestToken) {
|
|
10241
|
+
this.timing.activeAdRequestToken = null;
|
|
10242
|
+
}
|
|
10243
|
+
errorMessage = error === null || error === void 0 ? void 0 : error.message;
|
|
10244
|
+
if (this.isStale(epoch, generation)) {
|
|
10245
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10246
|
+
requestId: requestToken,
|
|
10247
|
+
source: "edge",
|
|
10248
|
+
errorMessage: errorMessage
|
|
10249
|
+
});
|
|
10250
|
+
return [
|
|
10251
|
+
2,
|
|
10252
|
+
"stale"
|
|
10253
|
+
];
|
|
10254
|
+
}
|
|
10255
|
+
classification = classifyEdgeVastResponse({
|
|
10256
|
+
podAdCount: 0,
|
|
10257
|
+
error: error
|
|
10258
|
+
});
|
|
10259
|
+
diag = this.requestDiagnostics.get(requestToken);
|
|
10260
|
+
if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
|
|
10261
|
+
this.markEdgeExhausted("edge_".concat(classification), {
|
|
10262
|
+
errorMessage: errorMessage
|
|
10263
|
+
});
|
|
10264
|
+
return [
|
|
10265
|
+
2,
|
|
10266
|
+
"fallback"
|
|
10267
|
+
];
|
|
10268
|
+
case 5:
|
|
10269
|
+
return [
|
|
10270
|
+
2
|
|
10271
|
+
];
|
|
10272
|
+
}
|
|
10273
|
+
});
|
|
10274
|
+
}).call(this);
|
|
10275
|
+
}
|
|
10276
|
+
},
|
|
10277
|
+
{
|
|
10278
|
+
key: "continueAfterEdgeOutcome",
|
|
10279
|
+
value: function continueAfterEdgeOutcome(outcome, epoch) {
|
|
10280
|
+
if (outcome !== "fallback") return;
|
|
10281
|
+
if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
|
|
10282
|
+
if (this.debug) {
|
|
10283
|
+
console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
|
|
10284
|
+
}
|
|
10285
|
+
this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
|
|
10286
|
+
this.requestNextAd("edge_fallback");
|
|
10287
|
+
}
|
|
10288
|
+
},
|
|
9862
10289
|
{
|
|
9863
10290
|
// ───────────────────────────────────────────────────────────────
|
|
9864
10291
|
// Next-ad scheduling (single flight)
|
|
@@ -9914,7 +10341,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9914
10341
|
value: function getStopRequestingReason(remainingMs) {
|
|
9915
10342
|
if (this.breakSource === "vmap") {
|
|
9916
10343
|
if (this.adPodQueue.length === 0) return "vmap_queue_empty";
|
|
9917
|
-
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
|
|
10344
|
+
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
|
|
9918
10345
|
return "no_follow_up_source";
|
|
9919
10346
|
}
|
|
9920
10347
|
if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
|
|
@@ -9926,7 +10353,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9926
10353
|
if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
|
|
9927
10354
|
return "request_cap";
|
|
9928
10355
|
}
|
|
9929
|
-
if (this.timing.isGamInCooldown()) {
|
|
10356
|
+
if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
|
|
9930
10357
|
return "gam_cooldown";
|
|
9931
10358
|
}
|
|
9932
10359
|
if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
@@ -10020,10 +10447,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10020
10447
|
key: "requestFollowUpAd",
|
|
10021
10448
|
value: function requestFollowUpAd(trigger) {
|
|
10022
10449
|
return _async_to_generator(function() {
|
|
10023
|
-
var url, epoch, unused;
|
|
10450
|
+
var edgeUrl, epoch2, outcome, url, epoch, unused;
|
|
10024
10451
|
return _ts_generator(this, function(_state) {
|
|
10025
10452
|
switch(_state.label){
|
|
10026
10453
|
case 0:
|
|
10454
|
+
if (!this.canRequestEdge()) return [
|
|
10455
|
+
3,
|
|
10456
|
+
2
|
|
10457
|
+
];
|
|
10458
|
+
edgeUrl = this.prepareEdgePodRequest();
|
|
10459
|
+
if (!edgeUrl) {
|
|
10460
|
+
this.requestNextAd("".concat(trigger, ":edge_unavailable"));
|
|
10461
|
+
return [
|
|
10462
|
+
2
|
|
10463
|
+
];
|
|
10464
|
+
}
|
|
10465
|
+
epoch2 = this.timing.adBreakEpoch;
|
|
10466
|
+
return [
|
|
10467
|
+
4,
|
|
10468
|
+
this.runEdgePod(edgeUrl, "edge_".concat(trigger))
|
|
10469
|
+
];
|
|
10470
|
+
case 1:
|
|
10471
|
+
outcome = _state.sent();
|
|
10472
|
+
this.continueAfterEdgeOutcome(outcome, epoch2);
|
|
10473
|
+
return [
|
|
10474
|
+
2
|
|
10475
|
+
];
|
|
10476
|
+
case 2:
|
|
10027
10477
|
if (this.breakSource === "vmap") {
|
|
10028
10478
|
url = this.adPodQueue.shift();
|
|
10029
10479
|
} else if (this.followUpBaseVastUrl) {
|
|
@@ -10034,32 +10484,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10034
10484
|
];
|
|
10035
10485
|
this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
|
|
10036
10486
|
epoch = this.timing.adBreakEpoch;
|
|
10037
|
-
_state.label =
|
|
10038
|
-
case
|
|
10487
|
+
_state.label = 3;
|
|
10488
|
+
case 3:
|
|
10039
10489
|
_state.trys.push([
|
|
10040
|
-
1,
|
|
10041
10490
|
3,
|
|
10491
|
+
5,
|
|
10042
10492
|
,
|
|
10043
|
-
|
|
10493
|
+
6
|
|
10044
10494
|
]);
|
|
10045
10495
|
return [
|
|
10046
10496
|
4,
|
|
10047
10497
|
this.playSingleAd(url, trigger)
|
|
10048
10498
|
];
|
|
10049
|
-
case
|
|
10499
|
+
case 4:
|
|
10050
10500
|
_state.sent();
|
|
10051
10501
|
return [
|
|
10052
10502
|
3,
|
|
10053
|
-
|
|
10503
|
+
6
|
|
10054
10504
|
];
|
|
10055
|
-
case
|
|
10505
|
+
case 5:
|
|
10056
10506
|
unused = _state.sent();
|
|
10057
10507
|
this.continueAfterRequestFailure(epoch);
|
|
10058
10508
|
return [
|
|
10059
10509
|
3,
|
|
10060
|
-
|
|
10510
|
+
6
|
|
10061
10511
|
];
|
|
10062
|
-
case
|
|
10512
|
+
case 6:
|
|
10063
10513
|
return [
|
|
10064
10514
|
2
|
|
10065
10515
|
];
|
|
@@ -10172,7 +10622,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10172
10622
|
case "gam_http_request_sent":
|
|
10173
10623
|
diag.gamRequestSent++;
|
|
10174
10624
|
break;
|
|
10625
|
+
case "edge_http_request_sent":
|
|
10626
|
+
diag.edgeRequestSent++;
|
|
10627
|
+
break;
|
|
10175
10628
|
case "gam_response_received":
|
|
10629
|
+
case "edge_response_received":
|
|
10176
10630
|
diag.vastHttpStatus = payload.httpStatus;
|
|
10177
10631
|
break;
|
|
10178
10632
|
case "vast_parsed":
|
|
@@ -10359,6 +10813,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10359
10813
|
{
|
|
10360
10814
|
key: "beginFunnelRequest",
|
|
10361
10815
|
value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
|
|
10816
|
+
var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
|
|
10362
10817
|
var _adPlayer_setFunnelContext;
|
|
10363
10818
|
if (this.controllerCallInFlight) {
|
|
10364
10819
|
this.logOrchestratorFunnel("duplicate_request_detected", {
|
|
@@ -10373,7 +10828,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10373
10828
|
requestId: requestToken,
|
|
10374
10829
|
controllerId: this.controllerGeneration,
|
|
10375
10830
|
trigger: trigger,
|
|
10831
|
+
source: source,
|
|
10376
10832
|
gamRequestSent: 0,
|
|
10833
|
+
edgeRequestSent: 0,
|
|
10377
10834
|
wrapperDepth: 0,
|
|
10378
10835
|
inlineResolved: false,
|
|
10379
10836
|
mediaCandidateCount: 0,
|
|
@@ -10504,6 +10961,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10504
10961
|
this.timing.activeAdRequestToken = requestToken;
|
|
10505
10962
|
ap = this.host.getAdPlayer();
|
|
10506
10963
|
budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
|
|
10964
|
+
this.currentPodSource = "gam";
|
|
10507
10965
|
this.setSlotState("REQUESTING", trigger);
|
|
10508
10966
|
this.beginFunnelRequest(ap, requestToken, trigger);
|
|
10509
10967
|
requestUrl = this.applyOpportunityFloor(budgetedUrl);
|
|
@@ -10651,6 +11109,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10651
11109
|
requests: requests,
|
|
10652
11110
|
requestRetries: requestRetries,
|
|
10653
11111
|
gamResponses: count("gam_response_received"),
|
|
11112
|
+
edgeRequests: count("edge_request_sent"),
|
|
11113
|
+
edgeFills: count("edge_fill"),
|
|
11114
|
+
edgeEmptySentinels: count("edge_empty_sentinel"),
|
|
11115
|
+
edgeFallbacks: countPrefix("edge_fallback:"),
|
|
10654
11116
|
requestsSuppressed: count("request_suppressed"),
|
|
10655
11117
|
duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
|
|
10656
11118
|
filled: count("vast_received"),
|
|
@@ -10747,6 +11209,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10747
11209
|
this.breakSource = void 0;
|
|
10748
11210
|
this.followUpBaseVastUrl = void 0;
|
|
10749
11211
|
this.unusableResponsesInBreak = 0;
|
|
11212
|
+
this.resetEdgeStateForBreak();
|
|
10750
11213
|
adPlayer.stop().catch(function() {});
|
|
10751
11214
|
if (!alreadyEnded) this.logBreakFunnel(reason);
|
|
10752
11215
|
this.opportunityFloor = void 0;
|
|
@@ -11060,7 +11523,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
11060
11523
|
});
|
|
11061
11524
|
return;
|
|
11062
11525
|
}
|
|
11063
|
-
this.
|
|
11526
|
+
if (this.currentPodSource === "edge") {
|
|
11527
|
+
this.markEdgeExhausted("edge_playback_failed", {
|
|
11528
|
+
reason: reason
|
|
11529
|
+
});
|
|
11530
|
+
} else {
|
|
11531
|
+
this.timing.consecutiveFailures++;
|
|
11532
|
+
}
|
|
11064
11533
|
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
11065
11534
|
if (diag && !diag.failureReason) diag.failureReason = reason;
|
|
11066
11535
|
if (this.debug) {
|
|
@@ -11091,7 +11560,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11091
11560
|
if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
|
|
11092
11561
|
if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
|
|
11093
11562
|
this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
|
|
11563
|
+
this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
|
|
11094
11564
|
this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11565
|
+
this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
|
|
11095
11566
|
this.adPlayer = this.createAdPlayer(false);
|
|
11096
11567
|
this.palNonce = createPalNonceManager();
|
|
11097
11568
|
this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
|
|
@@ -11191,11 +11662,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11191
11662
|
generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
|
|
11192
11663
|
return _this.generatePodVastUrl(base, breakDurationMs);
|
|
11193
11664
|
},
|
|
11665
|
+
getEdgePodBaseUrl: function getEdgePodBaseUrl() {
|
|
11666
|
+
return _this.edgePodBaseUrl;
|
|
11667
|
+
},
|
|
11194
11668
|
getFloorSnapshot: function getFloorSnapshot(position) {
|
|
11195
|
-
return _this.floorLadder.snapshotFor({
|
|
11669
|
+
return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
|
|
11196
11670
|
position: position,
|
|
11197
11671
|
isCtv: _this.isCtvEnvironment()
|
|
11198
|
-
});
|
|
11672
|
+
}) : void 0;
|
|
11199
11673
|
},
|
|
11200
11674
|
onAdClick: function onAdClick() {
|
|
11201
11675
|
return _this.palNonce.sendAdClick();
|
|
@@ -11246,11 +11720,43 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11246
11720
|
return report;
|
|
11247
11721
|
}
|
|
11248
11722
|
},
|
|
11723
|
+
{
|
|
11724
|
+
key: "setAdFloorLadderEnabled",
|
|
11725
|
+
value: function setAdFloorLadderEnabled(enabled) {
|
|
11726
|
+
this.floorLadderEnabled = enabled;
|
|
11727
|
+
if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11728
|
+
}
|
|
11729
|
+
},
|
|
11730
|
+
{
|
|
11731
|
+
key: "isAdFloorLadderEnabled",
|
|
11732
|
+
value: function isAdFloorLadderEnabled() {
|
|
11733
|
+
return this.floorLadderEnabled;
|
|
11734
|
+
}
|
|
11735
|
+
},
|
|
11736
|
+
{
|
|
11737
|
+
key: "setEdgePodRequest",
|
|
11738
|
+
value: function setEdgePodRequest(update) {
|
|
11739
|
+
if (update.enableEdgePodRequest === this.config.enableEdgePodRequest && update.edgePodUrl === this.config.edgePodUrl) {
|
|
11740
|
+
return;
|
|
11741
|
+
}
|
|
11742
|
+
if (update.enableEdgePodRequest === void 0) delete this.config.enableEdgePodRequest;
|
|
11743
|
+
else this.config.enableEdgePodRequest = update.enableEdgePodRequest;
|
|
11744
|
+
if (update.edgePodUrl === void 0) delete this.config.edgePodUrl;
|
|
11745
|
+
else this.config.edgePodUrl = update.edgePodUrl;
|
|
11746
|
+
this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
|
|
11747
|
+
}
|
|
11748
|
+
},
|
|
11749
|
+
{
|
|
11750
|
+
key: "getEdgePodUrl",
|
|
11751
|
+
value: function getEdgePodUrl() {
|
|
11752
|
+
return this.edgePodBaseUrl;
|
|
11753
|
+
}
|
|
11754
|
+
},
|
|
11249
11755
|
{
|
|
11250
11756
|
key: "warnOnInvalidFloorLadder",
|
|
11251
11757
|
value: function warnOnInvalidFloorLadder(report) {
|
|
11252
11758
|
var config = this.floorLadder.get();
|
|
11253
|
-
if (report.ok || !config.enabled) return;
|
|
11759
|
+
if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
|
|
11254
11760
|
console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
|
|
11255
11761
|
errors: report.errors,
|
|
11256
11762
|
configurationVersion: config.configurationVersion,
|
|
@@ -11983,6 +12489,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11983
12489
|
this.timing.destroy();
|
|
11984
12490
|
this.adBreak.clearPendingAdBreak();
|
|
11985
12491
|
this.placeholder.destroy();
|
|
12492
|
+
0;
|
|
11986
12493
|
if (this.timeUpdateHandler) {
|
|
11987
12494
|
this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
|
|
11988
12495
|
delete this.timeUpdateHandler;
|
|
@@ -12088,7 +12595,7 @@ var CRITICAL_PROPS = [
|
|
|
12088
12595
|
var CONTROLS_HIDE_DELAY = 3e3;
|
|
12089
12596
|
var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
|
|
12090
12597
|
var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
12091
|
-
var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, restVideoAttrs = _object_without_properties(props, [
|
|
12598
|
+
var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, adFloorLadderEnabled = props.adFloorLadderEnabled, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, enableEdgePodRequest = props.enableEdgePodRequest, edgePodUrl = props.edgePodUrl, restVideoAttrs = _object_without_properties(props, [
|
|
12092
12599
|
"src",
|
|
12093
12600
|
"autoplay",
|
|
12094
12601
|
"muted",
|
|
@@ -12125,10 +12632,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12125
12632
|
"minRemainingMsToStartAd",
|
|
12126
12633
|
"minRemainingMsToRequestAd",
|
|
12127
12634
|
"maxNoFillsPerBreak",
|
|
12635
|
+
"adFloorLadderEnabled",
|
|
12128
12636
|
"adFloorLadder",
|
|
12129
12637
|
"adFloorMinCents",
|
|
12130
12638
|
"adFloorMaxCents",
|
|
12131
|
-
"adFloorStepCents"
|
|
12639
|
+
"adFloorStepCents",
|
|
12640
|
+
"enableEdgePodRequest",
|
|
12641
|
+
"edgePodUrl"
|
|
12132
12642
|
]);
|
|
12133
12643
|
var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
|
|
12134
12644
|
var videoRef = useRef(null);
|
|
@@ -12329,10 +12839,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12329
12839
|
if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
|
|
12330
12840
|
if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
|
|
12331
12841
|
if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
|
|
12842
|
+
if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
|
|
12332
12843
|
if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
|
|
12333
12844
|
if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
|
|
12334
12845
|
if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
|
|
12335
12846
|
if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
|
|
12847
|
+
if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
|
|
12848
|
+
if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
|
|
12336
12849
|
var player = new StormcloudVideoPlayer(cfg);
|
|
12337
12850
|
playerRef.current = player;
|
|
12338
12851
|
appliedFloorLadderKeyRef.current = adFloorLadderKey;
|
|
@@ -12381,6 +12894,25 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12381
12894
|
}, [
|
|
12382
12895
|
adFloorLadderKey
|
|
12383
12896
|
]);
|
|
12897
|
+
useEffect(function() {
|
|
12898
|
+
if (!playerRef.current) return;
|
|
12899
|
+
var enabled = adFloorLadderEnabled === true;
|
|
12900
|
+
if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
|
|
12901
|
+
playerRef.current.setAdFloorLadderEnabled(enabled);
|
|
12902
|
+
}, [
|
|
12903
|
+
adFloorLadderEnabled
|
|
12904
|
+
]);
|
|
12905
|
+
useEffect(function() {
|
|
12906
|
+
if (!playerRef.current) return;
|
|
12907
|
+
playerRef.current.setEdgePodRequest(_object_spread({}, enableEdgePodRequest !== void 0 ? {
|
|
12908
|
+
enableEdgePodRequest: enableEdgePodRequest
|
|
12909
|
+
} : {}, edgePodUrl !== void 0 ? {
|
|
12910
|
+
edgePodUrl: edgePodUrl
|
|
12911
|
+
} : {}));
|
|
12912
|
+
}, [
|
|
12913
|
+
enableEdgePodRequest,
|
|
12914
|
+
edgePodUrl
|
|
12915
|
+
]);
|
|
12384
12916
|
useEffect(function() {
|
|
12385
12917
|
if (!playerRef.current) return;
|
|
12386
12918
|
var checkAdStatus = function checkAdStatus() {
|
|
@@ -13457,6 +13989,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
13457
13989
|
}
|
|
13458
13990
|
}
|
|
13459
13991
|
}
|
|
13992
|
+
if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled || prevProps.enableEdgePodRequest !== nextProps.enableEdgePodRequest || prevProps.edgePodUrl !== nextProps.edgePodUrl) {
|
|
13993
|
+
return false;
|
|
13994
|
+
}
|
|
13460
13995
|
if (JSON.stringify((_prevProps_adFloorLadder = prevProps.adFloorLadder) !== null && _prevProps_adFloorLadder !== void 0 ? _prevProps_adFloorLadder : null) !== JSON.stringify((_nextProps_adFloorLadder = nextProps.adFloorLadder) !== null && _nextProps_adFloorLadder !== void 0 ? _nextProps_adFloorLadder : null)) {
|
|
13461
13996
|
return false;
|
|
13462
13997
|
}
|