stormcloud-video-player 0.2.8 → 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 +413 -100
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +413 -100
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +150 -48
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +150 -48
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +150 -48
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +94 -32
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +413 -100
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/utils/tracking.cjs +7 -1
- package/lib/utils/tracking.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,8 +305,6 @@ function createImaController(video, options) {
|
|
|
268
305
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
269
306
|
() => {
|
|
270
307
|
console.log("[IMA] Content pause requested");
|
|
271
|
-
originalMutedState = video.muted;
|
|
272
|
-
video.muted = true;
|
|
273
308
|
if (!options?.continueLiveStreamDuringAds) {
|
|
274
309
|
video.pause();
|
|
275
310
|
console.log("[IMA] Video paused (VOD mode)");
|
|
@@ -278,20 +313,34 @@ function createImaController(video, options) {
|
|
|
278
313
|
"[IMA] Video continues playing but muted (Live mode)"
|
|
279
314
|
);
|
|
280
315
|
}
|
|
316
|
+
video.muted = true;
|
|
281
317
|
adPlaying = true;
|
|
282
|
-
if (adContainerEl)
|
|
283
|
-
adContainerEl.style.pointerEvents = "auto";
|
|
284
318
|
emit("content_pause");
|
|
285
319
|
}
|
|
286
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
|
+
});
|
|
287
331
|
adsManager.addEventListener(
|
|
288
332
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
289
333
|
() => {
|
|
290
334
|
console.log("[IMA] Content resume requested");
|
|
291
335
|
adPlaying = false;
|
|
292
336
|
video.muted = originalMutedState;
|
|
293
|
-
if (adContainerEl)
|
|
337
|
+
if (adContainerEl) {
|
|
294
338
|
adContainerEl.style.pointerEvents = "none";
|
|
339
|
+
adContainerEl.style.display = "none";
|
|
340
|
+
console.log(
|
|
341
|
+
"[IMA] Ad container hidden - pointer events disabled"
|
|
342
|
+
);
|
|
343
|
+
}
|
|
295
344
|
if (!options?.continueLiveStreamDuringAds) {
|
|
296
345
|
video.play()?.catch(() => {
|
|
297
346
|
});
|
|
@@ -308,7 +357,13 @@ function createImaController(video, options) {
|
|
|
308
357
|
console.log("[IMA] All ads completed");
|
|
309
358
|
adPlaying = false;
|
|
310
359
|
video.muted = originalMutedState;
|
|
311
|
-
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
|
+
}
|
|
312
367
|
if (!options?.continueLiveStreamDuringAds) {
|
|
313
368
|
video.play().catch(() => {
|
|
314
369
|
});
|
|
@@ -351,6 +406,13 @@ function createImaController(video, options) {
|
|
|
351
406
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
352
407
|
(adErrorEvent) => {
|
|
353
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
|
+
}
|
|
354
416
|
if (adsLoadedReject) {
|
|
355
417
|
adsLoadedReject(new Error("Ads loader error"));
|
|
356
418
|
adsLoadedReject = void 0;
|
|
@@ -366,11 +428,9 @@ function createImaController(video, options) {
|
|
|
366
428
|
return adsLoadedPromise;
|
|
367
429
|
} catch (error) {
|
|
368
430
|
console.error("[IMA] Failed to request ads:", error);
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
adsLoadedResolve = void 0;
|
|
373
|
-
}
|
|
431
|
+
currentReject?.(error);
|
|
432
|
+
adsLoadedReject = void 0;
|
|
433
|
+
adsLoadedResolve = void 0;
|
|
374
434
|
return Promise.reject(error);
|
|
375
435
|
}
|
|
376
436
|
},
|
|
@@ -390,14 +450,6 @@ function createImaController(video, options) {
|
|
|
390
450
|
const height = video.clientHeight || 360;
|
|
391
451
|
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
392
452
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
393
|
-
if (!options?.continueLiveStreamDuringAds) {
|
|
394
|
-
console.log("[IMA] Pausing video for ad playback (VOD mode)");
|
|
395
|
-
video.pause();
|
|
396
|
-
} else {
|
|
397
|
-
console.log(
|
|
398
|
-
"[IMA] Keeping video playing but muted for ad playback (Live mode)"
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
453
|
adPlaying = true;
|
|
402
454
|
console.log("[IMA] Starting ad playback");
|
|
403
455
|
adsManager.start();
|
|
@@ -415,10 +467,16 @@ function createImaController(video, options) {
|
|
|
415
467
|
async stop() {
|
|
416
468
|
adPlaying = false;
|
|
417
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
|
+
}
|
|
418
475
|
try {
|
|
419
476
|
adsManager?.stop?.();
|
|
420
477
|
} catch {
|
|
421
478
|
}
|
|
479
|
+
destroyAdsManager();
|
|
422
480
|
if (!options?.continueLiveStreamDuringAds) {
|
|
423
481
|
video.play().catch(() => {
|
|
424
482
|
});
|
|
@@ -428,12 +486,13 @@ function createImaController(video, options) {
|
|
|
428
486
|
}
|
|
429
487
|
},
|
|
430
488
|
destroy() {
|
|
431
|
-
|
|
432
|
-
adsManager?.destroy?.();
|
|
433
|
-
} catch {
|
|
434
|
-
}
|
|
489
|
+
destroyAdsManager();
|
|
435
490
|
adPlaying = false;
|
|
436
491
|
video.muted = originalMutedState;
|
|
492
|
+
if (adContainerEl) {
|
|
493
|
+
adContainerEl.style.pointerEvents = "none";
|
|
494
|
+
adContainerEl.style.display = "none";
|
|
495
|
+
}
|
|
437
496
|
try {
|
|
438
497
|
adsLoader?.destroy?.();
|
|
439
498
|
} catch {
|
|
@@ -441,6 +500,9 @@ function createImaController(video, options) {
|
|
|
441
500
|
if (adContainerEl?.parentElement) {
|
|
442
501
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
443
502
|
}
|
|
503
|
+
adContainerEl = void 0;
|
|
504
|
+
adDisplayContainer = void 0;
|
|
505
|
+
adsLoader = void 0;
|
|
444
506
|
},
|
|
445
507
|
isAdPlaying() {
|
|
446
508
|
return adPlaying;
|
|
@@ -496,6 +558,7 @@ function createImaController(video, options) {
|
|
|
496
558
|
}
|
|
497
559
|
|
|
498
560
|
// src/utils/tracking.ts
|
|
561
|
+
var cachedBrowserId = null;
|
|
499
562
|
function getClientInfo() {
|
|
500
563
|
const ua = navigator.userAgent;
|
|
501
564
|
const platform = navigator.platform;
|
|
@@ -638,6 +701,9 @@ function getClientInfo() {
|
|
|
638
701
|
};
|
|
639
702
|
}
|
|
640
703
|
async function getBrowserID(clientInfo) {
|
|
704
|
+
if (cachedBrowserId) {
|
|
705
|
+
return cachedBrowserId;
|
|
706
|
+
}
|
|
641
707
|
const fingerprintString = JSON.stringify(clientInfo);
|
|
642
708
|
if (typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest) {
|
|
643
709
|
try {
|
|
@@ -648,6 +714,7 @@ async function getBrowserID(clientInfo) {
|
|
|
648
714
|
);
|
|
649
715
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
650
716
|
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
717
|
+
cachedBrowserId = hashHex;
|
|
651
718
|
return hashHex;
|
|
652
719
|
} catch (error) {
|
|
653
720
|
console.warn(
|
|
@@ -664,7 +731,8 @@ async function getBrowserID(clientInfo) {
|
|
|
664
731
|
const fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
|
|
665
732
|
const timestamp = Date.now().toString(16).padStart(12, "0");
|
|
666
733
|
const random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
|
|
667
|
-
|
|
734
|
+
cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, "0");
|
|
735
|
+
return cachedBrowserId;
|
|
668
736
|
}
|
|
669
737
|
async function sendInitialTracking(licenseKey) {
|
|
670
738
|
try {
|
|
@@ -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);
|
|
@@ -1353,17 +1432,21 @@ var StormcloudVideoPlayer = class {
|
|
|
1353
1432
|
return void 0;
|
|
1354
1433
|
}
|
|
1355
1434
|
initializeTracking() {
|
|
1356
|
-
sendInitialTracking(this.config.licenseKey).
|
|
1435
|
+
sendInitialTracking(this.config.licenseKey).then(() => {
|
|
1436
|
+
this.heartbeatInterval = window.setInterval(() => {
|
|
1437
|
+
this.sendHeartbeatIfNeeded();
|
|
1438
|
+
}, 5e3);
|
|
1439
|
+
}).catch((error) => {
|
|
1357
1440
|
if (this.config.debugAdTiming) {
|
|
1358
1441
|
console.warn(
|
|
1359
1442
|
"[StormcloudVideoPlayer] Failed to send initial tracking:",
|
|
1360
1443
|
error
|
|
1361
1444
|
);
|
|
1362
1445
|
}
|
|
1446
|
+
this.heartbeatInterval = window.setInterval(() => {
|
|
1447
|
+
this.sendHeartbeatIfNeeded();
|
|
1448
|
+
}, 5e3);
|
|
1363
1449
|
});
|
|
1364
|
-
this.heartbeatInterval = window.setInterval(() => {
|
|
1365
|
-
this.sendHeartbeatIfNeeded();
|
|
1366
|
-
}, 5e3);
|
|
1367
1450
|
}
|
|
1368
1451
|
sendHeartbeatIfNeeded() {
|
|
1369
1452
|
const now = Date.now();
|
|
@@ -1598,9 +1681,21 @@ var StormcloudVideoPlayer = class {
|
|
|
1598
1681
|
if (this.config.debugAdTiming) {
|
|
1599
1682
|
console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
|
|
1600
1683
|
}
|
|
1684
|
+
if (this.ima.isAdPlaying()) {
|
|
1685
|
+
if (this.config.debugAdTiming) {
|
|
1686
|
+
console.warn(
|
|
1687
|
+
"[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
this.ima.updateOriginalMutedState(this.video.muted);
|
|
1601
1693
|
this.startAdFailsafeTimer();
|
|
1602
1694
|
try {
|
|
1603
1695
|
await this.ima.requestAds(vastTagUrl);
|
|
1696
|
+
if (this.config.debugAdTiming) {
|
|
1697
|
+
console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
|
|
1698
|
+
}
|
|
1604
1699
|
await this.ima.play();
|
|
1605
1700
|
if (this.config.debugAdTiming) {
|
|
1606
1701
|
console.log("[StormcloudVideoPlayer] Ad playback started successfully");
|
|
@@ -1628,6 +1723,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1628
1723
|
this.showAds = false;
|
|
1629
1724
|
this.currentAdIndex = 0;
|
|
1630
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
|
+
}
|
|
1631
1733
|
if (this.video.paused) {
|
|
1632
1734
|
this.video.play()?.catch(() => {
|
|
1633
1735
|
if (this.config.debugAdTiming) {
|
|
@@ -2571,39 +2673,144 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2571
2673
|
left: "50%",
|
|
2572
2674
|
transform: "translateX(-50%)",
|
|
2573
2675
|
marginBottom: "4px",
|
|
2574
|
-
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%)",
|
|
2575
2677
|
backdropFilter: "blur(15px)",
|
|
2576
|
-
padding: "
|
|
2577
|
-
borderRadius: "
|
|
2578
|
-
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)",
|
|
2579
2681
|
display: "flex",
|
|
2580
2682
|
flexDirection: "column",
|
|
2581
2683
|
alignItems: "center",
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
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"
|
|
2585
2689
|
},
|
|
2586
|
-
onMouseEnter: () =>
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
"
|
|
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",
|
|
2590
2704
|
{
|
|
2591
|
-
type: "range",
|
|
2592
|
-
min: "0",
|
|
2593
|
-
max: "1",
|
|
2594
|
-
step: "0.01",
|
|
2595
|
-
value: isMuted ? 0 : volume,
|
|
2596
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2597
2705
|
style: {
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
}
|
|
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
|
+
]
|
|
2607
2814
|
}
|
|
2608
2815
|
)
|
|
2609
2816
|
}
|
|
@@ -2920,40 +3127,146 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2920
3127
|
left: "50%",
|
|
2921
3128
|
transform: "translateX(-50%)",
|
|
2922
3129
|
marginBottom: "4px",
|
|
2923
|
-
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%)",
|
|
2924
3131
|
backdropFilter: "blur(20px)",
|
|
2925
|
-
padding: "
|
|
2926
|
-
borderRadius: "
|
|
2927
|
-
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)",
|
|
2928
3135
|
display: "flex",
|
|
2929
3136
|
flexDirection: "column",
|
|
2930
3137
|
alignItems: "center",
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
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"
|
|
2934
3143
|
},
|
|
2935
|
-
onMouseEnter: () =>
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
"
|
|
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",
|
|
2939
3158
|
{
|
|
2940
|
-
type: "range",
|
|
2941
|
-
min: "0",
|
|
2942
|
-
max: "1",
|
|
2943
|
-
step: "0.01",
|
|
2944
|
-
value: isMuted ? 0 : volume,
|
|
2945
|
-
onChange: (e) => handleVolumeChange(parseFloat(e.target.value)),
|
|
2946
3159
|
style: {
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
height: "90px",
|
|
2951
|
-
background: "linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%)",
|
|
2952
|
-
borderRadius: "3px",
|
|
2953
|
-
outline: "none",
|
|
3160
|
+
position: "relative",
|
|
3161
|
+
width: "8px",
|
|
3162
|
+
height: "104px",
|
|
2954
3163
|
cursor: "pointer",
|
|
2955
|
-
|
|
2956
|
-
}
|
|
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
|
+
]
|
|
2957
3270
|
}
|
|
2958
3271
|
)
|
|
2959
3272
|
}
|