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.cjs
CHANGED
|
@@ -2700,7 +2700,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2700
2700
|
img.onload = null;
|
|
2701
2701
|
img.onerror = null;
|
|
2702
2702
|
inFlightBeacons.delete(img);
|
|
2703
|
-
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(
|
|
2703
|
+
console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingHost));
|
|
2704
2704
|
if (outcome !== "load") {
|
|
2705
2705
|
logFunnel("tracking_request_settled", {
|
|
2706
2706
|
reason: outcome,
|
|
@@ -2718,7 +2718,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
2718
2718
|
return release("timeout");
|
|
2719
2719
|
}, BEACON_TIMEOUT_MS);
|
|
2720
2720
|
img.src = trackingUrl;
|
|
2721
|
-
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(
|
|
2721
|
+
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingHost));
|
|
2722
2722
|
logFunnel("tracking_request_created", {
|
|
2723
2723
|
trackingHost: trackingHost,
|
|
2724
2724
|
errorCode: options2 === null || options2 === void 0 ? void 0 : options2.errorCode
|
|
@@ -3172,7 +3172,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3172
3172
|
});
|
|
3173
3173
|
}
|
|
3174
3174
|
if (parsed.type === "wrapper") {
|
|
3175
|
-
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
|
|
3175
|
+
console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(redactUrl(parsed.vastAdTagUri)));
|
|
3176
3176
|
}
|
|
3177
3177
|
return parsed;
|
|
3178
3178
|
}
|
|
@@ -3364,8 +3364,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3364
3364
|
switch(_state.label){
|
|
3365
3365
|
case 0:
|
|
3366
3366
|
attempt++;
|
|
3367
|
-
if (kind
|
|
3368
|
-
logFunnel("
|
|
3367
|
+
if (kind !== "wrapper") {
|
|
3368
|
+
logFunnel("".concat(kind, "_http_request_sent"), {
|
|
3369
3369
|
attempt: attempt,
|
|
3370
3370
|
credentials: creds
|
|
3371
3371
|
});
|
|
@@ -3385,8 +3385,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3385
3385
|
];
|
|
3386
3386
|
case 1:
|
|
3387
3387
|
response = _state.sent();
|
|
3388
|
-
if (kind
|
|
3389
|
-
logFunnel("
|
|
3388
|
+
if (kind !== "wrapper") {
|
|
3389
|
+
logFunnel("".concat(kind, "_response_received"), {
|
|
3390
3390
|
attempt: attempt,
|
|
3391
3391
|
httpStatus: response.status,
|
|
3392
3392
|
ok: response.ok,
|
|
@@ -3556,8 +3556,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3556
3556
|
elapsedMs: Date.now() - fetchStartedAt
|
|
3557
3557
|
});
|
|
3558
3558
|
}
|
|
3559
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
3560
|
-
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3559
|
+
console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
|
|
3561
3560
|
parsed = parseVastXml(vastXml);
|
|
3562
3561
|
if (parsed.type === "empty") {
|
|
3563
3562
|
;
|
|
@@ -3598,16 +3597,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3598
3597
|
});
|
|
3599
3598
|
}).apply(this, arguments);
|
|
3600
3599
|
}
|
|
3600
|
+
function isEdgeEmptySentinelAd(adElement) {
|
|
3601
|
+
var _textOf;
|
|
3602
|
+
if ((adElement.getAttribute("id") || "").trim().toLowerCase() === "empty") {
|
|
3603
|
+
return true;
|
|
3604
|
+
}
|
|
3605
|
+
var inLine = adElement.querySelector(":scope > InLine");
|
|
3606
|
+
if (!inLine) return false;
|
|
3607
|
+
if (/^no ad available$/i.test((_textOf = textOf(inLine.querySelector(":scope > AdTitle"))) !== null && _textOf !== void 0 ? _textOf : "")) {
|
|
3608
|
+
return true;
|
|
3609
|
+
}
|
|
3610
|
+
var durations = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear > Duration")).map(function(el) {
|
|
3611
|
+
return parseVastTime(textOf(el));
|
|
3612
|
+
});
|
|
3613
|
+
return durations.length > 0 && durations.every(function(seconds) {
|
|
3614
|
+
return seconds === 0;
|
|
3615
|
+
});
|
|
3616
|
+
}
|
|
3601
3617
|
function fetchAndParsePod(vastTagUrl) {
|
|
3618
|
+
var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
|
|
3602
3619
|
return _async_to_generator(function() {
|
|
3603
|
-
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;
|
|
3620
|
+
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;
|
|
3604
3621
|
return _ts_generator(this, function(_state) {
|
|
3605
3622
|
switch(_state.label){
|
|
3606
3623
|
case 0:
|
|
3607
3624
|
lastPodAdElementCount = 0;
|
|
3625
|
+
isEdge = source === "edge";
|
|
3608
3626
|
return [
|
|
3609
3627
|
4,
|
|
3610
|
-
fetchVastXml(vastTagUrl)
|
|
3628
|
+
fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
|
|
3611
3629
|
];
|
|
3612
3630
|
case 1:
|
|
3613
3631
|
vastXml = _state.sent();
|
|
@@ -3630,7 +3648,6 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3630
3648
|
}
|
|
3631
3649
|
xmlDoc = parseXml(vastXml);
|
|
3632
3650
|
if (!xmlDoc) {
|
|
3633
|
-
console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
3634
3651
|
logFunnel("vast_parsed", {
|
|
3635
3652
|
adElementCount: 0,
|
|
3636
3653
|
reason: "xml_parse_error"
|
|
@@ -3702,12 +3719,24 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3702
3719
|
});
|
|
3703
3720
|
})();
|
|
3704
3721
|
};
|
|
3705
|
-
|
|
3722
|
+
candidates = adElements;
|
|
3723
|
+
if (isEdge) {
|
|
3724
|
+
candidates = adElements.filter(function(el) {
|
|
3725
|
+
return !isEdgeEmptySentinelAd(el);
|
|
3726
|
+
});
|
|
3727
|
+
if (candidates.length < adElements.length) {
|
|
3728
|
+
logFunnel("edge_empty_sentinel", {
|
|
3729
|
+
sentinelCount: adElements.length - candidates.length,
|
|
3730
|
+
adElementCount: adElements.length
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
podElements = candidates.filter(function(el) {
|
|
3706
3735
|
return getAdSequence(el) !== void 0;
|
|
3707
3736
|
}).sort(function(a, b) {
|
|
3708
3737
|
return getAdSequence(a) - getAdSequence(b);
|
|
3709
3738
|
});
|
|
3710
|
-
buffet =
|
|
3739
|
+
buffet = candidates.filter(function(el) {
|
|
3711
3740
|
return getAdSequence(el) === void 0;
|
|
3712
3741
|
});
|
|
3713
3742
|
resolveAll = function resolveAll(elements) {
|
|
@@ -3864,7 +3893,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
3864
3893
|
lastPodAdElementCount = adElements.length;
|
|
3865
3894
|
return [
|
|
3866
3895
|
2,
|
|
3867
|
-
ads
|
|
3896
|
+
isEdge ? ads.filter(function(ad) {
|
|
3897
|
+
return ad.duration > 0;
|
|
3898
|
+
}) : ads
|
|
3868
3899
|
];
|
|
3869
3900
|
}
|
|
3870
3901
|
});
|
|
@@ -4865,13 +4896,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4865
4896
|
contentVideo[AD_CONTAINER_PROP] = adContainerEl;
|
|
4866
4897
|
attachContainerHandlers();
|
|
4867
4898
|
},
|
|
4868
|
-
requestAds: function requestAds(vastTagUrl) {
|
|
4899
|
+
requestAds: function requestAds(vastTagUrl, requestOptions) {
|
|
4869
4900
|
return _async_to_generator(function() {
|
|
4870
|
-
var ads, preloaded, error;
|
|
4901
|
+
var _ref, source, ads, preloaded, error;
|
|
4871
4902
|
return _ts_generator(this, function(_state) {
|
|
4872
4903
|
switch(_state.label){
|
|
4873
4904
|
case 0:
|
|
4874
|
-
|
|
4905
|
+
source = (_ref = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.source) !== null && _ref !== void 0 ? _ref : "gam";
|
|
4906
|
+
console.log("[HlsAdPlayer] Requesting ads (".concat(source, "):"), redactUrl(vastTagUrl));
|
|
4875
4907
|
if (adPlaying) {
|
|
4876
4908
|
console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
|
|
4877
4909
|
return [
|
|
@@ -4916,7 +4948,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
4916
4948
|
case 2:
|
|
4917
4949
|
return [
|
|
4918
4950
|
4,
|
|
4919
|
-
fetchAndParsePod(vastTagUrl)
|
|
4951
|
+
fetchAndParsePod(vastTagUrl, source)
|
|
4920
4952
|
];
|
|
4921
4953
|
case 3:
|
|
4922
4954
|
ads = _state.sent();
|
|
@@ -5326,6 +5358,75 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
5326
5358
|
return podAds.reduce(function(total, ad) {
|
|
5327
5359
|
return total + (ad.duration > 0 ? ad.duration * 1e3 : 0);
|
|
5328
5360
|
}, 0);
|
|
5361
|
+
},
|
|
5362
|
+
limitPodToBudget: function limitPodToBudget(maxDurationMs, maxAds) {
|
|
5363
|
+
if (adPlaying) return podAds.length;
|
|
5364
|
+
var kept = [];
|
|
5365
|
+
var dropped = [];
|
|
5366
|
+
var totalMs = 0;
|
|
5367
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
5368
|
+
try {
|
|
5369
|
+
for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
5370
|
+
var ad = _step.value;
|
|
5371
|
+
var durationMs = Math.round(ad.duration * 1e3);
|
|
5372
|
+
if (kept.length < maxAds && totalMs + durationMs <= maxDurationMs) {
|
|
5373
|
+
kept.push(ad);
|
|
5374
|
+
totalMs += durationMs;
|
|
5375
|
+
} else {
|
|
5376
|
+
dropped.push(ad);
|
|
5377
|
+
}
|
|
5378
|
+
}
|
|
5379
|
+
} catch (err) {
|
|
5380
|
+
_didIteratorError = true;
|
|
5381
|
+
_iteratorError = err;
|
|
5382
|
+
} finally{
|
|
5383
|
+
try {
|
|
5384
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
5385
|
+
_iterator.return();
|
|
5386
|
+
}
|
|
5387
|
+
} finally{
|
|
5388
|
+
if (_didIteratorError) {
|
|
5389
|
+
throw _iteratorError;
|
|
5390
|
+
}
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
if (dropped.length > 0) {
|
|
5394
|
+
logFunnel("pod_trimmed_to_budget", {
|
|
5395
|
+
keptCount: kept.length,
|
|
5396
|
+
droppedCount: dropped.length,
|
|
5397
|
+
keptDurationMs: totalMs,
|
|
5398
|
+
maxDurationMs: maxDurationMs,
|
|
5399
|
+
maxAds: maxAds
|
|
5400
|
+
});
|
|
5401
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
5402
|
+
try {
|
|
5403
|
+
for(var _iterator1 = dropped[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
5404
|
+
var ad1 = _step1.value;
|
|
5405
|
+
resolvedAds.add(ad1);
|
|
5406
|
+
fireTrackingPixels(ad1.trackingUrls.notUsed, {
|
|
5407
|
+
ad: ad1
|
|
5408
|
+
});
|
|
5409
|
+
}
|
|
5410
|
+
} catch (err) {
|
|
5411
|
+
_didIteratorError1 = true;
|
|
5412
|
+
_iteratorError1 = err;
|
|
5413
|
+
} finally{
|
|
5414
|
+
try {
|
|
5415
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
5416
|
+
_iterator1.return();
|
|
5417
|
+
}
|
|
5418
|
+
} finally{
|
|
5419
|
+
if (_didIteratorError1) {
|
|
5420
|
+
throw _iteratorError1;
|
|
5421
|
+
}
|
|
5422
|
+
}
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
5425
|
+
podAds = kept;
|
|
5426
|
+
podIndex = 0;
|
|
5427
|
+
currentAd = kept[0];
|
|
5428
|
+
currentAdMediaFile = void 0;
|
|
5429
|
+
return kept.length;
|
|
5329
5430
|
}
|
|
5330
5431
|
};
|
|
5331
5432
|
}
|
|
@@ -9330,6 +9431,59 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
9330
9431
|
]);
|
|
9331
9432
|
return HlsEngine;
|
|
9332
9433
|
}();
|
|
9434
|
+
// src/player/EdgePodRequest.ts
|
|
9435
|
+
var EDGE_POD_MAX_ADS = 10;
|
|
9436
|
+
var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
|
|
9437
|
+
function resolveEdgePodBaseUrl(config) {
|
|
9438
|
+
var _config_edgePodUrl;
|
|
9439
|
+
if (config.enableEdgePodRequest !== true) return void 0;
|
|
9440
|
+
var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
|
|
9441
|
+
if (!raw) {
|
|
9442
|
+
console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
|
|
9443
|
+
return void 0;
|
|
9444
|
+
}
|
|
9445
|
+
try {
|
|
9446
|
+
var url = new URL(raw);
|
|
9447
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
9448
|
+
throw new Error("unsupported protocol ".concat(url.protocol));
|
|
9449
|
+
}
|
|
9450
|
+
return url.toString();
|
|
9451
|
+
} catch (unused) {
|
|
9452
|
+
console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
|
|
9453
|
+
return void 0;
|
|
9454
|
+
}
|
|
9455
|
+
}
|
|
9456
|
+
function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
|
|
9457
|
+
var url = new URL(baseUrl);
|
|
9458
|
+
var maxMs = Math.max(0, Math.floor(remainingMs));
|
|
9459
|
+
var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
|
|
9460
|
+
url.searchParams.set("pmxd", String(maxMs));
|
|
9461
|
+
url.searchParams.set("pmad", String(maxAds));
|
|
9462
|
+
url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
|
|
9463
|
+
url.searchParams.set("count", String(maxAds));
|
|
9464
|
+
return url.toString();
|
|
9465
|
+
}
|
|
9466
|
+
function classifyEdgeVastResponse(result) {
|
|
9467
|
+
var _ref;
|
|
9468
|
+
var _result_error;
|
|
9469
|
+
if (result.error == null) {
|
|
9470
|
+
return result.podAdCount > 0 ? "fill" : "no_fill";
|
|
9471
|
+
}
|
|
9472
|
+
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);
|
|
9473
|
+
if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
|
|
9474
|
+
return "no_fill";
|
|
9475
|
+
}
|
|
9476
|
+
return "invalid";
|
|
9477
|
+
}
|
|
9478
|
+
function describeEdgeUrl(url) {
|
|
9479
|
+
try {
|
|
9480
|
+
var parsed = new URL(url);
|
|
9481
|
+
return "".concat(parsed.origin).concat(parsed.pathname);
|
|
9482
|
+
} catch (unused) {
|
|
9483
|
+
var _url_split_;
|
|
9484
|
+
return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
|
|
9485
|
+
}
|
|
9486
|
+
}
|
|
9333
9487
|
// src/player/PlayerControls.ts
|
|
9334
9488
|
function getAdAudioVolume(adPlayer) {
|
|
9335
9489
|
return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
|
|
@@ -9488,6 +9642,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9488
9642
|
this.controllerCallInFlight = false;
|
|
9489
9643
|
this.playbackStartedForCurrentRequest = false;
|
|
9490
9644
|
this.opportunityEpoch = -1;
|
|
9645
|
+
this.edgeExhaustedForBreak = false;
|
|
9646
|
+
this.edgeRequestsInBreak = 0;
|
|
9491
9647
|
this.adPodQueue = [];
|
|
9492
9648
|
this.defaultMinRemainingMsToRequestAd = 1e4;
|
|
9493
9649
|
this.defaultMaxNoFillsPerBreak = 2;
|
|
@@ -9638,7 +9794,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9638
9794
|
_this.timing.clearAdRequestWatchdog();
|
|
9639
9795
|
_this.timing.activeAdRequestToken = null;
|
|
9640
9796
|
_this.showAds = true;
|
|
9641
|
-
_this.
|
|
9797
|
+
if (_this.currentPodSource !== "edge") {
|
|
9798
|
+
_this.timing.resetGamNoFillCounter();
|
|
9799
|
+
}
|
|
9642
9800
|
if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
|
|
9643
9801
|
_this.timing.scheduleAdStopAtBreakBoundary();
|
|
9644
9802
|
if (_this.debug) {
|
|
@@ -9770,6 +9928,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9770
9928
|
key: "beginVmapBreak",
|
|
9771
9929
|
value: function beginVmapBreak(breakKey, position) {
|
|
9772
9930
|
this.breakSource = "vmap";
|
|
9931
|
+
this.resetEdgeStateForBreak();
|
|
9773
9932
|
this.followUpBaseVastUrl = void 0;
|
|
9774
9933
|
this.unusableResponsesInBreak = 0;
|
|
9775
9934
|
this.timing.totalAdRequestsInBreak = 0;
|
|
@@ -9781,7 +9940,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9781
9940
|
key: "handleAdStart",
|
|
9782
9941
|
value: function handleAdStart(marker) {
|
|
9783
9942
|
return _async_to_generator(function() {
|
|
9784
|
-
var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
|
|
9943
|
+
var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
|
|
9785
9944
|
return _ts_generator(this, function(_state) {
|
|
9786
9945
|
switch(_state.label){
|
|
9787
9946
|
case 0:
|
|
@@ -9795,7 +9954,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9795
9954
|
];
|
|
9796
9955
|
}
|
|
9797
9956
|
baseVastUrl = this.adConfig.apiVastTagUrl;
|
|
9798
|
-
|
|
9957
|
+
edgeConfigured = !!this.host.getEdgePodBaseUrl();
|
|
9958
|
+
if (!baseVastUrl && !edgeConfigured) {
|
|
9799
9959
|
console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
|
|
9800
9960
|
this.clearPendingAdBreak();
|
|
9801
9961
|
return [
|
|
@@ -9811,6 +9971,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9811
9971
|
this.breakSource = "scte35";
|
|
9812
9972
|
this.followUpBaseVastUrl = baseVastUrl;
|
|
9813
9973
|
this.unusableResponsesInBreak = 0;
|
|
9974
|
+
this.resetEdgeStateForBreak();
|
|
9814
9975
|
this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
|
|
9815
9976
|
if (this.adConfig.podAssignedByPrefetch) {
|
|
9816
9977
|
this.adConfig.podAssignedByPrefetch = false;
|
|
@@ -9832,7 +9993,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9832
9993
|
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
|
|
9833
9994
|
epoch = this.timing.adBreakEpoch;
|
|
9834
9995
|
hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
|
|
9835
|
-
if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
|
|
9996
|
+
if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
|
|
9836
9997
|
3,
|
|
9837
9998
|
2
|
|
9838
9999
|
];
|
|
@@ -9851,11 +10012,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9851
10012
|
mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
|
|
9852
10013
|
console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
|
|
9853
10014
|
}
|
|
10015
|
+
if (!edgeConfigured) return [
|
|
10016
|
+
3,
|
|
10017
|
+
5
|
|
10018
|
+
];
|
|
10019
|
+
edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
|
|
10020
|
+
if (!edgeUrl) return [
|
|
10021
|
+
3,
|
|
10022
|
+
4
|
|
10023
|
+
];
|
|
10024
|
+
this.clearPendingAdBreak();
|
|
9854
10025
|
return [
|
|
9855
10026
|
4,
|
|
9856
|
-
this.
|
|
10027
|
+
this.runEdgePod(edgeUrl, "edge_break_start")
|
|
9857
10028
|
];
|
|
9858
10029
|
case 3:
|
|
10030
|
+
outcome = _state.sent();
|
|
10031
|
+
this.continueAfterEdgeOutcome(outcome, epoch);
|
|
10032
|
+
return [
|
|
10033
|
+
2
|
|
10034
|
+
];
|
|
10035
|
+
case 4:
|
|
10036
|
+
if (!this.edgeExhaustedForBreak) {
|
|
10037
|
+
this.markEdgeExhausted("not_eligible_at_break_start", {
|
|
10038
|
+
isLive: this.isLiveBreak(),
|
|
10039
|
+
durationMs: this.timing.expectedAdBreakDurationMs
|
|
10040
|
+
});
|
|
10041
|
+
}
|
|
10042
|
+
_state.label = 5;
|
|
10043
|
+
case 5:
|
|
10044
|
+
if (!baseVastUrl) {
|
|
10045
|
+
this.requestNextAd("no_gam_source");
|
|
10046
|
+
return [
|
|
10047
|
+
2
|
|
10048
|
+
];
|
|
10049
|
+
}
|
|
10050
|
+
return [
|
|
10051
|
+
4,
|
|
10052
|
+
this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
|
|
10053
|
+
];
|
|
10054
|
+
case 6:
|
|
9859
10055
|
podPlayed = _state.sent();
|
|
9860
10056
|
if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
|
|
9861
10057
|
this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
|
|
@@ -9947,6 +10143,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
9947
10143
|
adPlayer = this.host.getAdPlayer();
|
|
9948
10144
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
9949
10145
|
this.timing.activeAdRequestToken = requestToken;
|
|
10146
|
+
this.currentPodSource = "gam";
|
|
9950
10147
|
this.setSlotState("REQUESTING", "initial_pod");
|
|
9951
10148
|
this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
|
|
9952
10149
|
requestUrl = this.applyOpportunityFloor(podUrl);
|
|
@@ -10063,6 +10260,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10063
10260
|
}).call(this);
|
|
10064
10261
|
}
|
|
10065
10262
|
},
|
|
10263
|
+
{
|
|
10264
|
+
// ───────────────────────────────────────────────────────────────
|
|
10265
|
+
// Edge-first pods (live SCTE-35 only, GAM fallback)
|
|
10266
|
+
// ───────────────────────────────────────────────────────────────
|
|
10267
|
+
key: "resetEdgeStateForBreak",
|
|
10268
|
+
value: function resetEdgeStateForBreak() {
|
|
10269
|
+
this.edgeExhaustedForBreak = false;
|
|
10270
|
+
this.edgeRequestsInBreak = 0;
|
|
10271
|
+
this.currentPodSource = void 0;
|
|
10272
|
+
}
|
|
10273
|
+
},
|
|
10274
|
+
{
|
|
10275
|
+
key: "isLiveBreak",
|
|
10276
|
+
value: function isLiveBreak() {
|
|
10277
|
+
return this.host.isLiveStream() || this.host.config.isLiveStream === true;
|
|
10278
|
+
}
|
|
10279
|
+
},
|
|
10280
|
+
{
|
|
10281
|
+
key: "canRequestEdge",
|
|
10282
|
+
value: function canRequestEdge() {
|
|
10283
|
+
return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
|
|
10284
|
+
}
|
|
10285
|
+
},
|
|
10286
|
+
{
|
|
10287
|
+
key: "markEdgeExhausted",
|
|
10288
|
+
value: function markEdgeExhausted(reason) {
|
|
10289
|
+
var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
10290
|
+
this.edgeExhaustedForBreak = true;
|
|
10291
|
+
this.countFunnelStage("edge_fallback:".concat(reason));
|
|
10292
|
+
this.logOrchestratorFunnel("edge_exhausted", _object_spread({
|
|
10293
|
+
reason: reason,
|
|
10294
|
+
edgeRequests: this.edgeRequestsInBreak,
|
|
10295
|
+
remainingMs: this.timing.getRemainingAdMs()
|
|
10296
|
+
}, extra));
|
|
10297
|
+
}
|
|
10298
|
+
},
|
|
10299
|
+
{
|
|
10300
|
+
/**
|
|
10301
|
+
* Builds the next Edge request from the budget left right now, or marks Edge
|
|
10302
|
+
* exhausted for this break. Synchronous on purpose: callers must reach the
|
|
10303
|
+
* REQUESTING state in the same tick so a second completion event cannot race
|
|
10304
|
+
* in a parallel request.
|
|
10305
|
+
*/ key: "prepareEdgePodRequest",
|
|
10306
|
+
value: function prepareEdgePodRequest() {
|
|
10307
|
+
var baseUrl = this.host.getEdgePodBaseUrl();
|
|
10308
|
+
if (!baseUrl) return void 0;
|
|
10309
|
+
var remainingMs = this.timing.getRemainingAdMs();
|
|
10310
|
+
var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
|
|
10311
|
+
if (remainingAds < 1) {
|
|
10312
|
+
this.markEdgeExhausted("ad_capacity_reached", {
|
|
10313
|
+
adsInBreak: this.timing.totalAdsInBreak
|
|
10314
|
+
});
|
|
10315
|
+
return void 0;
|
|
10316
|
+
}
|
|
10317
|
+
if (remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
10318
|
+
this.markEdgeExhausted("insufficient_break_time", {
|
|
10319
|
+
remainingMs: remainingMs
|
|
10320
|
+
});
|
|
10321
|
+
return void 0;
|
|
10322
|
+
}
|
|
10323
|
+
try {
|
|
10324
|
+
return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
|
|
10325
|
+
} catch (unused) {
|
|
10326
|
+
this.markEdgeExhausted("invalid_edge_url");
|
|
10327
|
+
return void 0;
|
|
10328
|
+
}
|
|
10329
|
+
}
|
|
10330
|
+
},
|
|
10331
|
+
{
|
|
10332
|
+
key: "runEdgePod",
|
|
10333
|
+
value: function runEdgePod(requestUrl, trigger) {
|
|
10334
|
+
return _async_to_generator(function() {
|
|
10335
|
+
var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
|
|
10336
|
+
return _ts_generator(this, function(_state) {
|
|
10337
|
+
switch(_state.label){
|
|
10338
|
+
case 0:
|
|
10339
|
+
epoch = this.timing.adBreakEpoch;
|
|
10340
|
+
this.recreateAdController("new_request");
|
|
10341
|
+
generation = this.controllerGeneration;
|
|
10342
|
+
adPlayer = this.host.getAdPlayer();
|
|
10343
|
+
requestToken = ++this.timing.adRequestTokenCounter;
|
|
10344
|
+
this.timing.activeAdRequestToken = requestToken;
|
|
10345
|
+
this.currentPodSource = "edge";
|
|
10346
|
+
this.edgeRequestsInBreak++;
|
|
10347
|
+
this.setSlotState("REQUESTING", trigger);
|
|
10348
|
+
this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
|
|
10349
|
+
this.currentVastUrl = requestUrl;
|
|
10350
|
+
params = new URL(requestUrl).searchParams;
|
|
10351
|
+
this.logOrchestratorFunnel("edge_request_sent", {
|
|
10352
|
+
trigger: trigger,
|
|
10353
|
+
attempt: this.edgeRequestsInBreak,
|
|
10354
|
+
endpoint: describeEdgeUrl(requestUrl),
|
|
10355
|
+
pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
|
|
10356
|
+
pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
|
|
10357
|
+
});
|
|
10358
|
+
_state.label = 1;
|
|
10359
|
+
case 1:
|
|
10360
|
+
_state.trys.push([
|
|
10361
|
+
1,
|
|
10362
|
+
4,
|
|
10363
|
+
,
|
|
10364
|
+
5
|
|
10365
|
+
]);
|
|
10366
|
+
this.timing.startAdRequestWatchdog(requestToken);
|
|
10367
|
+
return [
|
|
10368
|
+
4,
|
|
10369
|
+
this.callController(function() {
|
|
10370
|
+
return adPlayer.requestAds(requestUrl, {
|
|
10371
|
+
source: "edge"
|
|
10372
|
+
});
|
|
10373
|
+
})
|
|
10374
|
+
];
|
|
10375
|
+
case 2:
|
|
10376
|
+
_state.sent();
|
|
10377
|
+
this.timing.clearAdRequestWatchdog();
|
|
10378
|
+
if (this.isStale(epoch, generation)) {
|
|
10379
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10380
|
+
requestId: requestToken,
|
|
10381
|
+
source: "edge"
|
|
10382
|
+
});
|
|
10383
|
+
return [
|
|
10384
|
+
2,
|
|
10385
|
+
"stale"
|
|
10386
|
+
];
|
|
10387
|
+
}
|
|
10388
|
+
remainingMs = this.timing.getRemainingAdMs();
|
|
10389
|
+
remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
|
|
10390
|
+
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;
|
|
10391
|
+
if (classifyEdgeVastResponse({
|
|
10392
|
+
podAdCount: podCount
|
|
10393
|
+
}) !== "fill") {
|
|
10394
|
+
throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
|
|
10395
|
+
}
|
|
10396
|
+
this.setSlotState("READY", "edge_vast_ready");
|
|
10397
|
+
this.logOrchestratorFunnel("edge_fill", {
|
|
10398
|
+
podAdCount: podCount,
|
|
10399
|
+
podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
|
|
10400
|
+
remainingMs: remainingMs
|
|
10401
|
+
});
|
|
10402
|
+
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
10403
|
+
source: "hls",
|
|
10404
|
+
vastUrl: requestUrl,
|
|
10405
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10406
|
+
}, this.analyticsContext).catch(function() {});
|
|
10407
|
+
this.timing.startAdFailsafeTimer(requestToken);
|
|
10408
|
+
return [
|
|
10409
|
+
4,
|
|
10410
|
+
this.callController(function() {
|
|
10411
|
+
return adPlayer.play();
|
|
10412
|
+
})
|
|
10413
|
+
];
|
|
10414
|
+
case 3:
|
|
10415
|
+
_state.sent();
|
|
10416
|
+
if (this.isStale(epoch, generation)) return [
|
|
10417
|
+
2,
|
|
10418
|
+
"stale"
|
|
10419
|
+
];
|
|
10420
|
+
if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
|
|
10421
|
+
this.timing.scheduleAdStopAtBreakBoundary();
|
|
10422
|
+
}
|
|
10423
|
+
adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
|
|
10424
|
+
return [
|
|
10425
|
+
2,
|
|
10426
|
+
"fill"
|
|
10427
|
+
];
|
|
10428
|
+
case 4:
|
|
10429
|
+
error = _state.sent();
|
|
10430
|
+
this.timing.clearAdRequestWatchdog();
|
|
10431
|
+
this.timing.clearAdFailsafeTimer();
|
|
10432
|
+
if (this.timing.activeAdRequestToken === requestToken) {
|
|
10433
|
+
this.timing.activeAdRequestToken = null;
|
|
10434
|
+
}
|
|
10435
|
+
errorMessage = error === null || error === void 0 ? void 0 : error.message;
|
|
10436
|
+
if (this.isStale(epoch, generation)) {
|
|
10437
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
10438
|
+
requestId: requestToken,
|
|
10439
|
+
source: "edge",
|
|
10440
|
+
errorMessage: errorMessage
|
|
10441
|
+
});
|
|
10442
|
+
return [
|
|
10443
|
+
2,
|
|
10444
|
+
"stale"
|
|
10445
|
+
];
|
|
10446
|
+
}
|
|
10447
|
+
classification = classifyEdgeVastResponse({
|
|
10448
|
+
podAdCount: 0,
|
|
10449
|
+
error: error
|
|
10450
|
+
});
|
|
10451
|
+
diag = this.requestDiagnostics.get(requestToken);
|
|
10452
|
+
if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
|
|
10453
|
+
this.markEdgeExhausted("edge_".concat(classification), {
|
|
10454
|
+
errorMessage: errorMessage
|
|
10455
|
+
});
|
|
10456
|
+
return [
|
|
10457
|
+
2,
|
|
10458
|
+
"fallback"
|
|
10459
|
+
];
|
|
10460
|
+
case 5:
|
|
10461
|
+
return [
|
|
10462
|
+
2
|
|
10463
|
+
];
|
|
10464
|
+
}
|
|
10465
|
+
});
|
|
10466
|
+
}).call(this);
|
|
10467
|
+
}
|
|
10468
|
+
},
|
|
10469
|
+
{
|
|
10470
|
+
key: "continueAfterEdgeOutcome",
|
|
10471
|
+
value: function continueAfterEdgeOutcome(outcome, epoch) {
|
|
10472
|
+
if (outcome !== "fallback") return;
|
|
10473
|
+
if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
|
|
10474
|
+
if (this.debug) {
|
|
10475
|
+
console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
|
|
10476
|
+
}
|
|
10477
|
+
this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
|
|
10478
|
+
this.requestNextAd("edge_fallback");
|
|
10479
|
+
}
|
|
10480
|
+
},
|
|
10066
10481
|
{
|
|
10067
10482
|
// ───────────────────────────────────────────────────────────────
|
|
10068
10483
|
// Next-ad scheduling (single flight)
|
|
@@ -10118,7 +10533,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10118
10533
|
value: function getStopRequestingReason(remainingMs) {
|
|
10119
10534
|
if (this.breakSource === "vmap") {
|
|
10120
10535
|
if (this.adPodQueue.length === 0) return "vmap_queue_empty";
|
|
10121
|
-
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
|
|
10536
|
+
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
|
|
10122
10537
|
return "no_follow_up_source";
|
|
10123
10538
|
}
|
|
10124
10539
|
if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
|
|
@@ -10130,7 +10545,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10130
10545
|
if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
|
|
10131
10546
|
return "request_cap";
|
|
10132
10547
|
}
|
|
10133
|
-
if (this.timing.isGamInCooldown()) {
|
|
10548
|
+
if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
|
|
10134
10549
|
return "gam_cooldown";
|
|
10135
10550
|
}
|
|
10136
10551
|
if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
@@ -10224,10 +10639,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10224
10639
|
key: "requestFollowUpAd",
|
|
10225
10640
|
value: function requestFollowUpAd(trigger) {
|
|
10226
10641
|
return _async_to_generator(function() {
|
|
10227
|
-
var url, epoch, unused;
|
|
10642
|
+
var edgeUrl, epoch2, outcome, url, epoch, unused;
|
|
10228
10643
|
return _ts_generator(this, function(_state) {
|
|
10229
10644
|
switch(_state.label){
|
|
10230
10645
|
case 0:
|
|
10646
|
+
if (!this.canRequestEdge()) return [
|
|
10647
|
+
3,
|
|
10648
|
+
2
|
|
10649
|
+
];
|
|
10650
|
+
edgeUrl = this.prepareEdgePodRequest();
|
|
10651
|
+
if (!edgeUrl) {
|
|
10652
|
+
this.requestNextAd("".concat(trigger, ":edge_unavailable"));
|
|
10653
|
+
return [
|
|
10654
|
+
2
|
|
10655
|
+
];
|
|
10656
|
+
}
|
|
10657
|
+
epoch2 = this.timing.adBreakEpoch;
|
|
10658
|
+
return [
|
|
10659
|
+
4,
|
|
10660
|
+
this.runEdgePod(edgeUrl, "edge_".concat(trigger))
|
|
10661
|
+
];
|
|
10662
|
+
case 1:
|
|
10663
|
+
outcome = _state.sent();
|
|
10664
|
+
this.continueAfterEdgeOutcome(outcome, epoch2);
|
|
10665
|
+
return [
|
|
10666
|
+
2
|
|
10667
|
+
];
|
|
10668
|
+
case 2:
|
|
10231
10669
|
if (this.breakSource === "vmap") {
|
|
10232
10670
|
url = this.adPodQueue.shift();
|
|
10233
10671
|
} else if (this.followUpBaseVastUrl) {
|
|
@@ -10238,32 +10676,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10238
10676
|
];
|
|
10239
10677
|
this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
|
|
10240
10678
|
epoch = this.timing.adBreakEpoch;
|
|
10241
|
-
_state.label =
|
|
10242
|
-
case
|
|
10679
|
+
_state.label = 3;
|
|
10680
|
+
case 3:
|
|
10243
10681
|
_state.trys.push([
|
|
10244
|
-
1,
|
|
10245
10682
|
3,
|
|
10683
|
+
5,
|
|
10246
10684
|
,
|
|
10247
|
-
|
|
10685
|
+
6
|
|
10248
10686
|
]);
|
|
10249
10687
|
return [
|
|
10250
10688
|
4,
|
|
10251
10689
|
this.playSingleAd(url, trigger)
|
|
10252
10690
|
];
|
|
10253
|
-
case
|
|
10691
|
+
case 4:
|
|
10254
10692
|
_state.sent();
|
|
10255
10693
|
return [
|
|
10256
10694
|
3,
|
|
10257
|
-
|
|
10695
|
+
6
|
|
10258
10696
|
];
|
|
10259
|
-
case
|
|
10697
|
+
case 5:
|
|
10260
10698
|
unused = _state.sent();
|
|
10261
10699
|
this.continueAfterRequestFailure(epoch);
|
|
10262
10700
|
return [
|
|
10263
10701
|
3,
|
|
10264
|
-
|
|
10702
|
+
6
|
|
10265
10703
|
];
|
|
10266
|
-
case
|
|
10704
|
+
case 6:
|
|
10267
10705
|
return [
|
|
10268
10706
|
2
|
|
10269
10707
|
];
|
|
@@ -10376,7 +10814,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10376
10814
|
case "gam_http_request_sent":
|
|
10377
10815
|
diag.gamRequestSent++;
|
|
10378
10816
|
break;
|
|
10817
|
+
case "edge_http_request_sent":
|
|
10818
|
+
diag.edgeRequestSent++;
|
|
10819
|
+
break;
|
|
10379
10820
|
case "gam_response_received":
|
|
10821
|
+
case "edge_response_received":
|
|
10380
10822
|
diag.vastHttpStatus = payload.httpStatus;
|
|
10381
10823
|
break;
|
|
10382
10824
|
case "vast_parsed":
|
|
@@ -10563,6 +11005,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10563
11005
|
{
|
|
10564
11006
|
key: "beginFunnelRequest",
|
|
10565
11007
|
value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
|
|
11008
|
+
var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
|
|
10566
11009
|
var _adPlayer_setFunnelContext;
|
|
10567
11010
|
if (this.controllerCallInFlight) {
|
|
10568
11011
|
this.logOrchestratorFunnel("duplicate_request_detected", {
|
|
@@ -10577,7 +11020,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10577
11020
|
requestId: requestToken,
|
|
10578
11021
|
controllerId: this.controllerGeneration,
|
|
10579
11022
|
trigger: trigger,
|
|
11023
|
+
source: source,
|
|
10580
11024
|
gamRequestSent: 0,
|
|
11025
|
+
edgeRequestSent: 0,
|
|
10581
11026
|
wrapperDepth: 0,
|
|
10582
11027
|
inlineResolved: false,
|
|
10583
11028
|
mediaCandidateCount: 0,
|
|
@@ -10708,6 +11153,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10708
11153
|
this.timing.activeAdRequestToken = requestToken;
|
|
10709
11154
|
ap = this.host.getAdPlayer();
|
|
10710
11155
|
budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
|
|
11156
|
+
this.currentPodSource = "gam";
|
|
10711
11157
|
this.setSlotState("REQUESTING", trigger);
|
|
10712
11158
|
this.beginFunnelRequest(ap, requestToken, trigger);
|
|
10713
11159
|
requestUrl = this.applyOpportunityFloor(budgetedUrl);
|
|
@@ -10855,6 +11301,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10855
11301
|
requests: requests,
|
|
10856
11302
|
requestRetries: requestRetries,
|
|
10857
11303
|
gamResponses: count("gam_response_received"),
|
|
11304
|
+
edgeRequests: count("edge_request_sent"),
|
|
11305
|
+
edgeFills: count("edge_fill"),
|
|
11306
|
+
edgeEmptySentinels: count("edge_empty_sentinel"),
|
|
11307
|
+
edgeFallbacks: countPrefix("edge_fallback:"),
|
|
10858
11308
|
requestsSuppressed: count("request_suppressed"),
|
|
10859
11309
|
duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
|
|
10860
11310
|
filled: count("vast_received"),
|
|
@@ -10951,6 +11401,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
10951
11401
|
this.breakSource = void 0;
|
|
10952
11402
|
this.followUpBaseVastUrl = void 0;
|
|
10953
11403
|
this.unusableResponsesInBreak = 0;
|
|
11404
|
+
this.resetEdgeStateForBreak();
|
|
10954
11405
|
adPlayer.stop().catch(function() {});
|
|
10955
11406
|
if (!alreadyEnded) this.logBreakFunnel(reason);
|
|
10956
11407
|
this.opportunityFloor = void 0;
|
|
@@ -11264,7 +11715,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
11264
11715
|
});
|
|
11265
11716
|
return;
|
|
11266
11717
|
}
|
|
11267
|
-
this.
|
|
11718
|
+
if (this.currentPodSource === "edge") {
|
|
11719
|
+
this.markEdgeExhausted("edge_playback_failed", {
|
|
11720
|
+
reason: reason
|
|
11721
|
+
});
|
|
11722
|
+
} else {
|
|
11723
|
+
this.timing.consecutiveFailures++;
|
|
11724
|
+
}
|
|
11268
11725
|
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
11269
11726
|
if (diag && !diag.failureReason) diag.failureReason = reason;
|
|
11270
11727
|
if (this.debug) {
|
|
@@ -11294,7 +11751,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11294
11751
|
if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
|
|
11295
11752
|
if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
|
|
11296
11753
|
this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
|
|
11754
|
+
this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
|
|
11297
11755
|
this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11756
|
+
this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
|
|
11298
11757
|
this.adPlayer = this.createAdPlayer(false);
|
|
11299
11758
|
this.palNonce = createPalNonceManager();
|
|
11300
11759
|
this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
|
|
@@ -11394,11 +11853,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11394
11853
|
generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
|
|
11395
11854
|
return _this.generatePodVastUrl(base, breakDurationMs);
|
|
11396
11855
|
},
|
|
11856
|
+
getEdgePodBaseUrl: function getEdgePodBaseUrl() {
|
|
11857
|
+
return _this.edgePodBaseUrl;
|
|
11858
|
+
},
|
|
11397
11859
|
getFloorSnapshot: function getFloorSnapshot(position) {
|
|
11398
|
-
return _this.floorLadder.snapshotFor({
|
|
11860
|
+
return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
|
|
11399
11861
|
position: position,
|
|
11400
11862
|
isCtv: _this.isCtvEnvironment()
|
|
11401
|
-
});
|
|
11863
|
+
}) : void 0;
|
|
11402
11864
|
},
|
|
11403
11865
|
onAdClick: function onAdClick() {
|
|
11404
11866
|
return _this.palNonce.sendAdClick();
|
|
@@ -11449,11 +11911,24 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
11449
11911
|
return report;
|
|
11450
11912
|
}
|
|
11451
11913
|
},
|
|
11914
|
+
{
|
|
11915
|
+
key: "setAdFloorLadderEnabled",
|
|
11916
|
+
value: function setAdFloorLadderEnabled(enabled) {
|
|
11917
|
+
this.floorLadderEnabled = enabled;
|
|
11918
|
+
if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
|
|
11919
|
+
}
|
|
11920
|
+
},
|
|
11921
|
+
{
|
|
11922
|
+
key: "isAdFloorLadderEnabled",
|
|
11923
|
+
value: function isAdFloorLadderEnabled() {
|
|
11924
|
+
return this.floorLadderEnabled;
|
|
11925
|
+
}
|
|
11926
|
+
},
|
|
11452
11927
|
{
|
|
11453
11928
|
key: "warnOnInvalidFloorLadder",
|
|
11454
11929
|
value: function warnOnInvalidFloorLadder(report) {
|
|
11455
11930
|
var config = this.floorLadder.get();
|
|
11456
|
-
if (report.ok || !config.enabled) return;
|
|
11931
|
+
if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
|
|
11457
11932
|
console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
|
|
11458
11933
|
errors: report.errors,
|
|
11459
11934
|
configurationVersion: config.configurationVersion,
|
|
@@ -12186,6 +12661,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
12186
12661
|
this.timing.destroy();
|
|
12187
12662
|
this.adBreak.clearPendingAdBreak();
|
|
12188
12663
|
this.placeholder.destroy();
|
|
12664
|
+
0;
|
|
12189
12665
|
if (this.timeUpdateHandler) {
|
|
12190
12666
|
this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
|
|
12191
12667
|
delete this.timeUpdateHandler;
|
|
@@ -12286,12 +12762,14 @@ var CRITICAL_PROPS = [
|
|
|
12286
12762
|
"ctvAdRequest",
|
|
12287
12763
|
"adFloorMinCents",
|
|
12288
12764
|
"adFloorMaxCents",
|
|
12289
|
-
"adFloorStepCents"
|
|
12765
|
+
"adFloorStepCents",
|
|
12766
|
+
"enableEdgePodRequest",
|
|
12767
|
+
"edgePodUrl"
|
|
12290
12768
|
];
|
|
12291
12769
|
var CONTROLS_HIDE_DELAY = 3e3;
|
|
12292
12770
|
var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
|
|
12293
12771
|
var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
12294
|
-
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, [
|
|
12772
|
+
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, [
|
|
12295
12773
|
"src",
|
|
12296
12774
|
"autoplay",
|
|
12297
12775
|
"muted",
|
|
@@ -12328,10 +12806,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12328
12806
|
"minRemainingMsToStartAd",
|
|
12329
12807
|
"minRemainingMsToRequestAd",
|
|
12330
12808
|
"maxNoFillsPerBreak",
|
|
12809
|
+
"adFloorLadderEnabled",
|
|
12331
12810
|
"adFloorLadder",
|
|
12332
12811
|
"adFloorMinCents",
|
|
12333
12812
|
"adFloorMaxCents",
|
|
12334
|
-
"adFloorStepCents"
|
|
12813
|
+
"adFloorStepCents",
|
|
12814
|
+
"enableEdgePodRequest",
|
|
12815
|
+
"edgePodUrl"
|
|
12335
12816
|
]);
|
|
12336
12817
|
var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
|
|
12337
12818
|
var videoRef = (0, import_react.useRef)(null);
|
|
@@ -12482,7 +12963,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12482
12963
|
vastMode,
|
|
12483
12964
|
adFloorMinCents,
|
|
12484
12965
|
adFloorMaxCents,
|
|
12485
|
-
adFloorStepCents
|
|
12966
|
+
adFloorStepCents,
|
|
12967
|
+
enableEdgePodRequest,
|
|
12968
|
+
edgePodUrl
|
|
12486
12969
|
]);
|
|
12487
12970
|
(0, import_react.useEffect)(function() {
|
|
12488
12971
|
if (typeof window === "undefined") return;
|
|
@@ -12532,10 +13015,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12532
13015
|
if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
|
|
12533
13016
|
if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
|
|
12534
13017
|
if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
|
|
13018
|
+
if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
|
|
12535
13019
|
if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
|
|
12536
13020
|
if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
|
|
12537
13021
|
if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
|
|
12538
13022
|
if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
|
|
13023
|
+
if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
|
|
13024
|
+
if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
|
|
12539
13025
|
var player = new StormcloudVideoPlayer(cfg);
|
|
12540
13026
|
playerRef.current = player;
|
|
12541
13027
|
appliedFloorLadderKeyRef.current = adFloorLadderKey;
|
|
@@ -12584,6 +13070,14 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
12584
13070
|
}, [
|
|
12585
13071
|
adFloorLadderKey
|
|
12586
13072
|
]);
|
|
13073
|
+
(0, import_react.useEffect)(function() {
|
|
13074
|
+
if (!playerRef.current) return;
|
|
13075
|
+
var enabled = adFloorLadderEnabled === true;
|
|
13076
|
+
if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
|
|
13077
|
+
playerRef.current.setAdFloorLadderEnabled(enabled);
|
|
13078
|
+
}, [
|
|
13079
|
+
adFloorLadderEnabled
|
|
13080
|
+
]);
|
|
12587
13081
|
(0, import_react.useEffect)(function() {
|
|
12588
13082
|
if (!playerRef.current) return;
|
|
12589
13083
|
var checkAdStatus = function checkAdStatus() {
|
|
@@ -13660,6 +14154,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
|
|
|
13660
14154
|
}
|
|
13661
14155
|
}
|
|
13662
14156
|
}
|
|
14157
|
+
if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled) {
|
|
14158
|
+
return false;
|
|
14159
|
+
}
|
|
13663
14160
|
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)) {
|
|
13664
14161
|
return false;
|
|
13665
14162
|
}
|