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.cjs
CHANGED
|
@@ -267,6 +267,13 @@ function createImaController(video, options) {
|
|
|
267
267
|
let adPlaying = false;
|
|
268
268
|
let originalMutedState = false;
|
|
269
269
|
const listeners = /* @__PURE__ */ new Map();
|
|
270
|
+
function setAdPlayingFlag(isPlaying) {
|
|
271
|
+
if (isPlaying) {
|
|
272
|
+
video.dataset.stormcloudAdPlaying = "true";
|
|
273
|
+
} else {
|
|
274
|
+
delete video.dataset.stormcloudAdPlaying;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
270
277
|
function emit(event, payload) {
|
|
271
278
|
const set = listeners.get(event);
|
|
272
279
|
if (!set) return;
|
|
@@ -509,7 +516,12 @@ function createImaController(video, options) {
|
|
|
509
516
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
510
517
|
destroyAdsManager();
|
|
511
518
|
adPlaying = false;
|
|
519
|
+
const previousMutedState = video.muted;
|
|
512
520
|
video.muted = originalMutedState;
|
|
521
|
+
setAdPlayingFlag(false);
|
|
522
|
+
console.log(
|
|
523
|
+
`[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
|
|
524
|
+
);
|
|
513
525
|
if (adContainerEl) {
|
|
514
526
|
adContainerEl.style.pointerEvents = "none";
|
|
515
527
|
adContainerEl.style.display = "none";
|
|
@@ -562,11 +574,13 @@ function createImaController(video, options) {
|
|
|
562
574
|
}
|
|
563
575
|
video.muted = true;
|
|
564
576
|
adPlaying = true;
|
|
577
|
+
setAdPlayingFlag(true);
|
|
565
578
|
emit("content_pause");
|
|
566
579
|
}
|
|
567
580
|
);
|
|
568
581
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
569
582
|
console.log("[IMA] Ad started playing");
|
|
583
|
+
setAdPlayingFlag(true);
|
|
570
584
|
if (adContainerEl) {
|
|
571
585
|
adContainerEl.style.pointerEvents = "auto";
|
|
572
586
|
adContainerEl.style.display = "flex";
|
|
@@ -582,6 +596,7 @@ function createImaController(video, options) {
|
|
|
582
596
|
console.log("[IMA] Content resume requested");
|
|
583
597
|
adPlaying = false;
|
|
584
598
|
video.muted = originalMutedState;
|
|
599
|
+
setAdPlayingFlag(false);
|
|
585
600
|
if (adContainerEl) {
|
|
586
601
|
adContainerEl.style.pointerEvents = "none";
|
|
587
602
|
adContainerEl.style.display = "none";
|
|
@@ -605,6 +620,7 @@ function createImaController(video, options) {
|
|
|
605
620
|
console.log("[IMA] All ads completed");
|
|
606
621
|
adPlaying = false;
|
|
607
622
|
video.muted = originalMutedState;
|
|
623
|
+
setAdPlayingFlag(false);
|
|
608
624
|
if (adContainerEl) {
|
|
609
625
|
adContainerEl.style.pointerEvents = "none";
|
|
610
626
|
adContainerEl.style.display = "none";
|
|
@@ -635,6 +651,7 @@ function createImaController(video, options) {
|
|
|
635
651
|
console.error("[IMA] Error setting up ads manager:", e);
|
|
636
652
|
adPlaying = false;
|
|
637
653
|
video.muted = originalMutedState;
|
|
654
|
+
setAdPlayingFlag(false);
|
|
638
655
|
if (adContainerEl) {
|
|
639
656
|
adContainerEl.style.pointerEvents = "none";
|
|
640
657
|
adContainerEl.style.display = "none";
|
|
@@ -664,7 +681,12 @@ function createImaController(video, options) {
|
|
|
664
681
|
(adErrorEvent) => {
|
|
665
682
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
666
683
|
adPlaying = false;
|
|
684
|
+
const previousMutedState = video.muted;
|
|
667
685
|
video.muted = originalMutedState;
|
|
686
|
+
setAdPlayingFlag(false);
|
|
687
|
+
console.log(
|
|
688
|
+
`[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
689
|
+
);
|
|
668
690
|
if (adContainerEl) {
|
|
669
691
|
adContainerEl.style.pointerEvents = "none";
|
|
670
692
|
adContainerEl.style.display = "none";
|
|
@@ -716,12 +738,20 @@ function createImaController(video, options) {
|
|
|
716
738
|
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
717
739
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
718
740
|
adPlaying = true;
|
|
741
|
+
const adVolume = originalMutedState ? 0 : video.volume;
|
|
742
|
+
try {
|
|
743
|
+
adsManager.setVolume(adVolume);
|
|
744
|
+
console.log(`[IMA] Set ad volume to ${adVolume}`);
|
|
745
|
+
} catch (error) {
|
|
746
|
+
console.warn("[IMA] Failed to set ad volume:", error);
|
|
747
|
+
}
|
|
719
748
|
console.log("[IMA] Starting ad playback");
|
|
720
749
|
adsManager.start();
|
|
721
750
|
return Promise.resolve();
|
|
722
751
|
} catch (error) {
|
|
723
752
|
console.error("[IMA] Error starting ad playback:", error);
|
|
724
753
|
adPlaying = false;
|
|
754
|
+
setAdPlayingFlag(false);
|
|
725
755
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
726
756
|
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
727
757
|
});
|
|
@@ -733,6 +763,7 @@ function createImaController(video, options) {
|
|
|
733
763
|
var _a;
|
|
734
764
|
adPlaying = false;
|
|
735
765
|
video.muted = originalMutedState;
|
|
766
|
+
setAdPlayingFlag(false);
|
|
736
767
|
if (adContainerEl) {
|
|
737
768
|
adContainerEl.style.pointerEvents = "none";
|
|
738
769
|
adContainerEl.style.display = "none";
|
|
@@ -756,6 +787,7 @@ function createImaController(video, options) {
|
|
|
756
787
|
destroyAdsManager();
|
|
757
788
|
adPlaying = false;
|
|
758
789
|
video.muted = originalMutedState;
|
|
790
|
+
setAdPlayingFlag(false);
|
|
759
791
|
if (adContainerEl) {
|
|
760
792
|
adContainerEl.style.pointerEvents = "none";
|
|
761
793
|
adContainerEl.style.display = "none";
|
|
@@ -798,6 +830,9 @@ function createImaController(video, options) {
|
|
|
798
830
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
799
831
|
},
|
|
800
832
|
updateOriginalMutedState(muted) {
|
|
833
|
+
console.log(
|
|
834
|
+
`[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
835
|
+
);
|
|
801
836
|
originalMutedState = muted;
|
|
802
837
|
},
|
|
803
838
|
getOriginalMutedState() {
|
|
@@ -854,7 +889,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
854
889
|
try {
|
|
855
890
|
fn(payload);
|
|
856
891
|
} catch (error) {
|
|
857
|
-
console.warn(
|
|
892
|
+
console.warn(
|
|
893
|
+
`[HlsAdPlayer] Error in event listener for ${event}:`,
|
|
894
|
+
error
|
|
895
|
+
);
|
|
858
896
|
}
|
|
859
897
|
}
|
|
860
898
|
}
|
|
@@ -917,7 +955,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
917
955
|
}
|
|
918
956
|
const mainQuality = getMainStreamQuality();
|
|
919
957
|
if (!mainQuality) {
|
|
920
|
-
console.log(
|
|
958
|
+
console.log(
|
|
959
|
+
"[HlsAdPlayer] No main stream quality info, using first media file"
|
|
960
|
+
);
|
|
921
961
|
return firstFile;
|
|
922
962
|
}
|
|
923
963
|
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
@@ -953,7 +993,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
953
993
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
954
994
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
955
995
|
if (parserError) {
|
|
956
|
-
console.error(
|
|
996
|
+
console.error(
|
|
997
|
+
"[HlsAdPlayer] XML parsing error (malformed VAST XML):",
|
|
998
|
+
parserError.textContent
|
|
999
|
+
);
|
|
957
1000
|
return null;
|
|
958
1001
|
}
|
|
959
1002
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -969,17 +1012,23 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
969
1012
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
970
1013
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
971
1014
|
const mediaFiles = [];
|
|
972
|
-
console.log(
|
|
1015
|
+
console.log(
|
|
1016
|
+
`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`
|
|
1017
|
+
);
|
|
973
1018
|
mediaFileElements.forEach((mf, index) => {
|
|
974
1019
|
var _a2;
|
|
975
1020
|
const type = mf.getAttribute("type") || "";
|
|
976
1021
|
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
977
1022
|
const width = mf.getAttribute("width") || "";
|
|
978
1023
|
const height = mf.getAttribute("height") || "";
|
|
979
|
-
console.log(
|
|
1024
|
+
console.log(
|
|
1025
|
+
`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`
|
|
1026
|
+
);
|
|
980
1027
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
981
1028
|
if (!url) {
|
|
982
|
-
console.warn(
|
|
1029
|
+
console.warn(
|
|
1030
|
+
`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`
|
|
1031
|
+
);
|
|
983
1032
|
return;
|
|
984
1033
|
}
|
|
985
1034
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
@@ -993,12 +1042,16 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
993
1042
|
});
|
|
994
1043
|
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
995
1044
|
} else {
|
|
996
|
-
console.log(
|
|
1045
|
+
console.log(
|
|
1046
|
+
`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`
|
|
1047
|
+
);
|
|
997
1048
|
}
|
|
998
1049
|
});
|
|
999
1050
|
if (mediaFiles.length === 0) {
|
|
1000
1051
|
if (isNoAdAvailable) {
|
|
1001
|
-
console.warn(
|
|
1052
|
+
console.warn(
|
|
1053
|
+
"[HlsAdPlayer] No ads available (VAST response indicates no ads)"
|
|
1054
|
+
);
|
|
1002
1055
|
} else {
|
|
1003
1056
|
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
1004
1057
|
}
|
|
@@ -1061,6 +1114,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1061
1114
|
video.style.backgroundColor = "#000";
|
|
1062
1115
|
video.playsInline = true;
|
|
1063
1116
|
video.muted = false;
|
|
1117
|
+
video.volume = 1;
|
|
1118
|
+
console.log(
|
|
1119
|
+
`[HlsAdPlayer] Created ad video element with volume ${video.volume}`
|
|
1120
|
+
);
|
|
1064
1121
|
return video;
|
|
1065
1122
|
}
|
|
1066
1123
|
function setupAdEventListeners() {
|
|
@@ -1120,10 +1177,22 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1120
1177
|
}
|
|
1121
1178
|
});
|
|
1122
1179
|
}
|
|
1180
|
+
function setAdPlayingFlag(isPlaying) {
|
|
1181
|
+
if (isPlaying) {
|
|
1182
|
+
contentVideo.dataset.stormcloudAdPlaying = "true";
|
|
1183
|
+
} else {
|
|
1184
|
+
delete contentVideo.dataset.stormcloudAdPlaying;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1123
1187
|
function handleAdComplete() {
|
|
1124
1188
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1125
1189
|
adPlaying = false;
|
|
1190
|
+
setAdPlayingFlag(false);
|
|
1191
|
+
const previousMutedState = contentVideo.muted;
|
|
1126
1192
|
contentVideo.muted = originalMutedState;
|
|
1193
|
+
console.log(
|
|
1194
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1195
|
+
);
|
|
1127
1196
|
if (adContainerEl) {
|
|
1128
1197
|
adContainerEl.style.display = "none";
|
|
1129
1198
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1141,7 +1210,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1141
1210
|
function handleAdError() {
|
|
1142
1211
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1143
1212
|
adPlaying = false;
|
|
1213
|
+
setAdPlayingFlag(false);
|
|
1214
|
+
const previousMutedState = contentVideo.muted;
|
|
1144
1215
|
contentVideo.muted = originalMutedState;
|
|
1216
|
+
console.log(
|
|
1217
|
+
`[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
|
|
1218
|
+
);
|
|
1145
1219
|
if (adContainerEl) {
|
|
1146
1220
|
adContainerEl.style.display = "none";
|
|
1147
1221
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1178,7 +1252,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1178
1252
|
async requestAds(vastTagUrl) {
|
|
1179
1253
|
console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
|
|
1180
1254
|
if (adPlaying) {
|
|
1181
|
-
console.warn(
|
|
1255
|
+
console.warn(
|
|
1256
|
+
"[HlsAdPlayer] Cannot request new ads while an ad is playing"
|
|
1257
|
+
);
|
|
1182
1258
|
return Promise.reject(new Error("Ad already playing"));
|
|
1183
1259
|
}
|
|
1184
1260
|
try {
|
|
@@ -1189,14 +1265,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1189
1265
|
}
|
|
1190
1266
|
const vastXml = await response.text();
|
|
1191
1267
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1192
|
-
console.log(
|
|
1268
|
+
console.log(
|
|
1269
|
+
"[HlsAdPlayer] VAST XML content (first 2000 chars):",
|
|
1270
|
+
vastXml.substring(0, 2e3)
|
|
1271
|
+
);
|
|
1193
1272
|
const ad = parseVastXml(vastXml);
|
|
1194
1273
|
if (!ad) {
|
|
1195
1274
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1275
|
+
emit("ad_error");
|
|
1196
1276
|
return Promise.resolve();
|
|
1197
1277
|
}
|
|
1198
1278
|
currentAd = ad;
|
|
1199
|
-
console.log(
|
|
1279
|
+
console.log(
|
|
1280
|
+
`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`
|
|
1281
|
+
);
|
|
1200
1282
|
fireTrackingPixels(ad.trackingUrls.impression);
|
|
1201
1283
|
trackingFired.impression = true;
|
|
1202
1284
|
return Promise.resolve();
|
|
@@ -1208,7 +1290,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1208
1290
|
},
|
|
1209
1291
|
async play() {
|
|
1210
1292
|
if (!currentAd) {
|
|
1211
|
-
console.warn(
|
|
1293
|
+
console.warn(
|
|
1294
|
+
"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)"
|
|
1295
|
+
);
|
|
1212
1296
|
return Promise.reject(new Error("No ad loaded"));
|
|
1213
1297
|
}
|
|
1214
1298
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
@@ -1226,6 +1310,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1226
1310
|
thirdQuartile: false,
|
|
1227
1311
|
complete: false
|
|
1228
1312
|
};
|
|
1313
|
+
const contentVolume = contentVideo.volume;
|
|
1229
1314
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1230
1315
|
contentVideo.pause();
|
|
1231
1316
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
@@ -1234,6 +1319,15 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1234
1319
|
}
|
|
1235
1320
|
contentVideo.muted = true;
|
|
1236
1321
|
adPlaying = true;
|
|
1322
|
+
setAdPlayingFlag(true);
|
|
1323
|
+
if (adVideoElement) {
|
|
1324
|
+
const adVolume = originalMutedState ? 0 : contentVolume;
|
|
1325
|
+
adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
|
|
1326
|
+
adVideoElement.muted = false;
|
|
1327
|
+
console.log(
|
|
1328
|
+
`[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1237
1331
|
if (adContainerEl) {
|
|
1238
1332
|
adContainerEl.style.display = "flex";
|
|
1239
1333
|
adContainerEl.style.pointerEvents = "auto";
|
|
@@ -1286,6 +1380,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1286
1380
|
async stop() {
|
|
1287
1381
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1288
1382
|
adPlaying = false;
|
|
1383
|
+
setAdPlayingFlag(false);
|
|
1289
1384
|
contentVideo.muted = originalMutedState;
|
|
1290
1385
|
if (adContainerEl) {
|
|
1291
1386
|
adContainerEl.style.display = "none";
|
|
@@ -1308,6 +1403,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1308
1403
|
destroy() {
|
|
1309
1404
|
console.log("[HlsAdPlayer] Destroying");
|
|
1310
1405
|
adPlaying = false;
|
|
1406
|
+
setAdPlayingFlag(false);
|
|
1311
1407
|
contentVideo.muted = originalMutedState;
|
|
1312
1408
|
if (adHls) {
|
|
1313
1409
|
adHls.destroy();
|
|
@@ -1349,6 +1445,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1349
1445
|
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1350
1446
|
},
|
|
1351
1447
|
updateOriginalMutedState(muted) {
|
|
1448
|
+
console.log(
|
|
1449
|
+
`[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`
|
|
1450
|
+
);
|
|
1352
1451
|
originalMutedState = muted;
|
|
1353
1452
|
},
|
|
1354
1453
|
getOriginalMutedState() {
|
|
@@ -1841,6 +1940,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1841
1940
|
this.isLiveStream = false;
|
|
1842
1941
|
this.nativeHlsMode = false;
|
|
1843
1942
|
this.videoSrcProtection = null;
|
|
1943
|
+
this.bufferedSegmentsCount = 0;
|
|
1944
|
+
this.shouldAutoplayAfterBuffering = false;
|
|
1945
|
+
this.hasInitialBufferCompleted = false;
|
|
1844
1946
|
initializePolyfills();
|
|
1845
1947
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1846
1948
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1927,14 +2029,22 @@ var StormcloudVideoPlayer = class {
|
|
|
1927
2029
|
liveDurationInfinity: true,
|
|
1928
2030
|
lowLatencyMode: !!this.config.lowLatencyMode,
|
|
1929
2031
|
maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,
|
|
1930
|
-
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
2032
|
+
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},
|
|
2033
|
+
maxBufferLength: 30,
|
|
2034
|
+
maxMaxBufferLength: 600,
|
|
2035
|
+
maxBufferSize: 60 * 1e3 * 1e3,
|
|
2036
|
+
maxBufferHole: 0.5,
|
|
2037
|
+
highBufferWatchdogPeriod: 2,
|
|
2038
|
+
nudgeOffset: 0.1,
|
|
2039
|
+
nudgeMaxRetry: 3,
|
|
2040
|
+
startPosition: -1
|
|
1931
2041
|
});
|
|
1932
2042
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1933
2043
|
var _a2;
|
|
1934
2044
|
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1935
2045
|
});
|
|
1936
2046
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1937
|
-
var _a2, _b2, _c, _d;
|
|
2047
|
+
var _a2, _b2, _c, _d, _e;
|
|
1938
2048
|
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1939
2049
|
(level) => {
|
|
1940
2050
|
var _a3, _b3;
|
|
@@ -1952,9 +2062,51 @@ var StormcloudVideoPlayer = class {
|
|
|
1952
2062
|
this.ima.destroy();
|
|
1953
2063
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1954
2064
|
this.ima.initialize();
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
2065
|
+
this.bufferedSegmentsCount = 0;
|
|
2066
|
+
this.hasInitialBufferCompleted = false;
|
|
2067
|
+
this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
|
|
2068
|
+
const minSegments = (_d = this.config.minSegmentsBeforePlay) != null ? _d : 2;
|
|
2069
|
+
if (this.config.debugAdTiming) {
|
|
2070
|
+
console.log(
|
|
2071
|
+
"[StormcloudVideoPlayer] Waiting for",
|
|
2072
|
+
minSegments,
|
|
2073
|
+
"segments to buffer before playback"
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
if (minSegments === 0 || !this.config.autoplay) {
|
|
2077
|
+
this.hasInitialBufferCompleted = true;
|
|
2078
|
+
if (this.config.autoplay) {
|
|
2079
|
+
await ((_e = this.video.play()) == null ? void 0 : _e.catch(() => {
|
|
2080
|
+
}));
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
});
|
|
2084
|
+
this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, data) => {
|
|
2085
|
+
var _a2, _b2;
|
|
2086
|
+
if (this.hasInitialBufferCompleted) {
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
this.bufferedSegmentsCount++;
|
|
2090
|
+
const minSegments = (_a2 = this.config.minSegmentsBeforePlay) != null ? _a2 : 2;
|
|
2091
|
+
if (this.config.debugAdTiming) {
|
|
2092
|
+
console.log(
|
|
2093
|
+
`[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`
|
|
2094
|
+
);
|
|
2095
|
+
}
|
|
2096
|
+
if (this.bufferedSegmentsCount >= minSegments) {
|
|
2097
|
+
this.hasInitialBufferCompleted = true;
|
|
2098
|
+
if (this.shouldAutoplayAfterBuffering) {
|
|
2099
|
+
if (this.config.debugAdTiming) {
|
|
2100
|
+
console.log(
|
|
2101
|
+
`[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
await ((_b2 = this.video.play()) == null ? void 0 : _b2.catch((err) => {
|
|
2105
|
+
if (this.config.debugAdTiming) {
|
|
2106
|
+
console.warn("[StormcloudVideoPlayer] Autoplay failed:", err);
|
|
2107
|
+
}
|
|
2108
|
+
}));
|
|
2109
|
+
}
|
|
1958
2110
|
}
|
|
1959
2111
|
});
|
|
1960
2112
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
@@ -2050,6 +2202,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2050
2202
|
this.video.autoplay = !!this.config.autoplay;
|
|
2051
2203
|
this.video.muted = !!this.config.muted;
|
|
2052
2204
|
this.ima.initialize();
|
|
2205
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2053
2206
|
this.ima.on("all_ads_completed", () => {
|
|
2054
2207
|
if (this.config.debugAdTiming) {
|
|
2055
2208
|
console.log(
|
|
@@ -2787,14 +2940,66 @@ var StormcloudVideoPlayer = class {
|
|
|
2787
2940
|
}
|
|
2788
2941
|
}
|
|
2789
2942
|
ensureAdStoppedByTimer() {
|
|
2943
|
+
var _a, _b;
|
|
2790
2944
|
if (!this.inAdBreak) return;
|
|
2945
|
+
this.adStopTimerId = void 0;
|
|
2946
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
2947
|
+
const pendingAds = this.adPodQueue.length > 0;
|
|
2948
|
+
const checkIntervalMs = Math.max(
|
|
2949
|
+
250,
|
|
2950
|
+
Math.floor((_a = this.config.adBreakCheckIntervalMs) != null ? _a : 1e3)
|
|
2951
|
+
);
|
|
2952
|
+
const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
|
|
2953
|
+
const maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
|
|
2954
|
+
let elapsedSinceStartMs = 0;
|
|
2955
|
+
if (this.currentAdBreakStartWallClockMs != null) {
|
|
2956
|
+
elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
|
|
2957
|
+
}
|
|
2958
|
+
const expectedDurationMs = (_b = this.expectedAdBreakDurationMs) != null ? _b : 0;
|
|
2959
|
+
const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
|
|
2960
|
+
const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
|
|
2961
|
+
if (shouldExtendAdBreak) {
|
|
2962
|
+
if (this.config.debugAdTiming) {
|
|
2963
|
+
console.log(
|
|
2964
|
+
"[StormcloudVideoPlayer] Extending ad break beyond scheduled duration",
|
|
2965
|
+
{
|
|
2966
|
+
adPlaying,
|
|
2967
|
+
pendingAds,
|
|
2968
|
+
showAds: this.showAds,
|
|
2969
|
+
overrunMs,
|
|
2970
|
+
checkIntervalMs,
|
|
2971
|
+
maxExtensionMs
|
|
2972
|
+
}
|
|
2973
|
+
);
|
|
2974
|
+
}
|
|
2975
|
+
this.scheduleAdStopCountdown(checkIntervalMs);
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
if (this.config.debugAdTiming) {
|
|
2979
|
+
console.log("[StormcloudVideoPlayer] Ending ad break via timer", {
|
|
2980
|
+
adPlaying,
|
|
2981
|
+
pendingAds,
|
|
2982
|
+
showAds: this.showAds,
|
|
2983
|
+
overrunMs,
|
|
2984
|
+
maxExtensionMs
|
|
2985
|
+
});
|
|
2986
|
+
}
|
|
2791
2987
|
this.inAdBreak = false;
|
|
2792
2988
|
this.expectedAdBreakDurationMs = void 0;
|
|
2793
2989
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
2794
|
-
this.
|
|
2795
|
-
|
|
2990
|
+
this.showAds = false;
|
|
2991
|
+
this.adPodQueue = [];
|
|
2992
|
+
this.currentAdIndex = 0;
|
|
2993
|
+
this.totalAdsInBreak = 0;
|
|
2994
|
+
this.clearAdFailsafeTimer();
|
|
2995
|
+
if (adPlaying) {
|
|
2796
2996
|
this.ima.stop().catch(() => {
|
|
2797
2997
|
});
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
const originalMutedState = this.ima.getOriginalMutedState();
|
|
3001
|
+
if (this.video.muted !== originalMutedState) {
|
|
3002
|
+
this.video.muted = originalMutedState;
|
|
2798
3003
|
}
|
|
2799
3004
|
}
|
|
2800
3005
|
scheduleAdStartIn(delayMs) {
|
|
@@ -2834,7 +3039,23 @@ var StormcloudVideoPlayer = class {
|
|
|
2834
3039
|
}
|
|
2835
3040
|
return;
|
|
2836
3041
|
}
|
|
2837
|
-
|
|
3042
|
+
if (!this.showAds) {
|
|
3043
|
+
if (this.config.debugAdTiming) {
|
|
3044
|
+
console.log(
|
|
3045
|
+
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
3046
|
+
{
|
|
3047
|
+
videoMuted: this.video.muted,
|
|
3048
|
+
videoVolume: this.video.volume,
|
|
3049
|
+
showAds: this.showAds
|
|
3050
|
+
}
|
|
3051
|
+
);
|
|
3052
|
+
}
|
|
3053
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
3054
|
+
} else if (this.config.debugAdTiming) {
|
|
3055
|
+
console.log(
|
|
3056
|
+
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
3057
|
+
);
|
|
3058
|
+
}
|
|
2838
3059
|
this.startAdFailsafeTimer();
|
|
2839
3060
|
try {
|
|
2840
3061
|
await this.ima.requestAds(vastTagUrl);
|
|
@@ -2889,11 +3110,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2889
3110
|
this.showAds = false;
|
|
2890
3111
|
this.currentAdIndex = 0;
|
|
2891
3112
|
this.totalAdsInBreak = 0;
|
|
3113
|
+
const currentMutedState = this.video.muted;
|
|
2892
3114
|
const originalMutedState = this.ima.getOriginalMutedState();
|
|
2893
3115
|
this.video.muted = originalMutedState;
|
|
2894
3116
|
if (this.config.debugAdTiming) {
|
|
2895
3117
|
console.log(
|
|
2896
|
-
`[StormcloudVideoPlayer] Restored mute state
|
|
3118
|
+
`[StormcloudVideoPlayer] Restored mute state: ${currentMutedState} -> ${originalMutedState}`
|
|
2897
3119
|
);
|
|
2898
3120
|
}
|
|
2899
3121
|
if (this.video.paused) {
|
|
@@ -2985,6 +3207,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2985
3207
|
}
|
|
2986
3208
|
} else {
|
|
2987
3209
|
this.video.muted = !this.video.muted;
|
|
3210
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
2988
3211
|
if (this.config.debugAdTiming) {
|
|
2989
3212
|
console.log("[StormcloudVideoPlayer] Muted:", this.video.muted);
|
|
2990
3213
|
}
|
|
@@ -3029,11 +3252,47 @@ var StormcloudVideoPlayer = class {
|
|
|
3029
3252
|
}
|
|
3030
3253
|
isMuted() {
|
|
3031
3254
|
if (this.ima.isAdPlaying()) {
|
|
3032
|
-
|
|
3033
|
-
|
|
3255
|
+
if (this.config.debugAdTiming) {
|
|
3256
|
+
console.log(
|
|
3257
|
+
"[StormcloudVideoPlayer] isMuted() override during ad playback -> false"
|
|
3258
|
+
);
|
|
3259
|
+
}
|
|
3260
|
+
return false;
|
|
3261
|
+
}
|
|
3262
|
+
if (this.config.debugAdTiming) {
|
|
3263
|
+
console.log(
|
|
3264
|
+
`[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
|
|
3265
|
+
);
|
|
3034
3266
|
}
|
|
3035
3267
|
return this.video.muted;
|
|
3036
3268
|
}
|
|
3269
|
+
setMuted(muted) {
|
|
3270
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
3271
|
+
if (adPlaying && muted === this.video.muted) {
|
|
3272
|
+
if (this.config.debugAdTiming) {
|
|
3273
|
+
console.log(
|
|
3274
|
+
"[StormcloudVideoPlayer] setMuted reflective update during ad ignored",
|
|
3275
|
+
{ muted }
|
|
3276
|
+
);
|
|
3277
|
+
}
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3280
|
+
this.video.muted = muted;
|
|
3281
|
+
if (adPlaying) {
|
|
3282
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3283
|
+
this.ima.setAdVolume(muted ? 0 : 1);
|
|
3284
|
+
if (this.config.debugAdTiming) {
|
|
3285
|
+
console.log("[StormcloudVideoPlayer] setMuted applied during ad", {
|
|
3286
|
+
muted
|
|
3287
|
+
});
|
|
3288
|
+
}
|
|
3289
|
+
return;
|
|
3290
|
+
}
|
|
3291
|
+
this.ima.updateOriginalMutedState(muted);
|
|
3292
|
+
if (this.config.debugAdTiming) {
|
|
3293
|
+
console.log("[StormcloudVideoPlayer] setMuted called:", muted);
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3037
3296
|
isFullscreen() {
|
|
3038
3297
|
return !!document.fullscreenElement;
|
|
3039
3298
|
}
|
|
@@ -3112,10 +3371,12 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3112
3371
|
vastMode,
|
|
3113
3372
|
vastTagUrl,
|
|
3114
3373
|
adPlayerType,
|
|
3374
|
+
minSegmentsBeforePlay,
|
|
3115
3375
|
...restVideoAttrs
|
|
3116
3376
|
} = props;
|
|
3117
3377
|
const videoRef = (0, import_react.useRef)(null);
|
|
3118
3378
|
const playerRef = (0, import_react.useRef)(null);
|
|
3379
|
+
const bufferingTimeoutRef = (0, import_react.useRef)(null);
|
|
3119
3380
|
const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });
|
|
3120
3381
|
const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);
|
|
3121
3382
|
const [isMuted, setIsMuted] = import_react.default.useState(false);
|
|
@@ -3237,6 +3498,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3237
3498
|
return;
|
|
3238
3499
|
}
|
|
3239
3500
|
setShowLicenseWarning(false);
|
|
3501
|
+
if (debugAdTiming) {
|
|
3502
|
+
console.log("[StormcloudUI] Initializing player, isLoading=true");
|
|
3503
|
+
}
|
|
3240
3504
|
if (playerRef.current) {
|
|
3241
3505
|
try {
|
|
3242
3506
|
playerRef.current.destroy();
|
|
@@ -3267,17 +3531,25 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3267
3531
|
if (vastMode !== void 0) cfg.vastMode = vastMode;
|
|
3268
3532
|
if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;
|
|
3269
3533
|
if (adPlayerType !== void 0) cfg.adPlayerType = adPlayerType;
|
|
3534
|
+
if (minSegmentsBeforePlay !== void 0)
|
|
3535
|
+
cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
|
|
3270
3536
|
const player = new StormcloudVideoPlayer(cfg);
|
|
3271
3537
|
playerRef.current = player;
|
|
3272
3538
|
player.load().then(() => {
|
|
3273
3539
|
const showNative = player.shouldShowNativeControls();
|
|
3274
3540
|
setShouldShowNativeControls(showNative);
|
|
3541
|
+
if (debugAdTiming) {
|
|
3542
|
+
console.log(
|
|
3543
|
+
"[StormcloudUI] Player loaded successfully, waiting for video ready"
|
|
3544
|
+
);
|
|
3545
|
+
}
|
|
3275
3546
|
onReady == null ? void 0 : onReady(player);
|
|
3276
3547
|
}).catch((error) => {
|
|
3277
3548
|
console.error(
|
|
3278
3549
|
"StormcloudVideoPlayer: Failed to load player:",
|
|
3279
3550
|
error
|
|
3280
3551
|
);
|
|
3552
|
+
setIsLoading(false);
|
|
3281
3553
|
onReady == null ? void 0 : onReady(player);
|
|
3282
3554
|
});
|
|
3283
3555
|
return () => {
|
|
@@ -3294,8 +3566,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3294
3566
|
if (autoplay !== void 0 && playerRef.current.videoElement) {
|
|
3295
3567
|
playerRef.current.videoElement.autoplay = autoplay;
|
|
3296
3568
|
}
|
|
3297
|
-
if (muted !== void 0
|
|
3298
|
-
playerRef.current.
|
|
3569
|
+
if (muted !== void 0) {
|
|
3570
|
+
playerRef.current.setMuted(muted);
|
|
3299
3571
|
}
|
|
3300
3572
|
} catch (error) {
|
|
3301
3573
|
console.warn("Failed to update player properties:", error);
|
|
@@ -3376,26 +3648,108 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3376
3648
|
(0, import_react.useEffect)(() => {
|
|
3377
3649
|
if (!videoRef.current) return;
|
|
3378
3650
|
const handleLoadedMetadata = () => {
|
|
3651
|
+
var _a;
|
|
3379
3652
|
if (videoRef.current) {
|
|
3380
3653
|
const video2 = videoRef.current;
|
|
3381
3654
|
void video2.offsetHeight;
|
|
3382
3655
|
}
|
|
3656
|
+
if (debugAdTiming) {
|
|
3657
|
+
console.log(
|
|
3658
|
+
"[StormcloudUI] Video event: loadedmetadata, readyState:",
|
|
3659
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3660
|
+
);
|
|
3661
|
+
}
|
|
3662
|
+
};
|
|
3663
|
+
const handleLoadedData = () => {
|
|
3664
|
+
var _a;
|
|
3665
|
+
if (debugAdTiming) {
|
|
3666
|
+
console.log(
|
|
3667
|
+
"[StormcloudUI] Video event: loadeddata, readyState:",
|
|
3668
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3383
3671
|
};
|
|
3384
3672
|
const handleLoadStart = () => {
|
|
3385
|
-
|
|
3386
|
-
|
|
3673
|
+
var _a;
|
|
3674
|
+
if (debugAdTiming) {
|
|
3675
|
+
console.log(
|
|
3676
|
+
"[StormcloudUI] Video event: loadstart, readyState:",
|
|
3677
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState
|
|
3678
|
+
);
|
|
3679
|
+
}
|
|
3387
3680
|
};
|
|
3388
3681
|
const handleCanPlay = () => {
|
|
3682
|
+
var _a;
|
|
3683
|
+
setIsLoading(false);
|
|
3684
|
+
if (bufferingTimeoutRef.current) {
|
|
3685
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3686
|
+
bufferingTimeoutRef.current = null;
|
|
3687
|
+
}
|
|
3688
|
+
setIsBuffering(false);
|
|
3689
|
+
if (debugAdTiming) {
|
|
3690
|
+
console.log(
|
|
3691
|
+
"[StormcloudUI] Video event: canplay, readyState:",
|
|
3692
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3693
|
+
"- clearing loading state, isLoading=false"
|
|
3694
|
+
);
|
|
3695
|
+
}
|
|
3696
|
+
};
|
|
3697
|
+
const handleCanPlayThrough = () => {
|
|
3698
|
+
var _a;
|
|
3389
3699
|
setIsLoading(false);
|
|
3700
|
+
if (bufferingTimeoutRef.current) {
|
|
3701
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3702
|
+
bufferingTimeoutRef.current = null;
|
|
3703
|
+
}
|
|
3390
3704
|
setIsBuffering(false);
|
|
3705
|
+
if (debugAdTiming) {
|
|
3706
|
+
console.log(
|
|
3707
|
+
"[StormcloudUI] Video event: canplaythrough, readyState:",
|
|
3708
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3709
|
+
"- clearing loading state, isLoading=false"
|
|
3710
|
+
);
|
|
3711
|
+
}
|
|
3391
3712
|
};
|
|
3392
3713
|
const handleWaiting = () => {
|
|
3393
|
-
|
|
3714
|
+
var _a;
|
|
3715
|
+
if (bufferingTimeoutRef.current) {
|
|
3716
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3717
|
+
}
|
|
3718
|
+
bufferingTimeoutRef.current = window.setTimeout(() => {
|
|
3719
|
+
var _a2;
|
|
3720
|
+
setIsBuffering(true);
|
|
3721
|
+
if (debugAdTiming) {
|
|
3722
|
+
console.log(
|
|
3723
|
+
"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:",
|
|
3724
|
+
(_a2 = videoRef.current) == null ? void 0 : _a2.readyState,
|
|
3725
|
+
"- showing spinner, isBuffering=true"
|
|
3726
|
+
);
|
|
3727
|
+
}
|
|
3728
|
+
}, 300);
|
|
3729
|
+
if (debugAdTiming) {
|
|
3730
|
+
console.log(
|
|
3731
|
+
"[StormcloudUI] Video event: waiting, readyState:",
|
|
3732
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3733
|
+
"- buffering delay started (300ms)"
|
|
3734
|
+
);
|
|
3735
|
+
}
|
|
3394
3736
|
};
|
|
3395
3737
|
const handlePlaying = () => {
|
|
3738
|
+
var _a;
|
|
3396
3739
|
setIsLoading(false);
|
|
3740
|
+
if (bufferingTimeoutRef.current) {
|
|
3741
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3742
|
+
bufferingTimeoutRef.current = null;
|
|
3743
|
+
}
|
|
3397
3744
|
setIsBuffering(false);
|
|
3398
3745
|
setShowCenterPlay(false);
|
|
3746
|
+
if (debugAdTiming) {
|
|
3747
|
+
console.log(
|
|
3748
|
+
"[StormcloudUI] Video event: playing, readyState:",
|
|
3749
|
+
(_a = videoRef.current) == null ? void 0 : _a.readyState,
|
|
3750
|
+
"- playback started, isLoading=false, isBuffering=false"
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3399
3753
|
};
|
|
3400
3754
|
const handlePause = () => {
|
|
3401
3755
|
if (playerRef.current && !playerRef.current.isShowingAds()) {
|
|
@@ -3410,8 +3764,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3410
3764
|
const video = videoRef.current;
|
|
3411
3765
|
video.addEventListener("loadstart", handleLoadStart);
|
|
3412
3766
|
video.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
3413
|
-
video.addEventListener("loadeddata",
|
|
3767
|
+
video.addEventListener("loadeddata", handleLoadedData);
|
|
3414
3768
|
video.addEventListener("canplay", handleCanPlay);
|
|
3769
|
+
video.addEventListener("canplaythrough", handleCanPlayThrough);
|
|
3415
3770
|
video.addEventListener("waiting", handleWaiting);
|
|
3416
3771
|
video.addEventListener("playing", handlePlaying);
|
|
3417
3772
|
video.addEventListener("pause", handlePause);
|
|
@@ -3420,16 +3775,21 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3420
3775
|
setShowCenterPlay(true);
|
|
3421
3776
|
}
|
|
3422
3777
|
return () => {
|
|
3778
|
+
if (bufferingTimeoutRef.current) {
|
|
3779
|
+
clearTimeout(bufferingTimeoutRef.current);
|
|
3780
|
+
bufferingTimeoutRef.current = null;
|
|
3781
|
+
}
|
|
3423
3782
|
video.removeEventListener("loadstart", handleLoadStart);
|
|
3424
3783
|
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
3425
|
-
video.removeEventListener("loadeddata",
|
|
3784
|
+
video.removeEventListener("loadeddata", handleLoadedData);
|
|
3426
3785
|
video.removeEventListener("canplay", handleCanPlay);
|
|
3786
|
+
video.removeEventListener("canplaythrough", handleCanPlayThrough);
|
|
3427
3787
|
video.removeEventListener("waiting", handleWaiting);
|
|
3428
3788
|
video.removeEventListener("playing", handlePlaying);
|
|
3429
3789
|
video.removeEventListener("pause", handlePause);
|
|
3430
3790
|
video.removeEventListener("ended", handleEnded);
|
|
3431
3791
|
};
|
|
3432
|
-
}, []);
|
|
3792
|
+
}, [debugAdTiming]);
|
|
3433
3793
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
3434
3794
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
|
|
3435
3795
|
@keyframes spin {
|
|
@@ -3536,35 +3896,18 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3536
3896
|
}
|
|
3537
3897
|
),
|
|
3538
3898
|
(isLoading || isBuffering) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3539
|
-
|
|
3899
|
+
import_fa.FaSpinner,
|
|
3540
3900
|
{
|
|
3901
|
+
size: 42,
|
|
3902
|
+
color: "white",
|
|
3541
3903
|
style: {
|
|
3542
3904
|
position: "absolute",
|
|
3543
|
-
top: "50%",
|
|
3544
|
-
left: "50%",
|
|
3545
|
-
transform: "translate(-50%, -50%)",
|
|
3905
|
+
top: "calc(50% - 21px)",
|
|
3906
|
+
left: "calc(50% - 21px)",
|
|
3546
3907
|
zIndex: 20,
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(20, 20, 20, 0.6) 100%)",
|
|
3551
|
-
width: "80px",
|
|
3552
|
-
height: "80px",
|
|
3553
|
-
borderRadius: "50%",
|
|
3554
|
-
backdropFilter: "blur(20px)",
|
|
3555
|
-
boxShadow: "0 12px 40px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.1)"
|
|
3556
|
-
},
|
|
3557
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3558
|
-
import_fa.FaSpinner,
|
|
3559
|
-
{
|
|
3560
|
-
size: 28,
|
|
3561
|
-
color: "white",
|
|
3562
|
-
style: {
|
|
3563
|
-
animation: "spin 1s linear infinite",
|
|
3564
|
-
filter: "drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))"
|
|
3565
|
-
}
|
|
3566
|
-
}
|
|
3567
|
-
)
|
|
3908
|
+
animation: "spin 1s linear infinite",
|
|
3909
|
+
filter: "drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))"
|
|
3910
|
+
}
|
|
3568
3911
|
}
|
|
3569
3912
|
),
|
|
3570
3913
|
showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -4677,6 +5020,7 @@ var defaultProps = {
|
|
|
4677
5020
|
showCustomControls: false,
|
|
4678
5021
|
licenseKey: "",
|
|
4679
5022
|
adFailsafeTimeoutMs: 1e4,
|
|
5023
|
+
minSegmentsBeforePlay: 2,
|
|
4680
5024
|
onStart: noop,
|
|
4681
5025
|
onPlay: noop,
|
|
4682
5026
|
onPause: noop,
|
|
@@ -4850,6 +5194,8 @@ var HlsPlayer = class extends import_react3.Component {
|
|
|
4850
5194
|
config.licenseKey = this.props.licenseKey;
|
|
4851
5195
|
if (this.props.adFailsafeTimeoutMs !== void 0)
|
|
4852
5196
|
config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
|
|
5197
|
+
if (this.props.minSegmentsBeforePlay !== void 0)
|
|
5198
|
+
config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;
|
|
4853
5199
|
this.player = new StormcloudVideoPlayer(config);
|
|
4854
5200
|
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4855
5201
|
await this.player.load();
|
|
@@ -5456,6 +5802,7 @@ var SUPPORTED_PROPS = [
|
|
|
5456
5802
|
"showCustomControls",
|
|
5457
5803
|
"licenseKey",
|
|
5458
5804
|
"adFailsafeTimeoutMs",
|
|
5805
|
+
"minSegmentsBeforePlay",
|
|
5459
5806
|
"onReady",
|
|
5460
5807
|
"onStart",
|
|
5461
5808
|
"onPlay",
|