stormcloud-video-player 0.2.9 → 0.2.10
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 +1 -1
- package/lib/index.cjs +395 -98
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +395 -98
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +132 -46
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +132 -46
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +132 -46
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +94 -26
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +395 -98
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -76,9 +76,22 @@ function createImaController(video, options) {
|
|
|
76
76
|
'script[data-ima="true"]'
|
|
77
77
|
);
|
|
78
78
|
if (existing) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
if (window.google?.ima) {
|
|
80
|
+
return Promise.resolve();
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const timeout = setTimeout(() => {
|
|
84
|
+
reject(new Error("IMA SDK load timeout"));
|
|
85
|
+
}, 1e4);
|
|
86
|
+
existing.addEventListener("load", () => {
|
|
87
|
+
clearTimeout(timeout);
|
|
88
|
+
resolve();
|
|
89
|
+
});
|
|
90
|
+
existing.addEventListener("error", () => {
|
|
91
|
+
clearTimeout(timeout);
|
|
92
|
+
reject(new Error("IMA SDK load failed"));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
82
95
|
}
|
|
83
96
|
return new Promise((resolve, reject) => {
|
|
84
97
|
const script = document.createElement("script");
|
|
@@ -107,6 +120,17 @@ function createImaController(video, options) {
|
|
|
107
120
|
adsRequest.adTagUrl = vastTagUrl;
|
|
108
121
|
adsLoader.requestAds(adsRequest);
|
|
109
122
|
}
|
|
123
|
+
function destroyAdsManager() {
|
|
124
|
+
if (adsManager) {
|
|
125
|
+
try {
|
|
126
|
+
console.log("[IMA] Destroying existing ads manager");
|
|
127
|
+
adsManager.destroy();
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.warn("[IMA] Error destroying ads manager:", error);
|
|
130
|
+
}
|
|
131
|
+
adsManager = void 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
110
134
|
return {
|
|
111
135
|
initialize() {
|
|
112
136
|
ensureImaLoaded().then(() => {
|
|
@@ -139,9 +163,22 @@ function createImaController(video, options) {
|
|
|
139
163
|
},
|
|
140
164
|
async requestAds(vastTagUrl) {
|
|
141
165
|
console.log("[IMA] Requesting ads:", vastTagUrl);
|
|
166
|
+
if (adPlaying) {
|
|
167
|
+
console.warn(
|
|
168
|
+
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
169
|
+
);
|
|
170
|
+
return Promise.reject(
|
|
171
|
+
new Error("Ad already playing - cannot request new ads")
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
destroyAdsManager();
|
|
175
|
+
adsLoadedReject = void 0;
|
|
176
|
+
adsLoadedResolve = void 0;
|
|
177
|
+
let currentReject;
|
|
142
178
|
adsLoadedPromise = new Promise((resolve, reject) => {
|
|
143
179
|
adsLoadedResolve = resolve;
|
|
144
180
|
adsLoadedReject = reject;
|
|
181
|
+
currentReject = reject;
|
|
145
182
|
setTimeout(() => {
|
|
146
183
|
if (adsLoadedReject) {
|
|
147
184
|
adsLoadedReject(new Error("Ad request timeout"));
|
|
@@ -163,7 +200,7 @@ function createImaController(video, options) {
|
|
|
163
200
|
container.style.top = "0";
|
|
164
201
|
container.style.right = "0";
|
|
165
202
|
container.style.bottom = "0";
|
|
166
|
-
container.style.display = "
|
|
203
|
+
container.style.display = "none";
|
|
167
204
|
container.style.alignItems = "center";
|
|
168
205
|
container.style.justifyContent = "center";
|
|
169
206
|
container.style.pointerEvents = "none";
|
|
@@ -203,14 +240,14 @@ function createImaController(video, options) {
|
|
|
203
240
|
AdErrorEvent.AD_ERROR,
|
|
204
241
|
(errorEvent) => {
|
|
205
242
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
206
|
-
|
|
207
|
-
adsManager?.destroy?.();
|
|
208
|
-
} catch {
|
|
209
|
-
}
|
|
243
|
+
destroyAdsManager();
|
|
210
244
|
adPlaying = false;
|
|
211
245
|
video.muted = originalMutedState;
|
|
212
|
-
if (adContainerEl)
|
|
246
|
+
if (adContainerEl) {
|
|
213
247
|
adContainerEl.style.pointerEvents = "none";
|
|
248
|
+
adContainerEl.style.display = "none";
|
|
249
|
+
console.log("[IMA] Ad container hidden after error");
|
|
250
|
+
}
|
|
214
251
|
if (adsLoadedReject) {
|
|
215
252
|
adsLoadedReject(new Error("Ad playback error"));
|
|
216
253
|
adsLoadedReject = void 0;
|
|
@@ -243,10 +280,6 @@ function createImaController(video, options) {
|
|
|
243
280
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
244
281
|
() => {
|
|
245
282
|
console.log("[IMA] Content pause requested");
|
|
246
|
-
if (!adPlaying) {
|
|
247
|
-
originalMutedState = video.muted;
|
|
248
|
-
}
|
|
249
|
-
video.muted = true;
|
|
250
283
|
if (!options?.continueLiveStreamDuringAds) {
|
|
251
284
|
video.pause();
|
|
252
285
|
console.log("[IMA] Video paused (VOD mode)");
|
|
@@ -255,20 +288,34 @@ function createImaController(video, options) {
|
|
|
255
288
|
"[IMA] Video continues playing but muted (Live mode)"
|
|
256
289
|
);
|
|
257
290
|
}
|
|
291
|
+
video.muted = true;
|
|
258
292
|
adPlaying = true;
|
|
259
|
-
if (adContainerEl)
|
|
260
|
-
adContainerEl.style.pointerEvents = "auto";
|
|
261
293
|
emit("content_pause");
|
|
262
294
|
}
|
|
263
295
|
);
|
|
296
|
+
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
297
|
+
console.log("[IMA] Ad started playing");
|
|
298
|
+
if (adContainerEl) {
|
|
299
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
300
|
+
adContainerEl.style.display = "flex";
|
|
301
|
+
console.log(
|
|
302
|
+
"[IMA] Ad container visibility set to flex with pointer events enabled"
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
264
306
|
adsManager.addEventListener(
|
|
265
307
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
266
308
|
() => {
|
|
267
309
|
console.log("[IMA] Content resume requested");
|
|
268
310
|
adPlaying = false;
|
|
269
311
|
video.muted = originalMutedState;
|
|
270
|
-
if (adContainerEl)
|
|
312
|
+
if (adContainerEl) {
|
|
271
313
|
adContainerEl.style.pointerEvents = "none";
|
|
314
|
+
adContainerEl.style.display = "none";
|
|
315
|
+
console.log(
|
|
316
|
+
"[IMA] Ad container hidden - pointer events disabled"
|
|
317
|
+
);
|
|
318
|
+
}
|
|
272
319
|
if (!options?.continueLiveStreamDuringAds) {
|
|
273
320
|
video.play()?.catch(() => {
|
|
274
321
|
});
|
|
@@ -285,7 +332,13 @@ function createImaController(video, options) {
|
|
|
285
332
|
console.log("[IMA] All ads completed");
|
|
286
333
|
adPlaying = false;
|
|
287
334
|
video.muted = originalMutedState;
|
|
288
|
-
if (adContainerEl)
|
|
335
|
+
if (adContainerEl) {
|
|
336
|
+
adContainerEl.style.pointerEvents = "none";
|
|
337
|
+
adContainerEl.style.display = "none";
|
|
338
|
+
console.log(
|
|
339
|
+
"[IMA] Ad container hidden after all ads completed"
|
|
340
|
+
);
|
|
341
|
+
}
|
|
289
342
|
if (!options?.continueLiveStreamDuringAds) {
|
|
290
343
|
video.play().catch(() => {
|
|
291
344
|
});
|
|
@@ -328,6 +381,13 @@ function createImaController(video, options) {
|
|
|
328
381
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
329
382
|
(adErrorEvent) => {
|
|
330
383
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
384
|
+
adPlaying = false;
|
|
385
|
+
video.muted = originalMutedState;
|
|
386
|
+
if (adContainerEl) adContainerEl.style.pointerEvents = "none";
|
|
387
|
+
if (!options?.continueLiveStreamDuringAds) {
|
|
388
|
+
video.play().catch(() => {
|
|
389
|
+
});
|
|
390
|
+
}
|
|
331
391
|
if (adsLoadedReject) {
|
|
332
392
|
adsLoadedReject(new Error("Ads loader error"));
|
|
333
393
|
adsLoadedReject = void 0;
|
|
@@ -343,11 +403,9 @@ function createImaController(video, options) {
|
|
|
343
403
|
return adsLoadedPromise;
|
|
344
404
|
} catch (error) {
|
|
345
405
|
console.error("[IMA] Failed to request ads:", error);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
adsLoadedResolve = void 0;
|
|
350
|
-
}
|
|
406
|
+
currentReject?.(error);
|
|
407
|
+
adsLoadedReject = void 0;
|
|
408
|
+
adsLoadedResolve = void 0;
|
|
351
409
|
return Promise.reject(error);
|
|
352
410
|
}
|
|
353
411
|
},
|
|
@@ -384,10 +442,16 @@ function createImaController(video, options) {
|
|
|
384
442
|
async stop() {
|
|
385
443
|
adPlaying = false;
|
|
386
444
|
video.muted = originalMutedState;
|
|
445
|
+
if (adContainerEl) {
|
|
446
|
+
adContainerEl.style.pointerEvents = "none";
|
|
447
|
+
adContainerEl.style.display = "none";
|
|
448
|
+
console.log("[IMA] Ad container hidden after stop");
|
|
449
|
+
}
|
|
387
450
|
try {
|
|
388
451
|
adsManager?.stop?.();
|
|
389
452
|
} catch {
|
|
390
453
|
}
|
|
454
|
+
destroyAdsManager();
|
|
391
455
|
if (!options?.continueLiveStreamDuringAds) {
|
|
392
456
|
video.play().catch(() => {
|
|
393
457
|
});
|
|
@@ -397,12 +461,13 @@ function createImaController(video, options) {
|
|
|
397
461
|
}
|
|
398
462
|
},
|
|
399
463
|
destroy() {
|
|
400
|
-
|
|
401
|
-
adsManager?.destroy?.();
|
|
402
|
-
} catch {
|
|
403
|
-
}
|
|
464
|
+
destroyAdsManager();
|
|
404
465
|
adPlaying = false;
|
|
405
466
|
video.muted = originalMutedState;
|
|
467
|
+
if (adContainerEl) {
|
|
468
|
+
adContainerEl.style.pointerEvents = "none";
|
|
469
|
+
adContainerEl.style.display = "none";
|
|
470
|
+
}
|
|
406
471
|
try {
|
|
407
472
|
adsLoader?.destroy?.();
|
|
408
473
|
} catch {
|
|
@@ -410,6 +475,9 @@ function createImaController(video, options) {
|
|
|
410
475
|
if (adContainerEl?.parentElement) {
|
|
411
476
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
412
477
|
}
|
|
478
|
+
adContainerEl = void 0;
|
|
479
|
+
adDisplayContainer = void 0;
|
|
480
|
+
adsLoader = void 0;
|
|
413
481
|
},
|
|
414
482
|
isAdPlaying() {
|
|
415
483
|
return adPlaying;
|
|
@@ -887,17 +955,8 @@ var StormcloudVideoPlayer = class {
|
|
|
887
955
|
this.video.muted = !!this.config.muted;
|
|
888
956
|
this.ima.initialize();
|
|
889
957
|
this.ima.on("all_ads_completed", () => {
|
|
890
|
-
if (
|
|
891
|
-
|
|
892
|
-
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
893
|
-
const next = this.adPodQueue.shift();
|
|
894
|
-
this.currentAdIndex++;
|
|
895
|
-
this.playSingleAd(next).catch(() => {
|
|
896
|
-
});
|
|
897
|
-
} else {
|
|
898
|
-
this.currentAdIndex = 0;
|
|
899
|
-
this.totalAdsInBreak = 0;
|
|
900
|
-
this.showAds = false;
|
|
958
|
+
if (this.config.debugAdTiming) {
|
|
959
|
+
console.log("[StormcloudVideoPlayer] IMA all_ads_completed event received");
|
|
901
960
|
}
|
|
902
961
|
});
|
|
903
962
|
this.ima.on("ad_error", () => {
|
|
@@ -928,6 +987,26 @@ var StormcloudVideoPlayer = class {
|
|
|
928
987
|
);
|
|
929
988
|
}
|
|
930
989
|
this.clearAdFailsafeTimer();
|
|
990
|
+
if (!this.inAdBreak) return;
|
|
991
|
+
const remaining = this.getRemainingAdMs();
|
|
992
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
993
|
+
const next = this.adPodQueue.shift();
|
|
994
|
+
this.currentAdIndex++;
|
|
995
|
+
if (this.config.debugAdTiming) {
|
|
996
|
+
console.log(
|
|
997
|
+
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
this.playSingleAd(next).catch(() => {
|
|
1001
|
+
});
|
|
1002
|
+
} else {
|
|
1003
|
+
if (this.config.debugAdTiming) {
|
|
1004
|
+
console.log("[StormcloudVideoPlayer] Ad pod completed");
|
|
1005
|
+
}
|
|
1006
|
+
this.currentAdIndex = 0;
|
|
1007
|
+
this.totalAdsInBreak = 0;
|
|
1008
|
+
this.showAds = false;
|
|
1009
|
+
}
|
|
931
1010
|
});
|
|
932
1011
|
this.video.addEventListener("timeupdate", () => {
|
|
933
1012
|
this.onTimeUpdate(this.video.currentTime);
|
|
@@ -1577,21 +1656,21 @@ var StormcloudVideoPlayer = class {
|
|
|
1577
1656
|
if (this.config.debugAdTiming) {
|
|
1578
1657
|
console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
|
|
1579
1658
|
}
|
|
1580
|
-
this.ima.
|
|
1581
|
-
if (!this.shouldContinueLiveStreamDuringAds()) {
|
|
1582
|
-
if (this.config.debugAdTiming) {
|
|
1583
|
-
console.log("[StormcloudVideoPlayer] Pausing video immediately for ad (VOD mode)");
|
|
1584
|
-
}
|
|
1585
|
-
this.video.pause();
|
|
1586
|
-
} else {
|
|
1659
|
+
if (this.ima.isAdPlaying()) {
|
|
1587
1660
|
if (this.config.debugAdTiming) {
|
|
1588
|
-
console.
|
|
1661
|
+
console.warn(
|
|
1662
|
+
"[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
|
|
1663
|
+
);
|
|
1589
1664
|
}
|
|
1590
|
-
|
|
1665
|
+
return;
|
|
1591
1666
|
}
|
|
1667
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
1592
1668
|
this.startAdFailsafeTimer();
|
|
1593
1669
|
try {
|
|
1594
1670
|
await this.ima.requestAds(vastTagUrl);
|
|
1671
|
+
if (this.config.debugAdTiming) {
|
|
1672
|
+
console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
|
|
1673
|
+
}
|
|
1595
1674
|
await this.ima.play();
|
|
1596
1675
|
if (this.config.debugAdTiming) {
|
|
1597
1676
|
console.log("[StormcloudVideoPlayer] Ad playback started successfully");
|
|
@@ -1619,6 +1698,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1619
1698
|
this.showAds = false;
|
|
1620
1699
|
this.currentAdIndex = 0;
|
|
1621
1700
|
this.totalAdsInBreak = 0;
|
|
1701
|
+
const originalMutedState = this.ima.getOriginalMutedState();
|
|
1702
|
+
this.video.muted = originalMutedState;
|
|
1703
|
+
if (this.config.debugAdTiming) {
|
|
1704
|
+
console.log(
|
|
1705
|
+
`[StormcloudVideoPlayer] Restored mute state to: ${originalMutedState}`
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1622
1708
|
if (this.video.paused) {
|
|
1623
1709
|
this.video.play()?.catch(() => {
|
|
1624
1710
|
if (this.config.debugAdTiming) {
|
|
@@ -2562,39 +2648,144 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2562
2648
|
left: "50%",
|
|
2563
2649
|
transform: "translateX(-50%)",
|
|
2564
2650
|
marginBottom: "4px",
|
|
2565
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.
|
|
2651
|
+
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)",
|
|
2566
2652
|
backdropFilter: "blur(15px)",
|
|
2567
|
-
padding: "
|
|
2568
|
-
borderRadius: "
|
|
2569
|
-
border: "1px solid rgba(255, 255, 255, 0.
|
|
2653
|
+
padding: "10px 14px",
|
|
2654
|
+
borderRadius: "14px",
|
|
2655
|
+
border: "1px solid rgba(255, 255, 255, 0.15)",
|
|
2570
2656
|
display: "flex",
|
|
2571
2657
|
flexDirection: "column",
|
|
2572
2658
|
alignItems: "center",
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2659
|
+
justifyContent: "center",
|
|
2660
|
+
height: "128px",
|
|
2661
|
+
boxShadow: "0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)",
|
|
2662
|
+
zIndex: 10,
|
|
2663
|
+
transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
|
|
2576
2664
|
},
|
|
2577
|
-
onMouseEnter: () =>
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
"
|
|
2665
|
+
onMouseEnter: (e) => {
|
|
2666
|
+
setShowVolumeSlider(true);
|
|
2667
|
+
e.currentTarget.style.transform = "translateX(-50%) translateY(-2px) scale(1.02)";
|
|
2668
|
+
e.currentTarget.style.boxShadow = "0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)";
|
|
2669
|
+
e.currentTarget.style.borderColor = "rgba(59, 130, 246, 0.4)";
|
|
2670
|
+
},
|
|
2671
|
+
onMouseLeave: (e) => {
|
|
2672
|
+
setShowVolumeSlider(false);
|
|
2673
|
+
e.currentTarget.style.transform = "translateX(-50%)";
|
|
2674
|
+
e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)";
|
|
2675
|
+
e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.15)";
|
|
2676
|
+
},
|
|
2677
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2678
|
+
"div",
|
|
2581
2679
|
{
|
|
2582
|
-
type: "range",
|
|
2583
|
-
min: "0",
|
|
2584
|
-
max: "1",
|
|
2585
|
-
step: "0.01",
|
|
2586
|
-
value: isMuted ? 0 : volume,
|
|
2587
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2588
2680
|
style: {
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
}
|
|
2681
|
+
position: "relative",
|
|
2682
|
+
width: "8px",
|
|
2683
|
+
height: "104px",
|
|
2684
|
+
cursor: "pointer",
|
|
2685
|
+
transition: "transform 0.2s ease-in-out"
|
|
2686
|
+
},
|
|
2687
|
+
onMouseEnter: (e) => {
|
|
2688
|
+
e.currentTarget.style.transform = "scaleX(1.2)";
|
|
2689
|
+
},
|
|
2690
|
+
onMouseLeave: (e) => {
|
|
2691
|
+
e.currentTarget.style.transform = "scaleX(1)";
|
|
2692
|
+
},
|
|
2693
|
+
onMouseDown: (e) => {
|
|
2694
|
+
e.preventDefault();
|
|
2695
|
+
const sliderElement = e.currentTarget;
|
|
2696
|
+
const handleMouseMove = (moveEvent) => {
|
|
2697
|
+
if (!sliderElement) return;
|
|
2698
|
+
const rect2 = sliderElement.getBoundingClientRect();
|
|
2699
|
+
const y2 = moveEvent.clientY - rect2.top;
|
|
2700
|
+
const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
|
|
2701
|
+
handleVolumeChange(percentage2);
|
|
2702
|
+
};
|
|
2703
|
+
const handleMouseUp = () => {
|
|
2704
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
2705
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
2706
|
+
};
|
|
2707
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
2708
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
2709
|
+
const rect = sliderElement.getBoundingClientRect();
|
|
2710
|
+
const y = e.clientY - rect.top;
|
|
2711
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
2712
|
+
handleVolumeChange(percentage);
|
|
2713
|
+
},
|
|
2714
|
+
onClick: (e) => {
|
|
2715
|
+
e.stopPropagation();
|
|
2716
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
2717
|
+
const y = e.clientY - rect.top;
|
|
2718
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
2719
|
+
handleVolumeChange(percentage);
|
|
2720
|
+
},
|
|
2721
|
+
children: [
|
|
2722
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2723
|
+
"div",
|
|
2724
|
+
{
|
|
2725
|
+
style: {
|
|
2726
|
+
position: "absolute",
|
|
2727
|
+
bottom: "0",
|
|
2728
|
+
left: "0",
|
|
2729
|
+
width: "100%",
|
|
2730
|
+
height: "100%",
|
|
2731
|
+
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)",
|
|
2732
|
+
borderRadius: "4px",
|
|
2733
|
+
boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
),
|
|
2737
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2738
|
+
"div",
|
|
2739
|
+
{
|
|
2740
|
+
style: {
|
|
2741
|
+
position: "absolute",
|
|
2742
|
+
bottom: "0",
|
|
2743
|
+
left: "0",
|
|
2744
|
+
width: "100%",
|
|
2745
|
+
height: `${(isMuted ? 0 : volume) * 100}%`,
|
|
2746
|
+
background: "linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)",
|
|
2747
|
+
borderRadius: "4px",
|
|
2748
|
+
transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
|
|
2749
|
+
boxShadow: "0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)"
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
),
|
|
2753
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2754
|
+
"div",
|
|
2755
|
+
{
|
|
2756
|
+
style: {
|
|
2757
|
+
position: "absolute",
|
|
2758
|
+
bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,
|
|
2759
|
+
left: "50%",
|
|
2760
|
+
transform: "translateX(-50%)",
|
|
2761
|
+
width: "14px",
|
|
2762
|
+
height: "14px",
|
|
2763
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
|
|
2764
|
+
borderRadius: "50%",
|
|
2765
|
+
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)",
|
|
2766
|
+
transition: "bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out",
|
|
2767
|
+
cursor: "grab"
|
|
2768
|
+
},
|
|
2769
|
+
onMouseEnter: (e) => {
|
|
2770
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.3)";
|
|
2771
|
+
e.currentTarget.style.boxShadow = "0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)";
|
|
2772
|
+
e.currentTarget.style.cursor = "grab";
|
|
2773
|
+
},
|
|
2774
|
+
onMouseLeave: (e) => {
|
|
2775
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1)";
|
|
2776
|
+
e.currentTarget.style.boxShadow = "0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)";
|
|
2777
|
+
},
|
|
2778
|
+
onMouseDown: (e) => {
|
|
2779
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.4)";
|
|
2780
|
+
e.currentTarget.style.cursor = "grabbing";
|
|
2781
|
+
},
|
|
2782
|
+
onMouseUp: (e) => {
|
|
2783
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.3)";
|
|
2784
|
+
e.currentTarget.style.cursor = "grab";
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
)
|
|
2788
|
+
]
|
|
2598
2789
|
}
|
|
2599
2790
|
)
|
|
2600
2791
|
}
|
|
@@ -2911,40 +3102,146 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2911
3102
|
left: "50%",
|
|
2912
3103
|
transform: "translateX(-50%)",
|
|
2913
3104
|
marginBottom: "4px",
|
|
2914
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.
|
|
3105
|
+
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)",
|
|
2915
3106
|
backdropFilter: "blur(20px)",
|
|
2916
|
-
padding: "
|
|
2917
|
-
borderRadius: "
|
|
2918
|
-
border: "2px solid rgba(255, 255, 255, 0.
|
|
3107
|
+
padding: "10px 14px",
|
|
3108
|
+
borderRadius: "14px",
|
|
3109
|
+
border: "2px solid rgba(255, 255, 255, 0.7)",
|
|
2919
3110
|
display: "flex",
|
|
2920
3111
|
flexDirection: "column",
|
|
2921
3112
|
alignItems: "center",
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
3113
|
+
justifyContent: "center",
|
|
3114
|
+
height: "128px",
|
|
3115
|
+
boxShadow: "0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)",
|
|
3116
|
+
zIndex: 10,
|
|
3117
|
+
transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
|
|
2925
3118
|
},
|
|
2926
|
-
onMouseEnter: () =>
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
"
|
|
3119
|
+
onMouseEnter: (e) => {
|
|
3120
|
+
setShowVolumeSlider(true);
|
|
3121
|
+
e.currentTarget.style.transform = "translateX(-50%) translateY(-2px) scale(1.02)";
|
|
3122
|
+
e.currentTarget.style.boxShadow = "0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)";
|
|
3123
|
+
e.currentTarget.style.borderColor = "rgba(96, 165, 250, 0.8)";
|
|
3124
|
+
},
|
|
3125
|
+
onMouseLeave: (e) => {
|
|
3126
|
+
setShowVolumeSlider(false);
|
|
3127
|
+
e.currentTarget.style.transform = "translateX(-50%)";
|
|
3128
|
+
e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)";
|
|
3129
|
+
e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.7)";
|
|
3130
|
+
},
|
|
3131
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3132
|
+
"div",
|
|
2930
3133
|
{
|
|
2931
|
-
type: "range",
|
|
2932
|
-
min: "0",
|
|
2933
|
-
max: "1",
|
|
2934
|
-
step: "0.01",
|
|
2935
|
-
value: isMuted ? 0 : volume,
|
|
2936
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2937
3134
|
style: {
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
height: "90px",
|
|
2942
|
-
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%)",
|
|
2943
|
-
borderRadius: "3px",
|
|
2944
|
-
outline: "none",
|
|
3135
|
+
position: "relative",
|
|
3136
|
+
width: "8px",
|
|
3137
|
+
height: "104px",
|
|
2945
3138
|
cursor: "pointer",
|
|
2946
|
-
|
|
2947
|
-
}
|
|
3139
|
+
transition: "transform 0.2s ease-in-out"
|
|
3140
|
+
},
|
|
3141
|
+
onMouseEnter: (e) => {
|
|
3142
|
+
e.currentTarget.style.transform = "scaleX(1.2)";
|
|
3143
|
+
},
|
|
3144
|
+
onMouseLeave: (e) => {
|
|
3145
|
+
e.currentTarget.style.transform = "scaleX(1)";
|
|
3146
|
+
},
|
|
3147
|
+
onMouseDown: (e) => {
|
|
3148
|
+
e.preventDefault();
|
|
3149
|
+
const sliderElement = e.currentTarget;
|
|
3150
|
+
const handleMouseMove = (moveEvent) => {
|
|
3151
|
+
if (!sliderElement) return;
|
|
3152
|
+
const rect2 = sliderElement.getBoundingClientRect();
|
|
3153
|
+
const y2 = moveEvent.clientY - rect2.top;
|
|
3154
|
+
const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
|
|
3155
|
+
handleVolumeChange(percentage2);
|
|
3156
|
+
};
|
|
3157
|
+
const handleMouseUp = () => {
|
|
3158
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
3159
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
3160
|
+
};
|
|
3161
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
3162
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
3163
|
+
const rect = sliderElement.getBoundingClientRect();
|
|
3164
|
+
const y = e.clientY - rect.top;
|
|
3165
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
3166
|
+
handleVolumeChange(percentage);
|
|
3167
|
+
},
|
|
3168
|
+
onClick: (e) => {
|
|
3169
|
+
e.stopPropagation();
|
|
3170
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
3171
|
+
const y = e.clientY - rect.top;
|
|
3172
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
3173
|
+
handleVolumeChange(percentage);
|
|
3174
|
+
},
|
|
3175
|
+
children: [
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3177
|
+
"div",
|
|
3178
|
+
{
|
|
3179
|
+
style: {
|
|
3180
|
+
position: "absolute",
|
|
3181
|
+
bottom: "0",
|
|
3182
|
+
left: "0",
|
|
3183
|
+
width: "100%",
|
|
3184
|
+
height: "100%",
|
|
3185
|
+
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)",
|
|
3186
|
+
borderRadius: "4px",
|
|
3187
|
+
border: "1px solid rgba(255, 255, 255, 0.4)",
|
|
3188
|
+
boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.3)"
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
),
|
|
3192
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3193
|
+
"div",
|
|
3194
|
+
{
|
|
3195
|
+
style: {
|
|
3196
|
+
position: "absolute",
|
|
3197
|
+
bottom: "0",
|
|
3198
|
+
left: "0",
|
|
3199
|
+
width: "100%",
|
|
3200
|
+
height: `${(isMuted ? 0 : volume) * 100}%`,
|
|
3201
|
+
background: "linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)",
|
|
3202
|
+
borderRadius: "4px",
|
|
3203
|
+
transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
|
|
3204
|
+
boxShadow: "0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)"
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
),
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3209
|
+
"div",
|
|
3210
|
+
{
|
|
3211
|
+
style: {
|
|
3212
|
+
position: "absolute",
|
|
3213
|
+
bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,
|
|
3214
|
+
left: "50%",
|
|
3215
|
+
transform: "translateX(-50%)",
|
|
3216
|
+
width: "16px",
|
|
3217
|
+
height: "16px",
|
|
3218
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
|
|
3219
|
+
borderRadius: "50%",
|
|
3220
|
+
border: "2px solid rgba(96, 165, 250, 0.9)",
|
|
3221
|
+
boxShadow: "0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)",
|
|
3222
|
+
transition: "bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out",
|
|
3223
|
+
cursor: "grab"
|
|
3224
|
+
},
|
|
3225
|
+
onMouseEnter: (e) => {
|
|
3226
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.35)";
|
|
3227
|
+
e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)";
|
|
3228
|
+
e.currentTarget.style.cursor = "grab";
|
|
3229
|
+
},
|
|
3230
|
+
onMouseLeave: (e) => {
|
|
3231
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1)";
|
|
3232
|
+
e.currentTarget.style.boxShadow = "0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)";
|
|
3233
|
+
},
|
|
3234
|
+
onMouseDown: (e) => {
|
|
3235
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.45)";
|
|
3236
|
+
e.currentTarget.style.cursor = "grabbing";
|
|
3237
|
+
},
|
|
3238
|
+
onMouseUp: (e) => {
|
|
3239
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.35)";
|
|
3240
|
+
e.currentTarget.style.cursor = "grab";
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
)
|
|
3244
|
+
]
|
|
2948
3245
|
}
|
|
2949
3246
|
)
|
|
2950
3247
|
}
|