stormcloud-video-player 0.8.69 → 0.8.70
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 +516 -40
- package/lib/StormcloudPlayer.cjs.map +1 -1
- package/lib/index.cjs +541 -44
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +13 -2
- package/lib/index.js +541 -44
- 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 +136 -0
- package/lib/player/EdgePodRequest.cjs.map +1 -0
- package/lib/player/EdgePodRequest.d.cts +14 -0
- package/lib/player/StormcloudVideoPlayer.cjs +516 -40
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +4 -0
- package/lib/players/HlsPlayer.cjs +516 -40
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +516 -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 +541 -44
- 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,59 @@ 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
|
+
function resolveEdgePodBaseUrl(config) {
|
|
9233
|
+
var _config_edgePodUrl;
|
|
9234
|
+
if (config.enableEdgePodRequest !== true) return void 0;
|
|
9235
|
+
var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
|
|
9236
|
+
if (!raw) {
|
|
9237
|
+
console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
|
|
9238
|
+
return void 0;
|
|
9239
|
+
}
|
|
9240
|
+
try {
|
|
9241
|
+
var url = new URL(raw);
|
|
9242
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
9243
|
+
throw new Error("unsupported protocol ".concat(url.protocol));
|
|
9244
|
+
}
|
|
9245
|
+
return url.toString();
|
|
9246
|
+
} catch (unused) {
|
|
9247
|
+
console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
|
|
9248
|
+
return void 0;
|
|
9249
|
+
}
|
|
9250
|
+
}
|
|
9251
|
+
function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
|
|
9252
|
+
var url = new URL(baseUrl);
|
|
9253
|
+
var maxMs = Math.max(0, Math.floor(remainingMs));
|
|
9254
|
+
var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
|
|
9255
|
+
url.searchParams.set("pmxd", String(maxMs));
|
|
9256
|
+
url.searchParams.set("pmad", String(maxAds));
|
|
9257
|
+
url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
|
|
9258
|
+
url.searchParams.set("count", String(maxAds));
|
|
9259
|
+
return url.toString();
|
|
9260
|
+
}
|
|
9261
|
+
function classifyEdgeVastResponse(result) {
|
|
9262
|
+
var _ref;
|
|
9263
|
+
var _result_error;
|
|
9264
|
+
if (result.error == null) {
|
|
9265
|
+
return result.podAdCount > 0 ? "fill" : "no_fill";
|
|
9266
|
+
}
|
|
9267
|
+
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);
|
|
9268
|
+
if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
|
|
9269
|
+
return "no_fill";
|
|
9270
|
+
}
|
|
9271
|
+
return "invalid";
|
|
9272
|
+
}
|
|
9273
|
+
function describeEdgeUrl(url) {
|
|
9274
|
+
try {
|
|
9275
|
+
var parsed = new URL(url);
|
|
9276
|
+
return "".concat(parsed.origin).concat(parsed.pathname);
|
|
9277
|
+
} catch (unused) {
|
|
9278
|
+
var _url_split_;
|
|
9279
|
+
return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
|
|
9280
|
+
}
|
|
9281
|
+
}
|
|
9128
9282
|
// src/player/PlayerControls.ts
|
|
9129
9283
|
function getAdAudioVolume(adPlayer) {
|
|
9130
9284
|
return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
|
|
@@ -9284,6 +9438,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9284
9438
|
this.controllerCallInFlight = false;
|
|
9285
9439
|
this.playbackStartedForCurrentRequest = false;
|
|
9286
9440
|
this.opportunityEpoch = -1;
|
|
9441
|
+
this.edgeExhaustedForBreak = false;
|
|
9442
|
+
this.edgeRequestsInBreak = 0;
|
|
9287
9443
|
this.adPodQueue = [];
|
|
9288
9444
|
this.defaultMinRemainingMsToRequestAd = 1e4;
|
|
9289
9445
|
this.defaultMaxNoFillsPerBreak = 2;
|
|
@@ -9434,7 +9590,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9434
9590
|
_this.timing.clearAdRequestWatchdog();
|
|
9435
9591
|
_this.timing.activeAdRequestToken = null;
|
|
9436
9592
|
_this.showAds = true;
|
|
9437
|
-
_this.
|
|
9593
|
+
if (_this.currentPodSource !== "edge") {
|
|
9594
|
+
_this.timing.resetGamNoFillCounter();
|
|
9595
|
+
}
|
|
9438
9596
|
if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
|
|
9439
9597
|
_this.timing.scheduleAdStopAtBreakBoundary();
|
|
9440
9598
|
if (_this.debug) {
|
|
@@ -9566,6 +9724,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9566
9724
|
key: "beginVmapBreak",
|
|
9567
9725
|
value: function beginVmapBreak(breakKey, position) {
|
|
9568
9726
|
this.breakSource = "vmap";
|
|
9727
|
+
this.resetEdgeStateForBreak();
|
|
9569
9728
|
this.followUpBaseVastUrl = void 0;
|
|
9570
9729
|
this.unusableResponsesInBreak = 0;
|
|
9571
9730
|
this.timing.totalAdRequestsInBreak = 0;
|
|
@@ -9577,7 +9736,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9577
9736
|
key: "handleAdStart",
|
|
9578
9737
|
value: function handleAdStart(marker) {
|
|
9579
9738
|
return _async_to_generator(function() {
|
|
9580
|
-
var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
|
|
9739
|
+
var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
|
|
9581
9740
|
return _ts_generator(this, function(_state) {
|
|
9582
9741
|
switch(_state.label){
|
|
9583
9742
|
case 0:
|
|
@@ -9591,7 +9750,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9591
9750
|
];
|
|
9592
9751
|
}
|
|
9593
9752
|
baseVastUrl = this.adConfig.apiVastTagUrl;
|
|
9594
|
-
|
|
9753
|
+
edgeConfigured = !!this.host.getEdgePodBaseUrl();
|
|
9754
|
+
if (!baseVastUrl && !edgeConfigured) {
|
|
9595
9755
|
console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
|
|
9596
9756
|
this.clearPendingAdBreak();
|
|
9597
9757
|
return [
|
|
@@ -9607,6 +9767,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9607
9767
|
this.breakSource = "scte35";
|
|
9608
9768
|
this.followUpBaseVastUrl = baseVastUrl;
|
|
9609
9769
|
this.unusableResponsesInBreak = 0;
|
|
9770
|
+
this.resetEdgeStateForBreak();
|
|
9610
9771
|
this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
|
|
9611
9772
|
if (this.adConfig.podAssignedByPrefetch) {
|
|
9612
9773
|
this.adConfig.podAssignedByPrefetch = false;
|
|
@@ -9628,7 +9789,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9628
9789
|
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
|
|
9629
9790
|
epoch = this.timing.adBreakEpoch;
|
|
9630
9791
|
hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
|
|
9631
|
-
if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
|
|
9792
|
+
if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
|
|
9632
9793
|
3,
|
|
9633
9794
|
2
|
|
9634
9795
|
];
|
|
@@ -9647,11 +9808,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9647
9808
|
mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
|
|
9648
9809
|
console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
|
|
9649
9810
|
}
|
|
9811
|
+
if (!edgeConfigured) return [
|
|
9812
|
+
3,
|
|
9813
|
+
5
|
|
9814
|
+
];
|
|
9815
|
+
edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
|
|
9816
|
+
if (!edgeUrl) return [
|
|
9817
|
+
3,
|
|
9818
|
+
4
|
|
9819
|
+
];
|
|
9820
|
+
this.clearPendingAdBreak();
|
|
9650
9821
|
return [
|
|
9651
9822
|
4,
|
|
9652
|
-
this.
|
|
9823
|
+
this.runEdgePod(edgeUrl, "edge_break_start")
|
|
9653
9824
|
];
|
|
9654
9825
|
case 3:
|
|
9826
|
+
outcome = _state.sent();
|
|
9827
|
+
this.continueAfterEdgeOutcome(outcome, epoch);
|
|
9828
|
+
return [
|
|
9829
|
+
2
|
|
9830
|
+
];
|
|
9831
|
+
case 4:
|
|
9832
|
+
if (!this.edgeExhaustedForBreak) {
|
|
9833
|
+
this.markEdgeExhausted("not_eligible_at_break_start", {
|
|
9834
|
+
isLive: this.isLiveBreak(),
|
|
9835
|
+
durationMs: this.timing.expectedAdBreakDurationMs
|
|
9836
|
+
});
|
|
9837
|
+
}
|
|
9838
|
+
_state.label = 5;
|
|
9839
|
+
case 5:
|
|
9840
|
+
if (!baseVastUrl) {
|
|
9841
|
+
this.requestNextAd("no_gam_source");
|
|
9842
|
+
return [
|
|
9843
|
+
2
|
|
9844
|
+
];
|
|
9845
|
+
}
|
|
9846
|
+
return [
|
|
9847
|
+
4,
|
|
9848
|
+
this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
|
|
9849
|
+
];
|
|
9850
|
+
case 6:
|
|
9655
9851
|
podPlayed = _state.sent();
|
|
9656
9852
|
if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
|
|
9657
9853
|
this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
|
|
@@ -9743,6 +9939,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9743
9939
|
adPlayer = this.host.getAdPlayer();
|
|
9744
9940
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
9745
9941
|
this.timing.activeAdRequestToken = requestToken;
|
|
9942
|
+
this.currentPodSource = "gam";
|
|
9746
9943
|
this.setSlotState("REQUESTING", "initial_pod");
|
|
9747
9944
|
this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
|
|
9748
9945
|
requestUrl = this.applyOpportunityFloor(podUrl);
|
|
@@ -9859,6 +10056,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9859
10056
|
}).call(this);
|
|
9860
10057
|
}
|
|
9861
10058
|
},
|
|
10059
|
+
{
|
|
10060
|
+
// ───────────────────────────────────────────────────────────────
|
|
10061
|
+
// Edge-first pods (live SCTE-35 only, GAM fallback)
|
|
10062
|
+
// ───────────────────────────────────────────────────────────────
|
|
10063
|
+
key: "resetEdgeStateForBreak",
|
|
10064
|
+
value: function resetEdgeStateForBreak() {
|
|
10065
|
+
this.edgeExhaustedForBreak = false;
|
|
10066
|
+
this.edgeRequestsInBreak = 0;
|
|
10067
|
+
this.currentPodSource = void 0;
|
|
10068
|
+
}
|
|
10069
|
+
},
|
|
10070
|
+
{
|
|
10071
|
+
key: "isLiveBreak",
|
|
10072
|
+
value: function isLiveBreak() {
|
|
10073
|
+
return this.host.isLiveStream() || this.host.config.isLiveStream === true;
|
|
10074
|
+
}
|
|
10075
|
+
},
|
|
10076
|
+
{
|
|
10077
|
+
key: "canRequestEdge",
|
|
10078
|
+
value: function canRequestEdge() {
|
|
10079
|
+
return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
|
|
10080
|
+
}
|
|
10081
|
+
},
|
|
10082
|
+
{
|
|
10083
|
+
key: "markEdgeExhausted",
|
|
10084
|
+
value: function markEdgeExhausted(reason) {
|
|
10085
|
+
var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
10086
|
+
this.edgeExhaustedForBreak = true;
|
|
10087
|
+
this.countFunnelStage("edge_fallback:".concat(reason));
|
|
10088
|
+
this.logOrchestratorFunnel("edge_exhausted", _object_spread({
|
|
10089
|
+
reason: reason,
|
|
10090
|
+
edgeRequests: this.edgeRequestsInBreak,
|
|
10091
|
+
remainingMs: this.timing.getRemainingAdMs()
|
|
10092
|
+
}, extra));
|
|
10093
|
+
}
|
|
10094
|
+
},
|
|
10095
|
+
{
|
|
10096
|
+
/**
|
|
10097
|
+
* Builds the next Edge request from the budget left right now, or marks Edge
|
|
10098
|
+
* exhausted for this break. Synchronous on purpose: callers must reach the
|
|
10099
|
+
* REQUESTING state in the same tick so a second completion event cannot race
|
|
10100
|
+
* in a parallel request.
|
|
10101
|
+
*/ key: "prepareEdgePodRequest",
|
|
10102
|
+
value: function prepareEdgePodRequest() {
|
|
10103
|
+
var baseUrl = this.host.getEdgePodBaseUrl();
|
|
10104
|
+
if (!baseUrl) return void 0;
|
|
10105
|
+
var remainingMs = this.timing.getRemainingAdMs();
|
|
10106
|
+
var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
|
|
10107
|
+
if (remainingAds < 1) {
|
|
10108
|
+
this.markEdgeExhausted("ad_capacity_reached", {
|
|
10109
|
+
adsInBreak: this.timing.totalAdsInBreak
|
|
10110
|
+
});
|
|
10111
|
+
return void 0;
|
|
10112
|
+
}
|
|
10113
|
+
if (remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
10114
|
+
this.markEdgeExhausted("insufficient_break_time", {
|
|
10115
|
+
remainingMs: remainingMs
|
|
10116
|
+
});
|
|
10117
|
+
return void 0;
|
|
10118
|
+
}
|
|
10119
|
+
try {
|
|
10120
|
+
return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
|
|
10121
|
+
} catch (unused) {
|
|
10122
|
+
this.markEdgeExhausted("invalid_edge_url");
|
|
10123
|
+
return void 0;
|
|
10124
|
+
}
|
|
10125
|
+
}
|
|
10126
|
+
},
|
|
10127
|
+
{
|
|
10128
|
+
key: "runEdgePod",
|
|
10129
|
+
value: function runEdgePod(requestUrl, trigger) {
|
|
10130
|
+
return _async_to_generator(function() {
|
|
10131
|
+
var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
|
|
10132
|
+
return _ts_generator(this, function(_state) {
|
|
10133
|
+
switch(_state.label){
|
|
10134
|
+
case 0:
|
|
10135
|
+
epoch = this.timing.adBreakEpoch;
|
|
10136
|
+
this.recreateAdController("new_request");
|
|
10137
|
+
generation = this.controllerGeneration;
|
|
10138
|
+
adPlayer = this.host.getAdPlayer();
|
|
10139
|
+
requestToken = ++this.timing.adRequestTokenCounter;
|
|
10140
|
+
this.timing.activeAdRequestToken = requestToken;
|
|
10141
|
+
this.currentPodSource = "edge";
|
|
10142
|
+
this.edgeRequestsInBreak++;
|
|
10143
|
+
this.setSlotState("REQUESTING", trigger);
|
|
10144
|
+
this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
|
|
10145
|
+
this.currentVastUrl = requestUrl;
|
|
10146
|
+
params = new URL(requestUrl).searchParams;
|
|
10147
|
+
this.logOrchestratorFunnel("edge_request_sent", {
|
|
10148
|
+
trigger: trigger,
|
|
10149
|
+
attempt: this.edgeRequestsInBreak,
|
|
10150
|
+
endpoint: describeEdgeUrl(requestUrl),
|
|
10151
|
+
pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
|
|
10152
|
+
pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
|
|
10153
|
+
});
|
|
10154
|
+
_state.label = 1;
|
|
10155
|
+
case 1:
|
|
10156
|
+
_state.trys.push([
|
|
10157
|
+
1,
|
|
10158
|
+
4,
|
|
10159
|
+
,
|
|
10160
|
+
5
|
|
10161
|
+
]);
|
|
10162
|
+
this.timing.startAdRequestWatchdog(requestToken);
|
|
10163
|
+
return [
|
|
10164
|
+
4,
|
|
10165
|
+
this.callController(function() {
|
|
10166
|
+
return adPlayer.requestAds(requestUrl, {
|
|
10167
|
+
source: "edge"
|
|
10168
|
+
});
|
|
10169
|
+
})
|
|
10170
|
+
];
|
|
10171
|
+
case 2:
|
|
10172
|
+
_state.sent();
|
|
10173
|
+
this.timing.clearAdRequestWatchdog();
|
|
10174
|
+
if (this.isStale(epoch, generation)) {
|
|
10175
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10176
|
+
requestId: requestToken,
|
|
10177
|
+
source: "edge"
|
|
10178
|
+
});
|
|
10179
|
+
return [
|
|
10180
|
+
2,
|
|
10181
|
+
"stale"
|
|
10182
|
+
];
|
|
10183
|
+
}
|
|
10184
|
+
remainingMs = this.timing.getRemainingAdMs();
|
|
10185
|
+
remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
|
|
10186
|
+
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;
|
|
10187
|
+
if (classifyEdgeVastResponse({
|
|
10188
|
+
podAdCount: podCount
|
|
10189
|
+
}) !== "fill") {
|
|
10190
|
+
throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
|
|
10191
|
+
}
|
|
10192
|
+
this.setSlotState("READY", "edge_vast_ready");
|
|
10193
|
+
this.logOrchestratorFunnel("edge_fill", {
|
|
10194
|
+
podAdCount: podCount,
|
|
10195
|
+
podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
|
|
10196
|
+
remainingMs: remainingMs
|
|
10197
|
+
});
|
|
10198
|
+
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
10199
|
+
source: "hls",
|
|
10200
|
+
vastUrl: requestUrl,
|
|
10201
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10202
|
+
}, this.analyticsContext).catch(function() {});
|
|
10203
|
+
this.timing.startAdFailsafeTimer(requestToken);
|
|
10204
|
+
return [
|
|
10205
|
+
4,
|
|
10206
|
+
this.callController(function() {
|
|
10207
|
+
return adPlayer.play();
|
|
10208
|
+
})
|
|
10209
|
+
];
|
|
10210
|
+
case 3:
|
|
10211
|
+
_state.sent();
|
|
10212
|
+
if (this.isStale(epoch, generation)) return [
|
|
10213
|
+
2,
|
|
10214
|
+
"stale"
|
|
10215
|
+
];
|
|
10216
|
+
if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
|
|
10217
|
+
this.timing.scheduleAdStopAtBreakBoundary();
|
|
10218
|
+
}
|
|
10219
|
+
adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
|
|
10220
|
+
return [
|
|
10221
|
+
2,
|
|
10222
|
+
"fill"
|
|
10223
|
+
];
|
|
10224
|
+
case 4:
|
|
10225
|
+
error = _state.sent();
|
|
10226
|
+
this.timing.clearAdRequestWatchdog();
|
|
10227
|
+
this.timing.clearAdFailsafeTimer();
|
|
10228
|
+
if (this.timing.activeAdRequestToken === requestToken) {
|
|
10229
|
+
this.timing.activeAdRequestToken = null;
|
|
10230
|
+
}
|
|
10231
|
+
errorMessage = error === null || error === void 0 ? void 0 : error.message;
|
|
10232
|
+
if (this.isStale(epoch, generation)) {
|
|
10233
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10234
|
+
requestId: requestToken,
|
|
10235
|
+
source: "edge",
|
|
10236
|
+
errorMessage: errorMessage
|
|
10237
|
+
});
|
|
10238
|
+
return [
|
|
10239
|
+
2,
|
|
10240
|
+
"stale"
|
|
10241
|
+
];
|
|
10242
|
+
}
|
|
10243
|
+
classification = classifyEdgeVastResponse({
|
|
10244
|
+
podAdCount: 0,
|
|
10245
|
+
error: error
|
|
10246
|
+
});
|
|
10247
|
+
diag = this.requestDiagnostics.get(requestToken);
|
|
10248
|
+
if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
|
|
10249
|
+
this.markEdgeExhausted("edge_".concat(classification), {
|
|
10250
|
+
errorMessage: errorMessage
|
|
10251
|
+
});
|
|
10252
|
+
return [
|
|
10253
|
+
2,
|
|
10254
|
+
"fallback"
|
|
10255
|
+
];
|
|
10256
|
+
case 5:
|
|
10257
|
+
return [
|
|
10258
|
+
2
|
|
10259
|
+
];
|
|
10260
|
+
}
|
|
10261
|
+
});
|
|
10262
|
+
}).call(this);
|
|
10263
|
+
}
|
|
10264
|
+
},
|
|
10265
|
+
{
|
|
10266
|
+
key: "continueAfterEdgeOutcome",
|
|
10267
|
+
value: function continueAfterEdgeOutcome(outcome, epoch) {
|
|
10268
|
+
if (outcome !== "fallback") return;
|
|
10269
|
+
if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
|
|
10270
|
+
if (this.debug) {
|
|
10271
|
+
console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
|
|
10272
|
+
}
|
|
10273
|
+
this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
|
|
10274
|
+
this.requestNextAd("edge_fallback");
|
|
10275
|
+
}
|
|
10276
|
+
},
|
|
9862
10277
|
{
|
|
9863
10278
|
// ───────────────────────────────────────────────────────────────
|
|
9864
10279
|
// Next-ad scheduling (single flight)
|
|
@@ -9914,7 +10329,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9914
10329
|
value: function getStopRequestingReason(remainingMs) {
|
|
9915
10330
|
if (this.breakSource === "vmap") {
|
|
9916
10331
|
if (this.adPodQueue.length === 0) return "vmap_queue_empty";
|
|
9917
|
-
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
|
|
10332
|
+
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
|
|
9918
10333
|
return "no_follow_up_source";
|
|
9919
10334
|
}
|
|
9920
10335
|
if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
|
|
@@ -9926,7 +10341,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9926
10341
|
if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
|
|
9927
10342
|
return "request_cap";
|
|
9928
10343
|
}
|
|
9929
|
-
if (this.timing.isGamInCooldown()) {
|
|
10344
|
+
if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
|
|
9930
10345
|
return "gam_cooldown";
|
|
9931
10346
|
}
|
|
9932
10347
|
if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
@@ -10020,10 +10435,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10020
10435
|
key: "requestFollowUpAd",
|
|
10021
10436
|
value: function requestFollowUpAd(trigger) {
|
|
10022
10437
|
return _async_to_generator(function() {
|
|
10023
|
-
var url, epoch, unused;
|
|
10438
|
+
var edgeUrl, epoch2, outcome, url, epoch, unused;
|
|
10024
10439
|
return _ts_generator(this, function(_state) {
|
|
10025
10440
|
switch(_state.label){
|
|
10026
10441
|
case 0:
|
|
10442
|
+
if (!this.canRequestEdge()) return [
|
|
10443
|
+
3,
|
|
10444
|
+
2
|
|
10445
|
+
];
|
|
10446
|
+
edgeUrl = this.prepareEdgePodRequest();
|
|
10447
|
+
if (!edgeUrl) {
|
|
10448
|
+
this.requestNextAd("".concat(trigger, ":edge_unavailable"));
|
|
10449
|
+
return [
|
|
10450
|
+
2
|
|
10451
|
+
];
|
|
10452
|
+
}
|
|
10453
|
+
epoch2 = this.timing.adBreakEpoch;
|
|
10454
|
+
return [
|
|
10455
|
+
4,
|
|
10456
|
+
this.runEdgePod(edgeUrl, "edge_".concat(trigger))
|
|
10457
|
+
];
|
|
10458
|
+
case 1:
|
|
10459
|
+
outcome = _state.sent();
|
|
10460
|
+
this.continueAfterEdgeOutcome(outcome, epoch2);
|
|
10461
|
+
return [
|
|
10462
|
+
2
|
|
10463
|
+
];
|
|
10464
|
+
case 2:
|
|
10027
10465
|
if (this.breakSource === "vmap") {
|
|
10028
10466
|
url = this.adPodQueue.shift();
|
|
10029
10467
|
} else if (this.followUpBaseVastUrl) {
|
|
@@ -10034,32 +10472,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10034
10472
|
];
|
|
10035
10473
|
this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
|
|
10036
10474
|
epoch = this.timing.adBreakEpoch;
|
|
10037
|
-
_state.label =
|
|
10038
|
-
case
|
|
10475
|
+
_state.label = 3;
|
|
10476
|
+
case 3:
|
|
10039
10477
|
_state.trys.push([
|
|
10040
|
-
1,
|
|
10041
10478
|
3,
|
|
10479
|
+
5,
|
|
10042
10480
|
,
|
|
10043
|
-
|
|
10481
|
+
6
|
|
10044
10482
|
]);
|
|
10045
10483
|
return [
|
|
10046
10484
|
4,
|
|
10047
10485
|
this.playSingleAd(url, trigger)
|
|
10048
10486
|
];
|
|
10049
|
-
case
|
|
10487
|
+
case 4:
|
|
10050
10488
|
_state.sent();
|
|
10051
10489
|
return [
|
|
10052
10490
|
3,
|
|
10053
|
-
|
|
10491
|
+
6
|
|
10054
10492
|
];
|
|
10055
|
-
case
|
|
10493
|
+
case 5:
|
|
10056
10494
|
unused = _state.sent();
|
|
10057
10495
|
this.continueAfterRequestFailure(epoch);
|
|
10058
10496
|
return [
|
|
10059
10497
|
3,
|
|
10060
|
-
|
|
10498
|
+
6
|
|
10061
10499
|
];
|
|
10062
|
-
case
|
|
10500
|
+
case 6:
|
|
10063
10501
|
return [
|
|
10064
10502
|
2
|
|
10065
10503
|
];
|
|
@@ -10172,7 +10610,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10172
10610
|
case "gam_http_request_sent":
|
|
10173
10611
|
diag.gamRequestSent++;
|
|
10174
10612
|
break;
|
|
10613
|
+
case "edge_http_request_sent":
|
|
10614
|
+
diag.edgeRequestSent++;
|
|
10615
|
+
break;
|
|
10175
10616
|
case "gam_response_received":
|
|
10617
|
+
case "edge_response_received":
|
|
10176
10618
|
diag.vastHttpStatus = payload.httpStatus;
|
|
10177
10619
|
break;
|
|
10178
10620
|
case "vast_parsed":
|
|
@@ -10359,6 +10801,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10359
10801
|
{
|
|
10360
10802
|
key: "beginFunnelRequest",
|
|
10361
10803
|
value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
|
|
10804
|
+
var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
|
|
10362
10805
|
var _adPlayer_setFunnelContext;
|
|
10363
10806
|
if (this.controllerCallInFlight) {
|
|
10364
10807
|
this.logOrchestratorFunnel("duplicate_request_detected", {
|
|
@@ -10373,7 +10816,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10373
10816
|
requestId: requestToken,
|
|
10374
10817
|
controllerId: this.controllerGeneration,
|
|
10375
10818
|
trigger: trigger,
|
|
10819
|
+
source: source,
|
|
10376
10820
|
gamRequestSent: 0,
|
|
10821
|
+
edgeRequestSent: 0,
|
|
10377
10822
|
wrapperDepth: 0,
|
|
10378
10823
|
inlineResolved: false,
|
|
10379
10824
|
mediaCandidateCount: 0,
|
|
@@ -10504,6 +10949,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10504
10949
|
this.timing.activeAdRequestToken = requestToken;
|
|
10505
10950
|
ap = this.host.getAdPlayer();
|
|
10506
10951
|
budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
|
|
10952
|
+
this.currentPodSource = "gam";
|
|
10507
10953
|
this.setSlotState("REQUESTING", trigger);
|
|
10508
10954
|
this.beginFunnelRequest(ap, requestToken, trigger);
|
|
10509
10955
|
requestUrl = this.applyOpportunityFloor(budgetedUrl);
|
|
@@ -10651,6 +11097,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10651
11097
|
requests: requests,
|
|
10652
11098
|
requestRetries: requestRetries,
|
|
10653
11099
|
gamResponses: count("gam_response_received"),
|
|
11100
|
+
edgeRequests: count("edge_request_sent"),
|
|
11101
|
+
edgeFills: count("edge_fill"),
|
|
11102
|
+
edgeEmptySentinels: count("edge_empty_sentinel"),
|
|
11103
|
+
edgeFallbacks: countPrefix("edge_fallback:"),
|
|
10654
11104
|
requestsSuppressed: count("request_suppressed"),
|
|
10655
11105
|
duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
|
|
10656
11106
|
filled: count("vast_received"),
|
|
@@ -10747,6 +11197,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10747
11197
|
this.breakSource = void 0;
|
|
10748
11198
|
this.followUpBaseVastUrl = void 0;
|
|
10749
11199
|
this.unusableResponsesInBreak = 0;
|
|
11200
|
+
this.resetEdgeStateForBreak();
|
|
10750
11201
|
adPlayer.stop().catch(function() {});
|
|
10751
11202
|
if (!alreadyEnded) this.logBreakFunnel(reason);
|
|
10752
11203
|
this.opportunityFloor = void 0;
|
|
@@ -11060,7 +11511,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
11060
11511
|
});
|
|
11061
11512
|
return;
|
|
11062
11513
|
}
|
|
11063
|
-
this.
|
|
11514
|
+
if (this.currentPodSource === "edge") {
|
|
11515
|
+
this.markEdgeExhausted("edge_playback_failed", {
|
|
11516
|
+
reason: reason
|
|
11517
|
+
});
|
|
11518
|
+
} else {
|
|
11519
|
+
this.timing.consecutiveFailures++;
|
|
11520
|
+
}
|
|
11064
11521
|
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
11065
11522
|
if (diag && !diag.failureReason) diag.failureReason = reason;
|
|
11066
11523
|
if (this.debug) {
|
|
@@ -11091,7 +11548,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11091
11548
|
if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
|
|
11092
11549
|
if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
|
|
11093
11550
|
this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
|
|
11551
|
+
this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
|
|
11094
11552
|
this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11553
|
+
this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
|
|
11095
11554
|
this.adPlayer = this.createAdPlayer(false);
|
|
11096
11555
|
this.palNonce = createPalNonceManager();
|
|
11097
11556
|
this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
|
|
@@ -11191,11 +11650,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11191
11650
|
generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
|
|
11192
11651
|
return _this.generatePodVastUrl(base, breakDurationMs);
|
|
11193
11652
|
},
|
|
11653
|
+
getEdgePodBaseUrl: function getEdgePodBaseUrl() {
|
|
11654
|
+
return _this.edgePodBaseUrl;
|
|
11655
|
+
},
|
|
11194
11656
|
getFloorSnapshot: function getFloorSnapshot(position) {
|
|
11195
|
-
return _this.floorLadder.snapshotFor({
|
|
11657
|
+
return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
|
|
11196
11658
|
position: position,
|
|
11197
11659
|
isCtv: _this.isCtvEnvironment()
|
|
11198
|
-
});
|
|
11660
|
+
}) : void 0;
|
|
11199
11661
|
},
|
|
11200
11662
|
onAdClick: function onAdClick() {
|
|
11201
11663
|
return _this.palNonce.sendAdClick();
|
|
@@ -11246,11 +11708,24 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11246
11708
|
return report;
|
|
11247
11709
|
}
|
|
11248
11710
|
},
|
|
11711
|
+
{
|
|
11712
|
+
key: "setAdFloorLadderEnabled",
|
|
11713
|
+
value: function setAdFloorLadderEnabled(enabled) {
|
|
11714
|
+
this.floorLadderEnabled = enabled;
|
|
11715
|
+
if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11716
|
+
}
|
|
11717
|
+
},
|
|
11718
|
+
{
|
|
11719
|
+
key: "isAdFloorLadderEnabled",
|
|
11720
|
+
value: function isAdFloorLadderEnabled() {
|
|
11721
|
+
return this.floorLadderEnabled;
|
|
11722
|
+
}
|
|
11723
|
+
},
|
|
11249
11724
|
{
|
|
11250
11725
|
key: "warnOnInvalidFloorLadder",
|
|
11251
11726
|
value: function warnOnInvalidFloorLadder(report) {
|
|
11252
11727
|
var config = this.floorLadder.get();
|
|
11253
|
-
if (report.ok || !config.enabled) return;
|
|
11728
|
+
if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
|
|
11254
11729
|
console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
|
|
11255
11730
|
errors: report.errors,
|
|
11256
11731
|
configurationVersion: config.configurationVersion,
|
|
@@ -11983,6 +12458,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11983
12458
|
this.timing.destroy();
|
|
11984
12459
|
this.adBreak.clearPendingAdBreak();
|
|
11985
12460
|
this.placeholder.destroy();
|
|
12461
|
+
0;
|
|
11986
12462
|
if (this.timeUpdateHandler) {
|
|
11987
12463
|
this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
|
|
11988
12464
|
delete this.timeUpdateHandler;
|
|
@@ -12083,12 +12559,14 @@ var CRITICAL_PROPS = [
|
|
|
12083
12559
|
"ctvAdRequest",
|
|
12084
12560
|
"adFloorMinCents",
|
|
12085
12561
|
"adFloorMaxCents",
|
|
12086
|
-
"adFloorStepCents"
|
|
12562
|
+
"adFloorStepCents",
|
|
12563
|
+
"enableEdgePodRequest",
|
|
12564
|
+
"edgePodUrl"
|
|
12087
12565
|
];
|
|
12088
12566
|
var CONTROLS_HIDE_DELAY = 3e3;
|
|
12089
12567
|
var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
|
|
12090
12568
|
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, [
|
|
12569
|
+
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
12570
|
"src",
|
|
12093
12571
|
"autoplay",
|
|
12094
12572
|
"muted",
|
|
@@ -12125,10 +12603,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12125
12603
|
"minRemainingMsToStartAd",
|
|
12126
12604
|
"minRemainingMsToRequestAd",
|
|
12127
12605
|
"maxNoFillsPerBreak",
|
|
12606
|
+
"adFloorLadderEnabled",
|
|
12128
12607
|
"adFloorLadder",
|
|
12129
12608
|
"adFloorMinCents",
|
|
12130
12609
|
"adFloorMaxCents",
|
|
12131
|
-
"adFloorStepCents"
|
|
12610
|
+
"adFloorStepCents",
|
|
12611
|
+
"enableEdgePodRequest",
|
|
12612
|
+
"edgePodUrl"
|
|
12132
12613
|
]);
|
|
12133
12614
|
var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
|
|
12134
12615
|
var videoRef = useRef(null);
|
|
@@ -12279,7 +12760,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12279
12760
|
vastMode,
|
|
12280
12761
|
adFloorMinCents,
|
|
12281
12762
|
adFloorMaxCents,
|
|
12282
|
-
adFloorStepCents
|
|
12763
|
+
adFloorStepCents,
|
|
12764
|
+
enableEdgePodRequest,
|
|
12765
|
+
edgePodUrl
|
|
12283
12766
|
]);
|
|
12284
12767
|
useEffect(function() {
|
|
12285
12768
|
if (typeof window === "undefined") return;
|
|
@@ -12329,10 +12812,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12329
12812
|
if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
|
|
12330
12813
|
if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
|
|
12331
12814
|
if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
|
|
12815
|
+
if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
|
|
12332
12816
|
if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
|
|
12333
12817
|
if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
|
|
12334
12818
|
if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
|
|
12335
12819
|
if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
|
|
12820
|
+
if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
|
|
12821
|
+
if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
|
|
12336
12822
|
var player = new StormcloudVideoPlayer(cfg);
|
|
12337
12823
|
playerRef.current = player;
|
|
12338
12824
|
appliedFloorLadderKeyRef.current = adFloorLadderKey;
|
|
@@ -12381,6 +12867,14 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
12381
12867
|
}, [
|
|
12382
12868
|
adFloorLadderKey
|
|
12383
12869
|
]);
|
|
12870
|
+
useEffect(function() {
|
|
12871
|
+
if (!playerRef.current) return;
|
|
12872
|
+
var enabled = adFloorLadderEnabled === true;
|
|
12873
|
+
if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
|
|
12874
|
+
playerRef.current.setAdFloorLadderEnabled(enabled);
|
|
12875
|
+
}, [
|
|
12876
|
+
adFloorLadderEnabled
|
|
12877
|
+
]);
|
|
12384
12878
|
useEffect(function() {
|
|
12385
12879
|
if (!playerRef.current) return;
|
|
12386
12880
|
var checkAdStatus = function checkAdStatus() {
|
|
@@ -13457,6 +13951,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
|
|
|
13457
13951
|
}
|
|
13458
13952
|
}
|
|
13459
13953
|
}
|
|
13954
|
+
if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled) {
|
|
13955
|
+
return false;
|
|
13956
|
+
}
|
|
13460
13957
|
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
13958
|
return false;
|
|
13462
13959
|
}
|