stormcloud-video-player 0.1.7 → 0.1.9

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/lib/index.cjs CHANGED
@@ -121,6 +121,9 @@ function createImaController(video) {
121
121
  container.style.top = "0";
122
122
  container.style.right = "0";
123
123
  container.style.bottom = "0";
124
+ container.style.display = "flex";
125
+ container.style.alignItems = "center";
126
+ container.style.justifyContent = "center";
124
127
  container.style.pointerEvents = "none";
125
128
  container.style.zIndex = "2";
126
129
  video.parentElement?.appendChild(container);
@@ -163,6 +166,9 @@ function createImaController(video) {
163
166
  container.style.top = "0";
164
167
  container.style.right = "0";
165
168
  container.style.bottom = "0";
169
+ container.style.display = "flex";
170
+ container.style.alignItems = "center";
171
+ container.style.justifyContent = "center";
166
172
  container.style.pointerEvents = "none";
167
173
  container.style.zIndex = "2";
168
174
  if (!video.parentElement) {
@@ -369,6 +375,20 @@ function createImaController(video) {
369
375
  isAdPlaying() {
370
376
  return adPlaying;
371
377
  },
378
+ resize(width, height) {
379
+ if (!adsManager || !window.google?.ima) {
380
+ console.warn(
381
+ "[IMA] Cannot resize: No ads manager or IMA SDK available"
382
+ );
383
+ return;
384
+ }
385
+ try {
386
+ console.log(`[IMA] Resizing ads manager to ${width}x${height}`);
387
+ adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);
388
+ } catch (error) {
389
+ console.warn("[IMA] Error resizing ads manager:", error);
390
+ }
391
+ },
372
392
  on(event, listener) {
373
393
  if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
374
394
  listeners.get(event).add(listener);
@@ -539,7 +559,9 @@ async function sendInitialTracking(licenseKey) {
539
559
  browserId,
540
560
  ...clientInfo
541
561
  };
542
- const headers = { "Content-Type": "application/json" };
562
+ const headers = {
563
+ "Content-Type": "application/json"
564
+ };
543
565
  if (licenseKey) {
544
566
  headers["Authorization"] = `Bearer ${licenseKey}`;
545
567
  }
@@ -554,11 +576,7 @@ async function sendInitialTracking(licenseKey) {
554
576
  if (!response.ok) {
555
577
  throw new Error(`HTTP error! status: ${response.status}`);
556
578
  }
557
- const data = await response.json();
558
- console.log(
559
- "[StormcloudVideoPlayer] Initial tracking data sent successfully:",
560
- data
561
- );
579
+ await response.json();
562
580
  } catch (error) {
563
581
  console.error(
564
582
  "[StormcloudVideoPlayer] Error sending initial tracking data:",
@@ -574,7 +592,9 @@ async function sendHeartbeat(licenseKey) {
574
592
  browserId,
575
593
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
576
594
  };
577
- const headers = { "Content-Type": "application/json" };
595
+ const headers = {
596
+ "Content-Type": "application/json"
597
+ };
578
598
  if (licenseKey) {
579
599
  headers["Authorization"] = `Bearer ${licenseKey}`;
580
600
  }
@@ -589,8 +609,7 @@ async function sendHeartbeat(licenseKey) {
589
609
  if (!response.ok) {
590
610
  throw new Error(`HTTP error! status: ${response.status}`);
591
611
  }
592
- const data = await response.json();
593
- console.log("[StormcloudVideoPlayer] Heartbeat sent successfully:", data);
612
+ await response.json();
594
613
  } catch (error) {
595
614
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
596
615
  }
@@ -609,7 +628,6 @@ var StormcloudVideoPlayer = class {
609
628
  this.showAds = false;
610
629
  this.config = config;
611
630
  this.video = config.videoElement;
612
- this.adSchedule = config.adSchedule;
613
631
  this.ima = createImaController(this.video);
614
632
  }
615
633
  async load() {
@@ -915,70 +933,61 @@ var StormcloudVideoPlayer = class {
915
933
  const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
916
934
  this.expectedAdBreakDurationMs = durationMs;
917
935
  this.currentAdBreakStartWallClockMs = Date.now();
918
- const policy = this.adSchedule?.lateJoinPolicy ?? "play_remaining";
919
- if (policy !== "skip_to_content") {
920
- const isManifestMarker = this.isManifestBasedMarker(marker);
921
- const forceImmediate = this.config.immediateManifestAds ?? true;
936
+ const isManifestMarker = this.isManifestBasedMarker(marker);
937
+ const forceImmediate = this.config.immediateManifestAds ?? true;
938
+ if (this.config.debugAdTiming) {
939
+ console.log("[StormcloudVideoPlayer] Ad start decision:", {
940
+ isManifestMarker,
941
+ forceImmediate,
942
+ hasPts: typeof marker.ptsSeconds === "number"
943
+ });
944
+ }
945
+ if (isManifestMarker && forceImmediate) {
922
946
  if (this.config.debugAdTiming) {
923
- console.log("[StormcloudVideoPlayer] Ad start decision:", {
924
- isManifestMarker,
925
- forceImmediate,
926
- hasPts: typeof marker.ptsSeconds === "number",
927
- policy
947
+ console.log(
948
+ "[StormcloudVideoPlayer] Starting ad immediately (manifest-based)"
949
+ );
950
+ }
951
+ this.clearAdStartTimer();
952
+ this.handleAdStart(marker);
953
+ } else if (typeof marker.ptsSeconds === "number") {
954
+ const tol = this.config.driftToleranceMs ?? 1e3;
955
+ const nowMs = this.video.currentTime * 1e3;
956
+ const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
957
+ const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
958
+ if (this.config.debugAdTiming) {
959
+ console.log("[StormcloudVideoPlayer] PTS-based timing calculation:", {
960
+ nowMs,
961
+ estCurrentPtsMs,
962
+ markerPtsMs: marker.ptsSeconds * 1e3,
963
+ deltaMs,
964
+ tolerance: tol
928
965
  });
929
966
  }
930
- if (isManifestMarker && forceImmediate) {
931
- if (this.config.debugAdTiming) {
932
- console.log(
933
- "[StormcloudVideoPlayer] Starting ad immediately (manifest-based)"
934
- );
935
- }
936
- this.clearAdStartTimer();
937
- this.handleAdStart(marker);
938
- } else if (typeof marker.ptsSeconds === "number") {
939
- const tol = this.config.driftToleranceMs ?? 1e3;
940
- const nowMs = this.video.currentTime * 1e3;
941
- const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
942
- const deltaMs = Math.floor(
943
- marker.ptsSeconds * 1e3 - estCurrentPtsMs
944
- );
967
+ if (deltaMs > tol) {
945
968
  if (this.config.debugAdTiming) {
946
969
  console.log(
947
- "[StormcloudVideoPlayer] PTS-based timing calculation:",
948
- {
949
- nowMs,
950
- estCurrentPtsMs,
951
- markerPtsMs: marker.ptsSeconds * 1e3,
952
- deltaMs,
953
- tolerance: tol
954
- }
970
+ `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`
955
971
  );
956
972
  }
957
- if (deltaMs > tol) {
958
- if (this.config.debugAdTiming) {
959
- console.log(
960
- `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`
961
- );
962
- }
963
- this.scheduleAdStartIn(deltaMs);
964
- } else {
965
- if (this.config.debugAdTiming) {
966
- console.log(
967
- "[StormcloudVideoPlayer] Starting ad immediately (within tolerance)"
968
- );
969
- }
970
- this.clearAdStartTimer();
971
- this.handleAdStart(marker);
972
- }
973
+ this.scheduleAdStartIn(deltaMs);
973
974
  } else {
974
975
  if (this.config.debugAdTiming) {
975
976
  console.log(
976
- "[StormcloudVideoPlayer] Starting ad immediately (fallback)"
977
+ "[StormcloudVideoPlayer] Starting ad immediately (within tolerance)"
977
978
  );
978
979
  }
979
980
  this.clearAdStartTimer();
980
981
  this.handleAdStart(marker);
981
982
  }
983
+ } else {
984
+ if (this.config.debugAdTiming) {
985
+ console.log(
986
+ "[StormcloudVideoPlayer] Starting ad immediately (fallback)"
987
+ );
988
+ }
989
+ this.clearAdStartTimer();
990
+ this.handleAdStart(marker);
982
991
  }
983
992
  if (this.expectedAdBreakDurationMs != null) {
984
993
  this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
@@ -998,12 +1007,11 @@ var StormcloudVideoPlayer = class {
998
1007
  this.scheduleAdStopCountdown(remainingMs);
999
1008
  }
1000
1009
  if (!this.ima.isAdPlaying()) {
1001
- const policy = this.adSchedule?.lateJoinPolicy ?? "play_remaining";
1002
1010
  const scheduled = this.findCurrentOrNextBreak(
1003
1011
  this.video.currentTime * 1e3
1004
1012
  );
1005
1013
  const tags = this.selectVastTagsForBreak(scheduled) || (this.apiVastTagUrl ? [this.apiVastTagUrl] : void 0);
1006
- if (policy === "play_remaining" && tags && tags.length > 0) {
1014
+ if (tags && tags.length > 0) {
1007
1015
  const first = tags[0];
1008
1016
  const rest = tags.slice(1);
1009
1017
  this.adPodQueue = rest;
@@ -1202,11 +1210,11 @@ var StormcloudVideoPlayer = class {
1202
1210
  });
1203
1211
  this.heartbeatInterval = window.setInterval(() => {
1204
1212
  this.sendHeartbeatIfNeeded();
1205
- }, 1e3);
1213
+ }, 5e3);
1206
1214
  }
1207
1215
  sendHeartbeatIfNeeded() {
1208
1216
  const now = Date.now();
1209
- if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 1e4) {
1217
+ if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
1210
1218
  this.lastHeartbeatTime = now;
1211
1219
  sendHeartbeat(this.config.licenseKey).catch((error) => {
1212
1220
  if (this.config.debugAdTiming) {
@@ -1253,9 +1261,6 @@ var StormcloudVideoPlayer = class {
1253
1261
  });
1254
1262
  }
1255
1263
  }
1256
- setAdSchedule(schedule) {
1257
- this.adSchedule = schedule;
1258
- }
1259
1264
  getCurrentAdIndex() {
1260
1265
  return this.currentAdIndex;
1261
1266
  }
@@ -1278,17 +1283,11 @@ var StormcloudVideoPlayer = class {
1278
1283
  shouldShowNativeControls() {
1279
1284
  return this.getStreamType() !== "hls";
1280
1285
  }
1281
- async loadAdScheduleFromUrl(url) {
1282
- const res = await fetch(url);
1283
- if (!res.ok) throw new Error(`Failed to fetch ad schedule: ${res.status}`);
1284
- const data = await res.json();
1285
- this.adSchedule = data;
1286
- }
1287
- async loadDefaultVastFromAiry(airyApiUrl, params) {
1286
+ async loadDefaultVastFromAdstorm(adstormApiUrl, params) {
1288
1287
  const usp = new URLSearchParams(params || {});
1289
- const url = `${airyApiUrl}?${usp.toString()}`;
1288
+ const url = `${adstormApiUrl}?${usp.toString()}`;
1290
1289
  const res = await fetch(url);
1291
- if (!res.ok) throw new Error(`Failed to fetch Airy ads: ${res.status}`);
1290
+ if (!res.ok) throw new Error(`Failed to fetch adstorm ads: ${res.status}`);
1292
1291
  const data = await res.json();
1293
1292
  const tag = data?.adTagUrl || data?.vastTagUrl || data?.tagUrl;
1294
1293
  if (typeof tag === "string" && tag.length > 0) {
@@ -1351,7 +1350,7 @@ var StormcloudVideoPlayer = class {
1351
1350
  }
1352
1351
  }
1353
1352
  findCurrentOrNextBreak(nowMs) {
1354
- const schedule = this.adSchedule?.breaks || [];
1353
+ const schedule = [];
1355
1354
  let candidate;
1356
1355
  for (const b of schedule) {
1357
1356
  const tol = this.config.driftToleranceMs ?? 1e3;
@@ -1362,7 +1361,7 @@ var StormcloudVideoPlayer = class {
1362
1361
  return candidate;
1363
1362
  }
1364
1363
  onTimeUpdate(currentTimeSec) {
1365
- if (!this.adSchedule || this.ima.isAdPlaying()) return;
1364
+ if (this.ima.isAdPlaying()) return;
1366
1365
  const nowMs = currentTimeSec * 1e3;
1367
1366
  const breakToPlay = this.findBreakForTime(nowMs);
1368
1367
  if (breakToPlay) {
@@ -1374,10 +1373,8 @@ var StormcloudVideoPlayer = class {
1374
1373
  const endMs = adBreak.startTimeMs + durationMs;
1375
1374
  if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
1376
1375
  const remainingMs = endMs - nowMs;
1377
- const policy = this.adSchedule?.lateJoinPolicy ?? "play_remaining";
1378
- if (policy === "skip_to_content") return;
1379
1376
  const tags = this.selectVastTagsForBreak(adBreak) || (this.apiVastTagUrl ? [this.apiVastTagUrl] : void 0);
1380
- if (policy === "play_remaining" && tags && tags.length > 0) {
1377
+ if (tags && tags.length > 0) {
1381
1378
  const first = tags[0];
1382
1379
  const rest = tags.slice(1);
1383
1380
  this.adPodQueue = rest;
@@ -1525,7 +1522,7 @@ var StormcloudVideoPlayer = class {
1525
1522
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
1526
1523
  }
1527
1524
  findBreakForTime(nowMs) {
1528
- const schedule = this.adSchedule?.breaks || [];
1525
+ const schedule = [];
1529
1526
  for (const b of schedule) {
1530
1527
  const end = (b.startTimeMs || 0) + (b.durationMs || 0);
1531
1528
  if (nowMs >= (b.startTimeMs || 0) && (b.durationMs ? nowMs < end : true)) {
@@ -1534,6 +1531,73 @@ var StormcloudVideoPlayer = class {
1534
1531
  }
1535
1532
  return void 0;
1536
1533
  }
1534
+ toggleMute() {
1535
+ this.video.muted = !this.video.muted;
1536
+ if (this.config.debugAdTiming) {
1537
+ console.log("[StormcloudVideoPlayer] Muted:", this.video.muted);
1538
+ }
1539
+ }
1540
+ toggleFullscreen() {
1541
+ return new Promise((resolve, reject) => {
1542
+ if (!document.fullscreenElement) {
1543
+ const container = this.video.parentElement;
1544
+ if (!container) {
1545
+ reject(new Error("No parent container found for fullscreen"));
1546
+ return;
1547
+ }
1548
+ container.requestFullscreen().then(() => {
1549
+ if (this.config.debugAdTiming) {
1550
+ console.log("[StormcloudVideoPlayer] Entered fullscreen");
1551
+ }
1552
+ resolve();
1553
+ }).catch((err) => {
1554
+ if (this.config.debugAdTiming) {
1555
+ console.error("[StormcloudVideoPlayer] Fullscreen error:", err);
1556
+ }
1557
+ reject(err);
1558
+ });
1559
+ } else {
1560
+ document.exitFullscreen().then(() => {
1561
+ if (this.config.debugAdTiming) {
1562
+ console.log("[StormcloudVideoPlayer] Exited fullscreen");
1563
+ }
1564
+ resolve();
1565
+ }).catch((err) => {
1566
+ if (this.config.debugAdTiming) {
1567
+ console.error(
1568
+ "[StormcloudVideoPlayer] Exit fullscreen error:",
1569
+ err
1570
+ );
1571
+ }
1572
+ reject(err);
1573
+ });
1574
+ }
1575
+ });
1576
+ }
1577
+ isMuted() {
1578
+ return this.video.muted;
1579
+ }
1580
+ isFullscreen() {
1581
+ return !!document.fullscreenElement;
1582
+ }
1583
+ get videoElement() {
1584
+ return this.video;
1585
+ }
1586
+ resize() {
1587
+ if (this.config.debugAdTiming) {
1588
+ console.log("[StormcloudVideoPlayer] Resizing player");
1589
+ }
1590
+ if (this.ima && this.ima.isAdPlaying()) {
1591
+ const width = this.video.clientWidth || 640;
1592
+ const height = this.video.clientHeight || 360;
1593
+ if (this.config.debugAdTiming) {
1594
+ console.log(
1595
+ `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`
1596
+ );
1597
+ }
1598
+ this.ima.resize(width, height);
1599
+ }
1600
+ }
1537
1601
  destroy() {
1538
1602
  this.clearAdStartTimer();
1539
1603
  this.clearAdStopTimer();
@@ -1550,238 +1614,586 @@ var StormcloudVideoPlayer = class {
1550
1614
  // src/ui/StormcloudVideoPlayer.tsx
1551
1615
  var import_react = __toESM(require("react"), 1);
1552
1616
  var import_jsx_runtime = require("react/jsx-runtime");
1553
- var StormcloudVideoPlayerComponent = (props) => {
1554
- const {
1555
- src,
1556
- autoplay,
1557
- muted,
1558
- lowLatencyMode,
1559
- allowNativeHls,
1560
- driftToleranceMs,
1561
- adSchedule,
1562
- immediateManifestAds,
1563
- debugAdTiming,
1564
- showCustomControls,
1565
- onVolumeToggle,
1566
- onFullscreenToggle,
1567
- onControlClick,
1568
- onReady,
1569
- wrapperClassName,
1570
- wrapperStyle,
1571
- className,
1572
- style,
1573
- controls,
1574
- playsInline,
1575
- preload,
1576
- poster,
1577
- children,
1578
- licenseKey,
1579
- ...restVideoAttrs
1580
- } = props;
1581
- const videoRef = (0, import_react.useRef)(null);
1582
- const playerRef = (0, import_react.useRef)(null);
1583
- const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });
1584
- const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);
1585
- (0, import_react.useEffect)(() => {
1586
- if (typeof window === "undefined") return;
1587
- const el = videoRef.current;
1588
- if (!el || !src) return;
1589
- if (playerRef.current) {
1590
- try {
1591
- playerRef.current.destroy();
1592
- } catch {
1593
- }
1594
- playerRef.current = null;
1595
- }
1596
- const cfg = {
1617
+ var CRITICAL_PROPS = [
1618
+ "src",
1619
+ "allowNativeHls",
1620
+ "licenseKey",
1621
+ "lowLatencyMode",
1622
+ "driftToleranceMs"
1623
+ ];
1624
+ var StormcloudVideoPlayerComponent = import_react.default.memo(
1625
+ (props) => {
1626
+ const {
1597
1627
  src,
1598
- videoElement: el
1599
- };
1600
- if (autoplay !== void 0) cfg.autoplay = autoplay;
1601
- if (muted !== void 0) cfg.muted = muted;
1602
- if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;
1603
- if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;
1604
- if (driftToleranceMs !== void 0) cfg.driftToleranceMs = driftToleranceMs;
1605
- if (adSchedule !== void 0) cfg.adSchedule = adSchedule;
1606
- if (immediateManifestAds !== void 0)
1607
- cfg.immediateManifestAds = immediateManifestAds;
1608
- if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;
1609
- if (showCustomControls !== void 0)
1610
- cfg.showCustomControls = showCustomControls;
1611
- if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;
1612
- if (onFullscreenToggle !== void 0)
1613
- cfg.onFullscreenToggle = onFullscreenToggle;
1614
- if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
1615
- if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
1616
- const player = new StormcloudVideoPlayer(cfg);
1617
- playerRef.current = player;
1618
- player.load().then(() => {
1619
- const showNative = player.shouldShowNativeControls();
1620
- setShouldShowNativeControls(showNative);
1621
- onReady?.(player);
1622
- }).catch(() => {
1623
- });
1624
- return () => {
1625
- try {
1626
- player.destroy();
1627
- } catch {
1628
+ autoplay,
1629
+ muted,
1630
+ lowLatencyMode,
1631
+ allowNativeHls,
1632
+ driftToleranceMs,
1633
+ immediateManifestAds,
1634
+ debugAdTiming,
1635
+ showCustomControls,
1636
+ onVolumeToggle,
1637
+ onFullscreenToggle,
1638
+ onControlClick,
1639
+ onReady,
1640
+ wrapperClassName,
1641
+ wrapperStyle,
1642
+ className,
1643
+ style,
1644
+ controls,
1645
+ playsInline,
1646
+ preload,
1647
+ poster,
1648
+ children,
1649
+ licenseKey,
1650
+ ...restVideoAttrs
1651
+ } = props;
1652
+ const videoRef = (0, import_react.useRef)(null);
1653
+ const playerRef = (0, import_react.useRef)(null);
1654
+ const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });
1655
+ const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);
1656
+ const [isMuted, setIsMuted] = import_react.default.useState(false);
1657
+ const [isFullscreen, setIsFullscreen] = import_react.default.useState(false);
1658
+ const criticalPropsKey = (0, import_react.useMemo)(() => {
1659
+ return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join("|");
1660
+ }, [src, allowNativeHls, licenseKey, lowLatencyMode, driftToleranceMs]);
1661
+ (0, import_react.useEffect)(() => {
1662
+ if (typeof window === "undefined") return;
1663
+ const el = videoRef.current;
1664
+ if (!el || !src) return;
1665
+ if (playerRef.current) {
1666
+ try {
1667
+ playerRef.current.destroy();
1668
+ } catch {
1669
+ }
1670
+ playerRef.current = null;
1628
1671
  }
1629
- playerRef.current = null;
1630
- };
1631
- }, [
1632
- src,
1633
- autoplay,
1634
- muted,
1635
- lowLatencyMode,
1636
- allowNativeHls,
1637
- driftToleranceMs,
1638
- immediateManifestAds,
1639
- debugAdTiming,
1640
- showCustomControls,
1641
- onVolumeToggle,
1642
- onFullscreenToggle,
1643
- onControlClick,
1644
- onReady,
1645
- licenseKey
1646
- ]);
1647
- (0, import_react.useEffect)(() => {
1648
- if (!playerRef.current) return;
1649
- if (adSchedule) {
1672
+ const cfg = {
1673
+ src,
1674
+ videoElement: el
1675
+ };
1676
+ if (autoplay !== void 0) cfg.autoplay = autoplay;
1677
+ if (muted !== void 0) cfg.muted = muted;
1678
+ if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;
1679
+ if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;
1680
+ if (driftToleranceMs !== void 0)
1681
+ cfg.driftToleranceMs = driftToleranceMs;
1682
+ if (immediateManifestAds !== void 0)
1683
+ cfg.immediateManifestAds = immediateManifestAds;
1684
+ if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;
1685
+ if (showCustomControls !== void 0)
1686
+ cfg.showCustomControls = showCustomControls;
1687
+ if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;
1688
+ if (onFullscreenToggle !== void 0)
1689
+ cfg.onFullscreenToggle = onFullscreenToggle;
1690
+ if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
1691
+ if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
1692
+ const player = new StormcloudVideoPlayer(cfg);
1693
+ playerRef.current = player;
1694
+ player.load().then(() => {
1695
+ const showNative = player.shouldShowNativeControls();
1696
+ setShouldShowNativeControls(showNative);
1697
+ onReady?.(player);
1698
+ }).catch(() => {
1699
+ });
1700
+ return () => {
1701
+ try {
1702
+ player.destroy();
1703
+ } catch {
1704
+ }
1705
+ playerRef.current = null;
1706
+ };
1707
+ }, [criticalPropsKey]);
1708
+ (0, import_react.useEffect)(() => {
1709
+ if (!playerRef.current) return;
1650
1710
  try {
1651
- playerRef.current.setAdSchedule(adSchedule);
1652
- } catch {
1653
- }
1654
- }
1655
- }, [adSchedule]);
1656
- (0, import_react.useEffect)(() => {
1657
- if (!playerRef.current) return;
1658
- const checkAdStatus = () => {
1659
- if (playerRef.current) {
1660
- const showAds = playerRef.current.isShowingAds();
1661
- const currentIndex = playerRef.current.getCurrentAdIndex();
1662
- const totalAds = playerRef.current.getTotalAdsInBreak();
1663
- setAdStatus((prev) => {
1664
- if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {
1665
- return { showAds, currentIndex, totalAds };
1666
- }
1667
- return prev;
1668
- });
1711
+ if (autoplay !== void 0 && playerRef.current.videoElement) {
1712
+ playerRef.current.videoElement.autoplay = autoplay;
1713
+ }
1714
+ if (muted !== void 0 && playerRef.current.videoElement) {
1715
+ playerRef.current.videoElement.muted = muted;
1716
+ }
1717
+ } catch (error) {
1718
+ console.warn("Failed to update player properties:", error);
1669
1719
  }
1670
- };
1671
- const interval = setInterval(checkAdStatus, 500);
1672
- return () => clearInterval(interval);
1673
- }, []);
1674
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1675
- "div",
1676
- {
1677
- className: wrapperClassName,
1678
- style: { position: "relative", overflow: "hidden", ...wrapperStyle },
1679
- children: [
1680
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1681
- "video",
1682
- {
1683
- ref: videoRef,
1684
- className,
1685
- style: { display: "block", width: "100%", height: "100%", ...style },
1686
- controls: shouldShowNativeControls && controls,
1687
- playsInline,
1688
- preload,
1689
- poster,
1690
- ...restVideoAttrs,
1691
- children
1692
- }
1693
- ),
1694
- adStatus.showAds && adStatus.totalAds > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1695
- "div",
1696
- {
1697
- style: {
1698
- position: "absolute",
1699
- top: "10px",
1700
- right: "10px",
1701
- backgroundColor: "rgba(0, 0, 0, 0.7)",
1702
- color: "white",
1703
- padding: "4px 8px",
1704
- borderRadius: "4px",
1705
- fontSize: "12px",
1706
- fontFamily: "Arial, sans-serif",
1707
- zIndex: 10
1708
- },
1709
- children: [
1710
- "Ad ",
1711
- adStatus.currentIndex,
1712
- "/",
1713
- adStatus.totalAds
1714
- ]
1715
- }
1716
- ),
1717
- !shouldShowNativeControls && showCustomControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1718
- "div",
1719
- {
1720
- style: {
1721
- position: "absolute",
1722
- bottom: "10px",
1723
- right: "10px",
1724
- display: "flex",
1725
- gap: "8px",
1726
- zIndex: 10
1727
- },
1728
- children: [
1729
- onVolumeToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1730
- "button",
1731
- {
1732
- onClick: onVolumeToggle,
1733
- style: {
1734
- backgroundColor: "rgba(0, 0, 0, 0.7)",
1735
- color: "white",
1736
- border: "1px solid rgba(255, 255, 255, 0.3)",
1737
- borderRadius: "4px",
1738
- padding: "8px",
1739
- cursor: "pointer",
1740
- fontSize: "14px"
1741
- },
1742
- title: "Toggle Volume",
1743
- children: "\u{1F50A}"
1744
- }
1745
- ),
1746
- onFullscreenToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1747
- "button",
1748
- {
1749
- onClick: onFullscreenToggle,
1750
- style: {
1751
- backgroundColor: "rgba(0, 0, 0, 0.7)",
1752
- color: "white",
1753
- border: "1px solid rgba(255, 255, 255, 0.3)",
1754
- borderRadius: "4px",
1755
- padding: "8px",
1756
- cursor: "pointer",
1757
- fontSize: "14px"
1758
- },
1759
- title: "Toggle Fullscreen",
1760
- children: "\u2922"
1761
- }
1762
- )
1763
- ]
1764
- }
1765
- ),
1766
- onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1767
- "div",
1768
- {
1769
- onClick: onControlClick,
1770
- style: {
1771
- position: "absolute",
1772
- top: 0,
1773
- left: 0,
1774
- right: 0,
1775
- bottom: 0,
1776
- zIndex: 1,
1777
- cursor: "pointer"
1720
+ }, [autoplay, muted]);
1721
+ (0, import_react.useEffect)(() => {
1722
+ if (!playerRef.current) return;
1723
+ const checkAdStatus = () => {
1724
+ if (playerRef.current) {
1725
+ const showAds = playerRef.current.isShowingAds();
1726
+ const currentIndex = playerRef.current.getCurrentAdIndex();
1727
+ const totalAds = playerRef.current.getTotalAdsInBreak();
1728
+ setAdStatus((prev) => {
1729
+ if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {
1730
+ return { showAds, currentIndex, totalAds };
1778
1731
  }
1732
+ return prev;
1733
+ });
1734
+ }
1735
+ };
1736
+ const interval = setInterval(checkAdStatus, 500);
1737
+ return () => clearInterval(interval);
1738
+ }, []);
1739
+ (0, import_react.useEffect)(() => {
1740
+ if (typeof window === "undefined" || !playerRef.current) return;
1741
+ const handleResize = () => {
1742
+ if (playerRef.current && videoRef.current) {
1743
+ if (typeof playerRef.current.resize === "function") {
1744
+ playerRef.current.resize();
1779
1745
  }
1780
- )
1781
- ]
1746
+ }
1747
+ };
1748
+ window.addEventListener("resize", handleResize);
1749
+ return () => window.removeEventListener("resize", handleResize);
1750
+ }, []);
1751
+ (0, import_react.useEffect)(() => {
1752
+ if (!playerRef.current || !videoRef.current) return;
1753
+ const updateStates = () => {
1754
+ if (videoRef.current) {
1755
+ setIsMuted(videoRef.current.muted);
1756
+ }
1757
+ setIsFullscreen(
1758
+ document.fullscreenElement === videoRef.current?.parentElement
1759
+ );
1760
+ };
1761
+ const interval = setInterval(updateStates, 200);
1762
+ const handleFullscreenChange = () => {
1763
+ setIsFullscreen(
1764
+ document.fullscreenElement === videoRef.current?.parentElement
1765
+ );
1766
+ };
1767
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
1768
+ return () => {
1769
+ clearInterval(interval);
1770
+ document.removeEventListener(
1771
+ "fullscreenchange",
1772
+ handleFullscreenChange
1773
+ );
1774
+ };
1775
+ }, []);
1776
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1777
+ "div",
1778
+ {
1779
+ className: wrapperClassName,
1780
+ style: {
1781
+ display: "flex",
1782
+ alignItems: "center",
1783
+ justifyContent: "center",
1784
+ position: isFullscreen ? "fixed" : "relative",
1785
+ top: isFullscreen ? 0 : void 0,
1786
+ left: isFullscreen ? 0 : void 0,
1787
+ overflow: "hidden",
1788
+ width: isFullscreen ? "100vw" : "100%",
1789
+ height: isFullscreen ? "100vh" : "100%",
1790
+ maxWidth: isFullscreen ? "100vw" : "100%",
1791
+ maxHeight: isFullscreen ? "100vh" : "100%",
1792
+ zIndex: isFullscreen ? 9999 : void 0,
1793
+ backgroundColor: isFullscreen ? "#000" : void 0,
1794
+ ...wrapperStyle
1795
+ },
1796
+ children: [
1797
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1798
+ "video",
1799
+ {
1800
+ ref: videoRef,
1801
+ className,
1802
+ style: {
1803
+ display: "block",
1804
+ width: "100%",
1805
+ height: "100%",
1806
+ objectFit: isFullscreen ? "cover" : "contain",
1807
+ backgroundColor: "#000",
1808
+ ...style
1809
+ },
1810
+ controls: shouldShowNativeControls && controls && !showCustomControls,
1811
+ playsInline,
1812
+ preload,
1813
+ poster,
1814
+ ...restVideoAttrs,
1815
+ children
1816
+ }
1817
+ ),
1818
+ adStatus.showAds && adStatus.totalAds > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1819
+ "div",
1820
+ {
1821
+ style: {
1822
+ position: "absolute",
1823
+ top: "10px",
1824
+ right: "10px",
1825
+ backgroundColor: "rgba(0, 0, 0, 0.7)",
1826
+ color: "white",
1827
+ padding: "4px 8px",
1828
+ borderRadius: "4px",
1829
+ fontSize: "12px",
1830
+ fontFamily: "Arial, sans-serif",
1831
+ zIndex: 10
1832
+ },
1833
+ children: [
1834
+ "Ad ",
1835
+ adStatus.currentIndex,
1836
+ "/",
1837
+ adStatus.totalAds
1838
+ ]
1839
+ }
1840
+ ),
1841
+ showCustomControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1842
+ "div",
1843
+ {
1844
+ style: {
1845
+ position: "absolute",
1846
+ bottom: "10px",
1847
+ right: "10px",
1848
+ display: "flex",
1849
+ gap: "8px",
1850
+ zIndex: 10
1851
+ },
1852
+ children: [
1853
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1854
+ "button",
1855
+ {
1856
+ onClick: () => {
1857
+ if (onVolumeToggle) {
1858
+ onVolumeToggle();
1859
+ } else if (playerRef.current) {
1860
+ playerRef.current.toggleMute();
1861
+ }
1862
+ },
1863
+ onMouseEnter: (e) => {
1864
+ const target = e.currentTarget;
1865
+ target.style.transform = "translateY(-2px) scale(1.05)";
1866
+ target.style.boxShadow = "0 6px 20px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2)";
1867
+ target.style.background = "linear-gradient(135deg, rgba(20, 20, 20, 0.9) 0%, rgba(60, 60, 60, 0.95) 100%)";
1868
+ },
1869
+ onMouseLeave: (e) => {
1870
+ const target = e.currentTarget;
1871
+ target.style.transform = "translateY(0) scale(1)";
1872
+ target.style.boxShadow = "0 4px 15px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)";
1873
+ target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(40, 40, 40, 0.9) 100%)";
1874
+ },
1875
+ style: {
1876
+ background: "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(40, 40, 40, 0.9) 100%)",
1877
+ color: "white",
1878
+ border: "1px solid rgba(255, 255, 255, 0.2)",
1879
+ borderRadius: "8px",
1880
+ padding: "10px",
1881
+ cursor: "pointer",
1882
+ display: "flex",
1883
+ alignItems: "center",
1884
+ justifyContent: "center",
1885
+ backdropFilter: "blur(10px)",
1886
+ boxShadow: "0 4px 15px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
1887
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
1888
+ },
1889
+ title: isMuted ? "Unmute" : "Mute",
1890
+ children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1891
+ "svg",
1892
+ {
1893
+ width: "18",
1894
+ height: "18",
1895
+ viewBox: "0 0 24 24",
1896
+ fill: "none",
1897
+ xmlns: "http://www.w3.org/2000/svg",
1898
+ children: [
1899
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1900
+ "linearGradient",
1901
+ {
1902
+ id: "volumeGradient",
1903
+ x1: "0%",
1904
+ y1: "0%",
1905
+ x2: "100%",
1906
+ y2: "100%",
1907
+ children: [
1908
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: "#ffffff", stopOpacity: "1" }),
1909
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1910
+ "stop",
1911
+ {
1912
+ offset: "100%",
1913
+ stopColor: "#e0e0e0",
1914
+ stopOpacity: "0.9"
1915
+ }
1916
+ )
1917
+ ]
1918
+ }
1919
+ ) }),
1920
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1921
+ "path",
1922
+ {
1923
+ d: "M3 8.5v7c0 .28.22.5.5.5H7l4.29 4.29c.63.63 1.71.18 1.71-.71V4.41c0-.89-1.08-1.34-1.71-.71L7 8H3.5c-.28 0-.5.22-.5.5z",
1924
+ fill: "url(#volumeGradient)",
1925
+ stroke: "rgba(255,255,255,0.3)",
1926
+ strokeWidth: "0.5"
1927
+ }
1928
+ ),
1929
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1930
+ "path",
1931
+ {
1932
+ d: "M16.5 8.5l-1.41-1.41L12 10.18 8.91 7.09 7.5 8.5l3.09 3.09L7.5 14.68l1.41 1.41L12 13l3.09 3.09 1.41-1.41L13.41 12l3.09-3.5z",
1933
+ fill: "#ff4444",
1934
+ stroke: "rgba(255,255,255,0.5)",
1935
+ strokeWidth: "0.5"
1936
+ }
1937
+ )
1938
+ ]
1939
+ }
1940
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1941
+ "svg",
1942
+ {
1943
+ width: "18",
1944
+ height: "18",
1945
+ viewBox: "0 0 24 24",
1946
+ fill: "none",
1947
+ xmlns: "http://www.w3.org/2000/svg",
1948
+ children: [
1949
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1950
+ "linearGradient",
1951
+ {
1952
+ id: "volumeGradient",
1953
+ x1: "0%",
1954
+ y1: "0%",
1955
+ x2: "100%",
1956
+ y2: "100%",
1957
+ children: [
1958
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: "#ffffff", stopOpacity: "1" }),
1959
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1960
+ "stop",
1961
+ {
1962
+ offset: "100%",
1963
+ stopColor: "#e0e0e0",
1964
+ stopOpacity: "0.9"
1965
+ }
1966
+ )
1967
+ ]
1968
+ }
1969
+ ) }),
1970
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1971
+ "path",
1972
+ {
1973
+ d: "M3 8.5v7c0 .28.22.5.5.5H7l4.29 4.29c.63.63 1.71.18 1.71-.71V4.41c0-.89-1.08-1.34-1.71-.71L7 8H3.5c-.28 0-.5.22-.5.5z",
1974
+ fill: "url(#volumeGradient)",
1975
+ stroke: "rgba(255,255,255,0.3)",
1976
+ strokeWidth: "0.5"
1977
+ }
1978
+ ),
1979
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1980
+ "path",
1981
+ {
1982
+ d: "M15.5 12c0-1.33-.58-2.53-1.5-3.35v6.69c.92-.81 1.5-2.01 1.5-3.34z",
1983
+ fill: "url(#volumeGradient)",
1984
+ opacity: "0.8"
1985
+ }
1986
+ ),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1988
+ "path",
1989
+ {
1990
+ d: "M14 4.45v1.75c2.01.91 3.5 3.02 3.5 5.3 0 2.28-1.49 4.39-3.5 5.3v1.75c2.89-.86 5-3.54 5-7.05s-2.11-6.19-5-7.05z",
1991
+ fill: "url(#volumeGradient)",
1992
+ opacity: "0.6"
1993
+ }
1994
+ )
1995
+ ]
1996
+ }
1997
+ )
1998
+ }
1999
+ ),
2000
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2001
+ "button",
2002
+ {
2003
+ onClick: () => {
2004
+ if (onFullscreenToggle) {
2005
+ onFullscreenToggle();
2006
+ } else if (playerRef.current) {
2007
+ playerRef.current.toggleFullscreen().catch((err) => {
2008
+ console.error("Fullscreen error:", err);
2009
+ });
2010
+ }
2011
+ },
2012
+ onMouseEnter: (e) => {
2013
+ const target = e.currentTarget;
2014
+ target.style.transform = "translateY(-2px) scale(1.05)";
2015
+ target.style.boxShadow = "0 6px 20px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2)";
2016
+ target.style.background = "linear-gradient(135deg, rgba(20, 20, 20, 0.9) 0%, rgba(60, 60, 60, 0.95) 100%)";
2017
+ },
2018
+ onMouseLeave: (e) => {
2019
+ const target = e.currentTarget;
2020
+ target.style.transform = "translateY(0) scale(1)";
2021
+ target.style.boxShadow = "0 4px 15px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)";
2022
+ target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(40, 40, 40, 0.9) 100%)";
2023
+ },
2024
+ style: {
2025
+ background: "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(40, 40, 40, 0.9) 100%)",
2026
+ color: "white",
2027
+ border: "1px solid rgba(255, 255, 255, 0.2)",
2028
+ borderRadius: "8px",
2029
+ padding: "10px",
2030
+ cursor: "pointer",
2031
+ display: "flex",
2032
+ alignItems: "center",
2033
+ justifyContent: "center",
2034
+ backdropFilter: "blur(10px)",
2035
+ boxShadow: "0 4px 15px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
2036
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
2037
+ },
2038
+ title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
2039
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2040
+ "svg",
2041
+ {
2042
+ width: "20",
2043
+ height: "20",
2044
+ viewBox: "0 0 24 24",
2045
+ fill: "none",
2046
+ xmlns: "http://www.w3.org/2000/svg",
2047
+ children: [
2048
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2049
+ "path",
2050
+ {
2051
+ d: "M8 8h3v3l-1-1-2 2-1.5-1.5L8.5 8.5 8 8z",
2052
+ fill: "white",
2053
+ stroke: "rgba(255,255,255,0.8)",
2054
+ strokeWidth: "0.5"
2055
+ }
2056
+ ),
2057
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2058
+ "path",
2059
+ {
2060
+ d: "M16 8h-3v3l1-1 2 2 1.5-1.5L15.5 8.5 16 8z",
2061
+ fill: "white",
2062
+ stroke: "rgba(255,255,255,0.8)",
2063
+ strokeWidth: "0.5"
2064
+ }
2065
+ ),
2066
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2067
+ "path",
2068
+ {
2069
+ d: "M8 16h3v-3l-1 1-2-2-1.5 1.5L8.5 15.5 8 16z",
2070
+ fill: "white",
2071
+ stroke: "rgba(255,255,255,0.8)",
2072
+ strokeWidth: "0.5"
2073
+ }
2074
+ ),
2075
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2076
+ "path",
2077
+ {
2078
+ d: "M16 16h-3v-3l1 1 2-2 1.5 1.5L15.5 15.5 16 16z",
2079
+ fill: "white",
2080
+ stroke: "rgba(255,255,255,0.8)",
2081
+ strokeWidth: "0.5"
2082
+ }
2083
+ )
2084
+ ]
2085
+ }
2086
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2087
+ "svg",
2088
+ {
2089
+ width: "20",
2090
+ height: "20",
2091
+ viewBox: "0 0 24 24",
2092
+ fill: "none",
2093
+ xmlns: "http://www.w3.org/2000/svg",
2094
+ children: [
2095
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2096
+ "path",
2097
+ {
2098
+ d: "M3 3h6v2H5v4H3V3z",
2099
+ fill: "white",
2100
+ stroke: "rgba(255,255,255,0.8)",
2101
+ strokeWidth: "0.5"
2102
+ }
2103
+ ),
2104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2105
+ "path",
2106
+ {
2107
+ d: "M21 3h-6v2h4v4h2V3z",
2108
+ fill: "white",
2109
+ stroke: "rgba(255,255,255,0.8)",
2110
+ strokeWidth: "0.5"
2111
+ }
2112
+ ),
2113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2114
+ "path",
2115
+ {
2116
+ d: "M3 21v-6h2v4h4v2H3z",
2117
+ fill: "white",
2118
+ stroke: "rgba(255,255,255,0.8)",
2119
+ strokeWidth: "0.5"
2120
+ }
2121
+ ),
2122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2123
+ "path",
2124
+ {
2125
+ d: "M21 21h-6v-2h4v-4h2v6z",
2126
+ fill: "white",
2127
+ stroke: "rgba(255,255,255,0.8)",
2128
+ strokeWidth: "0.5"
2129
+ }
2130
+ )
2131
+ ]
2132
+ }
2133
+ )
2134
+ }
2135
+ )
2136
+ ]
2137
+ }
2138
+ ),
2139
+ onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2140
+ "div",
2141
+ {
2142
+ onClick: onControlClick,
2143
+ style: {
2144
+ position: "absolute",
2145
+ top: 0,
2146
+ left: 0,
2147
+ right: 0,
2148
+ bottom: 0,
2149
+ zIndex: 1,
2150
+ cursor: "pointer"
2151
+ }
2152
+ }
2153
+ )
2154
+ ]
2155
+ }
2156
+ );
2157
+ },
2158
+ (prevProps, nextProps) => {
2159
+ for (const prop of CRITICAL_PROPS) {
2160
+ if (prevProps[prop] !== nextProps[prop]) {
2161
+ return false;
2162
+ }
1782
2163
  }
1783
- );
1784
- };
2164
+ const uiProps = [
2165
+ "autoplay",
2166
+ "muted",
2167
+ "controls",
2168
+ "showCustomControls",
2169
+ "className",
2170
+ "style",
2171
+ "wrapperClassName",
2172
+ "wrapperStyle",
2173
+ "playsInline",
2174
+ "preload",
2175
+ "poster",
2176
+ "children"
2177
+ ];
2178
+ for (const prop of uiProps) {
2179
+ if (prevProps[prop] !== nextProps[prop]) {
2180
+ return false;
2181
+ }
2182
+ }
2183
+ const callbackProps = [
2184
+ "onReady",
2185
+ "onVolumeToggle",
2186
+ "onFullscreenToggle",
2187
+ "onControlClick"
2188
+ ];
2189
+ for (const prop of callbackProps) {
2190
+ if (prevProps[prop] !== nextProps[prop]) {
2191
+ return false;
2192
+ }
2193
+ }
2194
+ return true;
2195
+ }
2196
+ );
1785
2197
  // Annotate the CommonJS export names for ESM import in node:
1786
2198
  0 && (module.exports = {
1787
2199
  StormcloudVideoPlayer,