stormcloud-video-player 0.2.17 → 0.2.19
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 +403 -56
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +8 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +403 -56
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +282 -23
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +5 -1
- package/lib/players/HlsPlayer.cjs +284 -23
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +284 -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 +35 -0
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/sdk/ima.d.cts +1 -1
- package/lib/{types-mVgmKmzM.d.cts → types-D1xfSdLP.d.cts} +3 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +399 -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
package/lib/index.js
CHANGED
|
@@ -198,6 +198,13 @@ function createImaController(video, options) {
|
|
|
198
198
|
let adPlaying = false;
|
|
199
199
|
let originalMutedState = false;
|
|
200
200
|
const listeners = /* @__PURE__ */ new Map();
|
|
201
|
+
function setAdPlayingFlag(isPlaying) {
|
|
202
|
+
if (isPlaying) {
|
|
203
|
+
video.dataset.stormcloudAdPlaying = "true";
|
|
204
|
+
} else {
|
|
205
|
+
delete video.dataset.stormcloudAdPlaying;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
201
208
|
function emit(event, payload) {
|
|
202
209
|
const set = listeners.get(event);
|
|
203
210
|
if (!set) return;
|
|
@@ -440,7 +447,12 @@ function createImaController(video, options) {
|
|
|
440
447
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
441
448
|
destroyAdsManager();
|
|
442
449
|
adPlaying = false;
|
|
450
|
+
const previousMutedState = video.muted;
|
|
443
451
|
video.muted = originalMutedState;
|
|
452
|
+
setAdPlayingFlag(false);
|
|
453
|
+
console.log(
|
|
454
|
+
`[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
|
|
455
|
+
);
|
|
444
456
|
if (adContainerEl) {
|
|
445
457
|
adContainerEl.style.pointerEvents = "none";
|
|
446
458
|
adContainerEl.style.display = "none";
|
|
@@ -493,11 +505,13 @@ function createImaController(video, options) {
|
|
|
493
505
|
}
|
|
494
506
|
video.muted = true;
|
|
495
507
|
adPlaying = true;
|
|
508
|
+
setAdPlayingFlag(true);
|
|
496
509
|
emit("content_pause");
|
|
497
510
|
}
|
|
498
511
|
);
|
|
499
512
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
500
513
|
console.log("[IMA] Ad started playing");
|
|
514
|
+
setAdPlayingFlag(true);
|
|
501
515
|
if (adContainerEl) {
|
|
502
516
|
adContainerEl.style.pointerEvents = "auto";
|
|
503
517
|
adContainerEl.style.display = "flex";
|
|
@@ -513,6 +527,7 @@ function createImaController(video, options) {
|
|
|
513
527
|
console.log("[IMA] Content resume requested");
|
|
514
528
|
adPlaying = false;
|
|
515
529
|
video.muted = originalMutedState;
|
|
530
|
+
setAdPlayingFlag(false);
|
|
516
531
|
if (adContainerEl) {
|
|
517
532
|
adContainerEl.style.pointerEvents = "none";
|
|
518
533
|
adContainerEl.style.display = "none";
|
|
@@ -536,6 +551,7 @@ function createImaController(video, options) {
|
|
|
536
551
|
console.log("[IMA] All ads completed");
|
|
537
552
|
adPlaying = false;
|
|
538
553
|
video.muted = originalMutedState;
|
|
554
|
+
setAdPlayingFlag(false);
|
|
539
555
|
if (adContainerEl) {
|
|
540
556
|
adContainerEl.style.pointerEvents = "none";
|
|
541
557
|
adContainerEl.style.display = "none";
|
|
@@ -566,6 +582,7 @@ function createImaController(video, options) {
|
|
|
566
582
|
console.error("[IMA] Error setting up ads manager:", e);
|
|
567
583
|
adPlaying = false;
|
|
568
584
|
video.muted = originalMutedState;
|
|
585
|
+
setAdPlayingFlag(false);
|
|
569
586
|
if (adContainerEl) {
|
|
570
587
|
adContainerEl.style.pointerEvents = "none";
|
|
571
588
|
adContainerEl.style.display = "none";
|
|
@@ -595,7 +612,12 @@ function createImaController(video, options) {
|
|
|
595
612
|
(adErrorEvent) => {
|
|
596
613
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
597
614
|
adPlaying = false;
|
|
615
|
+
const previousMutedState = video.muted;
|
|
598
616
|
video.muted = originalMutedState;
|
|
617
|
+
setAdPlayingFlag(false);
|
|
618
|
+
console.log(
|
|
619
|
+
`[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
620
|
+
);
|
|
599
621
|
if (adContainerEl) {
|
|
600
622
|
adContainerEl.style.pointerEvents = "none";
|
|
601
623
|
adContainerEl.style.display = "none";
|
|
@@ -647,12 +669,20 @@ function createImaController(video, options) {
|
|
|
647
669
|
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
648
670
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
649
671
|
adPlaying = true;
|
|
672
|
+
const adVolume = originalMutedState ? 0 : video.volume;
|
|
673
|
+
try {
|
|
674
|
+
adsManager.setVolume(adVolume);
|
|
675
|
+
console.log(`[IMA] Set ad volume to ${adVolume}`);
|
|
676
|
+
} catch (error) {
|
|
677
|
+
console.warn("[IMA] Failed to set ad volume:", error);
|
|
678
|
+
}
|
|
650
679
|
console.log("[IMA] Starting ad playback");
|
|
651
680
|
adsManager.start();
|
|
652
681
|
return Promise.resolve();
|
|
653
682
|
} catch (error) {
|
|
654
683
|
console.error("[IMA] Error starting ad playback:", error);
|
|
655
684
|
adPlaying = false;
|
|
685
|
+
setAdPlayingFlag(false);
|
|
656
686
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
657
687
|
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
658
688
|
});
|
|
@@ -664,6 +694,7 @@ function createImaController(video, options) {
|
|
|
664
694
|
var _a;
|
|
665
695
|
adPlaying = false;
|
|
666
696
|
video.muted = originalMutedState;
|
|
697
|
+
setAdPlayingFlag(false);
|
|
667
698
|
if (adContainerEl) {
|
|
668
699
|
adContainerEl.style.pointerEvents = "none";
|
|
669
700
|
adContainerEl.style.display = "none";
|
|
@@ -687,6 +718,7 @@ function createImaController(video, options) {
|
|
|
687
718
|
destroyAdsManager();
|
|
688
719
|
adPlaying = false;
|
|
689
720
|
video.muted = originalMutedState;
|
|
721
|
+
setAdPlayingFlag(false);
|
|
690
722
|
if (adContainerEl) {
|
|
691
723
|
adContainerEl.style.pointerEvents = "none";
|
|
692
724
|
adContainerEl.style.display = "none";
|
|
@@ -729,6 +761,9 @@ function createImaController(video, options) {
|
|
|
729
761
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
730
762
|
},
|
|
731
763
|
updateOriginalMutedState(muted) {
|
|
764
|
+
console.log(
|
|
765
|
+
`[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
766
|
+
);
|
|
732
767
|
originalMutedState = muted;
|
|
733
768
|
},
|
|
734
769
|
getOriginalMutedState() {
|
|
@@ -785,7 +820,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
785
820
|
try {
|
|
786
821
|
fn(payload);
|
|
787
822
|
} catch (error) {
|
|
788
|
-
console.warn(
|
|
823
|
+
console.warn(
|
|
824
|
+
`[HlsAdPlayer] Error in event listener for ${event}:`,
|
|
825
|
+
error
|
|
826
|
+
);
|
|
789
827
|
}
|
|
790
828
|
}
|
|
791
829
|
}
|
|
@@ -848,7 +886,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
848
886
|
}
|
|
849
887
|
const mainQuality = getMainStreamQuality();
|
|
850
888
|
if (!mainQuality) {
|
|
851
|
-
console.log(
|
|
889
|
+
console.log(
|
|
890
|
+
"[HlsAdPlayer] No main stream quality info, using first media file"
|
|
891
|
+
);
|
|
852
892
|
return firstFile;
|
|
853
893
|
}
|
|
854
894
|
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
@@ -884,7 +924,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
884
924
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
885
925
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
886
926
|
if (parserError) {
|
|
887
|
-
console.error(
|
|
927
|
+
console.error(
|
|
928
|
+
"[HlsAdPlayer] XML parsing error (malformed VAST XML):",
|
|
929
|
+
parserError.textContent
|
|
930
|
+
);
|
|
888
931
|
return null;
|
|
889
932
|
}
|
|
890
933
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -900,17 +943,23 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
900
943
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
901
944
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
902
945
|
const mediaFiles = [];
|
|
903
|
-
console.log(
|
|
946
|
+
console.log(
|
|
947
|
+
`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`
|
|
948
|
+
);
|
|
904
949
|
mediaFileElements.forEach((mf, index) => {
|
|
905
950
|
var _a2;
|
|
906
951
|
const type = mf.getAttribute("type") || "";
|
|
907
952
|
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
908
953
|
const width = mf.getAttribute("width") || "";
|
|
909
954
|
const height = mf.getAttribute("height") || "";
|
|
910
|
-
console.log(
|
|
955
|
+
console.log(
|
|
956
|
+
`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`
|
|
957
|
+
);
|
|
911
958
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
912
959
|
if (!url) {
|
|
913
|
-
console.warn(
|
|
960
|
+
console.warn(
|
|
961
|
+
`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`
|
|
962
|
+
);
|
|
914
963
|
return;
|
|
915
964
|
}
|
|
916
965
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
@@ -924,12 +973,16 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
924
973
|
});
|
|
925
974
|
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
926
975
|
} else {
|
|
927
|
-
console.log(
|
|
976
|
+
console.log(
|
|
977
|
+
`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`
|
|
978
|
+
);
|
|
928
979
|
}
|
|
929
980
|
});
|
|
930
981
|
if (mediaFiles.length === 0) {
|
|
931
982
|
if (isNoAdAvailable) {
|
|
932
|
-
console.warn(
|
|
983
|
+
console.warn(
|
|
984
|
+
"[HlsAdPlayer] No ads available (VAST response indicates no ads)"
|
|
985
|
+
);
|
|
933
986
|
} else {
|
|
934
987
|
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
935
988
|
}
|
|
@@ -992,6 +1045,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
992
1045
|
video.style.backgroundColor = "#000";
|
|
993
1046
|
video.playsInline = true;
|
|
994
1047
|
video.muted = false;
|
|
1048
|
+
video.volume = 1;
|
|
1049
|
+
console.log(
|
|
1050
|
+
`[HlsAdPlayer] Created ad video element with volume ${video.volume}`
|
|
1051
|
+
);
|
|
995
1052
|
return video;
|
|
996
1053
|
}
|
|
997
1054
|
function setupAdEventListeners() {
|
|
@@ -1051,10 +1108,22 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1051
1108
|
}
|
|
1052
1109
|
});
|
|
1053
1110
|
}
|
|
1111
|
+
function setAdPlayingFlag(isPlaying) {
|
|
1112
|
+
if (isPlaying) {
|
|
1113
|
+
contentVideo.dataset.stormcloudAdPlaying = "true";
|
|
1114
|
+
} else {
|
|
1115
|
+
delete contentVideo.dataset.stormcloudAdPlaying;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1054
1118
|
function handleAdComplete() {
|
|
1055
1119
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1056
1120
|
adPlaying = false;
|
|
1121
|
+
setAdPlayingFlag(false);
|
|
1122
|
+
const previousMutedState = contentVideo.muted;
|
|
1057
1123
|
contentVideo.muted = originalMutedState;
|
|
1124
|
+
console.log(
|
|
1125
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1126
|
+
);
|
|
1058
1127
|
if (adContainerEl) {
|
|
1059
1128
|
adContainerEl.style.display = "none";
|
|
1060
1129
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1072,7 +1141,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1072
1141
|
function handleAdError() {
|
|
1073
1142
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1074
1143
|
adPlaying = false;
|
|
1144
|
+
setAdPlayingFlag(false);
|
|
1145
|
+
const previousMutedState = contentVideo.muted;
|
|
1075
1146
|
contentVideo.muted = originalMutedState;
|
|
1147
|
+
console.log(
|
|
1148
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1149
|
+
);
|
|
1076
1150
|
if (adContainerEl) {
|
|
1077
1151
|
adContainerEl.style.display = "none";
|
|
1078
1152
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1109,7 +1183,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1109
1183
|
async requestAds(vastTagUrl) {
|
|
1110
1184
|
console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
|
|
1111
1185
|
if (adPlaying) {
|
|
1112
|
-
console.warn(
|
|
1186
|
+
console.warn(
|
|
1187
|
+
"[HlsAdPlayer] Cannot request new ads while an ad is playing"
|
|
1188
|
+
);
|
|
1113
1189
|
return Promise.reject(new Error("Ad already playing"));
|
|
1114
1190
|
}
|
|
1115
1191
|
try {
|
|
@@ -1120,14 +1196,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1120
1196
|
}
|
|
1121
1197
|
const vastXml = await response.text();
|
|
1122
1198
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1123
|
-
console.log(
|
|
1199
|
+
console.log(
|
|
1200
|
+
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1201
|
+
vastXml.substring(0, 2e3)
|
|
1202
|
+
);
|
|
1124
1203
|
const ad = parseVastXml(vastXml);
|
|
1125
1204
|
if (!ad) {
|
|
1126
1205
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1206
|
+
emit("ad_error");
|
|
1127
1207
|
return Promise.resolve();
|
|
1128
1208
|
}
|
|
1129
1209
|
currentAd = ad;
|
|
1130
|
-
console.log(
|
|
1210
|
+
console.log(
|
|
1211
|
+
`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`
|
|
1212
|
+
);
|
|
1131
1213
|
fireTrackingPixels(ad.trackingUrls.impression);
|
|
1132
1214
|
trackingFired.impression = true;
|
|
1133
1215
|
return Promise.resolve();
|
|
@@ -1139,7 +1221,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1139
1221
|
},
|
|
1140
1222
|
async play() {
|
|
1141
1223
|
if (!currentAd) {
|
|
1142
|
-
console.warn(
|
|
1224
|
+
console.warn(
|
|
1225
|
+
"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)"
|
|
1226
|
+
);
|
|
1143
1227
|
return Promise.reject(new Error("No ad loaded"));
|
|
1144
1228
|
}
|
|
1145
1229
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
@@ -1157,6 +1241,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1157
1241
|
thirdQuartile: false,
|
|
1158
1242
|
complete: false
|
|
1159
1243
|
};
|
|
1244
|
+
const contentVolume = contentVideo.volume;
|
|
1160
1245
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1161
1246
|
contentVideo.pause();
|
|
1162
1247
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
@@ -1165,6 +1250,15 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1165
1250
|
}
|
|
1166
1251
|
contentVideo.muted = true;
|
|
1167
1252
|
adPlaying = true;
|
|
1253
|
+
setAdPlayingFlag(true);
|
|
1254
|
+
if (adVideoElement) {
|
|
1255
|
+
const adVolume = originalMutedState ? 0 : contentVolume;
|
|
1256
|
+
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
1257
|
+
adVideoElement.muted = false;
|
|
1258
|
+
console.log(
|
|
1259
|
+
`[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`
|
|
1260
|
+
);
|
|
1261
|
+
}
|
|
1168
1262
|
if (adContainerEl) {
|
|
1169
1263
|
adContainerEl.style.display = "flex";
|
|
1170
1264
|
adContainerEl.style.pointerEvents = "auto";
|
|
@@ -1217,6 +1311,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1217
1311
|
async stop() {
|
|
1218
1312
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1219
1313
|
adPlaying = false;
|
|
1314
|
+
setAdPlayingFlag(false);
|
|
1220
1315
|
contentVideo.muted = originalMutedState;
|
|
1221
1316
|
if (adContainerEl) {
|
|
1222
1317
|
adContainerEl.style.display = "none";
|
|
@@ -1239,6 +1334,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1239
1334
|
destroy() {
|
|
1240
1335
|
console.log("[HlsAdPlayer] Destroying");
|
|
1241
1336
|
adPlaying = false;
|
|
1337
|
+
setAdPlayingFlag(false);
|
|
1242
1338
|
contentVideo.muted = originalMutedState;
|
|
1243
1339
|
if (adHls) {
|
|
1244
1340
|
adHls.destroy();
|
|
@@ -1280,6 +1376,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1280
1376
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1281
1377
|
},
|
|
1282
1378
|
updateOriginalMutedState(muted) {
|
|
1379
|
+
console.log(
|
|
1380
|
+
`[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
1381
|
+
);
|
|
1283
1382
|
originalMutedState = muted;
|
|
1284
1383
|
},
|
|
1285
1384
|
getOriginalMutedState() {
|
|
@@ -1772,6 +1871,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1772
1871
|
this.isLiveStream = false;
|
|
1773
1872
|
this.nativeHlsMode = false;
|
|
1774
1873
|
this.videoSrcProtection = null;
|
|
1874
|
+
this.bufferedSegmentsCount = 0;
|
|
1875
|
+
this.shouldAutoplayAfterBuffering = false;
|
|
1876
|
+
this.hasInitialBufferCompleted = false;
|
|
1775
1877
|
initializePolyfills();
|
|
1776
1878
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1777
1879
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1858,14 +1960,22 @@ var StormcloudVideoPlayer = class {
|
|
|
1858
1960
|
liveDurationInfinity: true,
|
|
1859
1961
|
lowLatencyMode: !!this.config.lowLatencyMode,
|
|
1860
1962
|
maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,
|
|
1861
|
-
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1963
|
+
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},
|
|
1964
|
+
maxBufferLength: 30,
|
|
1965
|
+
maxMaxBufferLength: 600,
|
|
1966
|
+
maxBufferSize: 60 * 1e3 * 1e3,
|
|
1967
|
+
maxBufferHole: 0.5,
|
|
1968
|
+
highBufferWatchdogPeriod: 2,
|
|
1969
|
+
nudgeOffset: 0.1,
|
|
1970
|
+
nudgeMaxRetry: 3,
|
|
1971
|
+
startPosition: -1
|
|
1862
1972
|
});
|
|
1863
1973
|
this.hls.on(Hls2.Events.MEDIA_ATTACHED, () => {
|
|
1864
1974
|
var _a2;
|
|
1865
1975
|
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1866
1976
|
});
|
|
1867
1977
|
this.hls.on(Hls2.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1868
|
-
var _a2, _b2, _c, _d;
|
|
1978
|
+
var _a2, _b2, _c, _d, _e;
|
|
1869
1979
|
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1870
1980
|
(level) => {
|
|
1871
1981
|
var _a3, _b3;
|
|
@@ -1883,9 +1993,51 @@ var StormcloudVideoPlayer = class {
|
|
|
1883
1993
|
this.ima.destroy();
|
|
1884
1994
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1885
1995
|
this.ima.initialize();
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1996
|
+
this.bufferedSegmentsCount = 0;
|
|
1997
|
+
this.hasInitialBufferCompleted = false;
|
|
1998
|
+
this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
|
|
1999
|
+
const minSegments = (_d = this.config.minSegmentsBeforePlay) != null ? _d : 2;
|
|
2000
|
+
if (this.config.debugAdTiming) {
|
|
2001
|
+
console.log(
|
|
2002
|
+
"[StormcloudVideoPlayer] Waiting for",
|
|
2003
|
+
minSegments,
|
|
2004
|
+
"segments to buffer before playback"
|
|
2005
|
+
);
|
|
2006
|
+
}
|
|
2007
|
+
if (minSegments === 0 || !this.config.autoplay) {
|
|
2008
|
+
this.hasInitialBufferCompleted = true;
|
|
2009
|
+
if (this.config.autoplay) {
|
|
2010
|
+
await ((_e = this.video.play()) == null ? void 0 : _e.catch(() => {
|
|
2011
|
+
}));
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
2015
|
+
this.hls.on(Hls2.Events.FRAG_BUFFERED, async (_evt, data) => {
|
|
2016
|
+
var _a2, _b2;
|
|
2017
|
+
if (this.hasInitialBufferCompleted) {
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
this.bufferedSegmentsCount++;
|
|
2021
|
+
const minSegments = (_a2 = this.config.minSegmentsBeforePlay) != null ? _a2 : 2;
|
|
2022
|
+
if (this.config.debugAdTiming) {
|
|
2023
|
+
console.log(
|
|
2024
|
+
`[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
if (this.bufferedSegmentsCount >= minSegments) {
|
|
2028
|
+
this.hasInitialBufferCompleted = true;
|
|
2029
|
+
if (this.shouldAutoplayAfterBuffering) {
|
|
2030
|
+
if (this.config.debugAdTiming) {
|
|
2031
|
+
console.log(
|
|
2032
|
+
`[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
await ((_b2 = this.video.play()) == null ? void 0 : _b2.catch((err) => {
|
|
2036
|
+
if (this.config.debugAdTiming) {
|
|
2037
|
+
console.warn("[StormcloudVideoPlayer] Autoplay failed:", err);
|
|
2038
|
+
}
|
|
2039
|
+
}));
|
|
2040
|
+
}
|
|
1889
2041
|
}
|
|
1890
2042
|
});
|
|
1891
2043
|
this.hls.on(Hls2.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
@@ -1981,6 +2133,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1981
2133
|
this.video.autoplay = !!this.config.autoplay;
|
|
1982
2134
|
this.video.muted = !!this.config.muted;
|
|
1983
2135
|
this.ima.initialize();
|
|
2136
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
1984
2137
|
this.ima.on("all_ads_completed", () => {
|
|
1985
2138
|
if (this.config.debugAdTiming) {
|
|
1986
2139
|
console.log(
|
|
@@ -2718,14 +2871,66 @@ var StormcloudVideoPlayer = class {
|
|
|
2718
2871
|
}
|
|
2719
2872
|
}
|
|
2720
2873
|
ensureAdStoppedByTimer() {
|
|
2874
|
+
var _a, _b;
|
|
2721
2875
|
if (!this.inAdBreak) return;
|
|
2876
|
+
this.adStopTimerId = void 0;
|
|
2877
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
2878
|
+
const pendingAds = this.adPodQueue.length > 0;
|
|
2879
|
+
const checkIntervalMs = Math.max(
|
|
2880
|
+
250,
|
|
2881
|
+
Math.floor((_a = this.config.adBreakCheckIntervalMs) != null ? _a : 1e3)
|
|
2882
|
+
);
|
|
2883
|
+
const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
|
|
2884
|
+
const maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
|
|
2885
|
+
let elapsedSinceStartMs = 0;
|
|
2886
|
+
if (this.currentAdBreakStartWallClockMs != null) {
|
|
2887
|
+
elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
|
|
2888
|
+
}
|
|
2889
|
+
const expectedDurationMs = (_b = this.expectedAdBreakDurationMs) != null ? _b : 0;
|
|
2890
|
+
const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
|
|
2891
|
+
const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
|
|
2892
|
+
if (shouldExtendAdBreak) {
|
|
2893
|
+
if (this.config.debugAdTiming) {
|
|
2894
|
+
console.log(
|
|
2895
|
+
"[StormcloudVideoPlayer] Extending ad break beyond scheduled duration",
|
|
2896
|
+
{
|
|
2897
|
+
adPlaying,
|
|
2898
|
+
pendingAds,
|
|
2899
|
+
showAds: this.showAds,
|
|
2900
|
+
overrunMs,
|
|
2901
|
+
checkIntervalMs,
|
|
2902
|
+
maxExtensionMs
|
|
2903
|
+
}
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2906
|
+
this.scheduleAdStopCountdown(checkIntervalMs);
|
|
2907
|
+
return;
|
|
2908
|
+
}
|
|
2909
|
+
if (this.config.debugAdTiming) {
|
|
2910
|
+
console.log("[StormcloudVideoPlayer] Ending ad break via timer", {
|
|
2911
|
+
adPlaying,
|
|
2912
|
+
pendingAds,
|
|
2913
|
+
showAds: this.showAds,
|
|
2914
|
+
overrunMs,
|
|
2915
|
+
maxExtensionMs
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2722
2918
|
this.inAdBreak = false;
|
|
2723
2919
|
this.expectedAdBreakDurationMs = void 0;
|
|
2724
2920
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
2725
|
-
this.
|
|
2726
|
-
|
|
2921
|
+
this.showAds = false;
|
|
2922
|
+
this.adPodQueue = [];
|
|
2923
|
+
this.currentAdIndex = 0;
|
|
2924
|
+
this.totalAdsInBreak = 0;
|
|
2925
|
+
this.clearAdFailsafeTimer();
|
|
2926
|
+
if (adPlaying) {
|
|
2727
2927
|
this.ima.stop().catch(() => {
|
|
2728
2928
|
});
|
|
2929
|
+
return;
|
|
2930
|
+
}
|
|
2931
|
+
const originalMutedState = this.ima.getOriginalMutedState();
|
|
2932
|
+
if (this.video.muted !== originalMutedState) {
|
|
2933
|
+
this.video.muted = originalMutedState;
|
|
2729
2934
|
}
|
|
2730
2935
|
}
|
|
2731
2936
|
scheduleAdStartIn(delayMs) {
|
|
@@ -2765,7 +2970,23 @@ var StormcloudVideoPlayer = class {
|
|
|
2765
2970
|
}
|
|
2766
2971
|
return;
|
|
2767
2972
|
}
|
|
2768
|
-
|
|
2973
|
+
if (!this.showAds) {
|
|
2974
|
+
if (this.config.debugAdTiming) {
|
|
2975
|
+
console.log(
|
|
2976
|
+
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
2977
|
+
{
|
|
2978
|
+
videoMuted: this.video.muted,
|
|
2979
|
+
videoVolume: this.video.volume,
|
|
2980
|
+
showAds: this.showAds
|
|
2981
|
+
}
|
|
2982
|
+
);
|
|
2983
|
+
}
|
|
2984
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2985
|
+
} else if (this.config.debugAdTiming) {
|
|
2986
|
+
console.log(
|
|
2987
|
+
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
2988
|
+
);
|
|
2989
|
+
}
|
|
2769
2990
|
this.startAdFailsafeTimer();
|
|
2770
2991
|
try {
|
|
2771
2992
|
await this.ima.requestAds(vastTagUrl);
|
|
@@ -2820,11 +3041,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2820
3041
|
this.showAds = false;
|
|
2821
3042
|
this.currentAdIndex = 0;
|
|
2822
3043
|
this.totalAdsInBreak = 0;
|
|
3044
|
+
const currentMutedState = this.video.muted;
|
|
2823
3045
|
const originalMutedState = this.ima.getOriginalMutedState();
|
|
2824
3046
|
this.video.muted = originalMutedState;
|
|
2825
3047
|
if (this.config.debugAdTiming) {
|
|
2826
3048
|
console.log(
|
|
2827
|
-
`[StormcloudVideoPlayer] Restored mute state
|
|
3049
|
+
`[StormcloudVideoPlayer] Restored mute state: ${currentMutedState} -> ${originalMutedState}`
|
|
2828
3050
|
);
|
|
2829
3051
|
}
|
|
2830
3052
|
if (this.video.paused) {
|
|
@@ -2916,6 +3138,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2916
3138
|
}
|
|
2917
3139
|
} else {
|
|
2918
3140
|
this.video.muted = !this.video.muted;
|
|
3141
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2919
3142
|
if (this.config.debugAdTiming) {
|
|
2920
3143
|
console.log("[StormcloudVideoPlayer] Muted:", this.video.muted);
|
|
2921
3144
|
}
|
|
@@ -2960,11 +3183,47 @@ var StormcloudVideoPlayer = class {
|
|
|
2960
3183
|
}
|
|
2961
3184
|
isMuted() {
|
|
2962
3185
|
if (this.ima.isAdPlaying()) {
|
|
2963
|
-
|
|
2964
|
-
|
|
3186
|
+
if (this.config.debugAdTiming) {
|
|
3187
|
+
console.log(
|
|
3188
|
+
"[StormcloudVideoPlayer] isMuted() override during ad playback -> false"
|
|
3189
|
+
);
|
|
3190
|
+
}
|
|
3191
|
+
return false;
|
|
3192
|
+
}
|
|
3193
|
+
if (this.config.debugAdTiming) {
|
|
3194
|
+
console.log(
|
|
3195
|
+
`[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
|
|
3196
|
+
);
|
|
2965
3197
|
}
|
|
2966
3198
|
return this.video.muted;
|
|
2967
3199
|
}
|
|
3200
|
+
setMuted(muted) {
|
|
3201
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
3202
|
+
if (adPlaying && muted === this.video.muted) {
|
|
3203
|
+
if (this.config.debugAdTiming) {
|
|
3204
|
+
console.log(
|
|
3205
|
+
"[StormcloudVideoPlayer] setMuted reflective update during ad ignored",
|
|
3206
|
+
{ muted }
|
|
3207
|
+
);
|
|
3208
|
+
}
|
|
3209
|
+
return;
|
|
3210
|
+
}
|
|
3211
|
+
this.video.muted = muted;
|
|
3212
|
+
if (adPlaying) {
|
|
3213
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3214
|
+
this.ima.setAdVolume(muted ? 0 : 1);
|
|
3215
|
+
if (this.config.debugAdTiming) {
|
|
3216
|
+
console.log("[StormcloudVideoPlayer] setMuted applied during ad", {
|
|
3217
|
+
muted
|
|
3218
|
+
});
|
|
3219
|
+
}
|
|
3220
|
+
return;
|
|
3221
|
+
}
|
|
3222
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3223
|
+
if (this.config.debugAdTiming) {
|
|
3224
|
+
console.log("[StormcloudVideoPlayer] setMuted called:", muted);
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
2968
3227
|
isFullscreen() {
|
|
2969
3228
|
return !!document.fullscreenElement;
|
|
2970
3229
|
}
|
|
@@ -3052,10 +3311,12 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3052
3311
|
vastMode,
|
|
3053
3312
|
vastTagUrl,
|
|
3054
3313
|
adPlayerType,
|
|
3314
|
+
minSegmentsBeforePlay,
|
|
3055
3315
|
...restVideoAttrs
|
|
3056
3316
|
} = props;
|
|
3057
3317
|
const videoRef = useRef(null);
|
|
3058
3318
|
const playerRef = useRef(null);
|
|
3319
|
+
const bufferingTimeoutRef = useRef(null);
|
|
3059
3320
|
const [adStatus, setAdStatus] = React.useState({ showAds: false, currentIndex: 0, totalAds: 0 });
|
|
3060
3321
|
const [shouldShowNativeControls, setShouldShowNativeControls] = React.useState(true);
|
|
3061
3322
|
const [isMuted, setIsMuted] = React.useState(false);
|
|
@@ -3177,6 +3438,9 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3177
3438
|
return;
|
|
3178
3439
|
}
|
|
3179
3440
|
setShowLicenseWarning(false);
|
|
3441
|
+
if (debugAdTiming) {
|
|
3442
|
+
console.log("[StormcloudUI] Initializing player, isLoading=true");
|
|
3443
|
+
}
|
|
3180
3444
|
if (playerRef.current) {
|
|
3181
3445
|
try {
|
|
3182
3446
|
playerRef.current.destroy();
|
|
@@ -3207,17 +3471,25 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3207
3471
|
if (vastMode !== void 0) cfg.vastMode = vastMode;
|
|
3208
3472
|
if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;
|
|
3209
3473
|
if (adPlayerType !== void 0) cfg.adPlayerType = adPlayerType;
|
|
3474
|
+
if (minSegmentsBeforePlay !== void 0)
|
|
3475
|
+
cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
|
|
3210
3476
|
const player = new StormcloudVideoPlayer(cfg);
|
|
3211
3477
|
playerRef.current = player;
|
|
3212
3478
|
player.load().then(() => {
|
|
3213
3479
|
const showNative = player.shouldShowNativeControls();
|
|
3214
3480
|
setShouldShowNativeControls(showNative);
|
|
3481
|
+
if (debugAdTiming) {
|
|
3482
|
+
console.log(
|
|
3483
|
+
"[StormcloudUI] Player loaded successfully, waiting for video ready"
|
|
3484
|
+
);
|
|
3485
|
+
}
|
|
3215
3486
|
onReady == null ? void 0 : onReady(player);
|
|
3216
3487
|
}).catch((error) => {
|
|
3217
3488
|
console.error(
|
|
3218
3489
|
"StormcloudVideoPlayer: Failed to load player:",
|
|
3219
3490
|
error
|
|
3220
3491
|
);
|
|
3492
|
+
setIsLoading(false);
|
|
3221
3493
|
onReady == null ? void 0 : onReady(player);
|
|
3222
3494
|
});
|
|
3223
3495
|
return () => {
|
|
@@ -3234,8 +3506,8 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3234
3506
|
if (autoplay !== void 0 && playerRef.current.videoElement) {
|
|
3235
3507
|
playerRef.current.videoElement.autoplay = autoplay;
|
|
3236
3508
|
}
|
|
3237
|
-
if (muted !== void 0
|
|
3238
|
-
playerRef.current.
|
|
3509
|
+
if (muted !== void 0) {
|
|
3510
|
+
playerRef.current.setMuted(muted);
|
|
3239
3511
|
}
|
|
3240
3512
|
} catch (error) {
|
|
3241
3513
|
console.warn("Failed to update player properties:", error);
|
|
@@ -3316,26 +3588,108 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3316
3588
|
useEffect(() => {
|
|
3317
3589
|
if (!videoRef.current) return;
|
|
3318
3590
|
const handleLoadedMetadata = () => {
|
|
3591
|
+
var _a;
|
|
3319
3592
|
if (videoRef.current) {
|
|
3320
3593
|
const video2 = videoRef.current;
|
|
3321
3594
|
void video2.offsetHeight;
|
|
3322
3595
|
}
|
|
3596
|
+
if (debugAdTiming) {
|
|
3597
|
+
console.log(
|
|
3598
|
+
"[StormcloudUI] Video event: loadedmetadata, readyState:",
|
|
3599
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3600
|
+
);
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
const handleLoadedData = () => {
|
|
3604
|
+
var _a;
|
|
3605
|
+
if (debugAdTiming) {
|
|
3606
|
+
console.log(
|
|
3607
|
+
"[StormcloudUI] Video event: loadeddata, readyState:",
|
|
3608
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3609
|
+
);
|
|
3610
|
+
}
|
|
3323
3611
|
};
|
|
3324
3612
|
const handleLoadStart = () => {
|
|
3325
|
-
|
|
3326
|
-
|
|
3613
|
+
var _a;
|
|
3614
|
+
if (debugAdTiming) {
|
|
3615
|
+
console.log(
|
|
3616
|
+
"[StormcloudUI] Video event: loadstart, readyState:",
|
|
3617
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3618
|
+
);
|
|
3619
|
+
}
|
|
3327
3620
|
};
|
|
3328
3621
|
const handleCanPlay = () => {
|
|
3622
|
+
var _a;
|
|
3623
|
+
setIsLoading(false);
|
|
3624
|
+
if (bufferingTimeoutRef.current) {
|
|
3625
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3626
|
+
bufferingTimeoutRef.current = null;
|
|
3627
|
+
}
|
|
3628
|
+
setIsBuffering(false);
|
|
3629
|
+
if (debugAdTiming) {
|
|
3630
|
+
console.log(
|
|
3631
|
+
"[StormcloudUI] Video event: canplay, readyState:",
|
|
3632
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3633
|
+
"- clearing loading state, isLoading=false"
|
|
3634
|
+
);
|
|
3635
|
+
}
|
|
3636
|
+
};
|
|
3637
|
+
const handleCanPlayThrough = () => {
|
|
3638
|
+
var _a;
|
|
3329
3639
|
setIsLoading(false);
|
|
3640
|
+
if (bufferingTimeoutRef.current) {
|
|
3641
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3642
|
+
bufferingTimeoutRef.current = null;
|
|
3643
|
+
}
|
|
3330
3644
|
setIsBuffering(false);
|
|
3645
|
+
if (debugAdTiming) {
|
|
3646
|
+
console.log(
|
|
3647
|
+
"[StormcloudUI] Video event: canplaythrough, readyState:",
|
|
3648
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3649
|
+
"- clearing loading state, isLoading=false"
|
|
3650
|
+
);
|
|
3651
|
+
}
|
|
3331
3652
|
};
|
|
3332
3653
|
const handleWaiting = () => {
|
|
3333
|
-
|
|
3654
|
+
var _a;
|
|
3655
|
+
if (bufferingTimeoutRef.current) {
|
|
3656
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3657
|
+
}
|
|
3658
|
+
bufferingTimeoutRef.current = window.setTimeout(() => {
|
|
3659
|
+
var _a2;
|
|
3660
|
+
setIsBuffering(true);
|
|
3661
|
+
if (debugAdTiming) {
|
|
3662
|
+
console.log(
|
|
3663
|
+
"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:",
|
|
3664
|
+
(_a2 = videoRef.current) == null ? void 0 : _a2.readyState,
|
|
3665
|
+
"- showing spinner, isBuffering=true"
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
}, 300);
|
|
3669
|
+
if (debugAdTiming) {
|
|
3670
|
+
console.log(
|
|
3671
|
+
"[StormcloudUI] Video event: waiting, readyState:",
|
|
3672
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3673
|
+
"- buffering delay started (300ms)"
|
|
3674
|
+
);
|
|
3675
|
+
}
|
|
3334
3676
|
};
|
|
3335
3677
|
const handlePlaying = () => {
|
|
3678
|
+
var _a;
|
|
3336
3679
|
setIsLoading(false);
|
|
3680
|
+
if (bufferingTimeoutRef.current) {
|
|
3681
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3682
|
+
bufferingTimeoutRef.current = null;
|
|
3683
|
+
}
|
|
3337
3684
|
setIsBuffering(false);
|
|
3338
3685
|
setShowCenterPlay(false);
|
|
3686
|
+
if (debugAdTiming) {
|
|
3687
|
+
console.log(
|
|
3688
|
+
"[StormcloudUI] Video event: playing, readyState:",
|
|
3689
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3690
|
+
"- playback started, isLoading=false, isBuffering=false"
|
|
3691
|
+
);
|
|
3692
|
+
}
|
|
3339
3693
|
};
|
|
3340
3694
|
const handlePause = () => {
|
|
3341
3695
|
if (playerRef.current && !playerRef.current.isShowingAds()) {
|
|
@@ -3350,8 +3704,9 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3350
3704
|
const video = videoRef.current;
|
|
3351
3705
|
video.addEventListener("loadstart", handleLoadStart);
|
|
3352
3706
|
video.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
3353
|
-
video.addEventListener("loadeddata",
|
|
3707
|
+
video.addEventListener("loadeddata", handleLoadedData);
|
|
3354
3708
|
video.addEventListener("canplay", handleCanPlay);
|
|
3709
|
+
video.addEventListener("canplaythrough", handleCanPlayThrough);
|
|
3355
3710
|
video.addEventListener("waiting", handleWaiting);
|
|
3356
3711
|
video.addEventListener("playing", handlePlaying);
|
|
3357
3712
|
video.addEventListener("pause", handlePause);
|
|
@@ -3360,16 +3715,21 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3360
3715
|
setShowCenterPlay(true);
|
|
3361
3716
|
}
|
|
3362
3717
|
return () => {
|
|
3718
|
+
if (bufferingTimeoutRef.current) {
|
|
3719
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3720
|
+
bufferingTimeoutRef.current = null;
|
|
3721
|
+
}
|
|
3363
3722
|
video.removeEventListener("loadstart", handleLoadStart);
|
|
3364
3723
|
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
3365
|
-
video.removeEventListener("loadeddata",
|
|
3724
|
+
video.removeEventListener("loadeddata", handleLoadedData);
|
|
3366
3725
|
video.removeEventListener("canplay", handleCanPlay);
|
|
3726
|
+
video.removeEventListener("canplaythrough", handleCanPlayThrough);
|
|
3367
3727
|
video.removeEventListener("waiting", handleWaiting);
|
|
3368
3728
|
video.removeEventListener("playing", handlePlaying);
|
|
3369
3729
|
video.removeEventListener("pause", handlePause);
|
|
3370
3730
|
video.removeEventListener("ended", handleEnded);
|
|
3371
3731
|
};
|
|
3372
|
-
}, []);
|
|
3732
|
+
}, [debugAdTiming]);
|
|
3373
3733
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3374
3734
|
/* @__PURE__ */ jsx("style", { children: `
|
|
3375
3735
|
@keyframes spin {
|
|
@@ -3476,35 +3836,18 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3476
3836
|
}
|
|
3477
3837
|
),
|
|
3478
3838
|
(isLoading || isBuffering) && /* @__PURE__ */ jsx(
|
|
3479
|
-
|
|
3839
|
+
FaSpinner,
|
|
3480
3840
|
{
|
|
3841
|
+
size: 42,
|
|
3842
|
+
color: "white",
|
|
3481
3843
|
style: {
|
|
3482
3844
|
position: "absolute",
|
|
3483
|
-
top: "50%",
|
|
3484
|
-
left: "50%",
|
|
3485
|
-
transform: "translate(-50%, -50%)",
|
|
3845
|
+
top: "calc(50% - 21px)",
|
|
3846
|
+
left: "calc(50% - 21px)",
|
|
3486
3847
|
zIndex: 20,
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(20, 20, 20, 0.6) 100%)",
|
|
3491
|
-
width: "80px",
|
|
3492
|
-
height: "80px",
|
|
3493
|
-
borderRadius: "50%",
|
|
3494
|
-
backdropFilter: "blur(20px)",
|
|
3495
|
-
boxShadow: "0 12px 40px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.1)"
|
|
3496
|
-
},
|
|
3497
|
-
children: /* @__PURE__ */ jsx(
|
|
3498
|
-
FaSpinner,
|
|
3499
|
-
{
|
|
3500
|
-
size: 28,
|
|
3501
|
-
color: "white",
|
|
3502
|
-
style: {
|
|
3503
|
-
animation: "spin 1s linear infinite",
|
|
3504
|
-
filter: "drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))"
|
|
3505
|
-
}
|
|
3506
|
-
}
|
|
3507
|
-
)
|
|
3848
|
+
animation: "spin 1s linear infinite",
|
|
3849
|
+
filter: "drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))"
|
|
3850
|
+
}
|
|
3508
3851
|
}
|
|
3509
3852
|
),
|
|
3510
3853
|
showLicenseWarning && /* @__PURE__ */ jsxs(
|
|
@@ -4617,6 +4960,7 @@ var defaultProps = {
|
|
|
4617
4960
|
showCustomControls: false,
|
|
4618
4961
|
licenseKey: "",
|
|
4619
4962
|
adFailsafeTimeoutMs: 1e4,
|
|
4963
|
+
minSegmentsBeforePlay: 2,
|
|
4620
4964
|
onStart: noop,
|
|
4621
4965
|
onPlay: noop,
|
|
4622
4966
|
onPause: noop,
|
|
@@ -4790,6 +5134,8 @@ var HlsPlayer = class extends Component {
|
|
|
4790
5134
|
config.licenseKey = this.props.licenseKey;
|
|
4791
5135
|
if (this.props.adFailsafeTimeoutMs !== void 0)
|
|
4792
5136
|
config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
|
|
5137
|
+
if (this.props.minSegmentsBeforePlay !== void 0)
|
|
5138
|
+
config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;
|
|
4793
5139
|
this.player = new StormcloudVideoPlayer(config);
|
|
4794
5140
|
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4795
5141
|
await this.player.load();
|
|
@@ -5396,6 +5742,7 @@ var SUPPORTED_PROPS = [
|
|
|
5396
5742
|
"showCustomControls",
|
|
5397
5743
|
"licenseKey",
|
|
5398
5744
|
"adFailsafeTimeoutMs",
|
|
5745
|
+
"minSegmentsBeforePlay",
|
|
5399
5746
|
"onReady",
|
|
5400
5747
|
"onStart",
|
|
5401
5748
|
"onPlay",
|