stormcloud-video-player 0.2.24 → 0.2.26
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 +305 -45
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +12 -1
- package/lib/index.d.ts +12 -1
- package/lib/index.js +305 -45
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +305 -45
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +7 -1
- package/lib/players/HlsPlayer.cjs +305 -45
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +305 -45
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +102 -13
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/sdk/ima.cjs +113 -22
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/sdk/ima.d.cts +1 -1
- package/lib/{types-D1xfSdLP.d.cts → types-t9jEJXZy.d.cts} +6 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +305 -45
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
|
-
import { S as StormcloudVideoPlayerConfig } from '../types-
|
|
2
|
+
import { S as StormcloudVideoPlayerConfig } from '../types-t9jEJXZy.cjs';
|
|
3
3
|
|
|
4
4
|
interface HlsPlayerProps extends StormcloudVideoPlayerConfig {
|
|
5
5
|
onMount?: (player: any) => void;
|
package/lib/players/index.cjs
CHANGED
|
@@ -241,7 +241,10 @@ function getBrowserConfigOverrides() {
|
|
|
241
241
|
function createImaController(video, options) {
|
|
242
242
|
let adPlaying = false;
|
|
243
243
|
let originalMutedState = false;
|
|
244
|
+
let originalVolume = typeof video.volume === "number" && !Number.isNaN(video.volume) ? Math.max(0, Math.min(1, video.volume)) : 1;
|
|
244
245
|
const listeners = /* @__PURE__ */ new Map();
|
|
246
|
+
const preloadedVast = /* @__PURE__ */ new Map();
|
|
247
|
+
const preloadingVast = /* @__PURE__ */ new Map();
|
|
245
248
|
function setAdPlayingFlag(isPlaying) {
|
|
246
249
|
if (isPlaying) {
|
|
247
250
|
video.dataset.stormcloudAdPlaying = "true";
|
|
@@ -332,16 +335,70 @@ function createImaController(video, options) {
|
|
|
332
335
|
let adsLoadedReject;
|
|
333
336
|
function makeAdsRequest(google, vastTagUrl) {
|
|
334
337
|
const adsRequest = new google.ima.AdsRequest();
|
|
335
|
-
|
|
338
|
+
const preloadedResponse = preloadedVast.get(vastTagUrl);
|
|
339
|
+
if (preloadedResponse) {
|
|
340
|
+
adsRequest.adsResponse = preloadedResponse;
|
|
341
|
+
console.log(
|
|
342
|
+
"[IMA] Using preloaded VAST response for immediate ad request"
|
|
343
|
+
);
|
|
344
|
+
} else {
|
|
345
|
+
adsRequest.adTagUrl = vastTagUrl;
|
|
346
|
+
}
|
|
336
347
|
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
337
348
|
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
338
349
|
adsRequest.linearAdSlotWidth = videoWidth;
|
|
339
350
|
adsRequest.linearAdSlotHeight = videoHeight;
|
|
340
351
|
adsRequest.nonLinearAdSlotWidth = videoWidth;
|
|
341
352
|
adsRequest.nonLinearAdSlotHeight = videoHeight;
|
|
353
|
+
if (typeof adsRequest.setAdWillAutoPlay === "function") {
|
|
354
|
+
try {
|
|
355
|
+
const willAutoPlay = !video.paused || video.autoplay;
|
|
356
|
+
adsRequest.setAdWillAutoPlay(willAutoPlay);
|
|
357
|
+
} catch (error) {
|
|
358
|
+
console.warn("[IMA] Failed to call setAdWillAutoPlay:", error);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (typeof adsRequest.setAdWillPlayMuted === "function") {
|
|
362
|
+
try {
|
|
363
|
+
const willPlayMuted = video.muted || video.volume === 0;
|
|
364
|
+
adsRequest.setAdWillPlayMuted(willPlayMuted);
|
|
365
|
+
} catch (error) {
|
|
366
|
+
console.warn("[IMA] Failed to call setAdWillPlayMuted:", error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
342
369
|
adsRequest.vastLoadTimeout = 5e3;
|
|
343
370
|
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
344
371
|
adsLoader.requestAds(adsRequest);
|
|
372
|
+
if (preloadedResponse) {
|
|
373
|
+
preloadedVast.delete(vastTagUrl);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function ensurePlaceholderContainer() {
|
|
377
|
+
var _a;
|
|
378
|
+
if (adContainerEl) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const container = document.createElement("div");
|
|
382
|
+
container.style.position = "absolute";
|
|
383
|
+
container.style.left = "0";
|
|
384
|
+
container.style.top = "0";
|
|
385
|
+
container.style.right = "0";
|
|
386
|
+
container.style.bottom = "0";
|
|
387
|
+
container.style.display = "none";
|
|
388
|
+
container.style.alignItems = "center";
|
|
389
|
+
container.style.justifyContent = "center";
|
|
390
|
+
container.style.pointerEvents = "none";
|
|
391
|
+
container.style.zIndex = "10";
|
|
392
|
+
container.style.backgroundColor = "#000";
|
|
393
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
394
|
+
adContainerEl = container;
|
|
395
|
+
}
|
|
396
|
+
async function fetchVastDocument(vastTagUrl) {
|
|
397
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
398
|
+
if (!response.ok) {
|
|
399
|
+
throw new Error(`Failed to preload VAST: ${response.status}`);
|
|
400
|
+
}
|
|
401
|
+
return response.text();
|
|
345
402
|
}
|
|
346
403
|
function destroyAdsManager() {
|
|
347
404
|
if (adsManager) {
|
|
@@ -357,29 +414,16 @@ function createImaController(video, options) {
|
|
|
357
414
|
return {
|
|
358
415
|
initialize() {
|
|
359
416
|
ensureImaLoaded().then(() => {
|
|
360
|
-
var _a
|
|
417
|
+
var _a;
|
|
361
418
|
const google = window.google;
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
container.style.position = "absolute";
|
|
365
|
-
container.style.left = "0";
|
|
366
|
-
container.style.top = "0";
|
|
367
|
-
container.style.right = "0";
|
|
368
|
-
container.style.bottom = "0";
|
|
369
|
-
container.style.display = "none";
|
|
370
|
-
container.style.alignItems = "center";
|
|
371
|
-
container.style.justifyContent = "center";
|
|
372
|
-
container.style.pointerEvents = "none";
|
|
373
|
-
container.style.zIndex = "10";
|
|
374
|
-
container.style.backgroundColor = "#000";
|
|
375
|
-
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
376
|
-
adContainerEl = container;
|
|
419
|
+
ensurePlaceholderContainer();
|
|
420
|
+
if (!adDisplayContainer && adContainerEl) {
|
|
377
421
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
378
|
-
|
|
422
|
+
adContainerEl,
|
|
379
423
|
video
|
|
380
424
|
);
|
|
381
425
|
try {
|
|
382
|
-
(
|
|
426
|
+
(_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
|
|
383
427
|
} catch {
|
|
384
428
|
}
|
|
385
429
|
}
|
|
@@ -683,6 +727,32 @@ function createImaController(video, options) {
|
|
|
683
727
|
return Promise.reject(error);
|
|
684
728
|
}
|
|
685
729
|
},
|
|
730
|
+
async preloadAds(vastTagUrl) {
|
|
731
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
732
|
+
return Promise.resolve();
|
|
733
|
+
}
|
|
734
|
+
if (preloadedVast.has(vastTagUrl)) {
|
|
735
|
+
return Promise.resolve();
|
|
736
|
+
}
|
|
737
|
+
const inflight = preloadingVast.get(vastTagUrl);
|
|
738
|
+
if (inflight) {
|
|
739
|
+
return inflight;
|
|
740
|
+
}
|
|
741
|
+
const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {
|
|
742
|
+
preloadedVast.set(vastTagUrl, xml);
|
|
743
|
+
console.log("[IMA] Cached VAST response for preloading:", vastTagUrl);
|
|
744
|
+
}).catch((error) => {
|
|
745
|
+
console.warn("[IMA] Failed to preload VAST response:", error);
|
|
746
|
+
preloadedVast.delete(vastTagUrl);
|
|
747
|
+
}).finally(() => {
|
|
748
|
+
preloadingVast.delete(vastTagUrl);
|
|
749
|
+
});
|
|
750
|
+
preloadingVast.set(vastTagUrl, preloadPromise);
|
|
751
|
+
return preloadPromise;
|
|
752
|
+
},
|
|
753
|
+
hasPreloadedAd(vastTagUrl) {
|
|
754
|
+
return preloadedVast.has(vastTagUrl);
|
|
755
|
+
},
|
|
686
756
|
async play() {
|
|
687
757
|
var _a, _b;
|
|
688
758
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
@@ -701,7 +771,7 @@ function createImaController(video, options) {
|
|
|
701
771
|
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
702
772
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
703
773
|
adPlaying = true;
|
|
704
|
-
const adVolume = originalMutedState ? 0 :
|
|
774
|
+
const adVolume = originalMutedState ? 0 : originalVolume;
|
|
705
775
|
try {
|
|
706
776
|
adsManager.setVolume(adVolume);
|
|
707
777
|
console.log(`[IMA] Set ad volume to ${adVolume}`);
|
|
@@ -743,6 +813,7 @@ function createImaController(video, options) {
|
|
|
743
813
|
destroyAdsManager();
|
|
744
814
|
adPlaying = false;
|
|
745
815
|
video.muted = originalMutedState;
|
|
816
|
+
video.volume = originalVolume;
|
|
746
817
|
setAdPlayingFlag(false);
|
|
747
818
|
if (adContainerEl) {
|
|
748
819
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -758,6 +829,8 @@ function createImaController(video, options) {
|
|
|
758
829
|
adContainerEl = void 0;
|
|
759
830
|
adDisplayContainer = void 0;
|
|
760
831
|
adsLoader = void 0;
|
|
832
|
+
preloadedVast.clear();
|
|
833
|
+
preloadingVast.clear();
|
|
761
834
|
},
|
|
762
835
|
isAdPlaying() {
|
|
763
836
|
return adPlaying;
|
|
@@ -785,15 +858,20 @@ function createImaController(video, options) {
|
|
|
785
858
|
var _a;
|
|
786
859
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
787
860
|
},
|
|
788
|
-
updateOriginalMutedState(muted) {
|
|
861
|
+
updateOriginalMutedState(muted, volume) {
|
|
862
|
+
const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
|
|
789
863
|
console.log(
|
|
790
|
-
`[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
864
|
+
`[IMA] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
|
|
791
865
|
);
|
|
792
866
|
originalMutedState = muted;
|
|
867
|
+
originalVolume = nextVolume;
|
|
793
868
|
},
|
|
794
869
|
getOriginalMutedState() {
|
|
795
870
|
return originalMutedState;
|
|
796
871
|
},
|
|
872
|
+
getOriginalVolume() {
|
|
873
|
+
return originalVolume;
|
|
874
|
+
},
|
|
797
875
|
setAdVolume(volume) {
|
|
798
876
|
if (adsManager && adPlaying) {
|
|
799
877
|
try {
|
|
@@ -813,6 +891,19 @@ function createImaController(video, options) {
|
|
|
813
891
|
}
|
|
814
892
|
}
|
|
815
893
|
return 1;
|
|
894
|
+
},
|
|
895
|
+
showPlaceholder() {
|
|
896
|
+
ensurePlaceholderContainer();
|
|
897
|
+
if (adContainerEl) {
|
|
898
|
+
adContainerEl.style.display = "flex";
|
|
899
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
hidePlaceholder() {
|
|
903
|
+
if (adContainerEl) {
|
|
904
|
+
adContainerEl.style.display = "none";
|
|
905
|
+
adContainerEl.style.pointerEvents = "none";
|
|
906
|
+
}
|
|
816
907
|
}
|
|
817
908
|
};
|
|
818
909
|
}
|
|
@@ -822,6 +913,7 @@ var import_hls = __toESM(require("hls.js"), 1);
|
|
|
822
913
|
function createHlsAdPlayer(contentVideo, options) {
|
|
823
914
|
let adPlaying = false;
|
|
824
915
|
let originalMutedState = false;
|
|
916
|
+
let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
|
|
825
917
|
const listeners = /* @__PURE__ */ new Map();
|
|
826
918
|
const licenseKey = options == null ? void 0 : options.licenseKey;
|
|
827
919
|
const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
|
|
@@ -830,6 +922,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
830
922
|
let adContainerEl;
|
|
831
923
|
let currentAd;
|
|
832
924
|
let sessionId;
|
|
925
|
+
const preloadedAds = /* @__PURE__ */ new Map();
|
|
926
|
+
const preloadingAds = /* @__PURE__ */ new Map();
|
|
833
927
|
let trackingFired = {
|
|
834
928
|
impression: false,
|
|
835
929
|
start: false,
|
|
@@ -1059,6 +1153,19 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1059
1153
|
return null;
|
|
1060
1154
|
}
|
|
1061
1155
|
}
|
|
1156
|
+
async function fetchAndParseVastAd(vastTagUrl) {
|
|
1157
|
+
const response = await fetch(vastTagUrl);
|
|
1158
|
+
if (!response.ok) {
|
|
1159
|
+
throw new Error(`Failed to fetch VAST: ${response.statusText}`);
|
|
1160
|
+
}
|
|
1161
|
+
const vastXml = await response.text();
|
|
1162
|
+
console.log("[HlsAdPlayer] VAST XML received");
|
|
1163
|
+
console.log(
|
|
1164
|
+
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1165
|
+
vastXml.substring(0, 2e3)
|
|
1166
|
+
);
|
|
1167
|
+
return parseVastXml(vastXml);
|
|
1168
|
+
}
|
|
1062
1169
|
function createAdVideoElement() {
|
|
1063
1170
|
const video = document.createElement("video");
|
|
1064
1171
|
video.style.position = "absolute";
|
|
@@ -1164,6 +1271,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1164
1271
|
setAdPlayingFlag(false);
|
|
1165
1272
|
const previousMutedState = contentVideo.muted;
|
|
1166
1273
|
contentVideo.muted = originalMutedState;
|
|
1274
|
+
contentVideo.volume = originalMutedState ? 0 : originalVolume;
|
|
1167
1275
|
console.log(
|
|
1168
1276
|
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1169
1277
|
);
|
|
@@ -1210,17 +1318,17 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1210
1318
|
}
|
|
1211
1319
|
try {
|
|
1212
1320
|
sessionId = generateSessionId();
|
|
1213
|
-
|
|
1214
|
-
if (
|
|
1215
|
-
|
|
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);
|
|
1216
1331
|
}
|
|
1217
|
-
const vastXml = await response.text();
|
|
1218
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
1219
|
-
console.log(
|
|
1220
|
-
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1221
|
-
vastXml.substring(0, 2e3)
|
|
1222
|
-
);
|
|
1223
|
-
const ad = parseVastXml(vastXml);
|
|
1224
1332
|
if (!ad) {
|
|
1225
1333
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1226
1334
|
emit("ad_error");
|
|
@@ -1239,6 +1347,37 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1239
1347
|
return Promise.reject(error);
|
|
1240
1348
|
}
|
|
1241
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
|
+
},
|
|
1242
1381
|
async play() {
|
|
1243
1382
|
if (!currentAd) {
|
|
1244
1383
|
console.warn(
|
|
@@ -1262,6 +1401,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1262
1401
|
complete: false
|
|
1263
1402
|
};
|
|
1264
1403
|
const contentVolume = contentVideo.volume;
|
|
1404
|
+
originalVolume = Math.max(
|
|
1405
|
+
0,
|
|
1406
|
+
Math.min(1, contentVolume || originalVolume)
|
|
1407
|
+
);
|
|
1265
1408
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1266
1409
|
contentVideo.pause();
|
|
1267
1410
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
@@ -1274,7 +1417,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1274
1417
|
adPlaying = true;
|
|
1275
1418
|
setAdPlayingFlag(true);
|
|
1276
1419
|
if (adVideoElement) {
|
|
1277
|
-
const adVolume = originalMutedState ? 0 :
|
|
1420
|
+
const adVolume = originalMutedState ? 0 : originalVolume;
|
|
1278
1421
|
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
1279
1422
|
adVideoElement.muted = false;
|
|
1280
1423
|
console.log(
|
|
@@ -1353,6 +1496,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1353
1496
|
adPlaying = false;
|
|
1354
1497
|
setAdPlayingFlag(false);
|
|
1355
1498
|
contentVideo.muted = originalMutedState;
|
|
1499
|
+
contentVideo.volume = originalMutedState ? 0 : originalVolume;
|
|
1356
1500
|
if (adHls) {
|
|
1357
1501
|
adHls.destroy();
|
|
1358
1502
|
adHls = void 0;
|
|
@@ -1369,6 +1513,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1369
1513
|
adContainerEl = void 0;
|
|
1370
1514
|
currentAd = void 0;
|
|
1371
1515
|
listeners.clear();
|
|
1516
|
+
preloadedAds.clear();
|
|
1517
|
+
preloadingAds.clear();
|
|
1372
1518
|
},
|
|
1373
1519
|
isAdPlaying() {
|
|
1374
1520
|
return adPlaying;
|
|
@@ -1392,15 +1538,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1392
1538
|
var _a;
|
|
1393
1539
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1394
1540
|
},
|
|
1395
|
-
updateOriginalMutedState(muted) {
|
|
1541
|
+
updateOriginalMutedState(muted, volume) {
|
|
1542
|
+
const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
|
|
1396
1543
|
console.log(
|
|
1397
|
-
`[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
1544
|
+
`[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
|
|
1398
1545
|
);
|
|
1399
1546
|
originalMutedState = muted;
|
|
1547
|
+
originalVolume = nextVolume;
|
|
1400
1548
|
},
|
|
1401
1549
|
getOriginalMutedState() {
|
|
1402
1550
|
return originalMutedState;
|
|
1403
1551
|
},
|
|
1552
|
+
getOriginalVolume() {
|
|
1553
|
+
return originalVolume;
|
|
1554
|
+
},
|
|
1404
1555
|
setAdVolume(volume) {
|
|
1405
1556
|
if (adVideoElement && adPlaying) {
|
|
1406
1557
|
adVideoElement.volume = Math.max(0, Math.min(1, volume));
|
|
@@ -1411,6 +1562,35 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1411
1562
|
return adVideoElement.volume;
|
|
1412
1563
|
}
|
|
1413
1564
|
return 1;
|
|
1565
|
+
},
|
|
1566
|
+
showPlaceholder() {
|
|
1567
|
+
var _a;
|
|
1568
|
+
if (!adContainerEl) {
|
|
1569
|
+
const container = document.createElement("div");
|
|
1570
|
+
container.style.position = "absolute";
|
|
1571
|
+
container.style.left = "0";
|
|
1572
|
+
container.style.top = "0";
|
|
1573
|
+
container.style.right = "0";
|
|
1574
|
+
container.style.bottom = "0";
|
|
1575
|
+
container.style.display = "none";
|
|
1576
|
+
container.style.alignItems = "center";
|
|
1577
|
+
container.style.justifyContent = "center";
|
|
1578
|
+
container.style.pointerEvents = "none";
|
|
1579
|
+
container.style.zIndex = "10";
|
|
1580
|
+
container.style.backgroundColor = "#000";
|
|
1581
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
1582
|
+
adContainerEl = container;
|
|
1583
|
+
}
|
|
1584
|
+
if (adContainerEl) {
|
|
1585
|
+
adContainerEl.style.display = "flex";
|
|
1586
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
1587
|
+
}
|
|
1588
|
+
},
|
|
1589
|
+
hidePlaceholder() {
|
|
1590
|
+
if (adContainerEl) {
|
|
1591
|
+
adContainerEl.style.display = "none";
|
|
1592
|
+
adContainerEl.style.pointerEvents = "none";
|
|
1593
|
+
}
|
|
1414
1594
|
}
|
|
1415
1595
|
};
|
|
1416
1596
|
}
|
|
@@ -1891,6 +2071,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1891
2071
|
this.bufferedSegmentsCount = 0;
|
|
1892
2072
|
this.shouldAutoplayAfterBuffering = false;
|
|
1893
2073
|
this.hasInitialBufferCompleted = false;
|
|
2074
|
+
this.adPodAllUrls = [];
|
|
2075
|
+
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
1894
2076
|
initializePolyfills();
|
|
1895
2077
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1896
2078
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2150,7 +2332,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2150
2332
|
this.video.autoplay = !!this.config.autoplay;
|
|
2151
2333
|
this.video.muted = !!this.config.muted;
|
|
2152
2334
|
this.ima.initialize();
|
|
2153
|
-
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2335
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
2154
2336
|
this.ima.on("all_ads_completed", () => {
|
|
2155
2337
|
if (this.config.debugAdTiming) {
|
|
2156
2338
|
console.log(
|
|
@@ -2191,6 +2373,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2191
2373
|
console.log("[StormcloudVideoPlayer] IMA content_pause event received");
|
|
2192
2374
|
}
|
|
2193
2375
|
this.clearAdFailsafeTimer();
|
|
2376
|
+
this.enforceAdHoldState();
|
|
2194
2377
|
});
|
|
2195
2378
|
this.ima.on("content_resume", () => {
|
|
2196
2379
|
if (this.config.debugAdTiming) {
|
|
@@ -2215,9 +2398,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2215
2398
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2216
2399
|
const next = this.adPodQueue.shift();
|
|
2217
2400
|
this.currentAdIndex++;
|
|
2218
|
-
this.
|
|
2219
|
-
this.video.muted = true;
|
|
2220
|
-
this.video.volume = 0;
|
|
2401
|
+
this.enforceAdHoldState();
|
|
2221
2402
|
if (this.config.debugAdTiming) {
|
|
2222
2403
|
console.log(
|
|
2223
2404
|
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
@@ -2829,11 +3010,16 @@ var StormcloudVideoPlayer = class {
|
|
|
2829
3010
|
return;
|
|
2830
3011
|
}
|
|
2831
3012
|
if (vastTagUrls.length > 0) {
|
|
3013
|
+
this.adPodAllUrls = [...vastTagUrls];
|
|
3014
|
+
this.preloadingAdUrls.clear();
|
|
3015
|
+
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
2832
3016
|
this.inAdBreak = true;
|
|
2833
3017
|
this.showAds = true;
|
|
2834
3018
|
this.currentAdIndex = 0;
|
|
2835
3019
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
2836
3020
|
this.adPodQueue = [...vastTagUrls];
|
|
3021
|
+
this.enforceAdHoldState();
|
|
3022
|
+
this.preloadUpcomingAds();
|
|
2837
3023
|
if (this.config.debugAdTiming) {
|
|
2838
3024
|
console.log(
|
|
2839
3025
|
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - will play continuously`
|
|
@@ -2904,6 +3090,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2904
3090
|
const first = tags[0];
|
|
2905
3091
|
const rest = tags.slice(1);
|
|
2906
3092
|
this.adPodQueue = rest;
|
|
3093
|
+
this.enforceAdHoldState();
|
|
2907
3094
|
await this.playSingleAd(first);
|
|
2908
3095
|
this.inAdBreak = true;
|
|
2909
3096
|
this.expectedAdBreakDurationMs = remainingMs;
|
|
@@ -3017,6 +3204,12 @@ var StormcloudVideoPlayer = class {
|
|
|
3017
3204
|
}
|
|
3018
3205
|
return;
|
|
3019
3206
|
}
|
|
3207
|
+
const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
|
|
3208
|
+
if (wasPreloaded && this.config.debugAdTiming) {
|
|
3209
|
+
console.log(
|
|
3210
|
+
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3211
|
+
);
|
|
3212
|
+
}
|
|
3020
3213
|
if (!this.showAds) {
|
|
3021
3214
|
if (this.config.debugAdTiming) {
|
|
3022
3215
|
console.log(
|
|
@@ -3028,7 +3221,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3028
3221
|
}
|
|
3029
3222
|
);
|
|
3030
3223
|
}
|
|
3031
|
-
this.ima.updateOriginalMutedState(this.video.muted);
|
|
3224
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3032
3225
|
} else if (this.config.debugAdTiming) {
|
|
3033
3226
|
console.log(
|
|
3034
3227
|
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
@@ -3037,12 +3230,14 @@ var StormcloudVideoPlayer = class {
|
|
|
3037
3230
|
this.startAdFailsafeTimer();
|
|
3038
3231
|
try {
|
|
3039
3232
|
await this.ima.requestAds(vastTagUrl);
|
|
3233
|
+
this.preloadUpcomingAds();
|
|
3040
3234
|
try {
|
|
3041
3235
|
if (this.config.debugAdTiming) {
|
|
3042
3236
|
console.log(
|
|
3043
3237
|
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
3044
3238
|
);
|
|
3045
3239
|
}
|
|
3240
|
+
this.enforceAdHoldState();
|
|
3046
3241
|
await this.ima.play();
|
|
3047
3242
|
if (this.config.debugAdTiming) {
|
|
3048
3243
|
console.log(
|
|
@@ -3072,6 +3267,8 @@ var StormcloudVideoPlayer = class {
|
|
|
3072
3267
|
"[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
|
|
3073
3268
|
);
|
|
3074
3269
|
}
|
|
3270
|
+
this.releaseAdHoldState();
|
|
3271
|
+
this.preloadingAdUrls.clear();
|
|
3075
3272
|
this.inAdBreak = false;
|
|
3076
3273
|
this.expectedAdBreakDurationMs = void 0;
|
|
3077
3274
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3079,14 +3276,16 @@ var StormcloudVideoPlayer = class {
|
|
|
3079
3276
|
this.clearAdStopTimer();
|
|
3080
3277
|
this.clearAdFailsafeTimer();
|
|
3081
3278
|
this.adPodQueue = [];
|
|
3279
|
+
this.adPodAllUrls = [];
|
|
3082
3280
|
this.showAds = false;
|
|
3083
3281
|
this.currentAdIndex = 0;
|
|
3084
3282
|
this.totalAdsInBreak = 0;
|
|
3085
3283
|
this.ima.stop().catch(() => {
|
|
3086
3284
|
});
|
|
3087
3285
|
const originalMutedState = this.ima.getOriginalMutedState();
|
|
3286
|
+
const originalVolume = typeof this.ima.getOriginalVolume === "function" ? this.ima.getOriginalVolume() : this.video.volume;
|
|
3088
3287
|
this.video.muted = originalMutedState;
|
|
3089
|
-
this.video.volume =
|
|
3288
|
+
this.video.volume = originalVolume;
|
|
3090
3289
|
if (this.config.debugAdTiming) {
|
|
3091
3290
|
console.log(
|
|
3092
3291
|
`[StormcloudVideoPlayer] Restored main video - muted: ${originalMutedState}, volume: ${this.video.volume}`
|
|
@@ -3159,6 +3358,64 @@ var StormcloudVideoPlayer = class {
|
|
|
3159
3358
|
}
|
|
3160
3359
|
return [b.vastTagUrl];
|
|
3161
3360
|
}
|
|
3361
|
+
logQueuedAdUrls(urls) {
|
|
3362
|
+
if (!this.config.debugAdTiming) {
|
|
3363
|
+
return;
|
|
3364
|
+
}
|
|
3365
|
+
console.log("[StormcloudVideoPlayer] ALL ad URLs queued:", urls);
|
|
3366
|
+
}
|
|
3367
|
+
enforceAdHoldState() {
|
|
3368
|
+
this.video.dataset.stormcloudAdPlaying = "true";
|
|
3369
|
+
this.video.muted = true;
|
|
3370
|
+
this.video.volume = 0;
|
|
3371
|
+
if (typeof this.ima.showPlaceholder === "function") {
|
|
3372
|
+
this.ima.showPlaceholder();
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
releaseAdHoldState() {
|
|
3376
|
+
delete this.video.dataset.stormcloudAdPlaying;
|
|
3377
|
+
if (typeof this.ima.hidePlaceholder === "function") {
|
|
3378
|
+
this.ima.hidePlaceholder();
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
preloadUpcomingAds() {
|
|
3382
|
+
if (!this.ima.preloadAds || this.adPodQueue.length === 0) {
|
|
3383
|
+
return;
|
|
3384
|
+
}
|
|
3385
|
+
const upcoming = this.adPodQueue.slice(0, 2);
|
|
3386
|
+
for (const url of upcoming) {
|
|
3387
|
+
if (!url) continue;
|
|
3388
|
+
if (this.ima.hasPreloadedAd(url)) {
|
|
3389
|
+
this.preloadingAdUrls.delete(url);
|
|
3390
|
+
continue;
|
|
3391
|
+
}
|
|
3392
|
+
if (this.preloadingAdUrls.has(url)) {
|
|
3393
|
+
continue;
|
|
3394
|
+
}
|
|
3395
|
+
if (this.config.debugAdTiming) {
|
|
3396
|
+
console.log(
|
|
3397
|
+
`[StormcloudVideoPlayer] Scheduling IMA preload for upcoming ad: ${url}`
|
|
3398
|
+
);
|
|
3399
|
+
}
|
|
3400
|
+
this.preloadingAdUrls.add(url);
|
|
3401
|
+
this.ima.preloadAds(url).then(() => {
|
|
3402
|
+
if (this.config.debugAdTiming) {
|
|
3403
|
+
console.log(
|
|
3404
|
+
`[StormcloudVideoPlayer] IMA preload complete for ad: ${url}`
|
|
3405
|
+
);
|
|
3406
|
+
}
|
|
3407
|
+
}).catch((error) => {
|
|
3408
|
+
if (this.config.debugAdTiming) {
|
|
3409
|
+
console.warn(
|
|
3410
|
+
`[StormcloudVideoPlayer] IMA preload failed for ad: ${url}`,
|
|
3411
|
+
error
|
|
3412
|
+
);
|
|
3413
|
+
}
|
|
3414
|
+
}).finally(() => {
|
|
3415
|
+
this.preloadingAdUrls.delete(url);
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3162
3419
|
getRemainingAdMs() {
|
|
3163
3420
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3164
3421
|
return 0;
|
|
@@ -3179,7 +3436,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3179
3436
|
if (this.ima.isAdPlaying()) {
|
|
3180
3437
|
const currentPerceptualState = this.isMuted();
|
|
3181
3438
|
const newMutedState = !currentPerceptualState;
|
|
3182
|
-
this.ima.updateOriginalMutedState(newMutedState);
|
|
3439
|
+
this.ima.updateOriginalMutedState(newMutedState, this.video.volume);
|
|
3183
3440
|
this.ima.setAdVolume(newMutedState ? 0 : 1);
|
|
3184
3441
|
if (this.config.debugAdTiming) {
|
|
3185
3442
|
console.log(
|
|
@@ -3189,7 +3446,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3189
3446
|
}
|
|
3190
3447
|
} else {
|
|
3191
3448
|
this.video.muted = !this.video.muted;
|
|
3192
|
-
this.ima.updateOriginalMutedState(this.video.muted);
|
|
3449
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3193
3450
|
if (this.config.debugAdTiming) {
|
|
3194
3451
|
console.log("[StormcloudVideoPlayer] Muted:", this.video.muted);
|
|
3195
3452
|
}
|
|
@@ -3261,7 +3518,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3261
3518
|
}
|
|
3262
3519
|
this.video.muted = muted;
|
|
3263
3520
|
if (adPlaying) {
|
|
3264
|
-
this.ima.updateOriginalMutedState(muted);
|
|
3521
|
+
this.ima.updateOriginalMutedState(muted, this.video.volume);
|
|
3265
3522
|
this.ima.setAdVolume(muted ? 0 : 1);
|
|
3266
3523
|
if (this.config.debugAdTiming) {
|
|
3267
3524
|
console.log("[StormcloudVideoPlayer] setMuted applied during ad", {
|
|
@@ -3270,7 +3527,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3270
3527
|
}
|
|
3271
3528
|
return;
|
|
3272
3529
|
}
|
|
3273
|
-
this.ima.updateOriginalMutedState(muted);
|
|
3530
|
+
this.ima.updateOriginalMutedState(muted, this.video.volume);
|
|
3274
3531
|
if (this.config.debugAdTiming) {
|
|
3275
3532
|
console.log("[StormcloudVideoPlayer] setMuted called:", muted);
|
|
3276
3533
|
}
|
|
@@ -3310,6 +3567,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3310
3567
|
}
|
|
3311
3568
|
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
3312
3569
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3570
|
+
this.releaseAdHoldState();
|
|
3571
|
+
this.preloadingAdUrls.clear();
|
|
3572
|
+
this.adPodAllUrls = [];
|
|
3313
3573
|
}
|
|
3314
3574
|
};
|
|
3315
3575
|
|