stormcloud-video-player 0.8.68 → 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/Player.cjs +30 -8
- package/lib/Player.cjs.map +1 -1
- package/lib/Player.d.cts +2 -1
- package/lib/StormcloudPlayer.cjs +6104 -5114
- package/lib/StormcloudPlayer.cjs.map +1 -1
- package/lib/StormcloudPlayer.d.cts +1 -0
- package/lib/index.cjs +6217 -5149
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -1
- package/lib/index.d.ts +93 -2
- package/lib/index.js +6199 -5158
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.cjs +669 -131
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +27 -3
- 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/FloorLadder.cjs +578 -0
- package/lib/player/FloorLadder.cjs.map +1 -0
- package/lib/player/FloorLadder.d.cts +74 -0
- package/lib/player/StormcloudVideoPlayer.cjs +6104 -5114
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +13 -1
- package/lib/players/HlsPlayer.cjs +6104 -5114
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +6104 -5114
- package/lib/players/index.cjs.map +1 -1
- package/lib/props.cjs +30 -8
- package/lib/props.cjs.map +1 -1
- package/lib/props.d.cts +1 -0
- package/lib/sdk/hlsAdPlayer.cjs +120 -19
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/types.d.cts +30 -2
- package/lib/ui/StormcloudVideoPlayer.cjs +6169 -5129
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/utils/vastMacros.cjs +4 -0
- package/lib/utils/vastMacros.cjs.map +1 -1
- package/lib/utils/vastMacros.d.cts +2 -1
- package/package.json +1 -1
|
@@ -284,84 +284,6 @@ __export(AdBreakOrchestrator_exports, {
|
|
|
284
284
|
}
|
|
285
285
|
});
|
|
286
286
|
module.exports = __toCommonJS(AdBreakOrchestrator_exports);
|
|
287
|
-
// src/utils/trackingIngest.ts
|
|
288
|
-
var DEFAULT_TRACKING_INGEST_CONFIG = {
|
|
289
|
-
enabled: true,
|
|
290
|
-
baseUrl: "https://player-analytics-ingest-api-760490581852.us-central1.run.app/api/adstorm/player-tracking"
|
|
291
|
-
};
|
|
292
|
-
var trackingIngestConfig = _object_spread({}, DEFAULT_TRACKING_INGEST_CONFIG);
|
|
293
|
-
function isTrackingIngestEnabled() {
|
|
294
|
-
return trackingIngestConfig.enabled === true;
|
|
295
|
-
}
|
|
296
|
-
function normalizeIngestBaseUrl(baseUrl) {
|
|
297
|
-
return baseUrl.replace(/\/+$/, "");
|
|
298
|
-
}
|
|
299
|
-
function buildTrackingIngestUrl(channel) {
|
|
300
|
-
var base = normalizeIngestBaseUrl(trackingIngestConfig.baseUrl);
|
|
301
|
-
if (channel === "impressions") {
|
|
302
|
-
return "".concat(base, "/impressions/ingest");
|
|
303
|
-
}
|
|
304
|
-
return "".concat(base, "/metrics/ingest");
|
|
305
|
-
}
|
|
306
|
-
function ingestPlayerTracking(licenseKey, channel, body) {
|
|
307
|
-
return _async_to_generator(function() {
|
|
308
|
-
var response, error;
|
|
309
|
-
return _ts_generator(this, function(_state) {
|
|
310
|
-
switch(_state.label){
|
|
311
|
-
case 0:
|
|
312
|
-
if (!isTrackingIngestEnabled() || !licenseKey) {
|
|
313
|
-
return [
|
|
314
|
-
2,
|
|
315
|
-
false
|
|
316
|
-
];
|
|
317
|
-
}
|
|
318
|
-
_state.label = 1;
|
|
319
|
-
case 1:
|
|
320
|
-
_state.trys.push([
|
|
321
|
-
1,
|
|
322
|
-
3,
|
|
323
|
-
,
|
|
324
|
-
4
|
|
325
|
-
]);
|
|
326
|
-
return [
|
|
327
|
-
4,
|
|
328
|
-
fetch(buildTrackingIngestUrl(channel), {
|
|
329
|
-
method: "POST",
|
|
330
|
-
headers: {
|
|
331
|
-
"Content-Type": "application/json",
|
|
332
|
-
Authorization: "License-Key ".concat(licenseKey)
|
|
333
|
-
},
|
|
334
|
-
body: JSON.stringify(body)
|
|
335
|
-
})
|
|
336
|
-
];
|
|
337
|
-
case 2:
|
|
338
|
-
response = _state.sent();
|
|
339
|
-
if (!response.ok) {
|
|
340
|
-
console.warn("[StormcloudVideoPlayer] Tracking ingest failed (".concat(response.status, ") for ").concat(channel));
|
|
341
|
-
return [
|
|
342
|
-
2,
|
|
343
|
-
false
|
|
344
|
-
];
|
|
345
|
-
}
|
|
346
|
-
return [
|
|
347
|
-
2,
|
|
348
|
-
true
|
|
349
|
-
];
|
|
350
|
-
case 3:
|
|
351
|
-
error = _state.sent();
|
|
352
|
-
console.warn("[StormcloudVideoPlayer] Tracking ingest error for ".concat(channel, ":"), error);
|
|
353
|
-
return [
|
|
354
|
-
2,
|
|
355
|
-
false
|
|
356
|
-
];
|
|
357
|
-
case 4:
|
|
358
|
-
return [
|
|
359
|
-
2
|
|
360
|
-
];
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
})();
|
|
364
|
-
}
|
|
365
287
|
// src/utils/vastEnvironmentSignals.ts
|
|
366
288
|
var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
|
|
367
289
|
var DEVICE_ID_STORAGE_KEYS = [
|
|
@@ -807,6 +729,259 @@ function normalizeBoolean(value) {
|
|
|
807
729
|
}
|
|
808
730
|
return void 0;
|
|
809
731
|
}
|
|
732
|
+
// src/utils/vastMacros.ts
|
|
733
|
+
var GAM_AD_HOSTS = /* @__PURE__ */ new Set([
|
|
734
|
+
"pubads.g.doubleclick.net",
|
|
735
|
+
"securepubads.g.doubleclick.net"
|
|
736
|
+
]);
|
|
737
|
+
function ensureVideoAdType(rawUrl) {
|
|
738
|
+
try {
|
|
739
|
+
var url = new URL(rawUrl);
|
|
740
|
+
if (!GAM_AD_HOSTS.has(url.hostname)) return rawUrl;
|
|
741
|
+
if (url.searchParams.has("ad_type")) return rawUrl;
|
|
742
|
+
url.searchParams.set("ad_type", "video");
|
|
743
|
+
return url.toString();
|
|
744
|
+
} catch (unused) {
|
|
745
|
+
return rawUrl;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
// src/player/FloorLadder.ts
|
|
749
|
+
var DEFAULT_WEB_FLOOR_LADDER_CONFIG = Object.freeze({
|
|
750
|
+
enabled: false,
|
|
751
|
+
targetingKey: "airytv_web_floor",
|
|
752
|
+
minFloorCents: 25,
|
|
753
|
+
maxFloorCents: 300,
|
|
754
|
+
stepCents: 25,
|
|
755
|
+
selectedFloorCents: 25,
|
|
756
|
+
fallbackFloorCents: 25,
|
|
757
|
+
readyFloorCents: [],
|
|
758
|
+
mode: "fixed",
|
|
759
|
+
allowedPositions: [
|
|
760
|
+
"midroll"
|
|
761
|
+
],
|
|
762
|
+
targetAdUnitPath: "/21821455290/airytvadx/airytv-web",
|
|
763
|
+
configurationVersion: "2026-09-29.1"
|
|
764
|
+
});
|
|
765
|
+
var DEFAULT_FLOOR_LADDER_BOUNDS = Object.freeze({
|
|
766
|
+
minCents: 25,
|
|
767
|
+
maxCents: 300,
|
|
768
|
+
stepCents: 25
|
|
769
|
+
});
|
|
770
|
+
function decodeQueryComponent(value) {
|
|
771
|
+
try {
|
|
772
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
773
|
+
} catch (unused) {
|
|
774
|
+
return void 0;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
function mergeCustParams(decoded, key, cents) {
|
|
778
|
+
var prefix = "".concat(key, "=");
|
|
779
|
+
var kept = decoded.split("&").filter(function(pair) {
|
|
780
|
+
return pair !== "" && pair !== key && pair.indexOf(prefix) !== 0;
|
|
781
|
+
});
|
|
782
|
+
kept.push("".concat(prefix).concat(cents));
|
|
783
|
+
return kept.join("&");
|
|
784
|
+
}
|
|
785
|
+
function applyFloorToVastUrl(url, floor) {
|
|
786
|
+
if (floor.status !== "armed" || floor.floorCents == null) {
|
|
787
|
+
return {
|
|
788
|
+
url: url,
|
|
789
|
+
applied: false,
|
|
790
|
+
reason: floor.reason
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
var parsed;
|
|
794
|
+
try {
|
|
795
|
+
parsed = new URL(url);
|
|
796
|
+
} catch (unused) {
|
|
797
|
+
return {
|
|
798
|
+
url: url,
|
|
799
|
+
applied: false,
|
|
800
|
+
reason: "invalid_url"
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
if (!GAM_AD_HOSTS.has(parsed.hostname)) {
|
|
804
|
+
return {
|
|
805
|
+
url: url,
|
|
806
|
+
applied: false,
|
|
807
|
+
reason: "not_gam_host"
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
if (parsed.searchParams.get("iu") !== floor.targetAdUnitPath) {
|
|
811
|
+
return {
|
|
812
|
+
url: url,
|
|
813
|
+
applied: false,
|
|
814
|
+
reason: "ad_unit_mismatch"
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
var hashIndex = url.indexOf("#");
|
|
818
|
+
var beforeHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
819
|
+
var hash = hashIndex === -1 ? "" : url.slice(hashIndex);
|
|
820
|
+
var queryIndex = beforeHash.indexOf("?");
|
|
821
|
+
var base = beforeHash.slice(0, queryIndex);
|
|
822
|
+
var segments = beforeHash.slice(queryIndex + 1).split("&");
|
|
823
|
+
var existing = [];
|
|
824
|
+
var insertAt = -1;
|
|
825
|
+
var rest = [];
|
|
826
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
827
|
+
try {
|
|
828
|
+
for(var _iterator = segments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
829
|
+
var segment = _step.value;
|
|
830
|
+
var eq = segment.indexOf("=");
|
|
831
|
+
var rawKey = eq === -1 ? segment : segment.slice(0, eq);
|
|
832
|
+
if (decodeQueryComponent(rawKey) === "cust_params") {
|
|
833
|
+
if (insertAt === -1) insertAt = rest.length;
|
|
834
|
+
var value = eq === -1 ? "" : decodeQueryComponent(segment.slice(eq + 1));
|
|
835
|
+
if (value === void 0) {
|
|
836
|
+
return {
|
|
837
|
+
url: url,
|
|
838
|
+
applied: false,
|
|
839
|
+
reason: "malformed_cust_params"
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
if (value) existing.push(value);
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
rest.push(segment);
|
|
846
|
+
}
|
|
847
|
+
} catch (err) {
|
|
848
|
+
_didIteratorError = true;
|
|
849
|
+
_iteratorError = err;
|
|
850
|
+
} finally{
|
|
851
|
+
try {
|
|
852
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
853
|
+
_iterator.return();
|
|
854
|
+
}
|
|
855
|
+
} finally{
|
|
856
|
+
if (_didIteratorError) {
|
|
857
|
+
throw _iteratorError;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
if (insertAt === -1) insertAt = rest.length;
|
|
862
|
+
var merged = mergeCustParams(existing.join("&"), floor.targetingKey, floor.floorCents);
|
|
863
|
+
rest.splice(insertAt, 0, "cust_params=".concat(encodeURIComponent(merged)));
|
|
864
|
+
var query = rest.filter(function(segment) {
|
|
865
|
+
return segment !== "";
|
|
866
|
+
}).join("&");
|
|
867
|
+
return {
|
|
868
|
+
url: "".concat(base, "?").concat(query).concat(hash),
|
|
869
|
+
applied: true,
|
|
870
|
+
reason: void 0
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
// src/player/EdgePodRequest.ts
|
|
874
|
+
var EDGE_POD_MAX_ADS = 10;
|
|
875
|
+
var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
|
|
876
|
+
function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
|
|
877
|
+
var url = new URL(baseUrl);
|
|
878
|
+
var maxMs = Math.max(0, Math.floor(remainingMs));
|
|
879
|
+
var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
|
|
880
|
+
url.searchParams.set("pmxd", String(maxMs));
|
|
881
|
+
url.searchParams.set("pmad", String(maxAds));
|
|
882
|
+
url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
|
|
883
|
+
url.searchParams.set("count", String(maxAds));
|
|
884
|
+
return url.toString();
|
|
885
|
+
}
|
|
886
|
+
function classifyEdgeVastResponse(result) {
|
|
887
|
+
var _ref;
|
|
888
|
+
var _result_error;
|
|
889
|
+
if (result.error == null) {
|
|
890
|
+
return result.podAdCount > 0 ? "fill" : "no_fill";
|
|
891
|
+
}
|
|
892
|
+
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);
|
|
893
|
+
if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
|
|
894
|
+
return "no_fill";
|
|
895
|
+
}
|
|
896
|
+
return "invalid";
|
|
897
|
+
}
|
|
898
|
+
function describeEdgeUrl(url) {
|
|
899
|
+
try {
|
|
900
|
+
var parsed = new URL(url);
|
|
901
|
+
return "".concat(parsed.origin).concat(parsed.pathname);
|
|
902
|
+
} catch (unused) {
|
|
903
|
+
var _url_split_;
|
|
904
|
+
return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
// src/utils/trackingIngest.ts
|
|
908
|
+
var DEFAULT_TRACKING_INGEST_CONFIG = {
|
|
909
|
+
enabled: true,
|
|
910
|
+
baseUrl: "https://player-analytics-ingest-api-760490581852.us-central1.run.app/api/adstorm/player-tracking"
|
|
911
|
+
};
|
|
912
|
+
var trackingIngestConfig = _object_spread({}, DEFAULT_TRACKING_INGEST_CONFIG);
|
|
913
|
+
function isTrackingIngestEnabled() {
|
|
914
|
+
return trackingIngestConfig.enabled === true;
|
|
915
|
+
}
|
|
916
|
+
function normalizeIngestBaseUrl(baseUrl) {
|
|
917
|
+
return baseUrl.replace(/\/+$/, "");
|
|
918
|
+
}
|
|
919
|
+
function buildTrackingIngestUrl(channel) {
|
|
920
|
+
var base = normalizeIngestBaseUrl(trackingIngestConfig.baseUrl);
|
|
921
|
+
if (channel === "impressions") {
|
|
922
|
+
return "".concat(base, "/impressions/ingest");
|
|
923
|
+
}
|
|
924
|
+
return "".concat(base, "/metrics/ingest");
|
|
925
|
+
}
|
|
926
|
+
function ingestPlayerTracking(licenseKey, channel, body) {
|
|
927
|
+
return _async_to_generator(function() {
|
|
928
|
+
var response, error;
|
|
929
|
+
return _ts_generator(this, function(_state) {
|
|
930
|
+
switch(_state.label){
|
|
931
|
+
case 0:
|
|
932
|
+
if (!isTrackingIngestEnabled() || !licenseKey) {
|
|
933
|
+
return [
|
|
934
|
+
2,
|
|
935
|
+
false
|
|
936
|
+
];
|
|
937
|
+
}
|
|
938
|
+
_state.label = 1;
|
|
939
|
+
case 1:
|
|
940
|
+
_state.trys.push([
|
|
941
|
+
1,
|
|
942
|
+
3,
|
|
943
|
+
,
|
|
944
|
+
4
|
|
945
|
+
]);
|
|
946
|
+
return [
|
|
947
|
+
4,
|
|
948
|
+
fetch(buildTrackingIngestUrl(channel), {
|
|
949
|
+
method: "POST",
|
|
950
|
+
headers: {
|
|
951
|
+
"Content-Type": "application/json",
|
|
952
|
+
Authorization: "License-Key ".concat(licenseKey)
|
|
953
|
+
},
|
|
954
|
+
body: JSON.stringify(body)
|
|
955
|
+
})
|
|
956
|
+
];
|
|
957
|
+
case 2:
|
|
958
|
+
response = _state.sent();
|
|
959
|
+
if (!response.ok) {
|
|
960
|
+
console.warn("[StormcloudVideoPlayer] Tracking ingest failed (".concat(response.status, ") for ").concat(channel));
|
|
961
|
+
return [
|
|
962
|
+
2,
|
|
963
|
+
false
|
|
964
|
+
];
|
|
965
|
+
}
|
|
966
|
+
return [
|
|
967
|
+
2,
|
|
968
|
+
true
|
|
969
|
+
];
|
|
970
|
+
case 3:
|
|
971
|
+
error = _state.sent();
|
|
972
|
+
console.warn("[StormcloudVideoPlayer] Tracking ingest error for ".concat(channel, ":"), error);
|
|
973
|
+
return [
|
|
974
|
+
2,
|
|
975
|
+
false
|
|
976
|
+
];
|
|
977
|
+
case 4:
|
|
978
|
+
return [
|
|
979
|
+
2
|
|
980
|
+
];
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
})();
|
|
984
|
+
}
|
|
810
985
|
// src/utils/tracking.ts
|
|
811
986
|
var cachedBrowserId = null;
|
|
812
987
|
function buildAnalyticsContext(config) {
|
|
@@ -1288,22 +1463,6 @@ function sendHeartbeat(_0) {
|
|
|
1288
1463
|
function getAdAudioVolume(adPlayer) {
|
|
1289
1464
|
return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
|
|
1290
1465
|
}
|
|
1291
|
-
// src/utils/vastMacros.ts
|
|
1292
|
-
var GAM_AD_HOSTS = /* @__PURE__ */ new Set([
|
|
1293
|
-
"pubads.g.doubleclick.net",
|
|
1294
|
-
"securepubads.g.doubleclick.net"
|
|
1295
|
-
]);
|
|
1296
|
-
function ensureVideoAdType(rawUrl) {
|
|
1297
|
-
try {
|
|
1298
|
-
var url = new URL(rawUrl);
|
|
1299
|
-
if (!GAM_AD_HOSTS.has(url.hostname)) return rawUrl;
|
|
1300
|
-
if (url.searchParams.has("ad_type")) return rawUrl;
|
|
1301
|
-
url.searchParams.set("ad_type", "video");
|
|
1302
|
-
return url.toString();
|
|
1303
|
-
} catch (unused) {
|
|
1304
|
-
return rawUrl;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
1466
|
// src/player/AdBreakOrchestrator.ts
|
|
1308
1467
|
var REQUEST_FAILURE_STAGES = /* @__PURE__ */ new Set([
|
|
1309
1468
|
"no_fill",
|
|
@@ -1332,6 +1491,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1332
1491
|
this.controllerCallInFlight = false;
|
|
1333
1492
|
this.playbackStartedForCurrentRequest = false;
|
|
1334
1493
|
this.opportunityEpoch = -1;
|
|
1494
|
+
this.edgeExhaustedForBreak = false;
|
|
1495
|
+
this.edgeRequestsInBreak = 0;
|
|
1335
1496
|
this.adPodQueue = [];
|
|
1336
1497
|
this.defaultMinRemainingMsToRequestAd = 1e4;
|
|
1337
1498
|
this.defaultMaxNoFillsPerBreak = 2;
|
|
@@ -1482,7 +1643,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1482
1643
|
_this.timing.clearAdRequestWatchdog();
|
|
1483
1644
|
_this.timing.activeAdRequestToken = null;
|
|
1484
1645
|
_this.showAds = true;
|
|
1485
|
-
_this.
|
|
1646
|
+
if (_this.currentPodSource !== "edge") {
|
|
1647
|
+
_this.timing.resetGamNoFillCounter();
|
|
1648
|
+
}
|
|
1486
1649
|
if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
|
|
1487
1650
|
_this.timing.scheduleAdStopAtBreakBoundary();
|
|
1488
1651
|
if (_this.debug) {
|
|
@@ -1612,20 +1775,21 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1612
1775
|
},
|
|
1613
1776
|
{
|
|
1614
1777
|
key: "beginVmapBreak",
|
|
1615
|
-
value: function beginVmapBreak(breakKey) {
|
|
1778
|
+
value: function beginVmapBreak(breakKey, position) {
|
|
1616
1779
|
this.breakSource = "vmap";
|
|
1780
|
+
this.resetEdgeStateForBreak();
|
|
1617
1781
|
this.followUpBaseVastUrl = void 0;
|
|
1618
1782
|
this.unusableResponsesInBreak = 0;
|
|
1619
1783
|
this.timing.totalAdRequestsInBreak = 0;
|
|
1620
1784
|
this.setSlotState("NEEDS_NEXT_AD", "vmap_break_start");
|
|
1621
|
-
this.noteOpportunity("vmap", breakKey);
|
|
1785
|
+
this.noteOpportunity("vmap", breakKey, position);
|
|
1622
1786
|
}
|
|
1623
1787
|
},
|
|
1624
1788
|
{
|
|
1625
1789
|
key: "handleAdStart",
|
|
1626
1790
|
value: function handleAdStart(marker) {
|
|
1627
1791
|
return _async_to_generator(function() {
|
|
1628
|
-
var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
|
|
1792
|
+
var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
|
|
1629
1793
|
return _ts_generator(this, function(_state) {
|
|
1630
1794
|
switch(_state.label){
|
|
1631
1795
|
case 0:
|
|
@@ -1639,7 +1803,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1639
1803
|
];
|
|
1640
1804
|
}
|
|
1641
1805
|
baseVastUrl = this.adConfig.apiVastTagUrl;
|
|
1642
|
-
|
|
1806
|
+
edgeConfigured = !!this.host.getEdgePodBaseUrl();
|
|
1807
|
+
if (!baseVastUrl && !edgeConfigured) {
|
|
1643
1808
|
console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
|
|
1644
1809
|
this.clearPendingAdBreak();
|
|
1645
1810
|
return [
|
|
@@ -1655,6 +1820,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1655
1820
|
this.breakSource = "scte35";
|
|
1656
1821
|
this.followUpBaseVastUrl = baseVastUrl;
|
|
1657
1822
|
this.unusableResponsesInBreak = 0;
|
|
1823
|
+
this.resetEdgeStateForBreak();
|
|
1658
1824
|
this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
|
|
1659
1825
|
if (this.adConfig.podAssignedByPrefetch) {
|
|
1660
1826
|
this.adConfig.podAssignedByPrefetch = false;
|
|
@@ -1673,10 +1839,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1673
1839
|
if (this.timing.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
|
|
1674
1840
|
this.timing.expectedAdBreakDurationMs = adBreakDurationMs;
|
|
1675
1841
|
}
|
|
1676
|
-
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey);
|
|
1842
|
+
this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
|
|
1677
1843
|
epoch = this.timing.adBreakEpoch;
|
|
1678
1844
|
hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
|
|
1679
|
-
if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
|
|
1845
|
+
if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
|
|
1680
1846
|
3,
|
|
1681
1847
|
2
|
|
1682
1848
|
];
|
|
@@ -1695,11 +1861,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1695
1861
|
mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
|
|
1696
1862
|
console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
|
|
1697
1863
|
}
|
|
1864
|
+
if (!edgeConfigured) return [
|
|
1865
|
+
3,
|
|
1866
|
+
5
|
|
1867
|
+
];
|
|
1868
|
+
edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
|
|
1869
|
+
if (!edgeUrl) return [
|
|
1870
|
+
3,
|
|
1871
|
+
4
|
|
1872
|
+
];
|
|
1873
|
+
this.clearPendingAdBreak();
|
|
1698
1874
|
return [
|
|
1699
1875
|
4,
|
|
1700
|
-
this.
|
|
1876
|
+
this.runEdgePod(edgeUrl, "edge_break_start")
|
|
1701
1877
|
];
|
|
1702
1878
|
case 3:
|
|
1879
|
+
outcome = _state.sent();
|
|
1880
|
+
this.continueAfterEdgeOutcome(outcome, epoch);
|
|
1881
|
+
return [
|
|
1882
|
+
2
|
|
1883
|
+
];
|
|
1884
|
+
case 4:
|
|
1885
|
+
if (!this.edgeExhaustedForBreak) {
|
|
1886
|
+
this.markEdgeExhausted("not_eligible_at_break_start", {
|
|
1887
|
+
isLive: this.isLiveBreak(),
|
|
1888
|
+
durationMs: this.timing.expectedAdBreakDurationMs
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
_state.label = 5;
|
|
1892
|
+
case 5:
|
|
1893
|
+
if (!baseVastUrl) {
|
|
1894
|
+
this.requestNextAd("no_gam_source");
|
|
1895
|
+
return [
|
|
1896
|
+
2
|
|
1897
|
+
];
|
|
1898
|
+
}
|
|
1899
|
+
return [
|
|
1900
|
+
4,
|
|
1901
|
+
this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
|
|
1902
|
+
];
|
|
1903
|
+
case 6:
|
|
1703
1904
|
podPlayed = _state.sent();
|
|
1704
1905
|
if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
|
|
1705
1906
|
this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
|
|
@@ -1767,7 +1968,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1767
1968
|
// ───────────────────────────────────────────────────────────────
|
|
1768
1969
|
function startOptimizedPod(baseVastUrl, breakDurationMs) {
|
|
1769
1970
|
return _async_to_generator(function() {
|
|
1770
|
-
var podUrl, prefetched, epoch, generation, adPlayer, requestToken, _ref, _adPlayer_getPodAdCount, podCount, error;
|
|
1971
|
+
var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
|
|
1771
1972
|
return _ts_generator(this, function(_state) {
|
|
1772
1973
|
switch(_state.label){
|
|
1773
1974
|
case 0:
|
|
@@ -1791,9 +1992,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1791
1992
|
adPlayer = this.host.getAdPlayer();
|
|
1792
1993
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
1793
1994
|
this.timing.activeAdRequestToken = requestToken;
|
|
1794
|
-
this.
|
|
1995
|
+
this.currentPodSource = "gam";
|
|
1795
1996
|
this.setSlotState("REQUESTING", "initial_pod");
|
|
1796
1997
|
this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
|
|
1998
|
+
requestUrl = this.applyOpportunityFloor(podUrl);
|
|
1999
|
+
this.currentVastUrl = requestUrl;
|
|
1797
2000
|
_state.label = 1;
|
|
1798
2001
|
case 1:
|
|
1799
2002
|
_state.trys.push([
|
|
@@ -1816,7 +2019,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1816
2019
|
return [
|
|
1817
2020
|
4,
|
|
1818
2021
|
this.callController(function() {
|
|
1819
|
-
return adPlayer.requestAds(
|
|
2022
|
+
return adPlayer.requestAds(requestUrl);
|
|
1820
2023
|
})
|
|
1821
2024
|
];
|
|
1822
2025
|
case 3:
|
|
@@ -1848,7 +2051,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1848
2051
|
}
|
|
1849
2052
|
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
1850
2053
|
source: "hls",
|
|
1851
|
-
vastUrl:
|
|
2054
|
+
vastUrl: requestUrl,
|
|
1852
2055
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1853
2056
|
}, this.analyticsContext).catch(function() {});
|
|
1854
2057
|
this.timing.startAdFailsafeTimer(requestToken);
|
|
@@ -1906,6 +2109,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1906
2109
|
}).call(this);
|
|
1907
2110
|
}
|
|
1908
2111
|
},
|
|
2112
|
+
{
|
|
2113
|
+
// ───────────────────────────────────────────────────────────────
|
|
2114
|
+
// Edge-first pods (live SCTE-35 only, GAM fallback)
|
|
2115
|
+
// ───────────────────────────────────────────────────────────────
|
|
2116
|
+
key: "resetEdgeStateForBreak",
|
|
2117
|
+
value: function resetEdgeStateForBreak() {
|
|
2118
|
+
this.edgeExhaustedForBreak = false;
|
|
2119
|
+
this.edgeRequestsInBreak = 0;
|
|
2120
|
+
this.currentPodSource = void 0;
|
|
2121
|
+
}
|
|
2122
|
+
},
|
|
2123
|
+
{
|
|
2124
|
+
key: "isLiveBreak",
|
|
2125
|
+
value: function isLiveBreak() {
|
|
2126
|
+
return this.host.isLiveStream() || this.host.config.isLiveStream === true;
|
|
2127
|
+
}
|
|
2128
|
+
},
|
|
2129
|
+
{
|
|
2130
|
+
key: "canRequestEdge",
|
|
2131
|
+
value: function canRequestEdge() {
|
|
2132
|
+
return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
|
|
2133
|
+
}
|
|
2134
|
+
},
|
|
2135
|
+
{
|
|
2136
|
+
key: "markEdgeExhausted",
|
|
2137
|
+
value: function markEdgeExhausted(reason) {
|
|
2138
|
+
var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
2139
|
+
this.edgeExhaustedForBreak = true;
|
|
2140
|
+
this.countFunnelStage("edge_fallback:".concat(reason));
|
|
2141
|
+
this.logOrchestratorFunnel("edge_exhausted", _object_spread({
|
|
2142
|
+
reason: reason,
|
|
2143
|
+
edgeRequests: this.edgeRequestsInBreak,
|
|
2144
|
+
remainingMs: this.timing.getRemainingAdMs()
|
|
2145
|
+
}, extra));
|
|
2146
|
+
}
|
|
2147
|
+
},
|
|
2148
|
+
{
|
|
2149
|
+
/**
|
|
2150
|
+
* Builds the next Edge request from the budget left right now, or marks Edge
|
|
2151
|
+
* exhausted for this break. Synchronous on purpose: callers must reach the
|
|
2152
|
+
* REQUESTING state in the same tick so a second completion event cannot race
|
|
2153
|
+
* in a parallel request.
|
|
2154
|
+
*/ key: "prepareEdgePodRequest",
|
|
2155
|
+
value: function prepareEdgePodRequest() {
|
|
2156
|
+
var baseUrl = this.host.getEdgePodBaseUrl();
|
|
2157
|
+
if (!baseUrl) return void 0;
|
|
2158
|
+
var remainingMs = this.timing.getRemainingAdMs();
|
|
2159
|
+
var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
|
|
2160
|
+
if (remainingAds < 1) {
|
|
2161
|
+
this.markEdgeExhausted("ad_capacity_reached", {
|
|
2162
|
+
adsInBreak: this.timing.totalAdsInBreak
|
|
2163
|
+
});
|
|
2164
|
+
return void 0;
|
|
2165
|
+
}
|
|
2166
|
+
if (remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
2167
|
+
this.markEdgeExhausted("insufficient_break_time", {
|
|
2168
|
+
remainingMs: remainingMs
|
|
2169
|
+
});
|
|
2170
|
+
return void 0;
|
|
2171
|
+
}
|
|
2172
|
+
try {
|
|
2173
|
+
return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
|
|
2174
|
+
} catch (unused) {
|
|
2175
|
+
this.markEdgeExhausted("invalid_edge_url");
|
|
2176
|
+
return void 0;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
key: "runEdgePod",
|
|
2182
|
+
value: function runEdgePod(requestUrl, trigger) {
|
|
2183
|
+
return _async_to_generator(function() {
|
|
2184
|
+
var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
|
|
2185
|
+
return _ts_generator(this, function(_state) {
|
|
2186
|
+
switch(_state.label){
|
|
2187
|
+
case 0:
|
|
2188
|
+
epoch = this.timing.adBreakEpoch;
|
|
2189
|
+
this.recreateAdController("new_request");
|
|
2190
|
+
generation = this.controllerGeneration;
|
|
2191
|
+
adPlayer = this.host.getAdPlayer();
|
|
2192
|
+
requestToken = ++this.timing.adRequestTokenCounter;
|
|
2193
|
+
this.timing.activeAdRequestToken = requestToken;
|
|
2194
|
+
this.currentPodSource = "edge";
|
|
2195
|
+
this.edgeRequestsInBreak++;
|
|
2196
|
+
this.setSlotState("REQUESTING", trigger);
|
|
2197
|
+
this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
|
|
2198
|
+
this.currentVastUrl = requestUrl;
|
|
2199
|
+
params = new URL(requestUrl).searchParams;
|
|
2200
|
+
this.logOrchestratorFunnel("edge_request_sent", {
|
|
2201
|
+
trigger: trigger,
|
|
2202
|
+
attempt: this.edgeRequestsInBreak,
|
|
2203
|
+
endpoint: describeEdgeUrl(requestUrl),
|
|
2204
|
+
pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
|
|
2205
|
+
pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
|
|
2206
|
+
});
|
|
2207
|
+
_state.label = 1;
|
|
2208
|
+
case 1:
|
|
2209
|
+
_state.trys.push([
|
|
2210
|
+
1,
|
|
2211
|
+
4,
|
|
2212
|
+
,
|
|
2213
|
+
5
|
|
2214
|
+
]);
|
|
2215
|
+
this.timing.startAdRequestWatchdog(requestToken);
|
|
2216
|
+
return [
|
|
2217
|
+
4,
|
|
2218
|
+
this.callController(function() {
|
|
2219
|
+
return adPlayer.requestAds(requestUrl, {
|
|
2220
|
+
source: "edge"
|
|
2221
|
+
});
|
|
2222
|
+
})
|
|
2223
|
+
];
|
|
2224
|
+
case 2:
|
|
2225
|
+
_state.sent();
|
|
2226
|
+
this.timing.clearAdRequestWatchdog();
|
|
2227
|
+
if (this.isStale(epoch, generation)) {
|
|
2228
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
2229
|
+
requestId: requestToken,
|
|
2230
|
+
source: "edge"
|
|
2231
|
+
});
|
|
2232
|
+
return [
|
|
2233
|
+
2,
|
|
2234
|
+
"stale"
|
|
2235
|
+
];
|
|
2236
|
+
}
|
|
2237
|
+
remainingMs = this.timing.getRemainingAdMs();
|
|
2238
|
+
remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
|
|
2239
|
+
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;
|
|
2240
|
+
if (classifyEdgeVastResponse({
|
|
2241
|
+
podAdCount: podCount
|
|
2242
|
+
}) !== "fill") {
|
|
2243
|
+
throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
|
|
2244
|
+
}
|
|
2245
|
+
this.setSlotState("READY", "edge_vast_ready");
|
|
2246
|
+
this.logOrchestratorFunnel("edge_fill", {
|
|
2247
|
+
podAdCount: podCount,
|
|
2248
|
+
podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
|
|
2249
|
+
remainingMs: remainingMs
|
|
2250
|
+
});
|
|
2251
|
+
sendAdLoadedTracking(this.host.config.licenseKey, {
|
|
2252
|
+
source: "hls",
|
|
2253
|
+
vastUrl: requestUrl,
|
|
2254
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2255
|
+
}, this.analyticsContext).catch(function() {});
|
|
2256
|
+
this.timing.startAdFailsafeTimer(requestToken);
|
|
2257
|
+
return [
|
|
2258
|
+
4,
|
|
2259
|
+
this.callController(function() {
|
|
2260
|
+
return adPlayer.play();
|
|
2261
|
+
})
|
|
2262
|
+
];
|
|
2263
|
+
case 3:
|
|
2264
|
+
_state.sent();
|
|
2265
|
+
if (this.isStale(epoch, generation)) return [
|
|
2266
|
+
2,
|
|
2267
|
+
"stale"
|
|
2268
|
+
];
|
|
2269
|
+
if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
|
|
2270
|
+
this.timing.scheduleAdStopAtBreakBoundary();
|
|
2271
|
+
}
|
|
2272
|
+
adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
|
|
2273
|
+
return [
|
|
2274
|
+
2,
|
|
2275
|
+
"fill"
|
|
2276
|
+
];
|
|
2277
|
+
case 4:
|
|
2278
|
+
error = _state.sent();
|
|
2279
|
+
this.timing.clearAdRequestWatchdog();
|
|
2280
|
+
this.timing.clearAdFailsafeTimer();
|
|
2281
|
+
if (this.timing.activeAdRequestToken === requestToken) {
|
|
2282
|
+
this.timing.activeAdRequestToken = null;
|
|
2283
|
+
}
|
|
2284
|
+
errorMessage = error === null || error === void 0 ? void 0 : error.message;
|
|
2285
|
+
if (this.isStale(epoch, generation)) {
|
|
2286
|
+
this.logOrchestratorFunnel("stale_request_result_ignored", {
|
|
2287
|
+
requestId: requestToken,
|
|
2288
|
+
source: "edge",
|
|
2289
|
+
errorMessage: errorMessage
|
|
2290
|
+
});
|
|
2291
|
+
return [
|
|
2292
|
+
2,
|
|
2293
|
+
"stale"
|
|
2294
|
+
];
|
|
2295
|
+
}
|
|
2296
|
+
classification = classifyEdgeVastResponse({
|
|
2297
|
+
podAdCount: 0,
|
|
2298
|
+
error: error
|
|
2299
|
+
});
|
|
2300
|
+
diag = this.requestDiagnostics.get(requestToken);
|
|
2301
|
+
if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
|
|
2302
|
+
this.markEdgeExhausted("edge_".concat(classification), {
|
|
2303
|
+
errorMessage: errorMessage
|
|
2304
|
+
});
|
|
2305
|
+
return [
|
|
2306
|
+
2,
|
|
2307
|
+
"fallback"
|
|
2308
|
+
];
|
|
2309
|
+
case 5:
|
|
2310
|
+
return [
|
|
2311
|
+
2
|
|
2312
|
+
];
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
}).call(this);
|
|
2316
|
+
}
|
|
2317
|
+
},
|
|
2318
|
+
{
|
|
2319
|
+
key: "continueAfterEdgeOutcome",
|
|
2320
|
+
value: function continueAfterEdgeOutcome(outcome, epoch) {
|
|
2321
|
+
if (outcome !== "fallback") return;
|
|
2322
|
+
if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
|
|
2323
|
+
if (this.debug) {
|
|
2324
|
+
console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
|
|
2325
|
+
}
|
|
2326
|
+
this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
|
|
2327
|
+
this.requestNextAd("edge_fallback");
|
|
2328
|
+
}
|
|
2329
|
+
},
|
|
1909
2330
|
{
|
|
1910
2331
|
// ───────────────────────────────────────────────────────────────
|
|
1911
2332
|
// Next-ad scheduling (single flight)
|
|
@@ -1961,7 +2382,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1961
2382
|
value: function getStopRequestingReason(remainingMs) {
|
|
1962
2383
|
if (this.breakSource === "vmap") {
|
|
1963
2384
|
if (this.adPodQueue.length === 0) return "vmap_queue_empty";
|
|
1964
|
-
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
|
|
2385
|
+
} else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
|
|
1965
2386
|
return "no_follow_up_source";
|
|
1966
2387
|
}
|
|
1967
2388
|
if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
|
|
@@ -1973,7 +2394,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
1973
2394
|
if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
|
|
1974
2395
|
return "request_cap";
|
|
1975
2396
|
}
|
|
1976
|
-
if (this.timing.isGamInCooldown()) {
|
|
2397
|
+
if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
|
|
1977
2398
|
return "gam_cooldown";
|
|
1978
2399
|
}
|
|
1979
2400
|
if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
|
|
@@ -2067,10 +2488,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2067
2488
|
key: "requestFollowUpAd",
|
|
2068
2489
|
value: function requestFollowUpAd(trigger) {
|
|
2069
2490
|
return _async_to_generator(function() {
|
|
2070
|
-
var url, epoch, unused;
|
|
2491
|
+
var edgeUrl, epoch2, outcome, url, epoch, unused;
|
|
2071
2492
|
return _ts_generator(this, function(_state) {
|
|
2072
2493
|
switch(_state.label){
|
|
2073
2494
|
case 0:
|
|
2495
|
+
if (!this.canRequestEdge()) return [
|
|
2496
|
+
3,
|
|
2497
|
+
2
|
|
2498
|
+
];
|
|
2499
|
+
edgeUrl = this.prepareEdgePodRequest();
|
|
2500
|
+
if (!edgeUrl) {
|
|
2501
|
+
this.requestNextAd("".concat(trigger, ":edge_unavailable"));
|
|
2502
|
+
return [
|
|
2503
|
+
2
|
|
2504
|
+
];
|
|
2505
|
+
}
|
|
2506
|
+
epoch2 = this.timing.adBreakEpoch;
|
|
2507
|
+
return [
|
|
2508
|
+
4,
|
|
2509
|
+
this.runEdgePod(edgeUrl, "edge_".concat(trigger))
|
|
2510
|
+
];
|
|
2511
|
+
case 1:
|
|
2512
|
+
outcome = _state.sent();
|
|
2513
|
+
this.continueAfterEdgeOutcome(outcome, epoch2);
|
|
2514
|
+
return [
|
|
2515
|
+
2
|
|
2516
|
+
];
|
|
2517
|
+
case 2:
|
|
2074
2518
|
if (this.breakSource === "vmap") {
|
|
2075
2519
|
url = this.adPodQueue.shift();
|
|
2076
2520
|
} else if (this.followUpBaseVastUrl) {
|
|
@@ -2081,32 +2525,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2081
2525
|
];
|
|
2082
2526
|
this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
|
|
2083
2527
|
epoch = this.timing.adBreakEpoch;
|
|
2084
|
-
_state.label =
|
|
2085
|
-
case
|
|
2528
|
+
_state.label = 3;
|
|
2529
|
+
case 3:
|
|
2086
2530
|
_state.trys.push([
|
|
2087
|
-
1,
|
|
2088
2531
|
3,
|
|
2532
|
+
5,
|
|
2089
2533
|
,
|
|
2090
|
-
|
|
2534
|
+
6
|
|
2091
2535
|
]);
|
|
2092
2536
|
return [
|
|
2093
2537
|
4,
|
|
2094
2538
|
this.playSingleAd(url, trigger)
|
|
2095
2539
|
];
|
|
2096
|
-
case
|
|
2540
|
+
case 4:
|
|
2097
2541
|
_state.sent();
|
|
2098
2542
|
return [
|
|
2099
2543
|
3,
|
|
2100
|
-
|
|
2544
|
+
6
|
|
2101
2545
|
];
|
|
2102
|
-
case
|
|
2546
|
+
case 5:
|
|
2103
2547
|
unused = _state.sent();
|
|
2104
2548
|
this.continueAfterRequestFailure(epoch);
|
|
2105
2549
|
return [
|
|
2106
2550
|
3,
|
|
2107
|
-
|
|
2551
|
+
6
|
|
2108
2552
|
];
|
|
2109
|
-
case
|
|
2553
|
+
case 6:
|
|
2110
2554
|
return [
|
|
2111
2555
|
2
|
|
2112
2556
|
];
|
|
@@ -2195,12 +2639,14 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2195
2639
|
this.timing.failedVastUrls.add(vastTagUrl);
|
|
2196
2640
|
}
|
|
2197
2641
|
this.countFunnelStage("request_outcome:".concat(outcome));
|
|
2198
|
-
this.logOrchestratorFunnel("request_outcome", {
|
|
2642
|
+
this.logOrchestratorFunnel("request_outcome", _object_spread({
|
|
2199
2643
|
outcome: outcome,
|
|
2200
2644
|
errorMessage: message,
|
|
2201
2645
|
consecutiveFailures: this.timing.consecutiveFailures,
|
|
2202
|
-
unusableResponsesInBreak: this.unusableResponsesInBreak
|
|
2203
|
-
|
|
2646
|
+
unusableResponsesInBreak: this.unusableResponsesInBreak,
|
|
2647
|
+
vastAdCount: diag === null || diag === void 0 ? void 0 : diag.vastAdCount,
|
|
2648
|
+
impressionCount: diag === null || diag === void 0 ? void 0 : diag.impressionCount
|
|
2649
|
+
}, this.requestFloorFields(diag)));
|
|
2204
2650
|
}
|
|
2205
2651
|
},
|
|
2206
2652
|
{
|
|
@@ -2217,7 +2663,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2217
2663
|
case "gam_http_request_sent":
|
|
2218
2664
|
diag.gamRequestSent++;
|
|
2219
2665
|
break;
|
|
2666
|
+
case "edge_http_request_sent":
|
|
2667
|
+
diag.edgeRequestSent++;
|
|
2668
|
+
break;
|
|
2220
2669
|
case "gam_response_received":
|
|
2670
|
+
case "edge_response_received":
|
|
2221
2671
|
diag.vastHttpStatus = payload.httpStatus;
|
|
2222
2672
|
break;
|
|
2223
2673
|
case "vast_parsed":
|
|
@@ -2239,6 +2689,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2239
2689
|
break;
|
|
2240
2690
|
case "impression_fired":
|
|
2241
2691
|
diag.impressionFired = true;
|
|
2692
|
+
diag.impressionCount++;
|
|
2242
2693
|
break;
|
|
2243
2694
|
default:
|
|
2244
2695
|
if (REQUEST_FAILURE_STAGES.has(payload.stage) && !diag.failureReason) {
|
|
@@ -2295,6 +2746,67 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2295
2746
|
}
|
|
2296
2747
|
}
|
|
2297
2748
|
},
|
|
2749
|
+
{
|
|
2750
|
+
key: "opportunityFloorFields",
|
|
2751
|
+
value: function opportunityFloorFields() {
|
|
2752
|
+
var floor = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : this.opportunityFloor;
|
|
2753
|
+
if (!floor) return {};
|
|
2754
|
+
return {
|
|
2755
|
+
floorStatus: floor.status,
|
|
2756
|
+
floorCents: floor.floorCents,
|
|
2757
|
+
floorSource: floor.source,
|
|
2758
|
+
floorReason: floor.reason,
|
|
2759
|
+
floorSelector: floor.selector,
|
|
2760
|
+
floorConfigVersion: floor.configurationVersion,
|
|
2761
|
+
adPosition: floor.position
|
|
2762
|
+
};
|
|
2763
|
+
}
|
|
2764
|
+
},
|
|
2765
|
+
{
|
|
2766
|
+
key: "requestFloorFields",
|
|
2767
|
+
value: function requestFloorFields(diag) {
|
|
2768
|
+
if (!diag || diag.floorApplied === void 0) return {};
|
|
2769
|
+
return {
|
|
2770
|
+
floorApplied: diag.floorApplied,
|
|
2771
|
+
floorCents: diag.floorCents,
|
|
2772
|
+
floorSource: diag.floorSource,
|
|
2773
|
+
floorReason: diag.floorReason,
|
|
2774
|
+
floorConfigVersion: diag.floorConfigVersion
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
key: "applyOpportunityFloor",
|
|
2780
|
+
value: function applyOpportunityFloor(url) {
|
|
2781
|
+
var floor = this.opportunityFloor;
|
|
2782
|
+
if (!floor) return url;
|
|
2783
|
+
var result = applyFloorToVastUrl(url, floor);
|
|
2784
|
+
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
2785
|
+
if (diag) {
|
|
2786
|
+
diag.floorApplied = result.applied;
|
|
2787
|
+
if (result.applied && floor.floorCents != null) diag.floorCents = floor.floorCents;
|
|
2788
|
+
diag.floorSource = result.applied ? floor.source : "none";
|
|
2789
|
+
if (result.reason) diag.floorReason = result.reason;
|
|
2790
|
+
diag.floorConfigVersion = floor.configurationVersion;
|
|
2791
|
+
}
|
|
2792
|
+
if (floor.status === "skipped" && floor.reason === "disabled") {
|
|
2793
|
+
this.countFunnelStage("floor_skipped:disabled");
|
|
2794
|
+
return result.url;
|
|
2795
|
+
}
|
|
2796
|
+
this.logOrchestratorFunnel(result.applied ? "floor_applied" : "floor_skipped", {
|
|
2797
|
+
reason: result.reason,
|
|
2798
|
+
floorCents: result.applied ? floor.floorCents : void 0,
|
|
2799
|
+
floorSource: result.applied ? floor.source : "none",
|
|
2800
|
+
floorSelector: floor.selector,
|
|
2801
|
+
floorConfigVersion: floor.configurationVersion,
|
|
2802
|
+
adPosition: floor.position
|
|
2803
|
+
});
|
|
2804
|
+
if (!result.applied && result.reason) {
|
|
2805
|
+
this.countFunnelStage("floor_skipped:".concat(result.reason));
|
|
2806
|
+
}
|
|
2807
|
+
return result.url;
|
|
2808
|
+
}
|
|
2809
|
+
},
|
|
2298
2810
|
{
|
|
2299
2811
|
key: "countFunnelStage",
|
|
2300
2812
|
value: function countFunnelStage(stage) {
|
|
@@ -2317,7 +2829,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2317
2829
|
},
|
|
2318
2830
|
{
|
|
2319
2831
|
key: "noteOpportunity",
|
|
2320
|
-
value: function noteOpportunity(source, breakKey) {
|
|
2832
|
+
value: function noteOpportunity(source, breakKey, position) {
|
|
2321
2833
|
if (breakKey && breakKey === this.opportunityBreakKey && this.opportunityEpoch === this.timing.adBreakEpoch) {
|
|
2322
2834
|
this.logOrchestratorFunnel("duplicate_break_start", {
|
|
2323
2835
|
source: source,
|
|
@@ -2327,16 +2839,22 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2327
2839
|
}
|
|
2328
2840
|
this.opportunityBreakKey = breakKey;
|
|
2329
2841
|
this.opportunityEpoch = this.timing.adBreakEpoch;
|
|
2330
|
-
|
|
2842
|
+
try {
|
|
2843
|
+
this.opportunityFloor = this.host.getFloorSnapshot(position);
|
|
2844
|
+
} catch (unused) {
|
|
2845
|
+
this.opportunityFloor = void 0;
|
|
2846
|
+
}
|
|
2847
|
+
this.logOrchestratorFunnel("opportunity_created", _object_spread({
|
|
2331
2848
|
source: source,
|
|
2332
2849
|
breakKey: breakKey,
|
|
2333
2850
|
expectedDurationMs: this.timing.expectedAdBreakDurationMs
|
|
2334
|
-
});
|
|
2851
|
+
}, this.opportunityFloorFields()));
|
|
2335
2852
|
}
|
|
2336
2853
|
},
|
|
2337
2854
|
{
|
|
2338
2855
|
key: "beginFunnelRequest",
|
|
2339
2856
|
value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
|
|
2857
|
+
var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
|
|
2340
2858
|
var _adPlayer_setFunnelContext;
|
|
2341
2859
|
if (this.controllerCallInFlight) {
|
|
2342
2860
|
this.logOrchestratorFunnel("duplicate_request_detected", {
|
|
@@ -2351,13 +2869,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2351
2869
|
requestId: requestToken,
|
|
2352
2870
|
controllerId: this.controllerGeneration,
|
|
2353
2871
|
trigger: trigger,
|
|
2872
|
+
source: source,
|
|
2354
2873
|
gamRequestSent: 0,
|
|
2874
|
+
edgeRequestSent: 0,
|
|
2355
2875
|
wrapperDepth: 0,
|
|
2356
2876
|
inlineResolved: false,
|
|
2357
2877
|
mediaCandidateCount: 0,
|
|
2358
2878
|
supportedMediaCount: 0,
|
|
2359
2879
|
playStarted: false,
|
|
2360
2880
|
impressionFired: false,
|
|
2881
|
+
impressionCount: 0,
|
|
2361
2882
|
startedAt: Date.now()
|
|
2362
2883
|
});
|
|
2363
2884
|
(_adPlayer_setFunnelContext = adPlayer.setFunnelContext) === null || _adPlayer_setFunnelContext === void 0 ? void 0 : _adPlayer_setFunnelContext.call(adPlayer, {
|
|
@@ -2442,7 +2963,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2442
2963
|
value: function playSingleAd(vastTagUrl) {
|
|
2443
2964
|
var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
|
|
2444
2965
|
return _async_to_generator(function() {
|
|
2445
|
-
var epoch, generation, requestToken, ap, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
|
|
2966
|
+
var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
|
|
2446
2967
|
return _ts_generator(this, function(_state) {
|
|
2447
2968
|
switch(_state.label){
|
|
2448
2969
|
case 0:
|
|
@@ -2480,10 +3001,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2480
3001
|
requestToken = ++this.timing.adRequestTokenCounter;
|
|
2481
3002
|
this.timing.activeAdRequestToken = requestToken;
|
|
2482
3003
|
ap = this.host.getAdPlayer();
|
|
2483
|
-
|
|
2484
|
-
this.
|
|
3004
|
+
budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
|
|
3005
|
+
this.currentPodSource = "gam";
|
|
2485
3006
|
this.setSlotState("REQUESTING", trigger);
|
|
2486
3007
|
this.beginFunnelRequest(ap, requestToken, trigger);
|
|
3008
|
+
requestUrl = this.applyOpportunityFloor(budgetedUrl);
|
|
3009
|
+
this.currentVastUrl = requestUrl;
|
|
2487
3010
|
_state.label = 1;
|
|
2488
3011
|
case 1:
|
|
2489
3012
|
_state.trys.push([
|
|
@@ -2616,14 +3139,21 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2616
3139
|
endReason: endReason
|
|
2617
3140
|
});
|
|
2618
3141
|
}
|
|
2619
|
-
console.log("[AdBreak][FUNNEL] Break summary", {
|
|
3142
|
+
console.log("[AdBreak][FUNNEL] Break summary", _object_spread_props(_object_spread({
|
|
2620
3143
|
breakId: breakId,
|
|
2621
3144
|
endReason: endReason,
|
|
2622
|
-
opportunities: count("opportunity_created")
|
|
3145
|
+
opportunities: count("opportunity_created")
|
|
3146
|
+
}, this.opportunityFloorFields()), {
|
|
3147
|
+
floorAppliedRequests: count("floor_applied"),
|
|
3148
|
+
floorSkippedRequests: count("floor_skipped") + count("floor_skipped:disabled"),
|
|
2623
3149
|
vastUrlsGenerated: count("vast_url_generated"),
|
|
2624
3150
|
requests: requests,
|
|
2625
3151
|
requestRetries: requestRetries,
|
|
2626
3152
|
gamResponses: count("gam_response_received"),
|
|
3153
|
+
edgeRequests: count("edge_request_sent"),
|
|
3154
|
+
edgeFills: count("edge_fill"),
|
|
3155
|
+
edgeEmptySentinels: count("edge_empty_sentinel"),
|
|
3156
|
+
edgeFallbacks: countPrefix("edge_fallback:"),
|
|
2627
3157
|
requestsSuppressed: count("request_suppressed"),
|
|
2628
3158
|
duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
|
|
2629
3159
|
filled: count("vast_received"),
|
|
@@ -2671,7 +3201,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2671
3201
|
visibilityHidden: count("while_hidden"),
|
|
2672
3202
|
playbackFailures: count("play_failed") + count("media_error") + count("hls_fatal") + count("stall") + count("decode_failure") + count("media_unsupported"),
|
|
2673
3203
|
stages: funnel
|
|
2674
|
-
});
|
|
3204
|
+
}));
|
|
2675
3205
|
}
|
|
2676
3206
|
},
|
|
2677
3207
|
{
|
|
@@ -2720,8 +3250,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
2720
3250
|
this.breakSource = void 0;
|
|
2721
3251
|
this.followUpBaseVastUrl = void 0;
|
|
2722
3252
|
this.unusableResponsesInBreak = 0;
|
|
3253
|
+
this.resetEdgeStateForBreak();
|
|
2723
3254
|
adPlayer.stop().catch(function() {});
|
|
2724
3255
|
if (!alreadyEnded) this.logBreakFunnel(reason);
|
|
3256
|
+
this.opportunityFloor = void 0;
|
|
2725
3257
|
this.setSlotState("IDLE", "break_complete");
|
|
2726
3258
|
var restoredMuted = this.host.getAdPlayer().getOriginalMutedState();
|
|
2727
3259
|
var restoredVolume = this.host.getAdPlayer().getOriginalVolume();
|
|
@@ -3032,7 +3564,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
3032
3564
|
});
|
|
3033
3565
|
return;
|
|
3034
3566
|
}
|
|
3035
|
-
this.
|
|
3567
|
+
if (this.currentPodSource === "edge") {
|
|
3568
|
+
this.markEdgeExhausted("edge_playback_failed", {
|
|
3569
|
+
reason: reason
|
|
3570
|
+
});
|
|
3571
|
+
} else {
|
|
3572
|
+
this.timing.consecutiveFailures++;
|
|
3573
|
+
}
|
|
3036
3574
|
var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
|
|
3037
3575
|
if (diag && !diag.failureReason) diag.failureReason = reason;
|
|
3038
3576
|
if (this.debug) {
|