stormcloud-video-player 0.2.23 → 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 +299 -52
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +11 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +299 -52
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +299 -52
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +8 -1
- package/lib/players/HlsPlayer.cjs +299 -52
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +299 -52
- 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 +93 -21
- 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 +299 -52
- 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
|
}
|
|
@@ -506,9 +533,13 @@ function createImaController(video, options) {
|
|
|
506
533
|
adsLoader.addEventListener(
|
|
507
534
|
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
|
|
508
535
|
(evt) => {
|
|
509
|
-
console.log(
|
|
536
|
+
console.log(
|
|
537
|
+
"[IMA] Ads manager loaded - enabling preloading for continuous playback"
|
|
538
|
+
);
|
|
510
539
|
try {
|
|
511
|
-
|
|
540
|
+
const adsRenderingSettings = new google.ima.AdsRenderingSettings();
|
|
541
|
+
adsRenderingSettings.enablePreloading = true;
|
|
542
|
+
adsManager = evt.getAdsManager(video, adsRenderingSettings);
|
|
512
543
|
const AdEvent = google.ima.AdEvent.Type;
|
|
513
544
|
const AdErrorEvent = google.ima.AdErrorEvent.Type;
|
|
514
545
|
adsManager.addEventListener(
|
|
@@ -704,6 +735,32 @@ function createImaController(video, options) {
|
|
|
704
735
|
return Promise.reject(error);
|
|
705
736
|
}
|
|
706
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
|
+
},
|
|
707
764
|
async play() {
|
|
708
765
|
var _a, _b;
|
|
709
766
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
@@ -779,6 +836,8 @@ function createImaController(video, options) {
|
|
|
779
836
|
adContainerEl = void 0;
|
|
780
837
|
adDisplayContainer = void 0;
|
|
781
838
|
adsLoader = void 0;
|
|
839
|
+
preloadedVast.clear();
|
|
840
|
+
preloadingVast.clear();
|
|
782
841
|
},
|
|
783
842
|
isAdPlaying() {
|
|
784
843
|
return adPlaying;
|
|
@@ -834,6 +893,19 @@ function createImaController(video, options) {
|
|
|
834
893
|
}
|
|
835
894
|
}
|
|
836
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
|
+
}
|
|
837
909
|
}
|
|
838
910
|
};
|
|
839
911
|
}
|
|
@@ -851,6 +923,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
851
923
|
let adContainerEl;
|
|
852
924
|
let currentAd;
|
|
853
925
|
let sessionId;
|
|
926
|
+
const preloadedAds = /* @__PURE__ */ new Map();
|
|
927
|
+
const preloadingAds = /* @__PURE__ */ new Map();
|
|
854
928
|
let trackingFired = {
|
|
855
929
|
impression: false,
|
|
856
930
|
start: false,
|
|
@@ -1080,6 +1154,19 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1080
1154
|
return null;
|
|
1081
1155
|
}
|
|
1082
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
|
+
}
|
|
1083
1170
|
function createAdVideoElement() {
|
|
1084
1171
|
const video = document.createElement("video");
|
|
1085
1172
|
video.style.position = "absolute";
|
|
@@ -1231,17 +1318,17 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1231
1318
|
}
|
|
1232
1319
|
try {
|
|
1233
1320
|
sessionId = generateSessionId();
|
|
1234
|
-
|
|
1235
|
-
if (
|
|
1236
|
-
|
|
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);
|
|
1237
1331
|
}
|
|
1238
|
-
const vastXml = await response.text();
|
|
1239
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
1240
|
-
console.log(
|
|
1241
|
-
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1242
|
-
vastXml.substring(0, 2e3)
|
|
1243
|
-
);
|
|
1244
|
-
const ad = parseVastXml(vastXml);
|
|
1245
1332
|
if (!ad) {
|
|
1246
1333
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1247
1334
|
emit("ad_error");
|
|
@@ -1260,6 +1347,37 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1260
1347
|
return Promise.reject(error);
|
|
1261
1348
|
}
|
|
1262
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
|
+
},
|
|
1263
1381
|
async play() {
|
|
1264
1382
|
if (!currentAd) {
|
|
1265
1383
|
console.warn(
|
|
@@ -1390,6 +1508,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1390
1508
|
adContainerEl = void 0;
|
|
1391
1509
|
currentAd = void 0;
|
|
1392
1510
|
listeners.clear();
|
|
1511
|
+
preloadedAds.clear();
|
|
1512
|
+
preloadingAds.clear();
|
|
1393
1513
|
},
|
|
1394
1514
|
isAdPlaying() {
|
|
1395
1515
|
return adPlaying;
|
|
@@ -1432,6 +1552,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1432
1552
|
return adVideoElement.volume;
|
|
1433
1553
|
}
|
|
1434
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
|
+
}
|
|
1435
1584
|
}
|
|
1436
1585
|
};
|
|
1437
1586
|
}
|
|
@@ -1912,6 +2061,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1912
2061
|
this.bufferedSegmentsCount = 0;
|
|
1913
2062
|
this.shouldAutoplayAfterBuffering = false;
|
|
1914
2063
|
this.hasInitialBufferCompleted = false;
|
|
2064
|
+
this.adPodAllUrls = [];
|
|
2065
|
+
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
1915
2066
|
initializePolyfills();
|
|
1916
2067
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1917
2068
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2212,6 +2363,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2212
2363
|
console.log("[StormcloudVideoPlayer] IMA content_pause event received");
|
|
2213
2364
|
}
|
|
2214
2365
|
this.clearAdFailsafeTimer();
|
|
2366
|
+
this.enforceAdHoldState();
|
|
2215
2367
|
});
|
|
2216
2368
|
this.ima.on("content_resume", () => {
|
|
2217
2369
|
if (this.config.debugAdTiming) {
|
|
@@ -2236,12 +2388,10 @@ var StormcloudVideoPlayer = class {
|
|
|
2236
2388
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2237
2389
|
const next = this.adPodQueue.shift();
|
|
2238
2390
|
this.currentAdIndex++;
|
|
2239
|
-
this.
|
|
2240
|
-
this.video.muted = true;
|
|
2241
|
-
this.video.volume = 0;
|
|
2391
|
+
this.enforceAdHoldState();
|
|
2242
2392
|
if (this.config.debugAdTiming) {
|
|
2243
2393
|
console.log(
|
|
2244
|
-
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) -
|
|
2394
|
+
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
2245
2395
|
);
|
|
2246
2396
|
}
|
|
2247
2397
|
this.playSingleAd(next).catch(() => {
|
|
@@ -2826,25 +2976,21 @@ var StormcloudVideoPlayer = class {
|
|
|
2826
2976
|
this.video.currentTime * 1e3
|
|
2827
2977
|
);
|
|
2828
2978
|
const tags = this.selectVastTagsForBreak(scheduled);
|
|
2829
|
-
let
|
|
2979
|
+
let vastTagUrls = [];
|
|
2830
2980
|
if (this.apiVastTagUrl) {
|
|
2831
|
-
|
|
2832
|
-
this.adPodQueue = [];
|
|
2833
|
-
this.currentAdIndex = 0;
|
|
2834
|
-
this.totalAdsInBreak = 1;
|
|
2981
|
+
vastTagUrls = [this.apiVastTagUrl];
|
|
2835
2982
|
if (this.config.debugAdTiming) {
|
|
2836
|
-
console.log(
|
|
2983
|
+
console.log(
|
|
2984
|
+
"[StormcloudVideoPlayer] Using VAST endpoint:",
|
|
2985
|
+
this.apiVastTagUrl
|
|
2986
|
+
);
|
|
2837
2987
|
}
|
|
2838
2988
|
} else if (tags && tags.length > 0) {
|
|
2839
|
-
|
|
2840
|
-
const rest = tags.slice(1);
|
|
2841
|
-
this.adPodQueue = rest;
|
|
2842
|
-
this.currentAdIndex = 0;
|
|
2843
|
-
this.totalAdsInBreak = tags.length;
|
|
2989
|
+
vastTagUrls = tags;
|
|
2844
2990
|
if (this.config.debugAdTiming) {
|
|
2845
2991
|
console.log(
|
|
2846
|
-
"[StormcloudVideoPlayer] Using scheduled VAST
|
|
2847
|
-
|
|
2992
|
+
"[StormcloudVideoPlayer] Using scheduled VAST tags (count: " + tags.length + "):",
|
|
2993
|
+
tags
|
|
2848
2994
|
);
|
|
2849
2995
|
}
|
|
2850
2996
|
} else {
|
|
@@ -2853,16 +2999,28 @@ var StormcloudVideoPlayer = class {
|
|
|
2853
2999
|
}
|
|
2854
3000
|
return;
|
|
2855
3001
|
}
|
|
2856
|
-
if (
|
|
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
|
-
this.currentAdIndex
|
|
3008
|
+
this.currentAdIndex = 0;
|
|
3009
|
+
this.totalAdsInBreak = vastTagUrls.length;
|
|
3010
|
+
this.adPodQueue = [...vastTagUrls];
|
|
3011
|
+
this.enforceAdHoldState();
|
|
3012
|
+
this.preloadUpcomingAds();
|
|
3013
|
+
if (this.config.debugAdTiming) {
|
|
3014
|
+
console.log(
|
|
3015
|
+
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - will play continuously`
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
2860
3018
|
try {
|
|
2861
|
-
await this.
|
|
3019
|
+
await this.playAdPod();
|
|
2862
3020
|
} catch (error) {
|
|
2863
3021
|
if (this.config.debugAdTiming) {
|
|
2864
3022
|
console.error(
|
|
2865
|
-
"[StormcloudVideoPlayer] Ad playback failed
|
|
3023
|
+
"[StormcloudVideoPlayer] Ad pod playback failed:",
|
|
2866
3024
|
error
|
|
2867
3025
|
);
|
|
2868
3026
|
}
|
|
@@ -2875,6 +3033,22 @@ var StormcloudVideoPlayer = class {
|
|
|
2875
3033
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2876
3034
|
}
|
|
2877
3035
|
}
|
|
3036
|
+
async playAdPod() {
|
|
3037
|
+
if (this.adPodQueue.length === 0) {
|
|
3038
|
+
if (this.config.debugAdTiming) {
|
|
3039
|
+
console.log("[StormcloudVideoPlayer] No ads in pod to play");
|
|
3040
|
+
}
|
|
3041
|
+
return;
|
|
3042
|
+
}
|
|
3043
|
+
const firstAd = this.adPodQueue.shift();
|
|
3044
|
+
this.currentAdIndex++;
|
|
3045
|
+
if (this.config.debugAdTiming) {
|
|
3046
|
+
console.log(
|
|
3047
|
+
`[StormcloudVideoPlayer] Playing ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3048
|
+
);
|
|
3049
|
+
}
|
|
3050
|
+
await this.playSingleAd(firstAd);
|
|
3051
|
+
}
|
|
2878
3052
|
findCurrentOrNextBreak(nowMs) {
|
|
2879
3053
|
var _a;
|
|
2880
3054
|
const schedule = [];
|
|
@@ -2906,6 +3080,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2906
3080
|
const first = tags[0];
|
|
2907
3081
|
const rest = tags.slice(1);
|
|
2908
3082
|
this.adPodQueue = rest;
|
|
3083
|
+
this.enforceAdHoldState();
|
|
2909
3084
|
await this.playSingleAd(first);
|
|
2910
3085
|
this.inAdBreak = true;
|
|
2911
3086
|
this.expectedAdBreakDurationMs = remainingMs;
|
|
@@ -3019,6 +3194,12 @@ var StormcloudVideoPlayer = class {
|
|
|
3019
3194
|
}
|
|
3020
3195
|
return;
|
|
3021
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
|
+
}
|
|
3022
3203
|
if (!this.showAds) {
|
|
3023
3204
|
if (this.config.debugAdTiming) {
|
|
3024
3205
|
console.log(
|
|
@@ -3039,12 +3220,14 @@ var StormcloudVideoPlayer = class {
|
|
|
3039
3220
|
this.startAdFailsafeTimer();
|
|
3040
3221
|
try {
|
|
3041
3222
|
await this.ima.requestAds(vastTagUrl);
|
|
3223
|
+
this.preloadUpcomingAds();
|
|
3042
3224
|
try {
|
|
3043
3225
|
if (this.config.debugAdTiming) {
|
|
3044
3226
|
console.log(
|
|
3045
3227
|
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
3046
3228
|
);
|
|
3047
3229
|
}
|
|
3230
|
+
this.enforceAdHoldState();
|
|
3048
3231
|
await this.ima.play();
|
|
3049
3232
|
if (this.config.debugAdTiming) {
|
|
3050
3233
|
console.log(
|
|
@@ -3074,6 +3257,8 @@ var StormcloudVideoPlayer = class {
|
|
|
3074
3257
|
"[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
|
|
3075
3258
|
);
|
|
3076
3259
|
}
|
|
3260
|
+
this.releaseAdHoldState();
|
|
3261
|
+
this.preloadingAdUrls.clear();
|
|
3077
3262
|
this.inAdBreak = false;
|
|
3078
3263
|
this.expectedAdBreakDurationMs = void 0;
|
|
3079
3264
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3081,6 +3266,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3081
3266
|
this.clearAdStopTimer();
|
|
3082
3267
|
this.clearAdFailsafeTimer();
|
|
3083
3268
|
this.adPodQueue = [];
|
|
3269
|
+
this.adPodAllUrls = [];
|
|
3084
3270
|
this.showAds = false;
|
|
3085
3271
|
this.currentAdIndex = 0;
|
|
3086
3272
|
this.totalAdsInBreak = 0;
|
|
@@ -3161,6 +3347,64 @@ var StormcloudVideoPlayer = class {
|
|
|
3161
3347
|
}
|
|
3162
3348
|
return [b.vastTagUrl];
|
|
3163
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
|
+
}
|
|
3164
3408
|
getRemainingAdMs() {
|
|
3165
3409
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3166
3410
|
return 0;
|
|
@@ -3312,6 +3556,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3312
3556
|
}
|
|
3313
3557
|
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
3314
3558
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3559
|
+
this.releaseAdHoldState();
|
|
3560
|
+
this.preloadingAdUrls.clear();
|
|
3561
|
+
this.adPodAllUrls = [];
|
|
3315
3562
|
}
|
|
3316
3563
|
};
|
|
3317
3564
|
|