stormcloud-video-player 0.2.24 → 0.2.25
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/index.cjs +256 -32
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +10 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +256 -32
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +256 -32
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +7 -1
- package/lib/players/HlsPlayer.cjs +256 -32
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +256 -32
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +87 -10
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/sdk/ima.cjs +87 -19
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/sdk/ima.d.cts +1 -1
- package/lib/{types-D1xfSdLP.d.cts → types-9_2sbHCg.d.cts} +4 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +256 -32
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +1 -1
package/lib/index.cjs
CHANGED
|
@@ -267,6 +267,8 @@ function createImaController(video, options) {
|
|
|
267
267
|
let adPlaying = false;
|
|
268
268
|
let originalMutedState = false;
|
|
269
269
|
const listeners = /* @__PURE__ */ new Map();
|
|
270
|
+
const preloadedVast = /* @__PURE__ */ new Map();
|
|
271
|
+
const preloadingVast = /* @__PURE__ */ new Map();
|
|
270
272
|
function setAdPlayingFlag(isPlaying) {
|
|
271
273
|
if (isPlaying) {
|
|
272
274
|
video.dataset.stormcloudAdPlaying = "true";
|
|
@@ -357,7 +359,15 @@ function createImaController(video, options) {
|
|
|
357
359
|
let adsLoadedReject;
|
|
358
360
|
function makeAdsRequest(google, vastTagUrl) {
|
|
359
361
|
const adsRequest = new google.ima.AdsRequest();
|
|
360
|
-
|
|
362
|
+
const preloadedResponse = preloadedVast.get(vastTagUrl);
|
|
363
|
+
if (preloadedResponse) {
|
|
364
|
+
adsRequest.adsResponse = preloadedResponse;
|
|
365
|
+
console.log(
|
|
366
|
+
"[IMA] Using preloaded VAST response for immediate ad request"
|
|
367
|
+
);
|
|
368
|
+
} else {
|
|
369
|
+
adsRequest.adTagUrl = vastTagUrl;
|
|
370
|
+
}
|
|
361
371
|
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
362
372
|
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
363
373
|
adsRequest.linearAdSlotWidth = videoWidth;
|
|
@@ -367,6 +377,36 @@ function createImaController(video, options) {
|
|
|
367
377
|
adsRequest.vastLoadTimeout = 5e3;
|
|
368
378
|
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
369
379
|
adsLoader.requestAds(adsRequest);
|
|
380
|
+
if (preloadedResponse) {
|
|
381
|
+
preloadedVast.delete(vastTagUrl);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function ensurePlaceholderContainer() {
|
|
385
|
+
var _a;
|
|
386
|
+
if (adContainerEl) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const container = document.createElement("div");
|
|
390
|
+
container.style.position = "absolute";
|
|
391
|
+
container.style.left = "0";
|
|
392
|
+
container.style.top = "0";
|
|
393
|
+
container.style.right = "0";
|
|
394
|
+
container.style.bottom = "0";
|
|
395
|
+
container.style.display = "none";
|
|
396
|
+
container.style.alignItems = "center";
|
|
397
|
+
container.style.justifyContent = "center";
|
|
398
|
+
container.style.pointerEvents = "none";
|
|
399
|
+
container.style.zIndex = "10";
|
|
400
|
+
container.style.backgroundColor = "#000";
|
|
401
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
402
|
+
adContainerEl = container;
|
|
403
|
+
}
|
|
404
|
+
async function fetchVastDocument(vastTagUrl) {
|
|
405
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
406
|
+
if (!response.ok) {
|
|
407
|
+
throw new Error(`Failed to preload VAST: ${response.status}`);
|
|
408
|
+
}
|
|
409
|
+
return response.text();
|
|
370
410
|
}
|
|
371
411
|
function destroyAdsManager() {
|
|
372
412
|
if (adsManager) {
|
|
@@ -382,29 +422,16 @@ function createImaController(video, options) {
|
|
|
382
422
|
return {
|
|
383
423
|
initialize() {
|
|
384
424
|
ensureImaLoaded().then(() => {
|
|
385
|
-
var _a
|
|
425
|
+
var _a;
|
|
386
426
|
const google = window.google;
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
container.style.position = "absolute";
|
|
390
|
-
container.style.left = "0";
|
|
391
|
-
container.style.top = "0";
|
|
392
|
-
container.style.right = "0";
|
|
393
|
-
container.style.bottom = "0";
|
|
394
|
-
container.style.display = "none";
|
|
395
|
-
container.style.alignItems = "center";
|
|
396
|
-
container.style.justifyContent = "center";
|
|
397
|
-
container.style.pointerEvents = "none";
|
|
398
|
-
container.style.zIndex = "10";
|
|
399
|
-
container.style.backgroundColor = "#000";
|
|
400
|
-
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
401
|
-
adContainerEl = container;
|
|
427
|
+
ensurePlaceholderContainer();
|
|
428
|
+
if (!adDisplayContainer && adContainerEl) {
|
|
402
429
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
403
|
-
|
|
430
|
+
adContainerEl,
|
|
404
431
|
video
|
|
405
432
|
);
|
|
406
433
|
try {
|
|
407
|
-
(
|
|
434
|
+
(_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
|
|
408
435
|
} catch {
|
|
409
436
|
}
|
|
410
437
|
}
|
|
@@ -708,6 +735,32 @@ function createImaController(video, options) {
|
|
|
708
735
|
return Promise.reject(error);
|
|
709
736
|
}
|
|
710
737
|
},
|
|
738
|
+
async preloadAds(vastTagUrl) {
|
|
739
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
740
|
+
return Promise.resolve();
|
|
741
|
+
}
|
|
742
|
+
if (preloadedVast.has(vastTagUrl)) {
|
|
743
|
+
return Promise.resolve();
|
|
744
|
+
}
|
|
745
|
+
const inflight = preloadingVast.get(vastTagUrl);
|
|
746
|
+
if (inflight) {
|
|
747
|
+
return inflight;
|
|
748
|
+
}
|
|
749
|
+
const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {
|
|
750
|
+
preloadedVast.set(vastTagUrl, xml);
|
|
751
|
+
console.log("[IMA] Cached VAST response for preloading:", vastTagUrl);
|
|
752
|
+
}).catch((error) => {
|
|
753
|
+
console.warn("[IMA] Failed to preload VAST response:", error);
|
|
754
|
+
preloadedVast.delete(vastTagUrl);
|
|
755
|
+
}).finally(() => {
|
|
756
|
+
preloadingVast.delete(vastTagUrl);
|
|
757
|
+
});
|
|
758
|
+
preloadingVast.set(vastTagUrl, preloadPromise);
|
|
759
|
+
return preloadPromise;
|
|
760
|
+
},
|
|
761
|
+
hasPreloadedAd(vastTagUrl) {
|
|
762
|
+
return preloadedVast.has(vastTagUrl);
|
|
763
|
+
},
|
|
711
764
|
async play() {
|
|
712
765
|
var _a, _b;
|
|
713
766
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
@@ -783,6 +836,8 @@ function createImaController(video, options) {
|
|
|
783
836
|
adContainerEl = void 0;
|
|
784
837
|
adDisplayContainer = void 0;
|
|
785
838
|
adsLoader = void 0;
|
|
839
|
+
preloadedVast.clear();
|
|
840
|
+
preloadingVast.clear();
|
|
786
841
|
},
|
|
787
842
|
isAdPlaying() {
|
|
788
843
|
return adPlaying;
|
|
@@ -838,6 +893,19 @@ function createImaController(video, options) {
|
|
|
838
893
|
}
|
|
839
894
|
}
|
|
840
895
|
return 1;
|
|
896
|
+
},
|
|
897
|
+
showPlaceholder() {
|
|
898
|
+
ensurePlaceholderContainer();
|
|
899
|
+
if (adContainerEl) {
|
|
900
|
+
adContainerEl.style.display = "flex";
|
|
901
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
hidePlaceholder() {
|
|
905
|
+
if (adContainerEl) {
|
|
906
|
+
adContainerEl.style.display = "none";
|
|
907
|
+
adContainerEl.style.pointerEvents = "none";
|
|
908
|
+
}
|
|
841
909
|
}
|
|
842
910
|
};
|
|
843
911
|
}
|
|
@@ -855,6 +923,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
855
923
|
let adContainerEl;
|
|
856
924
|
let currentAd;
|
|
857
925
|
let sessionId;
|
|
926
|
+
const preloadedAds = /* @__PURE__ */ new Map();
|
|
927
|
+
const preloadingAds = /* @__PURE__ */ new Map();
|
|
858
928
|
let trackingFired = {
|
|
859
929
|
impression: false,
|
|
860
930
|
start: false,
|
|
@@ -1084,6 +1154,19 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1084
1154
|
return null;
|
|
1085
1155
|
}
|
|
1086
1156
|
}
|
|
1157
|
+
async function fetchAndParseVastAd(vastTagUrl) {
|
|
1158
|
+
const response = await fetch(vastTagUrl);
|
|
1159
|
+
if (!response.ok) {
|
|
1160
|
+
throw new Error(`Failed to fetch VAST: ${response.statusText}`);
|
|
1161
|
+
}
|
|
1162
|
+
const vastXml = await response.text();
|
|
1163
|
+
console.log("[HlsAdPlayer] VAST XML received");
|
|
1164
|
+
console.log(
|
|
1165
|
+
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1166
|
+
vastXml.substring(0, 2e3)
|
|
1167
|
+
);
|
|
1168
|
+
return parseVastXml(vastXml);
|
|
1169
|
+
}
|
|
1087
1170
|
function createAdVideoElement() {
|
|
1088
1171
|
const video = document.createElement("video");
|
|
1089
1172
|
video.style.position = "absolute";
|
|
@@ -1235,17 +1318,17 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1235
1318
|
}
|
|
1236
1319
|
try {
|
|
1237
1320
|
sessionId = generateSessionId();
|
|
1238
|
-
|
|
1239
|
-
if (
|
|
1240
|
-
|
|
1321
|
+
let ad;
|
|
1322
|
+
if (preloadedAds.has(vastTagUrl)) {
|
|
1323
|
+
ad = preloadedAds.get(vastTagUrl);
|
|
1324
|
+
preloadedAds.delete(vastTagUrl);
|
|
1325
|
+
console.log(
|
|
1326
|
+
"[HlsAdPlayer] Using preloaded VAST response:",
|
|
1327
|
+
vastTagUrl
|
|
1328
|
+
);
|
|
1329
|
+
} else {
|
|
1330
|
+
ad = await fetchAndParseVastAd(vastTagUrl);
|
|
1241
1331
|
}
|
|
1242
|
-
const vastXml = await response.text();
|
|
1243
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
1244
|
-
console.log(
|
|
1245
|
-
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1246
|
-
vastXml.substring(0, 2e3)
|
|
1247
|
-
);
|
|
1248
|
-
const ad = parseVastXml(vastXml);
|
|
1249
1332
|
if (!ad) {
|
|
1250
1333
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1251
1334
|
emit("ad_error");
|
|
@@ -1264,6 +1347,37 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1264
1347
|
return Promise.reject(error);
|
|
1265
1348
|
}
|
|
1266
1349
|
},
|
|
1350
|
+
async preloadAds(vastTagUrl) {
|
|
1351
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
1352
|
+
return Promise.resolve();
|
|
1353
|
+
}
|
|
1354
|
+
if (preloadedAds.has(vastTagUrl)) {
|
|
1355
|
+
return Promise.resolve();
|
|
1356
|
+
}
|
|
1357
|
+
const inflight = preloadingAds.get(vastTagUrl);
|
|
1358
|
+
if (inflight) {
|
|
1359
|
+
return inflight;
|
|
1360
|
+
}
|
|
1361
|
+
const preloadPromise = fetchAndParseVastAd(vastTagUrl).then((ad) => {
|
|
1362
|
+
if (ad) {
|
|
1363
|
+
preloadedAds.set(vastTagUrl, ad);
|
|
1364
|
+
console.log(
|
|
1365
|
+
"[HlsAdPlayer] Cached VAST response for preloading:",
|
|
1366
|
+
vastTagUrl
|
|
1367
|
+
);
|
|
1368
|
+
}
|
|
1369
|
+
}).catch((error) => {
|
|
1370
|
+
console.warn("[HlsAdPlayer] Failed to preload VAST response:", error);
|
|
1371
|
+
preloadedAds.delete(vastTagUrl);
|
|
1372
|
+
}).finally(() => {
|
|
1373
|
+
preloadingAds.delete(vastTagUrl);
|
|
1374
|
+
});
|
|
1375
|
+
preloadingAds.set(vastTagUrl, preloadPromise);
|
|
1376
|
+
return preloadPromise;
|
|
1377
|
+
},
|
|
1378
|
+
hasPreloadedAd(vastTagUrl) {
|
|
1379
|
+
return preloadedAds.has(vastTagUrl);
|
|
1380
|
+
},
|
|
1267
1381
|
async play() {
|
|
1268
1382
|
if (!currentAd) {
|
|
1269
1383
|
console.warn(
|
|
@@ -1394,6 +1508,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1394
1508
|
adContainerEl = void 0;
|
|
1395
1509
|
currentAd = void 0;
|
|
1396
1510
|
listeners.clear();
|
|
1511
|
+
preloadedAds.clear();
|
|
1512
|
+
preloadingAds.clear();
|
|
1397
1513
|
},
|
|
1398
1514
|
isAdPlaying() {
|
|
1399
1515
|
return adPlaying;
|
|
@@ -1436,6 +1552,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1436
1552
|
return adVideoElement.volume;
|
|
1437
1553
|
}
|
|
1438
1554
|
return 1;
|
|
1555
|
+
},
|
|
1556
|
+
showPlaceholder() {
|
|
1557
|
+
var _a;
|
|
1558
|
+
if (!adContainerEl) {
|
|
1559
|
+
const container = document.createElement("div");
|
|
1560
|
+
container.style.position = "absolute";
|
|
1561
|
+
container.style.left = "0";
|
|
1562
|
+
container.style.top = "0";
|
|
1563
|
+
container.style.right = "0";
|
|
1564
|
+
container.style.bottom = "0";
|
|
1565
|
+
container.style.display = "none";
|
|
1566
|
+
container.style.alignItems = "center";
|
|
1567
|
+
container.style.justifyContent = "center";
|
|
1568
|
+
container.style.pointerEvents = "none";
|
|
1569
|
+
container.style.zIndex = "10";
|
|
1570
|
+
container.style.backgroundColor = "#000";
|
|
1571
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
1572
|
+
adContainerEl = container;
|
|
1573
|
+
}
|
|
1574
|
+
if (adContainerEl) {
|
|
1575
|
+
adContainerEl.style.display = "flex";
|
|
1576
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
1577
|
+
}
|
|
1578
|
+
},
|
|
1579
|
+
hidePlaceholder() {
|
|
1580
|
+
if (adContainerEl) {
|
|
1581
|
+
adContainerEl.style.display = "none";
|
|
1582
|
+
adContainerEl.style.pointerEvents = "none";
|
|
1583
|
+
}
|
|
1439
1584
|
}
|
|
1440
1585
|
};
|
|
1441
1586
|
}
|
|
@@ -1916,6 +2061,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1916
2061
|
this.bufferedSegmentsCount = 0;
|
|
1917
2062
|
this.shouldAutoplayAfterBuffering = false;
|
|
1918
2063
|
this.hasInitialBufferCompleted = false;
|
|
2064
|
+
this.adPodAllUrls = [];
|
|
2065
|
+
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
1919
2066
|
initializePolyfills();
|
|
1920
2067
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1921
2068
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2216,6 +2363,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2216
2363
|
console.log("[StormcloudVideoPlayer] IMA content_pause event received");
|
|
2217
2364
|
}
|
|
2218
2365
|
this.clearAdFailsafeTimer();
|
|
2366
|
+
this.enforceAdHoldState();
|
|
2219
2367
|
});
|
|
2220
2368
|
this.ima.on("content_resume", () => {
|
|
2221
2369
|
if (this.config.debugAdTiming) {
|
|
@@ -2240,9 +2388,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2240
2388
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2241
2389
|
const next = this.adPodQueue.shift();
|
|
2242
2390
|
this.currentAdIndex++;
|
|
2243
|
-
this.
|
|
2244
|
-
this.video.muted = true;
|
|
2245
|
-
this.video.volume = 0;
|
|
2391
|
+
this.enforceAdHoldState();
|
|
2246
2392
|
if (this.config.debugAdTiming) {
|
|
2247
2393
|
console.log(
|
|
2248
2394
|
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
@@ -2854,11 +3000,16 @@ var StormcloudVideoPlayer = class {
|
|
|
2854
3000
|
return;
|
|
2855
3001
|
}
|
|
2856
3002
|
if (vastTagUrls.length > 0) {
|
|
3003
|
+
this.adPodAllUrls = [...vastTagUrls];
|
|
3004
|
+
this.preloadingAdUrls.clear();
|
|
3005
|
+
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
2857
3006
|
this.inAdBreak = true;
|
|
2858
3007
|
this.showAds = true;
|
|
2859
3008
|
this.currentAdIndex = 0;
|
|
2860
3009
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
2861
3010
|
this.adPodQueue = [...vastTagUrls];
|
|
3011
|
+
this.enforceAdHoldState();
|
|
3012
|
+
this.preloadUpcomingAds();
|
|
2862
3013
|
if (this.config.debugAdTiming) {
|
|
2863
3014
|
console.log(
|
|
2864
3015
|
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - will play continuously`
|
|
@@ -2929,6 +3080,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2929
3080
|
const first = tags[0];
|
|
2930
3081
|
const rest = tags.slice(1);
|
|
2931
3082
|
this.adPodQueue = rest;
|
|
3083
|
+
this.enforceAdHoldState();
|
|
2932
3084
|
await this.playSingleAd(first);
|
|
2933
3085
|
this.inAdBreak = true;
|
|
2934
3086
|
this.expectedAdBreakDurationMs = remainingMs;
|
|
@@ -3042,6 +3194,12 @@ var StormcloudVideoPlayer = class {
|
|
|
3042
3194
|
}
|
|
3043
3195
|
return;
|
|
3044
3196
|
}
|
|
3197
|
+
const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
|
|
3198
|
+
if (wasPreloaded && this.config.debugAdTiming) {
|
|
3199
|
+
console.log(
|
|
3200
|
+
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3201
|
+
);
|
|
3202
|
+
}
|
|
3045
3203
|
if (!this.showAds) {
|
|
3046
3204
|
if (this.config.debugAdTiming) {
|
|
3047
3205
|
console.log(
|
|
@@ -3062,12 +3220,14 @@ var StormcloudVideoPlayer = class {
|
|
|
3062
3220
|
this.startAdFailsafeTimer();
|
|
3063
3221
|
try {
|
|
3064
3222
|
await this.ima.requestAds(vastTagUrl);
|
|
3223
|
+
this.preloadUpcomingAds();
|
|
3065
3224
|
try {
|
|
3066
3225
|
if (this.config.debugAdTiming) {
|
|
3067
3226
|
console.log(
|
|
3068
3227
|
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
3069
3228
|
);
|
|
3070
3229
|
}
|
|
3230
|
+
this.enforceAdHoldState();
|
|
3071
3231
|
await this.ima.play();
|
|
3072
3232
|
if (this.config.debugAdTiming) {
|
|
3073
3233
|
console.log(
|
|
@@ -3097,6 +3257,8 @@ var StormcloudVideoPlayer = class {
|
|
|
3097
3257
|
"[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
|
|
3098
3258
|
);
|
|
3099
3259
|
}
|
|
3260
|
+
this.releaseAdHoldState();
|
|
3261
|
+
this.preloadingAdUrls.clear();
|
|
3100
3262
|
this.inAdBreak = false;
|
|
3101
3263
|
this.expectedAdBreakDurationMs = void 0;
|
|
3102
3264
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3104,6 +3266,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3104
3266
|
this.clearAdStopTimer();
|
|
3105
3267
|
this.clearAdFailsafeTimer();
|
|
3106
3268
|
this.adPodQueue = [];
|
|
3269
|
+
this.adPodAllUrls = [];
|
|
3107
3270
|
this.showAds = false;
|
|
3108
3271
|
this.currentAdIndex = 0;
|
|
3109
3272
|
this.totalAdsInBreak = 0;
|
|
@@ -3184,6 +3347,64 @@ var StormcloudVideoPlayer = class {
|
|
|
3184
3347
|
}
|
|
3185
3348
|
return [b.vastTagUrl];
|
|
3186
3349
|
}
|
|
3350
|
+
logQueuedAdUrls(urls) {
|
|
3351
|
+
if (!this.config.debugAdTiming) {
|
|
3352
|
+
return;
|
|
3353
|
+
}
|
|
3354
|
+
console.log("[StormcloudVideoPlayer] ALL ad URLs queued:", urls);
|
|
3355
|
+
}
|
|
3356
|
+
enforceAdHoldState() {
|
|
3357
|
+
this.video.dataset.stormcloudAdPlaying = "true";
|
|
3358
|
+
this.video.muted = true;
|
|
3359
|
+
this.video.volume = 0;
|
|
3360
|
+
if (typeof this.ima.showPlaceholder === "function") {
|
|
3361
|
+
this.ima.showPlaceholder();
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
releaseAdHoldState() {
|
|
3365
|
+
delete this.video.dataset.stormcloudAdPlaying;
|
|
3366
|
+
if (typeof this.ima.hidePlaceholder === "function") {
|
|
3367
|
+
this.ima.hidePlaceholder();
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
preloadUpcomingAds() {
|
|
3371
|
+
if (!this.ima.preloadAds || this.adPodQueue.length === 0) {
|
|
3372
|
+
return;
|
|
3373
|
+
}
|
|
3374
|
+
const upcoming = this.adPodQueue.slice(0, 2);
|
|
3375
|
+
for (const url of upcoming) {
|
|
3376
|
+
if (!url) continue;
|
|
3377
|
+
if (this.ima.hasPreloadedAd(url)) {
|
|
3378
|
+
this.preloadingAdUrls.delete(url);
|
|
3379
|
+
continue;
|
|
3380
|
+
}
|
|
3381
|
+
if (this.preloadingAdUrls.has(url)) {
|
|
3382
|
+
continue;
|
|
3383
|
+
}
|
|
3384
|
+
if (this.config.debugAdTiming) {
|
|
3385
|
+
console.log(
|
|
3386
|
+
`[StormcloudVideoPlayer] Scheduling IMA preload for upcoming ad: ${url}`
|
|
3387
|
+
);
|
|
3388
|
+
}
|
|
3389
|
+
this.preloadingAdUrls.add(url);
|
|
3390
|
+
this.ima.preloadAds(url).then(() => {
|
|
3391
|
+
if (this.config.debugAdTiming) {
|
|
3392
|
+
console.log(
|
|
3393
|
+
`[StormcloudVideoPlayer] IMA preload complete for ad: ${url}`
|
|
3394
|
+
);
|
|
3395
|
+
}
|
|
3396
|
+
}).catch((error) => {
|
|
3397
|
+
if (this.config.debugAdTiming) {
|
|
3398
|
+
console.warn(
|
|
3399
|
+
`[StormcloudVideoPlayer] IMA preload failed for ad: ${url}`,
|
|
3400
|
+
error
|
|
3401
|
+
);
|
|
3402
|
+
}
|
|
3403
|
+
}).finally(() => {
|
|
3404
|
+
this.preloadingAdUrls.delete(url);
|
|
3405
|
+
});
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3187
3408
|
getRemainingAdMs() {
|
|
3188
3409
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3189
3410
|
return 0;
|
|
@@ -3335,6 +3556,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3335
3556
|
}
|
|
3336
3557
|
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
3337
3558
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3559
|
+
this.releaseAdHoldState();
|
|
3560
|
+
this.preloadingAdUrls.clear();
|
|
3561
|
+
this.adPodAllUrls = [];
|
|
3338
3562
|
}
|
|
3339
3563
|
};
|
|
3340
3564
|
|