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
package/lib/index.cjs
CHANGED
|
@@ -101,9 +101,22 @@ function createImaController(video, options) {
|
|
|
101
101
|
'script[data-ima="true"]'
|
|
102
102
|
);
|
|
103
103
|
if (existing) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
if (window.google?.ima) {
|
|
105
|
+
return Promise.resolve();
|
|
106
|
+
}
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const timeout = setTimeout(() => {
|
|
109
|
+
reject(new Error("IMA SDK load timeout"));
|
|
110
|
+
}, 1e4);
|
|
111
|
+
existing.addEventListener("load", () => {
|
|
112
|
+
clearTimeout(timeout);
|
|
113
|
+
resolve();
|
|
114
|
+
});
|
|
115
|
+
existing.addEventListener("error", () => {
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
reject(new Error("IMA SDK load failed"));
|
|
118
|
+
});
|
|
119
|
+
});
|
|
107
120
|
}
|
|
108
121
|
return new Promise((resolve, reject) => {
|
|
109
122
|
const script = document.createElement("script");
|
|
@@ -132,6 +145,17 @@ function createImaController(video, options) {
|
|
|
132
145
|
adsRequest.adTagUrl = vastTagUrl;
|
|
133
146
|
adsLoader.requestAds(adsRequest);
|
|
134
147
|
}
|
|
148
|
+
function destroyAdsManager() {
|
|
149
|
+
if (adsManager) {
|
|
150
|
+
try {
|
|
151
|
+
console.log("[IMA] Destroying existing ads manager");
|
|
152
|
+
adsManager.destroy();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.warn("[IMA] Error destroying ads manager:", error);
|
|
155
|
+
}
|
|
156
|
+
adsManager = void 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
135
159
|
return {
|
|
136
160
|
initialize() {
|
|
137
161
|
ensureImaLoaded().then(() => {
|
|
@@ -164,9 +188,22 @@ function createImaController(video, options) {
|
|
|
164
188
|
},
|
|
165
189
|
async requestAds(vastTagUrl) {
|
|
166
190
|
console.log("[IMA] Requesting ads:", vastTagUrl);
|
|
191
|
+
if (adPlaying) {
|
|
192
|
+
console.warn(
|
|
193
|
+
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
194
|
+
);
|
|
195
|
+
return Promise.reject(
|
|
196
|
+
new Error("Ad already playing - cannot request new ads")
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
destroyAdsManager();
|
|
200
|
+
adsLoadedReject = void 0;
|
|
201
|
+
adsLoadedResolve = void 0;
|
|
202
|
+
let currentReject;
|
|
167
203
|
adsLoadedPromise = new Promise((resolve, reject) => {
|
|
168
204
|
adsLoadedResolve = resolve;
|
|
169
205
|
adsLoadedReject = reject;
|
|
206
|
+
currentReject = reject;
|
|
170
207
|
setTimeout(() => {
|
|
171
208
|
if (adsLoadedReject) {
|
|
172
209
|
adsLoadedReject(new Error("Ad request timeout"));
|
|
@@ -188,7 +225,7 @@ function createImaController(video, options) {
|
|
|
188
225
|
container.style.top = "0";
|
|
189
226
|
container.style.right = "0";
|
|
190
227
|
container.style.bottom = "0";
|
|
191
|
-
container.style.display = "
|
|
228
|
+
container.style.display = "none";
|
|
192
229
|
container.style.alignItems = "center";
|
|
193
230
|
container.style.justifyContent = "center";
|
|
194
231
|
container.style.pointerEvents = "none";
|
|
@@ -228,14 +265,14 @@ function createImaController(video, options) {
|
|
|
228
265
|
AdErrorEvent.AD_ERROR,
|
|
229
266
|
(errorEvent) => {
|
|
230
267
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
231
|
-
|
|
232
|
-
adsManager?.destroy?.();
|
|
233
|
-
} catch {
|
|
234
|
-
}
|
|
268
|
+
destroyAdsManager();
|
|
235
269
|
adPlaying = false;
|
|
236
270
|
video.muted = originalMutedState;
|
|
237
|
-
if (adContainerEl)
|
|
271
|
+
if (adContainerEl) {
|
|
238
272
|
adContainerEl.style.pointerEvents = "none";
|
|
273
|
+
adContainerEl.style.display = "none";
|
|
274
|
+
console.log("[IMA] Ad container hidden after error");
|
|
275
|
+
}
|
|
239
276
|
if (adsLoadedReject) {
|
|
240
277
|
adsLoadedReject(new Error("Ad playback error"));
|
|
241
278
|
adsLoadedReject = void 0;
|
|
@@ -268,10 +305,6 @@ function createImaController(video, options) {
|
|
|
268
305
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
269
306
|
() => {
|
|
270
307
|
console.log("[IMA] Content pause requested");
|
|
271
|
-
if (!adPlaying) {
|
|
272
|
-
originalMutedState = video.muted;
|
|
273
|
-
}
|
|
274
|
-
video.muted = true;
|
|
275
308
|
if (!options?.continueLiveStreamDuringAds) {
|
|
276
309
|
video.pause();
|
|
277
310
|
console.log("[IMA] Video paused (VOD mode)");
|
|
@@ -280,20 +313,34 @@ function createImaController(video, options) {
|
|
|
280
313
|
"[IMA] Video continues playing but muted (Live mode)"
|
|
281
314
|
);
|
|
282
315
|
}
|
|
316
|
+
video.muted = true;
|
|
283
317
|
adPlaying = true;
|
|
284
|
-
if (adContainerEl)
|
|
285
|
-
adContainerEl.style.pointerEvents = "auto";
|
|
286
318
|
emit("content_pause");
|
|
287
319
|
}
|
|
288
320
|
);
|
|
321
|
+
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
322
|
+
console.log("[IMA] Ad started playing");
|
|
323
|
+
if (adContainerEl) {
|
|
324
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
325
|
+
adContainerEl.style.display = "flex";
|
|
326
|
+
console.log(
|
|
327
|
+
"[IMA] Ad container visibility set to flex with pointer events enabled"
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
289
331
|
adsManager.addEventListener(
|
|
290
332
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
291
333
|
() => {
|
|
292
334
|
console.log("[IMA] Content resume requested");
|
|
293
335
|
adPlaying = false;
|
|
294
336
|
video.muted = originalMutedState;
|
|
295
|
-
if (adContainerEl)
|
|
337
|
+
if (adContainerEl) {
|
|
296
338
|
adContainerEl.style.pointerEvents = "none";
|
|
339
|
+
adContainerEl.style.display = "none";
|
|
340
|
+
console.log(
|
|
341
|
+
"[IMA] Ad container hidden - pointer events disabled"
|
|
342
|
+
);
|
|
343
|
+
}
|
|
297
344
|
if (!options?.continueLiveStreamDuringAds) {
|
|
298
345
|
video.play()?.catch(() => {
|
|
299
346
|
});
|
|
@@ -310,7 +357,13 @@ function createImaController(video, options) {
|
|
|
310
357
|
console.log("[IMA] All ads completed");
|
|
311
358
|
adPlaying = false;
|
|
312
359
|
video.muted = originalMutedState;
|
|
313
|
-
if (adContainerEl)
|
|
360
|
+
if (adContainerEl) {
|
|
361
|
+
adContainerEl.style.pointerEvents = "none";
|
|
362
|
+
adContainerEl.style.display = "none";
|
|
363
|
+
console.log(
|
|
364
|
+
"[IMA] Ad container hidden after all ads completed"
|
|
365
|
+
);
|
|
366
|
+
}
|
|
314
367
|
if (!options?.continueLiveStreamDuringAds) {
|
|
315
368
|
video.play().catch(() => {
|
|
316
369
|
});
|
|
@@ -353,6 +406,13 @@ function createImaController(video, options) {
|
|
|
353
406
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
354
407
|
(adErrorEvent) => {
|
|
355
408
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
409
|
+
adPlaying = false;
|
|
410
|
+
video.muted = originalMutedState;
|
|
411
|
+
if (adContainerEl) adContainerEl.style.pointerEvents = "none";
|
|
412
|
+
if (!options?.continueLiveStreamDuringAds) {
|
|
413
|
+
video.play().catch(() => {
|
|
414
|
+
});
|
|
415
|
+
}
|
|
356
416
|
if (adsLoadedReject) {
|
|
357
417
|
adsLoadedReject(new Error("Ads loader error"));
|
|
358
418
|
adsLoadedReject = void 0;
|
|
@@ -368,11 +428,9 @@ function createImaController(video, options) {
|
|
|
368
428
|
return adsLoadedPromise;
|
|
369
429
|
} catch (error) {
|
|
370
430
|
console.error("[IMA] Failed to request ads:", error);
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
adsLoadedResolve = void 0;
|
|
375
|
-
}
|
|
431
|
+
currentReject?.(error);
|
|
432
|
+
adsLoadedReject = void 0;
|
|
433
|
+
adsLoadedResolve = void 0;
|
|
376
434
|
return Promise.reject(error);
|
|
377
435
|
}
|
|
378
436
|
},
|
|
@@ -409,10 +467,16 @@ function createImaController(video, options) {
|
|
|
409
467
|
async stop() {
|
|
410
468
|
adPlaying = false;
|
|
411
469
|
video.muted = originalMutedState;
|
|
470
|
+
if (adContainerEl) {
|
|
471
|
+
adContainerEl.style.pointerEvents = "none";
|
|
472
|
+
adContainerEl.style.display = "none";
|
|
473
|
+
console.log("[IMA] Ad container hidden after stop");
|
|
474
|
+
}
|
|
412
475
|
try {
|
|
413
476
|
adsManager?.stop?.();
|
|
414
477
|
} catch {
|
|
415
478
|
}
|
|
479
|
+
destroyAdsManager();
|
|
416
480
|
if (!options?.continueLiveStreamDuringAds) {
|
|
417
481
|
video.play().catch(() => {
|
|
418
482
|
});
|
|
@@ -422,12 +486,13 @@ function createImaController(video, options) {
|
|
|
422
486
|
}
|
|
423
487
|
},
|
|
424
488
|
destroy() {
|
|
425
|
-
|
|
426
|
-
adsManager?.destroy?.();
|
|
427
|
-
} catch {
|
|
428
|
-
}
|
|
489
|
+
destroyAdsManager();
|
|
429
490
|
adPlaying = false;
|
|
430
491
|
video.muted = originalMutedState;
|
|
492
|
+
if (adContainerEl) {
|
|
493
|
+
adContainerEl.style.pointerEvents = "none";
|
|
494
|
+
adContainerEl.style.display = "none";
|
|
495
|
+
}
|
|
431
496
|
try {
|
|
432
497
|
adsLoader?.destroy?.();
|
|
433
498
|
} catch {
|
|
@@ -435,6 +500,9 @@ function createImaController(video, options) {
|
|
|
435
500
|
if (adContainerEl?.parentElement) {
|
|
436
501
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
437
502
|
}
|
|
503
|
+
adContainerEl = void 0;
|
|
504
|
+
adDisplayContainer = void 0;
|
|
505
|
+
adsLoader = void 0;
|
|
438
506
|
},
|
|
439
507
|
isAdPlaying() {
|
|
440
508
|
return adPlaying;
|
|
@@ -912,17 +980,8 @@ var StormcloudVideoPlayer = class {
|
|
|
912
980
|
this.video.muted = !!this.config.muted;
|
|
913
981
|
this.ima.initialize();
|
|
914
982
|
this.ima.on("all_ads_completed", () => {
|
|
915
|
-
if (
|
|
916
|
-
|
|
917
|
-
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
918
|
-
const next = this.adPodQueue.shift();
|
|
919
|
-
this.currentAdIndex++;
|
|
920
|
-
this.playSingleAd(next).catch(() => {
|
|
921
|
-
});
|
|
922
|
-
} else {
|
|
923
|
-
this.currentAdIndex = 0;
|
|
924
|
-
this.totalAdsInBreak = 0;
|
|
925
|
-
this.showAds = false;
|
|
983
|
+
if (this.config.debugAdTiming) {
|
|
984
|
+
console.log("[StormcloudVideoPlayer] IMA all_ads_completed event received");
|
|
926
985
|
}
|
|
927
986
|
});
|
|
928
987
|
this.ima.on("ad_error", () => {
|
|
@@ -953,6 +1012,26 @@ var StormcloudVideoPlayer = class {
|
|
|
953
1012
|
);
|
|
954
1013
|
}
|
|
955
1014
|
this.clearAdFailsafeTimer();
|
|
1015
|
+
if (!this.inAdBreak) return;
|
|
1016
|
+
const remaining = this.getRemainingAdMs();
|
|
1017
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
1018
|
+
const next = this.adPodQueue.shift();
|
|
1019
|
+
this.currentAdIndex++;
|
|
1020
|
+
if (this.config.debugAdTiming) {
|
|
1021
|
+
console.log(
|
|
1022
|
+
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
this.playSingleAd(next).catch(() => {
|
|
1026
|
+
});
|
|
1027
|
+
} else {
|
|
1028
|
+
if (this.config.debugAdTiming) {
|
|
1029
|
+
console.log("[StormcloudVideoPlayer] Ad pod completed");
|
|
1030
|
+
}
|
|
1031
|
+
this.currentAdIndex = 0;
|
|
1032
|
+
this.totalAdsInBreak = 0;
|
|
1033
|
+
this.showAds = false;
|
|
1034
|
+
}
|
|
956
1035
|
});
|
|
957
1036
|
this.video.addEventListener("timeupdate", () => {
|
|
958
1037
|
this.onTimeUpdate(this.video.currentTime);
|
|
@@ -1602,21 +1681,21 @@ var StormcloudVideoPlayer = class {
|
|
|
1602
1681
|
if (this.config.debugAdTiming) {
|
|
1603
1682
|
console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
|
|
1604
1683
|
}
|
|
1605
|
-
this.ima.
|
|
1606
|
-
if (!this.shouldContinueLiveStreamDuringAds()) {
|
|
1607
|
-
if (this.config.debugAdTiming) {
|
|
1608
|
-
console.log("[StormcloudVideoPlayer] Pausing video immediately for ad (VOD mode)");
|
|
1609
|
-
}
|
|
1610
|
-
this.video.pause();
|
|
1611
|
-
} else {
|
|
1684
|
+
if (this.ima.isAdPlaying()) {
|
|
1612
1685
|
if (this.config.debugAdTiming) {
|
|
1613
|
-
console.
|
|
1686
|
+
console.warn(
|
|
1687
|
+
"[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
|
|
1688
|
+
);
|
|
1614
1689
|
}
|
|
1615
|
-
|
|
1690
|
+
return;
|
|
1616
1691
|
}
|
|
1692
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
1617
1693
|
this.startAdFailsafeTimer();
|
|
1618
1694
|
try {
|
|
1619
1695
|
await this.ima.requestAds(vastTagUrl);
|
|
1696
|
+
if (this.config.debugAdTiming) {
|
|
1697
|
+
console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
|
|
1698
|
+
}
|
|
1620
1699
|
await this.ima.play();
|
|
1621
1700
|
if (this.config.debugAdTiming) {
|
|
1622
1701
|
console.log("[StormcloudVideoPlayer] Ad playback started successfully");
|
|
@@ -1644,6 +1723,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1644
1723
|
this.showAds = false;
|
|
1645
1724
|
this.currentAdIndex = 0;
|
|
1646
1725
|
this.totalAdsInBreak = 0;
|
|
1726
|
+
const originalMutedState = this.ima.getOriginalMutedState();
|
|
1727
|
+
this.video.muted = originalMutedState;
|
|
1728
|
+
if (this.config.debugAdTiming) {
|
|
1729
|
+
console.log(
|
|
1730
|
+
`[StormcloudVideoPlayer] Restored mute state to: ${originalMutedState}`
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1647
1733
|
if (this.video.paused) {
|
|
1648
1734
|
this.video.play()?.catch(() => {
|
|
1649
1735
|
if (this.config.debugAdTiming) {
|
|
@@ -2587,39 +2673,144 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2587
2673
|
left: "50%",
|
|
2588
2674
|
transform: "translateX(-50%)",
|
|
2589
2675
|
marginBottom: "4px",
|
|
2590
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.
|
|
2676
|
+
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)",
|
|
2591
2677
|
backdropFilter: "blur(15px)",
|
|
2592
|
-
padding: "
|
|
2593
|
-
borderRadius: "
|
|
2594
|
-
border: "1px solid rgba(255, 255, 255, 0.
|
|
2678
|
+
padding: "10px 14px",
|
|
2679
|
+
borderRadius: "14px",
|
|
2680
|
+
border: "1px solid rgba(255, 255, 255, 0.15)",
|
|
2595
2681
|
display: "flex",
|
|
2596
2682
|
flexDirection: "column",
|
|
2597
2683
|
alignItems: "center",
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2684
|
+
justifyContent: "center",
|
|
2685
|
+
height: "128px",
|
|
2686
|
+
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)",
|
|
2687
|
+
zIndex: 10,
|
|
2688
|
+
transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
|
|
2601
2689
|
},
|
|
2602
|
-
onMouseEnter: () =>
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
"
|
|
2690
|
+
onMouseEnter: (e) => {
|
|
2691
|
+
setShowVolumeSlider(true);
|
|
2692
|
+
e.currentTarget.style.transform = "translateX(-50%) translateY(-2px) scale(1.02)";
|
|
2693
|
+
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)";
|
|
2694
|
+
e.currentTarget.style.borderColor = "rgba(59, 130, 246, 0.4)";
|
|
2695
|
+
},
|
|
2696
|
+
onMouseLeave: (e) => {
|
|
2697
|
+
setShowVolumeSlider(false);
|
|
2698
|
+
e.currentTarget.style.transform = "translateX(-50%)";
|
|
2699
|
+
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)";
|
|
2700
|
+
e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.15)";
|
|
2701
|
+
},
|
|
2702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2703
|
+
"div",
|
|
2606
2704
|
{
|
|
2607
|
-
type: "range",
|
|
2608
|
-
min: "0",
|
|
2609
|
-
max: "1",
|
|
2610
|
-
step: "0.01",
|
|
2611
|
-
value: isMuted ? 0 : volume,
|
|
2612
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2613
2705
|
style: {
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
}
|
|
2706
|
+
position: "relative",
|
|
2707
|
+
width: "8px",
|
|
2708
|
+
height: "104px",
|
|
2709
|
+
cursor: "pointer",
|
|
2710
|
+
transition: "transform 0.2s ease-in-out"
|
|
2711
|
+
},
|
|
2712
|
+
onMouseEnter: (e) => {
|
|
2713
|
+
e.currentTarget.style.transform = "scaleX(1.2)";
|
|
2714
|
+
},
|
|
2715
|
+
onMouseLeave: (e) => {
|
|
2716
|
+
e.currentTarget.style.transform = "scaleX(1)";
|
|
2717
|
+
},
|
|
2718
|
+
onMouseDown: (e) => {
|
|
2719
|
+
e.preventDefault();
|
|
2720
|
+
const sliderElement = e.currentTarget;
|
|
2721
|
+
const handleMouseMove = (moveEvent) => {
|
|
2722
|
+
if (!sliderElement) return;
|
|
2723
|
+
const rect2 = sliderElement.getBoundingClientRect();
|
|
2724
|
+
const y2 = moveEvent.clientY - rect2.top;
|
|
2725
|
+
const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
|
|
2726
|
+
handleVolumeChange(percentage2);
|
|
2727
|
+
};
|
|
2728
|
+
const handleMouseUp = () => {
|
|
2729
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
2730
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
2731
|
+
};
|
|
2732
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
2733
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
2734
|
+
const rect = sliderElement.getBoundingClientRect();
|
|
2735
|
+
const y = e.clientY - rect.top;
|
|
2736
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
2737
|
+
handleVolumeChange(percentage);
|
|
2738
|
+
},
|
|
2739
|
+
onClick: (e) => {
|
|
2740
|
+
e.stopPropagation();
|
|
2741
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
2742
|
+
const y = e.clientY - rect.top;
|
|
2743
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
2744
|
+
handleVolumeChange(percentage);
|
|
2745
|
+
},
|
|
2746
|
+
children: [
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2748
|
+
"div",
|
|
2749
|
+
{
|
|
2750
|
+
style: {
|
|
2751
|
+
position: "absolute",
|
|
2752
|
+
bottom: "0",
|
|
2753
|
+
left: "0",
|
|
2754
|
+
width: "100%",
|
|
2755
|
+
height: "100%",
|
|
2756
|
+
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)",
|
|
2757
|
+
borderRadius: "4px",
|
|
2758
|
+
boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
),
|
|
2762
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2763
|
+
"div",
|
|
2764
|
+
{
|
|
2765
|
+
style: {
|
|
2766
|
+
position: "absolute",
|
|
2767
|
+
bottom: "0",
|
|
2768
|
+
left: "0",
|
|
2769
|
+
width: "100%",
|
|
2770
|
+
height: `${(isMuted ? 0 : volume) * 100}%`,
|
|
2771
|
+
background: "linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)",
|
|
2772
|
+
borderRadius: "4px",
|
|
2773
|
+
transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
|
|
2774
|
+
boxShadow: "0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)"
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
),
|
|
2778
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2779
|
+
"div",
|
|
2780
|
+
{
|
|
2781
|
+
style: {
|
|
2782
|
+
position: "absolute",
|
|
2783
|
+
bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,
|
|
2784
|
+
left: "50%",
|
|
2785
|
+
transform: "translateX(-50%)",
|
|
2786
|
+
width: "14px",
|
|
2787
|
+
height: "14px",
|
|
2788
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
|
|
2789
|
+
borderRadius: "50%",
|
|
2790
|
+
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)",
|
|
2791
|
+
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",
|
|
2792
|
+
cursor: "grab"
|
|
2793
|
+
},
|
|
2794
|
+
onMouseEnter: (e) => {
|
|
2795
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.3)";
|
|
2796
|
+
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)";
|
|
2797
|
+
e.currentTarget.style.cursor = "grab";
|
|
2798
|
+
},
|
|
2799
|
+
onMouseLeave: (e) => {
|
|
2800
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1)";
|
|
2801
|
+
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)";
|
|
2802
|
+
},
|
|
2803
|
+
onMouseDown: (e) => {
|
|
2804
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.4)";
|
|
2805
|
+
e.currentTarget.style.cursor = "grabbing";
|
|
2806
|
+
},
|
|
2807
|
+
onMouseUp: (e) => {
|
|
2808
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.3)";
|
|
2809
|
+
e.currentTarget.style.cursor = "grab";
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
)
|
|
2813
|
+
]
|
|
2623
2814
|
}
|
|
2624
2815
|
)
|
|
2625
2816
|
}
|
|
@@ -2936,40 +3127,146 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2936
3127
|
left: "50%",
|
|
2937
3128
|
transform: "translateX(-50%)",
|
|
2938
3129
|
marginBottom: "4px",
|
|
2939
|
-
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.
|
|
3130
|
+
background: "linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)",
|
|
2940
3131
|
backdropFilter: "blur(20px)",
|
|
2941
|
-
padding: "
|
|
2942
|
-
borderRadius: "
|
|
2943
|
-
border: "2px solid rgba(255, 255, 255, 0.
|
|
3132
|
+
padding: "10px 14px",
|
|
3133
|
+
borderRadius: "14px",
|
|
3134
|
+
border: "2px solid rgba(255, 255, 255, 0.7)",
|
|
2944
3135
|
display: "flex",
|
|
2945
3136
|
flexDirection: "column",
|
|
2946
3137
|
alignItems: "center",
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
3138
|
+
justifyContent: "center",
|
|
3139
|
+
height: "128px",
|
|
3140
|
+
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)",
|
|
3141
|
+
zIndex: 10,
|
|
3142
|
+
transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
|
|
2950
3143
|
},
|
|
2951
|
-
onMouseEnter: () =>
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
"
|
|
3144
|
+
onMouseEnter: (e) => {
|
|
3145
|
+
setShowVolumeSlider(true);
|
|
3146
|
+
e.currentTarget.style.transform = "translateX(-50%) translateY(-2px) scale(1.02)";
|
|
3147
|
+
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)";
|
|
3148
|
+
e.currentTarget.style.borderColor = "rgba(96, 165, 250, 0.8)";
|
|
3149
|
+
},
|
|
3150
|
+
onMouseLeave: (e) => {
|
|
3151
|
+
setShowVolumeSlider(false);
|
|
3152
|
+
e.currentTarget.style.transform = "translateX(-50%)";
|
|
3153
|
+
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)";
|
|
3154
|
+
e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.7)";
|
|
3155
|
+
},
|
|
3156
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3157
|
+
"div",
|
|
2955
3158
|
{
|
|
2956
|
-
type: "range",
|
|
2957
|
-
min: "0",
|
|
2958
|
-
max: "1",
|
|
2959
|
-
step: "0.01",
|
|
2960
|
-
value: isMuted ? 0 : volume,
|
|
2961
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2962
3159
|
style: {
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
height: "90px",
|
|
2967
|
-
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%)",
|
|
2968
|
-
borderRadius: "3px",
|
|
2969
|
-
outline: "none",
|
|
3160
|
+
position: "relative",
|
|
3161
|
+
width: "8px",
|
|
3162
|
+
height: "104px",
|
|
2970
3163
|
cursor: "pointer",
|
|
2971
|
-
|
|
2972
|
-
}
|
|
3164
|
+
transition: "transform 0.2s ease-in-out"
|
|
3165
|
+
},
|
|
3166
|
+
onMouseEnter: (e) => {
|
|
3167
|
+
e.currentTarget.style.transform = "scaleX(1.2)";
|
|
3168
|
+
},
|
|
3169
|
+
onMouseLeave: (e) => {
|
|
3170
|
+
e.currentTarget.style.transform = "scaleX(1)";
|
|
3171
|
+
},
|
|
3172
|
+
onMouseDown: (e) => {
|
|
3173
|
+
e.preventDefault();
|
|
3174
|
+
const sliderElement = e.currentTarget;
|
|
3175
|
+
const handleMouseMove = (moveEvent) => {
|
|
3176
|
+
if (!sliderElement) return;
|
|
3177
|
+
const rect2 = sliderElement.getBoundingClientRect();
|
|
3178
|
+
const y2 = moveEvent.clientY - rect2.top;
|
|
3179
|
+
const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
|
|
3180
|
+
handleVolumeChange(percentage2);
|
|
3181
|
+
};
|
|
3182
|
+
const handleMouseUp = () => {
|
|
3183
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
3184
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
3185
|
+
};
|
|
3186
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
3187
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
3188
|
+
const rect = sliderElement.getBoundingClientRect();
|
|
3189
|
+
const y = e.clientY - rect.top;
|
|
3190
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
3191
|
+
handleVolumeChange(percentage);
|
|
3192
|
+
},
|
|
3193
|
+
onClick: (e) => {
|
|
3194
|
+
e.stopPropagation();
|
|
3195
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
3196
|
+
const y = e.clientY - rect.top;
|
|
3197
|
+
const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
|
|
3198
|
+
handleVolumeChange(percentage);
|
|
3199
|
+
},
|
|
3200
|
+
children: [
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3202
|
+
"div",
|
|
3203
|
+
{
|
|
3204
|
+
style: {
|
|
3205
|
+
position: "absolute",
|
|
3206
|
+
bottom: "0",
|
|
3207
|
+
left: "0",
|
|
3208
|
+
width: "100%",
|
|
3209
|
+
height: "100%",
|
|
3210
|
+
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)",
|
|
3211
|
+
borderRadius: "4px",
|
|
3212
|
+
border: "1px solid rgba(255, 255, 255, 0.4)",
|
|
3213
|
+
boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.3)"
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
),
|
|
3217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3218
|
+
"div",
|
|
3219
|
+
{
|
|
3220
|
+
style: {
|
|
3221
|
+
position: "absolute",
|
|
3222
|
+
bottom: "0",
|
|
3223
|
+
left: "0",
|
|
3224
|
+
width: "100%",
|
|
3225
|
+
height: `${(isMuted ? 0 : volume) * 100}%`,
|
|
3226
|
+
background: "linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)",
|
|
3227
|
+
borderRadius: "4px",
|
|
3228
|
+
transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
|
|
3229
|
+
boxShadow: "0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)"
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
),
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3234
|
+
"div",
|
|
3235
|
+
{
|
|
3236
|
+
style: {
|
|
3237
|
+
position: "absolute",
|
|
3238
|
+
bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,
|
|
3239
|
+
left: "50%",
|
|
3240
|
+
transform: "translateX(-50%)",
|
|
3241
|
+
width: "16px",
|
|
3242
|
+
height: "16px",
|
|
3243
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
|
|
3244
|
+
borderRadius: "50%",
|
|
3245
|
+
border: "2px solid rgba(96, 165, 250, 0.9)",
|
|
3246
|
+
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)",
|
|
3247
|
+
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",
|
|
3248
|
+
cursor: "grab"
|
|
3249
|
+
},
|
|
3250
|
+
onMouseEnter: (e) => {
|
|
3251
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.35)";
|
|
3252
|
+
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)";
|
|
3253
|
+
e.currentTarget.style.cursor = "grab";
|
|
3254
|
+
},
|
|
3255
|
+
onMouseLeave: (e) => {
|
|
3256
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1)";
|
|
3257
|
+
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)";
|
|
3258
|
+
},
|
|
3259
|
+
onMouseDown: (e) => {
|
|
3260
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.45)";
|
|
3261
|
+
e.currentTarget.style.cursor = "grabbing";
|
|
3262
|
+
},
|
|
3263
|
+
onMouseUp: (e) => {
|
|
3264
|
+
e.currentTarget.style.transform = "translateX(-50%) scale(1.35)";
|
|
3265
|
+
e.currentTarget.style.cursor = "grab";
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
)
|
|
3269
|
+
]
|
|
2973
3270
|
}
|
|
2974
3271
|
)
|
|
2975
3272
|
}
|