stormcloud-video-player 0.2.16 → 0.2.18
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 +387 -56
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +6 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +387 -56
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +266 -23
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +5 -1
- package/lib/players/HlsPlayer.cjs +268 -23
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +268 -23
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +76 -12
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/sdk/ima.cjs +73 -2
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/sdk/ima.d.cts +1 -1
- package/lib/{types-mVgmKmzM.d.cts → types-J6-Dpcvw.d.cts} +1 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +383 -56
- 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
|
@@ -200,6 +200,13 @@ function createImaController(video, options) {
|
|
|
200
200
|
let adPlaying = false;
|
|
201
201
|
let originalMutedState = false;
|
|
202
202
|
const listeners = /* @__PURE__ */ new Map();
|
|
203
|
+
function setAdPlayingFlag(isPlaying) {
|
|
204
|
+
if (isPlaying) {
|
|
205
|
+
video.dataset.stormcloudAdPlaying = "true";
|
|
206
|
+
} else {
|
|
207
|
+
delete video.dataset.stormcloudAdPlaying;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
203
210
|
function emit(event, payload) {
|
|
204
211
|
const set = listeners.get(event);
|
|
205
212
|
if (!set) return;
|
|
@@ -284,6 +291,14 @@ function createImaController(video, options) {
|
|
|
284
291
|
function makeAdsRequest(google, vastTagUrl) {
|
|
285
292
|
const adsRequest = new google.ima.AdsRequest();
|
|
286
293
|
adsRequest.adTagUrl = vastTagUrl;
|
|
294
|
+
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
295
|
+
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
296
|
+
adsRequest.linearAdSlotWidth = videoWidth;
|
|
297
|
+
adsRequest.linearAdSlotHeight = videoHeight;
|
|
298
|
+
adsRequest.nonLinearAdSlotWidth = videoWidth;
|
|
299
|
+
adsRequest.nonLinearAdSlotHeight = videoHeight;
|
|
300
|
+
adsRequest.vastLoadTimeout = 5e3;
|
|
301
|
+
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
287
302
|
adsLoader.requestAds(adsRequest);
|
|
288
303
|
}
|
|
289
304
|
function destroyAdsManager() {
|
|
@@ -330,6 +345,18 @@ function createImaController(video, options) {
|
|
|
330
345
|
},
|
|
331
346
|
async requestAds(vastTagUrl) {
|
|
332
347
|
console.log("[IMA] Requesting ads:", vastTagUrl);
|
|
348
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
349
|
+
const error = new Error("VAST tag URL is empty or undefined");
|
|
350
|
+
console.warn("[IMA]", error.message);
|
|
351
|
+
return Promise.reject(error);
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
new URL(vastTagUrl);
|
|
355
|
+
} catch (e) {
|
|
356
|
+
const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);
|
|
357
|
+
console.warn("[IMA]", error.message);
|
|
358
|
+
return Promise.reject(error);
|
|
359
|
+
}
|
|
333
360
|
if (adPlaying) {
|
|
334
361
|
console.warn(
|
|
335
362
|
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
@@ -391,6 +418,18 @@ function createImaController(video, options) {
|
|
|
391
418
|
);
|
|
392
419
|
}
|
|
393
420
|
}
|
|
421
|
+
const videoWidth = video.offsetWidth || video.clientWidth;
|
|
422
|
+
const videoHeight = video.offsetHeight || video.clientHeight;
|
|
423
|
+
if (!videoWidth || !videoHeight || videoWidth === 0 || videoHeight === 0) {
|
|
424
|
+
const error = new Error(
|
|
425
|
+
`Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`
|
|
426
|
+
);
|
|
427
|
+
console.warn("[IMA]", error.message);
|
|
428
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
429
|
+
adsLoadedReject = void 0;
|
|
430
|
+
adsLoadedResolve = void 0;
|
|
431
|
+
return Promise.reject(error);
|
|
432
|
+
}
|
|
394
433
|
if (!adsLoader) {
|
|
395
434
|
console.log("[IMA] Creating ads loader");
|
|
396
435
|
const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
|
|
@@ -410,7 +449,12 @@ function createImaController(video, options) {
|
|
|
410
449
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
411
450
|
destroyAdsManager();
|
|
412
451
|
adPlaying = false;
|
|
452
|
+
const previousMutedState = video.muted;
|
|
413
453
|
video.muted = originalMutedState;
|
|
454
|
+
setAdPlayingFlag(false);
|
|
455
|
+
console.log(
|
|
456
|
+
`[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
|
|
457
|
+
);
|
|
414
458
|
if (adContainerEl) {
|
|
415
459
|
adContainerEl.style.pointerEvents = "none";
|
|
416
460
|
adContainerEl.style.display = "none";
|
|
@@ -439,7 +483,9 @@ function createImaController(video, options) {
|
|
|
439
483
|
emit("ad_error");
|
|
440
484
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
441
485
|
if (video.paused) {
|
|
442
|
-
console.log(
|
|
486
|
+
console.log(
|
|
487
|
+
"[IMA] Resuming paused video after ad error"
|
|
488
|
+
);
|
|
443
489
|
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
444
490
|
});
|
|
445
491
|
}
|
|
@@ -461,11 +507,13 @@ function createImaController(video, options) {
|
|
|
461
507
|
}
|
|
462
508
|
video.muted = true;
|
|
463
509
|
adPlaying = true;
|
|
510
|
+
setAdPlayingFlag(true);
|
|
464
511
|
emit("content_pause");
|
|
465
512
|
}
|
|
466
513
|
);
|
|
467
514
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
468
515
|
console.log("[IMA] Ad started playing");
|
|
516
|
+
setAdPlayingFlag(true);
|
|
469
517
|
if (adContainerEl) {
|
|
470
518
|
adContainerEl.style.pointerEvents = "auto";
|
|
471
519
|
adContainerEl.style.display = "flex";
|
|
@@ -481,6 +529,7 @@ function createImaController(video, options) {
|
|
|
481
529
|
console.log("[IMA] Content resume requested");
|
|
482
530
|
adPlaying = false;
|
|
483
531
|
video.muted = originalMutedState;
|
|
532
|
+
setAdPlayingFlag(false);
|
|
484
533
|
if (adContainerEl) {
|
|
485
534
|
adContainerEl.style.pointerEvents = "none";
|
|
486
535
|
adContainerEl.style.display = "none";
|
|
@@ -504,6 +553,7 @@ function createImaController(video, options) {
|
|
|
504
553
|
console.log("[IMA] All ads completed");
|
|
505
554
|
adPlaying = false;
|
|
506
555
|
video.muted = originalMutedState;
|
|
556
|
+
setAdPlayingFlag(false);
|
|
507
557
|
if (adContainerEl) {
|
|
508
558
|
adContainerEl.style.pointerEvents = "none";
|
|
509
559
|
adContainerEl.style.display = "none";
|
|
@@ -534,6 +584,7 @@ function createImaController(video, options) {
|
|
|
534
584
|
console.error("[IMA] Error setting up ads manager:", e);
|
|
535
585
|
adPlaying = false;
|
|
536
586
|
video.muted = originalMutedState;
|
|
587
|
+
setAdPlayingFlag(false);
|
|
537
588
|
if (adContainerEl) {
|
|
538
589
|
adContainerEl.style.pointerEvents = "none";
|
|
539
590
|
adContainerEl.style.display = "none";
|
|
@@ -541,7 +592,9 @@ function createImaController(video, options) {
|
|
|
541
592
|
}
|
|
542
593
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
543
594
|
if (video.paused) {
|
|
544
|
-
console.log(
|
|
595
|
+
console.log(
|
|
596
|
+
"[IMA] Resuming paused video after setup error"
|
|
597
|
+
);
|
|
545
598
|
video.play().catch(() => {
|
|
546
599
|
});
|
|
547
600
|
}
|
|
@@ -561,7 +614,12 @@ function createImaController(video, options) {
|
|
|
561
614
|
(adErrorEvent) => {
|
|
562
615
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
563
616
|
adPlaying = false;
|
|
617
|
+
const previousMutedState = video.muted;
|
|
564
618
|
video.muted = originalMutedState;
|
|
619
|
+
setAdPlayingFlag(false);
|
|
620
|
+
console.log(
|
|
621
|
+
`[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
622
|
+
);
|
|
565
623
|
if (adContainerEl) {
|
|
566
624
|
adContainerEl.style.pointerEvents = "none";
|
|
567
625
|
adContainerEl.style.display = "none";
|
|
@@ -613,12 +671,20 @@ function createImaController(video, options) {
|
|
|
613
671
|
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
614
672
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
615
673
|
adPlaying = true;
|
|
674
|
+
const adVolume = originalMutedState ? 0 : video.volume;
|
|
675
|
+
try {
|
|
676
|
+
adsManager.setVolume(adVolume);
|
|
677
|
+
console.log(`[IMA] Set ad volume to ${adVolume}`);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
console.warn("[IMA] Failed to set ad volume:", error);
|
|
680
|
+
}
|
|
616
681
|
console.log("[IMA] Starting ad playback");
|
|
617
682
|
adsManager.start();
|
|
618
683
|
return Promise.resolve();
|
|
619
684
|
} catch (error) {
|
|
620
685
|
console.error("[IMA] Error starting ad playback:", error);
|
|
621
686
|
adPlaying = false;
|
|
687
|
+
setAdPlayingFlag(false);
|
|
622
688
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
623
689
|
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
624
690
|
});
|
|
@@ -630,6 +696,7 @@ function createImaController(video, options) {
|
|
|
630
696
|
var _a;
|
|
631
697
|
adPlaying = false;
|
|
632
698
|
video.muted = originalMutedState;
|
|
699
|
+
setAdPlayingFlag(false);
|
|
633
700
|
if (adContainerEl) {
|
|
634
701
|
adContainerEl.style.pointerEvents = "none";
|
|
635
702
|
adContainerEl.style.display = "none";
|
|
@@ -653,6 +720,7 @@ function createImaController(video, options) {
|
|
|
653
720
|
destroyAdsManager();
|
|
654
721
|
adPlaying = false;
|
|
655
722
|
video.muted = originalMutedState;
|
|
723
|
+
setAdPlayingFlag(false);
|
|
656
724
|
if (adContainerEl) {
|
|
657
725
|
adContainerEl.style.pointerEvents = "none";
|
|
658
726
|
adContainerEl.style.display = "none";
|
|
@@ -695,6 +763,9 @@ function createImaController(video, options) {
|
|
|
695
763
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
696
764
|
},
|
|
697
765
|
updateOriginalMutedState(muted) {
|
|
766
|
+
console.log(
|
|
767
|
+
`[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
768
|
+
);
|
|
698
769
|
originalMutedState = muted;
|
|
699
770
|
},
|
|
700
771
|
getOriginalMutedState() {
|
|
@@ -751,7 +822,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
751
822
|
try {
|
|
752
823
|
fn(payload);
|
|
753
824
|
} catch (error) {
|
|
754
|
-
console.warn(
|
|
825
|
+
console.warn(
|
|
826
|
+
`[HlsAdPlayer] Error in event listener for ${event}:`,
|
|
827
|
+
error
|
|
828
|
+
);
|
|
755
829
|
}
|
|
756
830
|
}
|
|
757
831
|
}
|
|
@@ -814,7 +888,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
814
888
|
}
|
|
815
889
|
const mainQuality = getMainStreamQuality();
|
|
816
890
|
if (!mainQuality) {
|
|
817
|
-
console.log(
|
|
891
|
+
console.log(
|
|
892
|
+
"[HlsAdPlayer] No main stream quality info, using first media file"
|
|
893
|
+
);
|
|
818
894
|
return firstFile;
|
|
819
895
|
}
|
|
820
896
|
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
@@ -850,7 +926,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
850
926
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
851
927
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
852
928
|
if (parserError) {
|
|
853
|
-
console.error(
|
|
929
|
+
console.error(
|
|
930
|
+
"[HlsAdPlayer] XML parsing error (malformed VAST XML):",
|
|
931
|
+
parserError.textContent
|
|
932
|
+
);
|
|
854
933
|
return null;
|
|
855
934
|
}
|
|
856
935
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -866,17 +945,23 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
866
945
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
867
946
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
868
947
|
const mediaFiles = [];
|
|
869
|
-
console.log(
|
|
948
|
+
console.log(
|
|
949
|
+
`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`
|
|
950
|
+
);
|
|
870
951
|
mediaFileElements.forEach((mf, index) => {
|
|
871
952
|
var _a2;
|
|
872
953
|
const type = mf.getAttribute("type") || "";
|
|
873
954
|
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
874
955
|
const width = mf.getAttribute("width") || "";
|
|
875
956
|
const height = mf.getAttribute("height") || "";
|
|
876
|
-
console.log(
|
|
957
|
+
console.log(
|
|
958
|
+
`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`
|
|
959
|
+
);
|
|
877
960
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
878
961
|
if (!url) {
|
|
879
|
-
console.warn(
|
|
962
|
+
console.warn(
|
|
963
|
+
`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`
|
|
964
|
+
);
|
|
880
965
|
return;
|
|
881
966
|
}
|
|
882
967
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
@@ -890,12 +975,16 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
890
975
|
});
|
|
891
976
|
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
892
977
|
} else {
|
|
893
|
-
console.log(
|
|
978
|
+
console.log(
|
|
979
|
+
`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`
|
|
980
|
+
);
|
|
894
981
|
}
|
|
895
982
|
});
|
|
896
983
|
if (mediaFiles.length === 0) {
|
|
897
984
|
if (isNoAdAvailable) {
|
|
898
|
-
console.warn(
|
|
985
|
+
console.warn(
|
|
986
|
+
"[HlsAdPlayer] No ads available (VAST response indicates no ads)"
|
|
987
|
+
);
|
|
899
988
|
} else {
|
|
900
989
|
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
901
990
|
}
|
|
@@ -958,6 +1047,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
958
1047
|
video.style.backgroundColor = "#000";
|
|
959
1048
|
video.playsInline = true;
|
|
960
1049
|
video.muted = false;
|
|
1050
|
+
video.volume = 1;
|
|
1051
|
+
console.log(
|
|
1052
|
+
`[HlsAdPlayer] Created ad video element with volume ${video.volume}`
|
|
1053
|
+
);
|
|
961
1054
|
return video;
|
|
962
1055
|
}
|
|
963
1056
|
function setupAdEventListeners() {
|
|
@@ -1017,10 +1110,22 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1017
1110
|
}
|
|
1018
1111
|
});
|
|
1019
1112
|
}
|
|
1113
|
+
function setAdPlayingFlag(isPlaying) {
|
|
1114
|
+
if (isPlaying) {
|
|
1115
|
+
contentVideo.dataset.stormcloudAdPlaying = "true";
|
|
1116
|
+
} else {
|
|
1117
|
+
delete contentVideo.dataset.stormcloudAdPlaying;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1020
1120
|
function handleAdComplete() {
|
|
1021
1121
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1022
1122
|
adPlaying = false;
|
|
1123
|
+
setAdPlayingFlag(false);
|
|
1124
|
+
const previousMutedState = contentVideo.muted;
|
|
1023
1125
|
contentVideo.muted = originalMutedState;
|
|
1126
|
+
console.log(
|
|
1127
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1128
|
+
);
|
|
1024
1129
|
if (adContainerEl) {
|
|
1025
1130
|
adContainerEl.style.display = "none";
|
|
1026
1131
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1038,7 +1143,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1038
1143
|
function handleAdError() {
|
|
1039
1144
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1040
1145
|
adPlaying = false;
|
|
1146
|
+
setAdPlayingFlag(false);
|
|
1147
|
+
const previousMutedState = contentVideo.muted;
|
|
1041
1148
|
contentVideo.muted = originalMutedState;
|
|
1149
|
+
console.log(
|
|
1150
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1151
|
+
);
|
|
1042
1152
|
if (adContainerEl) {
|
|
1043
1153
|
adContainerEl.style.display = "none";
|
|
1044
1154
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1075,7 +1185,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1075
1185
|
async requestAds(vastTagUrl) {
|
|
1076
1186
|
console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
|
|
1077
1187
|
if (adPlaying) {
|
|
1078
|
-
console.warn(
|
|
1188
|
+
console.warn(
|
|
1189
|
+
"[HlsAdPlayer] Cannot request new ads while an ad is playing"
|
|
1190
|
+
);
|
|
1079
1191
|
return Promise.reject(new Error("Ad already playing"));
|
|
1080
1192
|
}
|
|
1081
1193
|
try {
|
|
@@ -1086,14 +1198,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1086
1198
|
}
|
|
1087
1199
|
const vastXml = await response.text();
|
|
1088
1200
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1089
|
-
console.log(
|
|
1201
|
+
console.log(
|
|
1202
|
+
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1203
|
+
vastXml.substring(0, 2e3)
|
|
1204
|
+
);
|
|
1090
1205
|
const ad = parseVastXml(vastXml);
|
|
1091
1206
|
if (!ad) {
|
|
1092
1207
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1208
|
+
emit("ad_error");
|
|
1093
1209
|
return Promise.resolve();
|
|
1094
1210
|
}
|
|
1095
1211
|
currentAd = ad;
|
|
1096
|
-
console.log(
|
|
1212
|
+
console.log(
|
|
1213
|
+
`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`
|
|
1214
|
+
);
|
|
1097
1215
|
fireTrackingPixels(ad.trackingUrls.impression);
|
|
1098
1216
|
trackingFired.impression = true;
|
|
1099
1217
|
return Promise.resolve();
|
|
@@ -1105,7 +1223,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1105
1223
|
},
|
|
1106
1224
|
async play() {
|
|
1107
1225
|
if (!currentAd) {
|
|
1108
|
-
console.warn(
|
|
1226
|
+
console.warn(
|
|
1227
|
+
"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)"
|
|
1228
|
+
);
|
|
1109
1229
|
return Promise.reject(new Error("No ad loaded"));
|
|
1110
1230
|
}
|
|
1111
1231
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
@@ -1123,6 +1243,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1123
1243
|
thirdQuartile: false,
|
|
1124
1244
|
complete: false
|
|
1125
1245
|
};
|
|
1246
|
+
const contentVolume = contentVideo.volume;
|
|
1126
1247
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1127
1248
|
contentVideo.pause();
|
|
1128
1249
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
@@ -1131,6 +1252,15 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1131
1252
|
}
|
|
1132
1253
|
contentVideo.muted = true;
|
|
1133
1254
|
adPlaying = true;
|
|
1255
|
+
setAdPlayingFlag(true);
|
|
1256
|
+
if (adVideoElement) {
|
|
1257
|
+
const adVolume = originalMutedState ? 0 : contentVolume;
|
|
1258
|
+
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
1259
|
+
adVideoElement.muted = false;
|
|
1260
|
+
console.log(
|
|
1261
|
+
`[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1134
1264
|
if (adContainerEl) {
|
|
1135
1265
|
adContainerEl.style.display = "flex";
|
|
1136
1266
|
adContainerEl.style.pointerEvents = "auto";
|
|
@@ -1183,6 +1313,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1183
1313
|
async stop() {
|
|
1184
1314
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1185
1315
|
adPlaying = false;
|
|
1316
|
+
setAdPlayingFlag(false);
|
|
1186
1317
|
contentVideo.muted = originalMutedState;
|
|
1187
1318
|
if (adContainerEl) {
|
|
1188
1319
|
adContainerEl.style.display = "none";
|
|
@@ -1205,6 +1336,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1205
1336
|
destroy() {
|
|
1206
1337
|
console.log("[HlsAdPlayer] Destroying");
|
|
1207
1338
|
adPlaying = false;
|
|
1339
|
+
setAdPlayingFlag(false);
|
|
1208
1340
|
contentVideo.muted = originalMutedState;
|
|
1209
1341
|
if (adHls) {
|
|
1210
1342
|
adHls.destroy();
|
|
@@ -1246,6 +1378,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1246
1378
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1247
1379
|
},
|
|
1248
1380
|
updateOriginalMutedState(muted) {
|
|
1381
|
+
console.log(
|
|
1382
|
+
`[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
1383
|
+
);
|
|
1249
1384
|
originalMutedState = muted;
|
|
1250
1385
|
},
|
|
1251
1386
|
getOriginalMutedState() {
|
|
@@ -1738,6 +1873,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1738
1873
|
this.isLiveStream = false;
|
|
1739
1874
|
this.nativeHlsMode = false;
|
|
1740
1875
|
this.videoSrcProtection = null;
|
|
1876
|
+
this.bufferedSegmentsCount = 0;
|
|
1877
|
+
this.shouldAutoplayAfterBuffering = false;
|
|
1878
|
+
this.hasInitialBufferCompleted = false;
|
|
1741
1879
|
initializePolyfills();
|
|
1742
1880
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1743
1881
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1824,14 +1962,22 @@ var StormcloudVideoPlayer = class {
|
|
|
1824
1962
|
liveDurationInfinity: true,
|
|
1825
1963
|
lowLatencyMode: !!this.config.lowLatencyMode,
|
|
1826
1964
|
maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,
|
|
1827
|
-
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1965
|
+
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},
|
|
1966
|
+
maxBufferLength: 30,
|
|
1967
|
+
maxMaxBufferLength: 600,
|
|
1968
|
+
maxBufferSize: 60 * 1e3 * 1e3,
|
|
1969
|
+
maxBufferHole: 0.5,
|
|
1970
|
+
highBufferWatchdogPeriod: 2,
|
|
1971
|
+
nudgeOffset: 0.1,
|
|
1972
|
+
nudgeMaxRetry: 3,
|
|
1973
|
+
startPosition: -1
|
|
1828
1974
|
});
|
|
1829
1975
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1830
1976
|
var _a2;
|
|
1831
1977
|
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1832
1978
|
});
|
|
1833
1979
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1834
|
-
var _a2, _b2, _c, _d;
|
|
1980
|
+
var _a2, _b2, _c, _d, _e;
|
|
1835
1981
|
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1836
1982
|
(level) => {
|
|
1837
1983
|
var _a3, _b3;
|
|
@@ -1849,9 +1995,51 @@ var StormcloudVideoPlayer = class {
|
|
|
1849
1995
|
this.ima.destroy();
|
|
1850
1996
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1851
1997
|
this.ima.initialize();
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1998
|
+
this.bufferedSegmentsCount = 0;
|
|
1999
|
+
this.hasInitialBufferCompleted = false;
|
|
2000
|
+
this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
|
|
2001
|
+
const minSegments = (_d = this.config.minSegmentsBeforePlay) != null ? _d : 2;
|
|
2002
|
+
if (this.config.debugAdTiming) {
|
|
2003
|
+
console.log(
|
|
2004
|
+
"[StormcloudVideoPlayer] Waiting for",
|
|
2005
|
+
minSegments,
|
|
2006
|
+
"segments to buffer before playback"
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
if (minSegments === 0 || !this.config.autoplay) {
|
|
2010
|
+
this.hasInitialBufferCompleted = true;
|
|
2011
|
+
if (this.config.autoplay) {
|
|
2012
|
+
await ((_e = this.video.play()) == null ? void 0 : _e.catch(() => {
|
|
2013
|
+
}));
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, data) => {
|
|
2018
|
+
var _a2, _b2;
|
|
2019
|
+
if (this.hasInitialBufferCompleted) {
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
this.bufferedSegmentsCount++;
|
|
2023
|
+
const minSegments = (_a2 = this.config.minSegmentsBeforePlay) != null ? _a2 : 2;
|
|
2024
|
+
if (this.config.debugAdTiming) {
|
|
2025
|
+
console.log(
|
|
2026
|
+
`[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`
|
|
2027
|
+
);
|
|
2028
|
+
}
|
|
2029
|
+
if (this.bufferedSegmentsCount >= minSegments) {
|
|
2030
|
+
this.hasInitialBufferCompleted = true;
|
|
2031
|
+
if (this.shouldAutoplayAfterBuffering) {
|
|
2032
|
+
if (this.config.debugAdTiming) {
|
|
2033
|
+
console.log(
|
|
2034
|
+
`[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`
|
|
2035
|
+
);
|
|
2036
|
+
}
|
|
2037
|
+
await ((_b2 = this.video.play()) == null ? void 0 : _b2.catch((err) => {
|
|
2038
|
+
if (this.config.debugAdTiming) {
|
|
2039
|
+
console.warn("[StormcloudVideoPlayer] Autoplay failed:", err);
|
|
2040
|
+
}
|
|
2041
|
+
}));
|
|
2042
|
+
}
|
|
1855
2043
|
}
|
|
1856
2044
|
});
|
|
1857
2045
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
@@ -1947,6 +2135,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1947
2135
|
this.video.autoplay = !!this.config.autoplay;
|
|
1948
2136
|
this.video.muted = !!this.config.muted;
|
|
1949
2137
|
this.ima.initialize();
|
|
2138
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
1950
2139
|
this.ima.on("all_ads_completed", () => {
|
|
1951
2140
|
if (this.config.debugAdTiming) {
|
|
1952
2141
|
console.log(
|
|
@@ -2731,7 +2920,23 @@ var StormcloudVideoPlayer = class {
|
|
|
2731
2920
|
}
|
|
2732
2921
|
return;
|
|
2733
2922
|
}
|
|
2734
|
-
|
|
2923
|
+
if (!this.showAds) {
|
|
2924
|
+
if (this.config.debugAdTiming) {
|
|
2925
|
+
console.log(
|
|
2926
|
+
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
2927
|
+
{
|
|
2928
|
+
videoMuted: this.video.muted,
|
|
2929
|
+
videoVolume: this.video.volume,
|
|
2930
|
+
showAds: this.showAds
|
|
2931
|
+
}
|
|
2932
|
+
);
|
|
2933
|
+
}
|
|
2934
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2935
|
+
} else if (this.config.debugAdTiming) {
|
|
2936
|
+
console.log(
|
|
2937
|
+
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
2938
|
+
);
|
|
2939
|
+
}
|
|
2735
2940
|
this.startAdFailsafeTimer();
|
|
2736
2941
|
try {
|
|
2737
2942
|
await this.ima.requestAds(vastTagUrl);
|
|
@@ -2786,11 +2991,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2786
2991
|
this.showAds = false;
|
|
2787
2992
|
this.currentAdIndex = 0;
|
|
2788
2993
|
this.totalAdsInBreak = 0;
|
|
2994
|
+
const currentMutedState = this.video.muted;
|
|
2789
2995
|
const originalMutedState = this.ima.getOriginalMutedState();
|
|
2790
2996
|
this.video.muted = originalMutedState;
|
|
2791
2997
|
if (this.config.debugAdTiming) {
|
|
2792
2998
|
console.log(
|
|
2793
|
-
`[StormcloudVideoPlayer] Restored mute state
|
|
2999
|
+
`[StormcloudVideoPlayer] Restored mute state: ${currentMutedState} -> ${originalMutedState}`
|
|
2794
3000
|
);
|
|
2795
3001
|
}
|
|
2796
3002
|
if (this.video.paused) {
|
|
@@ -2882,6 +3088,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2882
3088
|
}
|
|
2883
3089
|
} else {
|
|
2884
3090
|
this.video.muted = !this.video.muted;
|
|
3091
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2885
3092
|
if (this.config.debugAdTiming) {
|
|
2886
3093
|
console.log("[StormcloudVideoPlayer] Muted:", this.video.muted);
|
|
2887
3094
|
}
|
|
@@ -2926,11 +3133,47 @@ var StormcloudVideoPlayer = class {
|
|
|
2926
3133
|
}
|
|
2927
3134
|
isMuted() {
|
|
2928
3135
|
if (this.ima.isAdPlaying()) {
|
|
2929
|
-
|
|
2930
|
-
|
|
3136
|
+
if (this.config.debugAdTiming) {
|
|
3137
|
+
console.log(
|
|
3138
|
+
"[StormcloudVideoPlayer] isMuted() override during ad playback -> false"
|
|
3139
|
+
);
|
|
3140
|
+
}
|
|
3141
|
+
return false;
|
|
3142
|
+
}
|
|
3143
|
+
if (this.config.debugAdTiming) {
|
|
3144
|
+
console.log(
|
|
3145
|
+
`[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
|
|
3146
|
+
);
|
|
2931
3147
|
}
|
|
2932
3148
|
return this.video.muted;
|
|
2933
3149
|
}
|
|
3150
|
+
setMuted(muted) {
|
|
3151
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
3152
|
+
if (adPlaying && muted === this.video.muted) {
|
|
3153
|
+
if (this.config.debugAdTiming) {
|
|
3154
|
+
console.log(
|
|
3155
|
+
"[StormcloudVideoPlayer] setMuted reflective update during ad ignored",
|
|
3156
|
+
{ muted }
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
3159
|
+
return;
|
|
3160
|
+
}
|
|
3161
|
+
this.video.muted = muted;
|
|
3162
|
+
if (adPlaying) {
|
|
3163
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3164
|
+
this.ima.setAdVolume(muted ? 0 : 1);
|
|
3165
|
+
if (this.config.debugAdTiming) {
|
|
3166
|
+
console.log("[StormcloudVideoPlayer] setMuted applied during ad", {
|
|
3167
|
+
muted
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3173
|
+
if (this.config.debugAdTiming) {
|
|
3174
|
+
console.log("[StormcloudVideoPlayer] setMuted called:", muted);
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
2934
3177
|
isFullscreen() {
|
|
2935
3178
|
return !!document.fullscreenElement;
|
|
2936
3179
|
}
|