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
|
@@ -2483,7 +2483,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2483
2483
|
img.onload = null;
|
|
2484
2484
|
img.onerror = null;
|
|
2485
2485
|
inFlightBeacons.delete(img);
|
|
2486
|
-
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(
|
|
2486
|
+
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingHost));
|
|
2487
2487
|
if (outcome !== "load") {
|
|
2488
2488
|
logFunnel("tracking_request_settled", {
|
|
2489
2489
|
reason: outcome,
|
|
@@ -2501,7 +2501,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2501
2501
|
return release("timeout");
|
|
2502
2502
|
}, BEACON_TIMEOUT_MS);
|
|
2503
2503
|
img.src = trackingUrl;
|
|
2504
|
-
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(
|
|
2504
|
+
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingHost));
|
|
2505
2505
|
logFunnel("tracking_request_created", {
|
|
2506
2506
|
trackingHost: trackingHost,
|
|
2507
2507
|
errorCode: options2 === null || options2 === void 0 ? void 0 : options2.errorCode
|
|
@@ -2955,7 +2955,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2955
2955
|
});
|
|
2956
2956
|
}
|
|
2957
2957
|
if (parsed.type === "wrapper") {
|
|
2958
|
-
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
|
|
2958
|
+
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(redactUrl(parsed.vastAdTagUri)));
|
|
2959
2959
|
}
|
|
2960
2960
|
return parsed;
|
|
2961
2961
|
}
|
|
@@ -3147,8 +3147,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3147
3147
|
switch(_state.label){
|
|
3148
3148
|
case 0:
|
|
3149
3149
|
attempt++;
|
|
3150
|
-
if (kind
|
|
3151
|
-
logFunnel("
|
|
3150
|
+
if (kind !== "wrapper") {
|
|
3151
|
+
logFunnel("".concat(kind, "_http_request_sent"), {
|
|
3152
3152
|
attempt: attempt,
|
|
3153
3153
|
credentials: creds
|
|
3154
3154
|
});
|
|
@@ -3168,8 +3168,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3168
3168
|
];
|
|
3169
3169
|
case 1:
|
|
3170
3170
|
response = _state.sent();
|
|
3171
|
-
if (kind
|
|
3172
|
-
logFunnel("
|
|
3171
|
+
if (kind !== "wrapper") {
|
|
3172
|
+
logFunnel("".concat(kind, "_response_received"), {
|
|
3173
3173
|
attempt: attempt,
|
|
3174
3174
|
httpStatus: response.status,
|
|
3175
3175
|
ok: response.ok,
|
|
@@ -3339,8 +3339,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3339
3339
|
elapsedMs: Date.now() - fetchStartedAt
|
|
3340
3340
|
});
|
|
3341
3341
|
}
|
|
3342
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
3343
|
-
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3342
|
+
console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
|
|
3344
3343
|
parsed = parseVastXml(vastXml);
|
|
3345
3344
|
if (parsed.type === "empty") {
|
|
3346
3345
|
;
|
|
@@ -3381,16 +3380,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3381
3380
|
});
|
|
3382
3381
|
}).apply(this, arguments);
|
|
3383
3382
|
}
|
|
3383
|
+
function isEdgeEmptySentinelAd(adElement) {
|
|
3384
|
+
var _textOf;
|
|
3385
|
+
if ((adElement.getAttribute("id") || "").trim().toLowerCase() === "empty") {
|
|
3386
|
+
return true;
|
|
3387
|
+
}
|
|
3388
|
+
var inLine = adElement.querySelector(":scope > InLine");
|
|
3389
|
+
if (!inLine) return false;
|
|
3390
|
+
if (/^no ad available$/i.test((_textOf = textOf(inLine.querySelector(":scope > AdTitle"))) !== null && _textOf !== void 0 ? _textOf : "")) {
|
|
3391
|
+
return true;
|
|
3392
|
+
}
|
|
3393
|
+
var durations = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear > Duration")).map(function(el) {
|
|
3394
|
+
return parseVastTime(textOf(el));
|
|
3395
|
+
});
|
|
3396
|
+
return durations.length > 0 && durations.every(function(seconds) {
|
|
3397
|
+
return seconds === 0;
|
|
3398
|
+
});
|
|
3399
|
+
}
|
|
3384
3400
|
function fetchAndParsePod(vastTagUrl) {
|
|
3401
|
+
var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
|
|
3385
3402
|
return _async_to_generator(function() {
|
|
3386
|
-
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;
|
|
3403
|
+
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;
|
|
3387
3404
|
return _ts_generator(this, function(_state) {
|
|
3388
3405
|
switch(_state.label){
|
|
3389
3406
|
case 0:
|
|
3390
3407
|
lastPodAdElementCount = 0;
|
|
3408
|
+
isEdge = source === "edge";
|
|
3391
3409
|
return [
|
|
3392
3410
|
4,
|
|
3393
|
-
fetchVastXml(vastTagUrl)
|
|
3411
|
+
fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
|
|
3394
3412
|
];
|
|
3395
3413
|
case 1:
|
|
3396
3414
|
vastXml = _state.sent();
|
|
@@ -3413,7 +3431,6 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3413
3431
|
}
|
|
3414
3432
|
xmlDoc = parseXml(vastXml);
|
|
3415
3433
|
if (!xmlDoc) {
|
|
3416
|
-
console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3417
3434
|
logFunnel("vast_parsed", {
|
|
3418
3435
|
adElementCount: 0,
|
|
3419
3436
|
reason: "xml_parse_error"
|
|
@@ -3485,12 +3502,24 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3485
3502
|
});
|
|
3486
3503
|
})();
|
|
3487
3504
|
};
|
|
3488
|
-
|
|
3505
|
+
candidates = adElements;
|
|
3506
|
+
if (isEdge) {
|
|
3507
|
+
candidates = adElements.filter(function(el) {
|
|
3508
|
+
return !isEdgeEmptySentinelAd(el);
|
|
3509
|
+
});
|
|
3510
|
+
if (candidates.length < adElements.length) {
|
|
3511
|
+
logFunnel("edge_empty_sentinel", {
|
|
3512
|
+
sentinelCount: adElements.length - candidates.length,
|
|
3513
|
+
adElementCount: adElements.length
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3517
|
+
podElements = candidates.filter(function(el) {
|
|
3489
3518
|
return getAdSequence(el) !== void 0;
|
|
3490
3519
|
}).sort(function(a, b) {
|
|
3491
3520
|
return getAdSequence(a) - getAdSequence(b);
|
|
3492
3521
|
});
|
|
3493
|
-
buffet =
|
|
3522
|
+
buffet = candidates.filter(function(el) {
|
|
3494
3523
|
return getAdSequence(el) === void 0;
|
|
3495
3524
|
});
|
|
3496
3525
|
resolveAll = function resolveAll(elements) {
|
|
@@ -3647,7 +3676,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3647
3676
|
lastPodAdElementCount = adElements.length;
|
|
3648
3677
|
return [
|
|
3649
3678
|
2,
|
|
3650
|
-
ads
|
|
3679
|
+
isEdge ? ads.filter(function(ad) {
|
|
3680
|
+
return ad.duration > 0;
|
|
3681
|
+
}) : ads
|
|
3651
3682
|
];
|
|
3652
3683
|
}
|
|
3653
3684
|
});
|
|
@@ -4648,13 +4679,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4648
4679
|
contentVideo[AD_CONTAINER_PROP] = adContainerEl;
|
|
4649
4680
|
attachContainerHandlers();
|
|
4650
4681
|
},
|
|
4651
|
-
requestAds: function requestAds(vastTagUrl) {
|
|
4682
|
+
requestAds: function requestAds(vastTagUrl, requestOptions) {
|
|
4652
4683
|
return _async_to_generator(function() {
|
|
4653
|
-
var ads, preloaded, error;
|
|
4684
|
+
var _ref, source, ads, preloaded, error;
|
|
4654
4685
|
return _ts_generator(this, function(_state) {
|
|
4655
4686
|
switch(_state.label){
|
|
4656
4687
|
case 0:
|
|
4657
|
-
|
|
4688
|
+
source = (_ref = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.source) !== null && _ref !== void 0 ? _ref : "gam";
|
|
4689
|
+
console.log("[HlsAdPlayer] Requesting ads (".concat(source, "):"), redactUrl(vastTagUrl));
|
|
4658
4690
|
if (adPlaying) {
|
|
4659
4691
|
console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
|
|
4660
4692
|
return [
|
|
@@ -4699,7 +4731,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4699
4731
|
case 2:
|
|
4700
4732
|
return [
|
|
4701
4733
|
4,
|
|
4702
|
-
fetchAndParsePod(vastTagUrl)
|
|
4734
|
+
fetchAndParsePod(vastTagUrl, source)
|
|
4703
4735
|
];
|
|
4704
4736
|
case 3:
|
|
4705
4737
|
ads = _state.sent();
|
|
@@ -5109,6 +5141,75 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
5109
5141
|
return podAds.reduce(function(total, ad) {
|
|
5110
5142
|
return total + (ad.duration > 0 ? ad.duration * 1e3 : 0);
|
|
5111
5143
|
}, 0);
|
|
5144
|
+
},
|
|
5145
|
+
limitPodToBudget: function limitPodToBudget(maxDurationMs, maxAds) {
|
|
5146
|
+
if (adPlaying) return podAds.length;
|
|
5147
|
+
var kept = [];
|
|
5148
|
+
var dropped = [];
|
|
5149
|
+
var totalMs = 0;
|
|
5150
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
5151
|
+
try {
|
|
5152
|
+
for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
5153
|
+
var ad = _step.value;
|
|
5154
|
+
var durationMs = Math.round(ad.duration * 1e3);
|
|
5155
|
+
if (kept.length < maxAds && totalMs + durationMs <= maxDurationMs) {
|
|
5156
|
+
kept.push(ad);
|
|
5157
|
+
totalMs += durationMs;
|
|
5158
|
+
} else {
|
|
5159
|
+
dropped.push(ad);
|
|
5160
|
+
}
|
|
5161
|
+
}
|
|
5162
|
+
} catch (err) {
|
|
5163
|
+
_didIteratorError = true;
|
|
5164
|
+
_iteratorError = err;
|
|
5165
|
+
} finally{
|
|
5166
|
+
try {
|
|
5167
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
5168
|
+
_iterator.return();
|
|
5169
|
+
}
|
|
5170
|
+
} finally{
|
|
5171
|
+
if (_didIteratorError) {
|
|
5172
|
+
throw _iteratorError;
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5176
|
+
if (dropped.length > 0) {
|
|
5177
|
+
logFunnel("pod_trimmed_to_budget", {
|
|
5178
|
+
keptCount: kept.length,
|
|
5179
|
+
droppedCount: dropped.length,
|
|
5180
|
+
keptDurationMs: totalMs,
|
|
5181
|
+
maxDurationMs: maxDurationMs,
|
|
5182
|
+
maxAds: maxAds
|
|
5183
|
+
});
|
|
5184
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
5185
|
+
try {
|
|
5186
|
+
for(var _iterator1 = dropped[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
5187
|
+
var ad1 = _step1.value;
|
|
5188
|
+
resolvedAds.add(ad1);
|
|
5189
|
+
fireTrackingPixels(ad1.trackingUrls.notUsed, {
|
|
5190
|
+
ad: ad1
|
|
5191
|
+
});
|
|
5192
|
+
}
|
|
5193
|
+
} catch (err) {
|
|
5194
|
+
_didIteratorError1 = true;
|
|
5195
|
+
_iteratorError1 = err;
|
|
5196
|
+
} finally{
|
|
5197
|
+
try {
|
|
5198
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
5199
|
+
_iterator1.return();
|
|
5200
|
+
}
|
|
5201
|
+
} finally{
|
|
5202
|
+
if (_didIteratorError1) {
|
|
5203
|
+
throw _iteratorError1;
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
podAds = kept;
|
|
5209
|
+
podIndex = 0;
|
|
5210
|
+
currentAd = kept[0];
|
|
5211
|
+
currentAdMediaFile = void 0;
|
|
5212
|
+
return kept.length;
|
|
5112
5213
|
}
|
|
5113
5214
|
};
|
|
5114
5215
|
}
|
|
@@ -9107,6 +9208,59 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
9107
9208
|
]);
|
|
9108
9209
|
return HlsEngine;
|
|
9109
9210
|
}();
|
|
9211
|
+
// src/player/EdgePodRequest.ts
|
|
9212
|
+
var EDGE_POD_MAX_ADS = 10;
|
|
9213
|
+
var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
|
|
9214
|
+
function resolveEdgePodBaseUrl(config) {
|
|
9215
|
+
var _config_edgePodUrl;
|
|
9216
|
+
if (config.enableEdgePodRequest !== true) return void 0;
|
|
9217
|
+
var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
|
|
9218
|
+
if (!raw) {
|
|
9219
|
+
console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
|
|
9220
|
+
return void 0;
|
|
9221
|
+
}
|
|
9222
|
+
try {
|
|
9223
|
+
var url = new URL(raw);
|
|
9224
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
9225
|
+
throw new Error("unsupported protocol ".concat(url.protocol));
|
|
9226
|
+
}
|
|
9227
|
+
return url.toString();
|
|
9228
|
+
} catch (unused) {
|
|
9229
|
+
console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
|
|
9230
|
+
return void 0;
|
|
9231
|
+
}
|
|
9232
|
+
}
|
|
9233
|
+
function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
|
|
9234
|
+
var url = new URL(baseUrl);
|
|
9235
|
+
var maxMs = Math.max(0, Math.floor(remainingMs));
|
|
9236
|
+
var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
|
|
9237
|
+
url.searchParams.set("pmxd", String(maxMs));
|
|
9238
|
+
url.searchParams.set("pmad", String(maxAds));
|
|
9239
|
+
url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
|
|
9240
|
+
url.searchParams.set("count", String(maxAds));
|
|
9241
|
+
return url.toString();
|
|
9242
|
+
}
|
|
9243
|
+
function classifyEdgeVastResponse(result) {
|
|
9244
|
+
var _ref;
|
|
9245
|
+
var _result_error;
|
|
9246
|
+
if (result.error == null) {
|
|
9247
|
+
return result.podAdCount > 0 ? "fill" : "no_fill";
|
|
9248
|
+
}
|
|
9249
|
+
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);
|
|
9250
|
+
if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
|
|
9251
|
+
return "no_fill";
|
|
9252
|
+
}
|
|
9253
|
+
return "invalid";
|
|
9254
|
+
}
|
|
9255
|
+
function describeEdgeUrl(url) {
|
|
9256
|
+
try {
|
|
9257
|
+
var parsed = new URL(url);
|
|
9258
|
+
return "".concat(parsed.origin).concat(parsed.pathname);
|
|
9259
|
+
} catch (unused) {
|
|
9260
|
+
var _url_split_;
|
|
9261
|
+
return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
|
|
9262
|
+
}
|
|
9263
|
+
}
|
|
9110
9264
|
// src/player/PlayerControls.ts
|
|
9111
9265
|
function getAdAudioVolume(adPlayer) {
|
|
9112
9266
|
return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
|
|
@@ -9265,6 +9419,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9265
9419
|
this.controllerCallInFlight = false;
|
|
9266
9420
|
this.playbackStartedForCurrentRequest = false;
|
|
9267
9421
|
this.opportunityEpoch = -1;
|
|
9422
|
+
this.edgeExhaustedForBreak = false;
|
|
9423
|
+
this.edgeRequestsInBreak = 0;
|
|
9268
9424
|
this.adPodQueue = [];
|
|
9269
9425
|
this.defaultMinRemainingMsToRequestAd = 1e4;
|
|
9270
9426
|
this.defaultMaxNoFillsPerBreak = 2;
|
|
@@ -9415,7 +9571,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9415
9571
|
_this.timing.clearAdRequestWatchdog();
|
|
9416
9572
|
_this.timing.activeAdRequestToken = null;
|
|
9417
9573
|
_this.showAds = true;
|
|
9418
|
-
_this.
|
|
9574
|
+
if (_this.currentPodSource !== "edge") {
|
|
9575
|
+
_this.timing.resetGamNoFillCounter();
|
|
9576
|
+
}
|
|
9419
9577
|
if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
|
|
9420
9578
|
_this.timing.scheduleAdStopAtBreakBoundary();
|
|
9421
9579
|
if (_this.debug) {
|
|
@@ -9547,6 +9705,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9547
9705
|
key: "beginVmapBreak",
|
|
9548
9706
|
value: function beginVmapBreak(breakKey, position) {
|
|
9549
9707
|
this.breakSource = "vmap";
|
|
9708
|
+
this.resetEdgeStateForBreak();
|
|
9550
9709
|
this.followUpBaseVastUrl = void 0;
|
|
9551
9710
|
this.unusableResponsesInBreak = 0;
|
|
9552
9711
|
this.timing.totalAdRequestsInBreak = 0;
|
|
@@ -9558,7 +9717,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9558
9717
|
key: "handleAdStart",
|
|
9559
9718
|
value: function handleAdStart(marker) {
|
|
9560
9719
|
return _async_to_generator(function() {
|
|
9561
|
-
var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
|
|
9720
|
+
var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
|
|
9562
9721
|
return _ts_generator(this, function(_state) {
|
|
9563
9722
|
switch(_state.label){
|
|
9564
9723
|
case 0:
|
|
@@ -9572,7 +9731,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9572
9731
|
];
|
|
9573
9732
|
}
|
|
9574
9733
|
baseVastUrl = this.adConfig.apiVastTagUrl;
|
|
9575
|
-
|
|
9734
|
+
edgeConfigured = !!this.host.getEdgePodBaseUrl();
|
|
9735
|
+
if (!baseVastUrl && !edgeConfigured) {
|
|
9576
9736
|
console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
|
|
9577
9737
|
this.clearPendingAdBreak();
|
|
9578
9738
|
return [
|
|
@@ -9588,6 +9748,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9588
9748
|
this.breakSource = "scte35";
|
|
9589
9749
|
this.followUpBaseVastUrl = baseVastUrl;
|
|
9590
9750
|
this.unusableResponsesInBreak = 0;
|
|
9751
|
+
this.resetEdgeStateForBreak();
|
|
9591
9752
|
this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
|
|
9592
9753
|
if (this.adConfig.podAssignedByPrefetch) {
|
|
9593
9754
|
this.adConfig.podAssignedByPrefetch = false;
|
|
@@ -9609,7 +9770,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9609
9770
|
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
|
|
9610
9771
|
epoch = this.timing.adBreakEpoch;
|
|
9611
9772
|
hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
|
|
9612
|
-
if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
|
|
9773
|
+
if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
|
|
9613
9774
|
3,
|
|
9614
9775
|
2
|
|
9615
9776
|
];
|
|
@@ -9628,11 +9789,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9628
9789
|
mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
|
|
9629
9790
|
console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
|
|
9630
9791
|
}
|
|
9792
|
+
if (!edgeConfigured) return [
|
|
9793
|
+
3,
|
|
9794
|
+
5
|
|
9795
|
+
];
|
|
9796
|
+
edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
|
|
9797
|
+
if (!edgeUrl) return [
|
|
9798
|
+
3,
|
|
9799
|
+
4
|
|
9800
|
+
];
|
|
9801
|
+
this.clearPendingAdBreak();
|
|
9631
9802
|
return [
|
|
9632
9803
|
4,
|
|
9633
|
-
this.
|
|
9804
|
+
this.runEdgePod(edgeUrl, "edge_break_start")
|
|
9634
9805
|
];
|
|
9635
9806
|
case 3:
|
|
9807
|
+
outcome = _state.sent();
|
|
9808
|
+
this.continueAfterEdgeOutcome(outcome, epoch);
|
|
9809
|
+
return [
|
|
9810
|
+
2
|
|
9811
|
+
];
|
|
9812
|
+
case 4:
|
|
9813
|
+
if (!this.edgeExhaustedForBreak) {
|
|
9814
|
+
this.markEdgeExhausted("not_eligible_at_break_start", {
|
|
9815
|
+
isLive: this.isLiveBreak(),
|
|
9816
|
+
durationMs: this.timing.expectedAdBreakDurationMs
|
|
9817
|
+
});
|
|
9818
|
+
}
|
|
9819
|
+
_state.label = 5;
|
|
9820
|
+
case 5:
|
|
9821
|
+
if (!baseVastUrl) {
|
|
9822
|
+
this.requestNextAd("no_gam_source");
|
|
9823
|
+
return [
|
|
9824
|
+
2
|
|
9825
|
+
];
|
|
9826
|
+
}
|
|
9827
|
+
return [
|
|
9828
|
+
4,
|
|
9829
|
+
this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
|
|
9830
|
+
];
|
|
9831
|
+
case 6:
|
|
9636
9832
|
podPlayed = _state.sent();
|
|
9637
9833
|
if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
|
|
9638
9834
|
this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
|
|
@@ -9724,6 +9920,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9724
9920
|
adPlayer = this.host.getAdPlayer();
|
|
9725
9921
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
9726
9922
|
this.timing.activeAdRequestToken = requestToken;
|
|
9923
|
+
this.currentPodSource = "gam";
|
|
9727
9924
|
this.setSlotState("REQUESTING", "initial_pod");
|
|
9728
9925
|
this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
|
|
9729
9926
|
requestUrl = this.applyOpportunityFloor(podUrl);
|
|
@@ -9840,6 +10037,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9840
10037
|
}).call(this);
|
|
9841
10038
|
}
|
|
9842
10039
|
},
|
|
10040
|
+
{
|
|
10041
|
+
// ───────────────────────────────────────────────────────────────
|
|
10042
|
+
// Edge-first pods (live SCTE-35 only, GAM fallback)
|
|
10043
|
+
// ───────────────────────────────────────────────────────────────
|
|
10044
|
+
key: "resetEdgeStateForBreak",
|
|
10045
|
+
value: function resetEdgeStateForBreak() {
|
|
10046
|
+
this.edgeExhaustedForBreak = false;
|
|
10047
|
+
this.edgeRequestsInBreak = 0;
|
|
10048
|
+
this.currentPodSource = void 0;
|
|
10049
|
+
}
|
|
10050
|
+
},
|
|
10051
|
+
{
|
|
10052
|
+
key: "isLiveBreak",
|
|
10053
|
+
value: function isLiveBreak() {
|
|
10054
|
+
return this.host.isLiveStream() || this.host.config.isLiveStream === true;
|
|
10055
|
+
}
|
|
10056
|
+
},
|
|
10057
|
+
{
|
|
10058
|
+
key: "canRequestEdge",
|
|
10059
|
+
value: function canRequestEdge() {
|
|
10060
|
+
return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
|
|
10061
|
+
}
|
|
10062
|
+
},
|
|
10063
|
+
{
|
|
10064
|
+
key: "markEdgeExhausted",
|
|
10065
|
+
value: function markEdgeExhausted(reason) {
|
|
10066
|
+
var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
10067
|
+
this.edgeExhaustedForBreak = true;
|
|
10068
|
+
this.countFunnelStage("edge_fallback:".concat(reason));
|
|
10069
|
+
this.logOrchestratorFunnel("edge_exhausted", _object_spread({
|
|
10070
|
+
reason: reason,
|
|
10071
|
+
edgeRequests: this.edgeRequestsInBreak,
|
|
10072
|
+
remainingMs: this.timing.getRemainingAdMs()
|
|
10073
|
+
}, extra));
|
|
10074
|
+
}
|
|
10075
|
+
},
|
|
10076
|
+
{
|
|
10077
|
+
/**
|
|
10078
|
+
* Builds the next Edge request from the budget left right now, or marks Edge
|
|
10079
|
+
* exhausted for this break. Synchronous on purpose: callers must reach the
|
|
10080
|
+
* REQUESTING state in the same tick so a second completion event cannot race
|
|
10081
|
+
* in a parallel request.
|
|
10082
|
+
*/ key: "prepareEdgePodRequest",
|
|
10083
|
+
value: function prepareEdgePodRequest() {
|
|
10084
|
+
var baseUrl = this.host.getEdgePodBaseUrl();
|
|
10085
|
+
if (!baseUrl) return void 0;
|
|
10086
|
+
var remainingMs = this.timing.getRemainingAdMs();
|
|
10087
|
+
var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
|
|
10088
|
+
if (remainingAds < 1) {
|
|
10089
|
+
this.markEdgeExhausted("ad_capacity_reached", {
|
|
10090
|
+
adsInBreak: this.timing.totalAdsInBreak
|
|
10091
|
+
});
|
|
10092
|
+
return void 0;
|
|
10093
|
+
}
|
|
10094
|
+
if (remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
10095
|
+
this.markEdgeExhausted("insufficient_break_time", {
|
|
10096
|
+
remainingMs: remainingMs
|
|
10097
|
+
});
|
|
10098
|
+
return void 0;
|
|
10099
|
+
}
|
|
10100
|
+
try {
|
|
10101
|
+
return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
|
|
10102
|
+
} catch (unused) {
|
|
10103
|
+
this.markEdgeExhausted("invalid_edge_url");
|
|
10104
|
+
return void 0;
|
|
10105
|
+
}
|
|
10106
|
+
}
|
|
10107
|
+
},
|
|
10108
|
+
{
|
|
10109
|
+
key: "runEdgePod",
|
|
10110
|
+
value: function runEdgePod(requestUrl, trigger) {
|
|
10111
|
+
return _async_to_generator(function() {
|
|
10112
|
+
var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
|
|
10113
|
+
return _ts_generator(this, function(_state) {
|
|
10114
|
+
switch(_state.label){
|
|
10115
|
+
case 0:
|
|
10116
|
+
epoch = this.timing.adBreakEpoch;
|
|
10117
|
+
this.recreateAdController("new_request");
|
|
10118
|
+
generation = this.controllerGeneration;
|
|
10119
|
+
adPlayer = this.host.getAdPlayer();
|
|
10120
|
+
requestToken = ++this.timing.adRequestTokenCounter;
|
|
10121
|
+
this.timing.activeAdRequestToken = requestToken;
|
|
10122
|
+
this.currentPodSource = "edge";
|
|
10123
|
+
this.edgeRequestsInBreak++;
|
|
10124
|
+
this.setSlotState("REQUESTING", trigger);
|
|
10125
|
+
this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
|
|
10126
|
+
this.currentVastUrl = requestUrl;
|
|
10127
|
+
params = new URL(requestUrl).searchParams;
|
|
10128
|
+
this.logOrchestratorFunnel("edge_request_sent", {
|
|
10129
|
+
trigger: trigger,
|
|
10130
|
+
attempt: this.edgeRequestsInBreak,
|
|
10131
|
+
endpoint: describeEdgeUrl(requestUrl),
|
|
10132
|
+
pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
|
|
10133
|
+
pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
|
|
10134
|
+
});
|
|
10135
|
+
_state.label = 1;
|
|
10136
|
+
case 1:
|
|
10137
|
+
_state.trys.push([
|
|
10138
|
+
1,
|
|
10139
|
+
4,
|
|
10140
|
+
,
|
|
10141
|
+
5
|
|
10142
|
+
]);
|
|
10143
|
+
this.timing.startAdRequestWatchdog(requestToken);
|
|
10144
|
+
return [
|
|
10145
|
+
4,
|
|
10146
|
+
this.callController(function() {
|
|
10147
|
+
return adPlayer.requestAds(requestUrl, {
|
|
10148
|
+
source: "edge"
|
|
10149
|
+
});
|
|
10150
|
+
})
|
|
10151
|
+
];
|
|
10152
|
+
case 2:
|
|
10153
|
+
_state.sent();
|
|
10154
|
+
this.timing.clearAdRequestWatchdog();
|
|
10155
|
+
if (this.isStale(epoch, generation)) {
|
|
10156
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10157
|
+
requestId: requestToken,
|
|
10158
|
+
source: "edge"
|
|
10159
|
+
});
|
|
10160
|
+
return [
|
|
10161
|
+
2,
|
|
10162
|
+
"stale"
|
|
10163
|
+
];
|
|
10164
|
+
}
|
|
10165
|
+
remainingMs = this.timing.getRemainingAdMs();
|
|
10166
|
+
remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
|
|
10167
|
+
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;
|
|
10168
|
+
if (classifyEdgeVastResponse({
|
|
10169
|
+
podAdCount: podCount
|
|
10170
|
+
}) !== "fill") {
|
|
10171
|
+
throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
|
|
10172
|
+
}
|
|
10173
|
+
this.setSlotState("READY", "edge_vast_ready");
|
|
10174
|
+
this.logOrchestratorFunnel("edge_fill", {
|
|
10175
|
+
podAdCount: podCount,
|
|
10176
|
+
podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
|
|
10177
|
+
remainingMs: remainingMs
|
|
10178
|
+
});
|
|
10179
|
+
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
10180
|
+
source: "hls",
|
|
10181
|
+
vastUrl: requestUrl,
|
|
10182
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10183
|
+
}, this.analyticsContext).catch(function() {});
|
|
10184
|
+
this.timing.startAdFailsafeTimer(requestToken);
|
|
10185
|
+
return [
|
|
10186
|
+
4,
|
|
10187
|
+
this.callController(function() {
|
|
10188
|
+
return adPlayer.play();
|
|
10189
|
+
})
|
|
10190
|
+
];
|
|
10191
|
+
case 3:
|
|
10192
|
+
_state.sent();
|
|
10193
|
+
if (this.isStale(epoch, generation)) return [
|
|
10194
|
+
2,
|
|
10195
|
+
"stale"
|
|
10196
|
+
];
|
|
10197
|
+
if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
|
|
10198
|
+
this.timing.scheduleAdStopAtBreakBoundary();
|
|
10199
|
+
}
|
|
10200
|
+
adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
|
|
10201
|
+
return [
|
|
10202
|
+
2,
|
|
10203
|
+
"fill"
|
|
10204
|
+
];
|
|
10205
|
+
case 4:
|
|
10206
|
+
error = _state.sent();
|
|
10207
|
+
this.timing.clearAdRequestWatchdog();
|
|
10208
|
+
this.timing.clearAdFailsafeTimer();
|
|
10209
|
+
if (this.timing.activeAdRequestToken === requestToken) {
|
|
10210
|
+
this.timing.activeAdRequestToken = null;
|
|
10211
|
+
}
|
|
10212
|
+
errorMessage = error === null || error === void 0 ? void 0 : error.message;
|
|
10213
|
+
if (this.isStale(epoch, generation)) {
|
|
10214
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10215
|
+
requestId: requestToken,
|
|
10216
|
+
source: "edge",
|
|
10217
|
+
errorMessage: errorMessage
|
|
10218
|
+
});
|
|
10219
|
+
return [
|
|
10220
|
+
2,
|
|
10221
|
+
"stale"
|
|
10222
|
+
];
|
|
10223
|
+
}
|
|
10224
|
+
classification = classifyEdgeVastResponse({
|
|
10225
|
+
podAdCount: 0,
|
|
10226
|
+
error: error
|
|
10227
|
+
});
|
|
10228
|
+
diag = this.requestDiagnostics.get(requestToken);
|
|
10229
|
+
if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
|
|
10230
|
+
this.markEdgeExhausted("edge_".concat(classification), {
|
|
10231
|
+
errorMessage: errorMessage
|
|
10232
|
+
});
|
|
10233
|
+
return [
|
|
10234
|
+
2,
|
|
10235
|
+
"fallback"
|
|
10236
|
+
];
|
|
10237
|
+
case 5:
|
|
10238
|
+
return [
|
|
10239
|
+
2
|
|
10240
|
+
];
|
|
10241
|
+
}
|
|
10242
|
+
});
|
|
10243
|
+
}).call(this);
|
|
10244
|
+
}
|
|
10245
|
+
},
|
|
10246
|
+
{
|
|
10247
|
+
key: "continueAfterEdgeOutcome",
|
|
10248
|
+
value: function continueAfterEdgeOutcome(outcome, epoch) {
|
|
10249
|
+
if (outcome !== "fallback") return;
|
|
10250
|
+
if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
|
|
10251
|
+
if (this.debug) {
|
|
10252
|
+
console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
|
|
10253
|
+
}
|
|
10254
|
+
this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
|
|
10255
|
+
this.requestNextAd("edge_fallback");
|
|
10256
|
+
}
|
|
10257
|
+
},
|
|
9843
10258
|
{
|
|
9844
10259
|
// ───────────────────────────────────────────────────────────────
|
|
9845
10260
|
// Next-ad scheduling (single flight)
|
|
@@ -9895,7 +10310,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9895
10310
|
value: function getStopRequestingReason(remainingMs) {
|
|
9896
10311
|
if (this.breakSource === "vmap") {
|
|
9897
10312
|
if (this.adPodQueue.length === 0) return "vmap_queue_empty";
|
|
9898
|
-
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
|
|
10313
|
+
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
|
|
9899
10314
|
return "no_follow_up_source";
|
|
9900
10315
|
}
|
|
9901
10316
|
if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
|
|
@@ -9907,7 +10322,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9907
10322
|
if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
|
|
9908
10323
|
return "request_cap";
|
|
9909
10324
|
}
|
|
9910
|
-
if (this.timing.isGamInCooldown()) {
|
|
10325
|
+
if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
|
|
9911
10326
|
return "gam_cooldown";
|
|
9912
10327
|
}
|
|
9913
10328
|
if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
@@ -10001,10 +10416,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10001
10416
|
key: "requestFollowUpAd",
|
|
10002
10417
|
value: function requestFollowUpAd(trigger) {
|
|
10003
10418
|
return _async_to_generator(function() {
|
|
10004
|
-
var url, epoch, unused;
|
|
10419
|
+
var edgeUrl, epoch2, outcome, url, epoch, unused;
|
|
10005
10420
|
return _ts_generator(this, function(_state) {
|
|
10006
10421
|
switch(_state.label){
|
|
10007
10422
|
case 0:
|
|
10423
|
+
if (!this.canRequestEdge()) return [
|
|
10424
|
+
3,
|
|
10425
|
+
2
|
|
10426
|
+
];
|
|
10427
|
+
edgeUrl = this.prepareEdgePodRequest();
|
|
10428
|
+
if (!edgeUrl) {
|
|
10429
|
+
this.requestNextAd("".concat(trigger, ":edge_unavailable"));
|
|
10430
|
+
return [
|
|
10431
|
+
2
|
|
10432
|
+
];
|
|
10433
|
+
}
|
|
10434
|
+
epoch2 = this.timing.adBreakEpoch;
|
|
10435
|
+
return [
|
|
10436
|
+
4,
|
|
10437
|
+
this.runEdgePod(edgeUrl, "edge_".concat(trigger))
|
|
10438
|
+
];
|
|
10439
|
+
case 1:
|
|
10440
|
+
outcome = _state.sent();
|
|
10441
|
+
this.continueAfterEdgeOutcome(outcome, epoch2);
|
|
10442
|
+
return [
|
|
10443
|
+
2
|
|
10444
|
+
];
|
|
10445
|
+
case 2:
|
|
10008
10446
|
if (this.breakSource === "vmap") {
|
|
10009
10447
|
url = this.adPodQueue.shift();
|
|
10010
10448
|
} else if (this.followUpBaseVastUrl) {
|
|
@@ -10015,32 +10453,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10015
10453
|
];
|
|
10016
10454
|
this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
|
|
10017
10455
|
epoch = this.timing.adBreakEpoch;
|
|
10018
|
-
_state.label =
|
|
10019
|
-
case
|
|
10456
|
+
_state.label = 3;
|
|
10457
|
+
case 3:
|
|
10020
10458
|
_state.trys.push([
|
|
10021
|
-
1,
|
|
10022
10459
|
3,
|
|
10460
|
+
5,
|
|
10023
10461
|
,
|
|
10024
|
-
|
|
10462
|
+
6
|
|
10025
10463
|
]);
|
|
10026
10464
|
return [
|
|
10027
10465
|
4,
|
|
10028
10466
|
this.playSingleAd(url, trigger)
|
|
10029
10467
|
];
|
|
10030
|
-
case
|
|
10468
|
+
case 4:
|
|
10031
10469
|
_state.sent();
|
|
10032
10470
|
return [
|
|
10033
10471
|
3,
|
|
10034
|
-
|
|
10472
|
+
6
|
|
10035
10473
|
];
|
|
10036
|
-
case
|
|
10474
|
+
case 5:
|
|
10037
10475
|
unused = _state.sent();
|
|
10038
10476
|
this.continueAfterRequestFailure(epoch);
|
|
10039
10477
|
return [
|
|
10040
10478
|
3,
|
|
10041
|
-
|
|
10479
|
+
6
|
|
10042
10480
|
];
|
|
10043
|
-
case
|
|
10481
|
+
case 6:
|
|
10044
10482
|
return [
|
|
10045
10483
|
2
|
|
10046
10484
|
];
|
|
@@ -10153,7 +10591,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10153
10591
|
case "gam_http_request_sent":
|
|
10154
10592
|
diag.gamRequestSent++;
|
|
10155
10593
|
break;
|
|
10594
|
+
case "edge_http_request_sent":
|
|
10595
|
+
diag.edgeRequestSent++;
|
|
10596
|
+
break;
|
|
10156
10597
|
case "gam_response_received":
|
|
10598
|
+
case "edge_response_received":
|
|
10157
10599
|
diag.vastHttpStatus = payload.httpStatus;
|
|
10158
10600
|
break;
|
|
10159
10601
|
case "vast_parsed":
|
|
@@ -10340,6 +10782,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10340
10782
|
{
|
|
10341
10783
|
key: "beginFunnelRequest",
|
|
10342
10784
|
value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
|
|
10785
|
+
var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
|
|
10343
10786
|
var _adPlayer_setFunnelContext;
|
|
10344
10787
|
if (this.controllerCallInFlight) {
|
|
10345
10788
|
this.logOrchestratorFunnel("duplicate_request_detected", {
|
|
@@ -10354,7 +10797,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10354
10797
|
requestId: requestToken,
|
|
10355
10798
|
controllerId: this.controllerGeneration,
|
|
10356
10799
|
trigger: trigger,
|
|
10800
|
+
source: source,
|
|
10357
10801
|
gamRequestSent: 0,
|
|
10802
|
+
edgeRequestSent: 0,
|
|
10358
10803
|
wrapperDepth: 0,
|
|
10359
10804
|
inlineResolved: false,
|
|
10360
10805
|
mediaCandidateCount: 0,
|
|
@@ -10485,6 +10930,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10485
10930
|
this.timing.activeAdRequestToken = requestToken;
|
|
10486
10931
|
ap = this.host.getAdPlayer();
|
|
10487
10932
|
budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
|
|
10933
|
+
this.currentPodSource = "gam";
|
|
10488
10934
|
this.setSlotState("REQUESTING", trigger);
|
|
10489
10935
|
this.beginFunnelRequest(ap, requestToken, trigger);
|
|
10490
10936
|
requestUrl = this.applyOpportunityFloor(budgetedUrl);
|
|
@@ -10632,6 +11078,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10632
11078
|
requests: requests,
|
|
10633
11079
|
requestRetries: requestRetries,
|
|
10634
11080
|
gamResponses: count("gam_response_received"),
|
|
11081
|
+
edgeRequests: count("edge_request_sent"),
|
|
11082
|
+
edgeFills: count("edge_fill"),
|
|
11083
|
+
edgeEmptySentinels: count("edge_empty_sentinel"),
|
|
11084
|
+
edgeFallbacks: countPrefix("edge_fallback:"),
|
|
10635
11085
|
requestsSuppressed: count("request_suppressed"),
|
|
10636
11086
|
duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
|
|
10637
11087
|
filled: count("vast_received"),
|
|
@@ -10728,6 +11178,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10728
11178
|
this.breakSource = void 0;
|
|
10729
11179
|
this.followUpBaseVastUrl = void 0;
|
|
10730
11180
|
this.unusableResponsesInBreak = 0;
|
|
11181
|
+
this.resetEdgeStateForBreak();
|
|
10731
11182
|
adPlayer.stop().catch(function() {});
|
|
10732
11183
|
if (!alreadyEnded) this.logBreakFunnel(reason);
|
|
10733
11184
|
this.opportunityFloor = void 0;
|
|
@@ -11041,7 +11492,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
11041
11492
|
});
|
|
11042
11493
|
return;
|
|
11043
11494
|
}
|
|
11044
|
-
this.
|
|
11495
|
+
if (this.currentPodSource === "edge") {
|
|
11496
|
+
this.markEdgeExhausted("edge_playback_failed", {
|
|
11497
|
+
reason: reason
|
|
11498
|
+
});
|
|
11499
|
+
} else {
|
|
11500
|
+
this.timing.consecutiveFailures++;
|
|
11501
|
+
}
|
|
11045
11502
|
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
11046
11503
|
if (diag && !diag.failureReason) diag.failureReason = reason;
|
|
11047
11504
|
if (this.debug) {
|
|
@@ -11071,7 +11528,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11071
11528
|
if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
|
|
11072
11529
|
if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
|
|
11073
11530
|
this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
|
|
11531
|
+
this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
|
|
11074
11532
|
this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11533
|
+
this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
|
|
11075
11534
|
this.adPlayer = this.createAdPlayer(false);
|
|
11076
11535
|
this.palNonce = createPalNonceManager();
|
|
11077
11536
|
this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
|
|
@@ -11171,11 +11630,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11171
11630
|
generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
|
|
11172
11631
|
return _this.generatePodVastUrl(base, breakDurationMs);
|
|
11173
11632
|
},
|
|
11633
|
+
getEdgePodBaseUrl: function getEdgePodBaseUrl() {
|
|
11634
|
+
return _this.edgePodBaseUrl;
|
|
11635
|
+
},
|
|
11174
11636
|
getFloorSnapshot: function getFloorSnapshot(position) {
|
|
11175
|
-
return _this.floorLadder.snapshotFor({
|
|
11637
|
+
return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
|
|
11176
11638
|
position: position,
|
|
11177
11639
|
isCtv: _this.isCtvEnvironment()
|
|
11178
|
-
});
|
|
11640
|
+
}) : void 0;
|
|
11179
11641
|
},
|
|
11180
11642
|
onAdClick: function onAdClick() {
|
|
11181
11643
|
return _this.palNonce.sendAdClick();
|
|
@@ -11226,11 +11688,24 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11226
11688
|
return report;
|
|
11227
11689
|
}
|
|
11228
11690
|
},
|
|
11691
|
+
{
|
|
11692
|
+
key: "setAdFloorLadderEnabled",
|
|
11693
|
+
value: function setAdFloorLadderEnabled(enabled) {
|
|
11694
|
+
this.floorLadderEnabled = enabled;
|
|
11695
|
+
if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11696
|
+
}
|
|
11697
|
+
},
|
|
11698
|
+
{
|
|
11699
|
+
key: "isAdFloorLadderEnabled",
|
|
11700
|
+
value: function isAdFloorLadderEnabled() {
|
|
11701
|
+
return this.floorLadderEnabled;
|
|
11702
|
+
}
|
|
11703
|
+
},
|
|
11229
11704
|
{
|
|
11230
11705
|
key: "warnOnInvalidFloorLadder",
|
|
11231
11706
|
value: function warnOnInvalidFloorLadder(report) {
|
|
11232
11707
|
var config = this.floorLadder.get();
|
|
11233
|
-
if (report.ok || !config.enabled) return;
|
|
11708
|
+
if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
|
|
11234
11709
|
console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
|
|
11235
11710
|
errors: report.errors,
|
|
11236
11711
|
configurationVersion: config.configurationVersion,
|
|
@@ -11963,6 +12438,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11963
12438
|
this.timing.destroy();
|
|
11964
12439
|
this.adBreak.clearPendingAdBreak();
|
|
11965
12440
|
this.placeholder.destroy();
|
|
12441
|
+
0;
|
|
11966
12442
|
if (this.timeUpdateHandler) {
|
|
11967
12443
|
this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
|
|
11968
12444
|
delete this.timeUpdateHandler;
|
|
@@ -12063,12 +12539,14 @@ var CRITICAL_PROPS = [
|
|
|
12063
12539
|
"ctvAdRequest",
|
|
12064
12540
|
"adFloorMinCents",
|
|
12065
12541
|
"adFloorMaxCents",
|
|
12066
|
-
"adFloorStepCents"
|
|
12542
|
+
"adFloorStepCents",
|
|
12543
|
+
"enableEdgePodRequest",
|
|
12544
|
+
"edgePodUrl"
|
|
12067
12545
|
];
|
|
12068
12546
|
var CONTROLS_HIDE_DELAY = 3e3;
|
|
12069
12547
|
var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
|
|
12070
12548
|
var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
12071
|
-
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, [
|
|
12549
|
+
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, [
|
|
12072
12550
|
"src",
|
|
12073
12551
|
"autoplay",
|
|
12074
12552
|
"muted",
|
|
@@ -12105,10 +12583,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12105
12583
|
"minRemainingMsToStartAd",
|
|
12106
12584
|
"minRemainingMsToRequestAd",
|
|
12107
12585
|
"maxNoFillsPerBreak",
|
|
12586
|
+
"adFloorLadderEnabled",
|
|
12108
12587
|
"adFloorLadder",
|
|
12109
12588
|
"adFloorMinCents",
|
|
12110
12589
|
"adFloorMaxCents",
|
|
12111
|
-
"adFloorStepCents"
|
|
12590
|
+
"adFloorStepCents",
|
|
12591
|
+
"enableEdgePodRequest",
|
|
12592
|
+
"edgePodUrl"
|
|
12112
12593
|
]);
|
|
12113
12594
|
var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
|
|
12114
12595
|
var videoRef = (0, import_react.useRef)(null);
|
|
@@ -12259,7 +12740,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12259
12740
|
vastMode,
|
|
12260
12741
|
adFloorMinCents,
|
|
12261
12742
|
adFloorMaxCents,
|
|
12262
|
-
adFloorStepCents
|
|
12743
|
+
adFloorStepCents,
|
|
12744
|
+
enableEdgePodRequest,
|
|
12745
|
+
edgePodUrl
|
|
12263
12746
|
]);
|
|
12264
12747
|
(0, import_react.useEffect)(function() {
|
|
12265
12748
|
if (typeof window === "undefined") return;
|
|
@@ -12309,10 +12792,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12309
12792
|
if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
|
|
12310
12793
|
if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
|
|
12311
12794
|
if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
|
|
12795
|
+
if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
|
|
12312
12796
|
if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
|
|
12313
12797
|
if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
|
|
12314
12798
|
if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
|
|
12315
12799
|
if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
|
|
12800
|
+
if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
|
|
12801
|
+
if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
|
|
12316
12802
|
var player = new StormcloudVideoPlayer(cfg);
|
|
12317
12803
|
playerRef.current = player;
|
|
12318
12804
|
appliedFloorLadderKeyRef.current = adFloorLadderKey;
|
|
@@ -12361,6 +12847,14 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12361
12847
|
}, [
|
|
12362
12848
|
adFloorLadderKey
|
|
12363
12849
|
]);
|
|
12850
|
+
(0, import_react.useEffect)(function() {
|
|
12851
|
+
if (!playerRef.current) return;
|
|
12852
|
+
var enabled = adFloorLadderEnabled === true;
|
|
12853
|
+
if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
|
|
12854
|
+
playerRef.current.setAdFloorLadderEnabled(enabled);
|
|
12855
|
+
}, [
|
|
12856
|
+
adFloorLadderEnabled
|
|
12857
|
+
]);
|
|
12364
12858
|
(0, import_react.useEffect)(function() {
|
|
12365
12859
|
if (!playerRef.current) return;
|
|
12366
12860
|
var checkAdStatus = function checkAdStatus() {
|
|
@@ -13437,6 +13931,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
13437
13931
|
}
|
|
13438
13932
|
}
|
|
13439
13933
|
}
|
|
13934
|
+
if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled) {
|
|
13935
|
+
return false;
|
|
13936
|
+
}
|
|
13440
13937
|
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)) {
|
|
13441
13938
|
return false;
|
|
13442
13939
|
}
|