stormcloud-video-player 0.7.1 → 0.7.2

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.js CHANGED
@@ -6133,7 +6133,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6133
6133
  return StormcloudVideoPlayer;
6134
6134
  }();
6135
6135
  // src/ui/StormcloudVideoPlayer.tsx
6136
- import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress, FaSpinner } from "react-icons/fa";
6136
+ import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress } from "react-icons/fa";
6137
6137
  // src/ui/OverlayRenderer.tsx
6138
6138
  import React, { useEffect, useRef, useState, useCallback } from "react";
6139
6139
  // src/utils/overlays.ts
@@ -7243,6 +7243,7 @@ var CRITICAL_PROPS = [
7243
7243
  "driftToleranceMs"
7244
7244
  ];
7245
7245
  var CONTROLS_HIDE_DELAY = 3e3;
7246
+ var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
7246
7247
  var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7247
7248
  var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, swirlProjectId = props.swirlProjectId, restVideoAttrs = _object_without_properties(props, [
7248
7249
  "src",
@@ -7303,6 +7304,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7303
7304
  var _React2_useState17 = _sliced_to_array(React2.useState(null), 2), overlayCoordSpace = _React2_useState17[0], setOverlayCoordSpace = _React2_useState17[1];
7304
7305
  var _React2_useState18 = _sliced_to_array(React2.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _React2_useState18[0], setViewportWidth = _React2_useState18[1];
7305
7306
  var _React2_useState19 = _sliced_to_array(React2.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _React2_useState19[0], setIsPortrait = _React2_useState19[1];
7307
+ var _React2_useState20 = _sliced_to_array(React2.useState(DEFAULT_PLAYER_ASPECT_RATIO), 2), playerAspectRatio = _React2_useState20[0], setPlayerAspectRatio = _React2_useState20[1];
7306
7308
  var getResponsiveScale = function getResponsiveScale() {
7307
7309
  if (viewportWidth < 480) return 0.7;
7308
7310
  if (viewportWidth < 768) return 0.8;
@@ -7598,6 +7600,13 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7598
7600
  }, []);
7599
7601
  useEffect2(function() {
7600
7602
  if (!videoRef.current) return;
7603
+ var handleLoadedMetadata = function handleLoadedMetadata() {
7604
+ var video2 = videoRef.current;
7605
+ if (!video2) return;
7606
+ if (video2.videoWidth > 0 && video2.videoHeight > 0) {
7607
+ setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);
7608
+ }
7609
+ };
7601
7610
  var handleCanPlay = function handleCanPlay() {
7602
7611
  setIsLoading(false);
7603
7612
  if (bufferingTimeoutRef.current) {
@@ -7644,6 +7653,8 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7644
7653
  setShowCenterPlay(true);
7645
7654
  };
7646
7655
  var video = videoRef.current;
7656
+ handleLoadedMetadata();
7657
+ video.addEventListener("loadedmetadata", handleLoadedMetadata);
7647
7658
  video.addEventListener("canplay", handleCanPlay);
7648
7659
  video.addEventListener("canplaythrough", handleCanPlayThrough);
7649
7660
  video.addEventListener("waiting", handleWaiting);
@@ -7658,6 +7669,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7658
7669
  clearTimeout(bufferingTimeoutRef.current);
7659
7670
  bufferingTimeoutRef.current = null;
7660
7671
  }
7672
+ video.removeEventListener("loadedmetadata", handleLoadedMetadata);
7661
7673
  video.removeEventListener("canplay", handleCanPlay);
7662
7674
  video.removeEventListener("canplaythrough", handleCanPlayThrough);
7663
7675
  video.removeEventListener("waiting", handleWaiting);
@@ -7668,6 +7680,11 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7668
7680
  }, [
7669
7681
  debugAdTiming
7670
7682
  ]);
7683
+ useEffect2(function() {
7684
+ setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);
7685
+ }, [
7686
+ src
7687
+ ]);
7671
7688
  useEffect2(function() {
7672
7689
  return function() {
7673
7690
  if (controlsTimerRef.current) {
@@ -7693,7 +7710,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7693
7710
  return /* @__PURE__ */ jsxs2(Fragment2, {
7694
7711
  children: [
7695
7712
  /* @__PURE__ */ jsx2("style", {
7696
- children: "\n @keyframes sc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes sc-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n @keyframes sc-fade-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .sc-wrapper:fullscreen,\n .sc-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .sc-ctrl-btn {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n padding: 8px;\n transition: background 0.15s ease, opacity 0.15s ease;\n opacity: 0.9;\n }\n .sc-ctrl-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .sc-ctrl-btn:active {\n opacity: 0.7;\n }\n .sc-controls-bar {\n transition: opacity 0.35s ease, transform 0.35s ease;\n }\n .sc-progress-track:hover .sc-progress-thumb {\n transform: translate(-50%, -50%) scale(1) !important;\n }\n .sc-loading-hidden .sc-loading-indicator {\n display: none !important;\n }\n "
7713
+ children: "\n @keyframes sc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes sc-loading-glow {\n 0%, 100% { opacity: 0.85; transform: scale(1); }\n 50% { opacity: 1; transform: scale(1.05); }\n }\n @keyframes sc-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n @keyframes sc-fade-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .sc-wrapper:fullscreen,\n .sc-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .sc-ctrl-btn {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n padding: 8px;\n transition: background 0.15s ease, opacity 0.15s ease;\n opacity: 0.9;\n }\n .sc-ctrl-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .sc-ctrl-btn:active {\n opacity: 0.7;\n }\n .sc-controls-bar {\n transition: opacity 0.35s ease, transform 0.35s ease;\n }\n .sc-progress-track:hover .sc-progress-thumb {\n transform: translate(-50%, -50%) scale(1) !important;\n }\n .sc-loading-hidden .sc-loading-indicator {\n display: none !important;\n }\n "
7697
7714
  }),
7698
7715
  /* @__PURE__ */ jsxs2("div", {
7699
7716
  ref: wrapperRef,
@@ -7711,6 +7728,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7711
7728
  width: isFullscreen ? "100vw" : "100%",
7712
7729
  height: isFullscreen ? "100vh" : "auto",
7713
7730
  minHeight: isFullscreen ? "100vh" : "auto",
7731
+ aspectRatio: isFullscreen ? void 0 : playerAspectRatio,
7714
7732
  maxWidth: isFullscreen ? "100vw" : "100%",
7715
7733
  maxHeight: isFullscreen ? "100vh" : "none",
7716
7734
  zIndex: isFullscreen ? 999999 : void 0,
@@ -7727,7 +7745,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7727
7745
  zIndex: 1,
7728
7746
  display: "block",
7729
7747
  width: "100%",
7730
- height: isFullscreen ? "100%" : "auto",
7748
+ height: "100%",
7731
7749
  maxWidth: "100%",
7732
7750
  maxHeight: isFullscreen ? "100%" : "none",
7733
7751
  objectFit: isFullscreen ? "cover" : "contain",
@@ -7747,18 +7765,44 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7747
7765
  videoRef: videoRef,
7748
7766
  coordinateSpace: overlayCoordSpace
7749
7767
  }),
7750
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsx2(FaSpinner, {
7768
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsxs2("div", {
7751
7769
  className: "sc-loading-indicator",
7752
- size: 40,
7753
- color: "rgba(255, 255, 255, 0.85)",
7754
7770
  style: {
7755
7771
  position: "absolute",
7756
- top: "calc(50% - 20px)",
7757
- left: "calc(50% - 20px)",
7772
+ top: "50%",
7773
+ left: "50%",
7774
+ transform: "translate(-50%, -50%)",
7758
7775
  zIndex: 20,
7759
- animation: "sc-spin 0.9s linear infinite",
7760
- filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
7761
- }
7776
+ width: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7777
+ height: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7778
+ display: "flex",
7779
+ alignItems: "center",
7780
+ justifyContent: "center",
7781
+ animation: "sc-loading-glow 1.4s ease-in-out infinite",
7782
+ filter: "drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))"
7783
+ },
7784
+ children: [
7785
+ /* @__PURE__ */ jsx2("div", {
7786
+ style: {
7787
+ position: "absolute",
7788
+ inset: 0,
7789
+ borderRadius: "50%",
7790
+ border: "3px solid rgba(255, 255, 255, 0.25)",
7791
+ borderTopColor: "#ff0000",
7792
+ borderRightColor: "rgba(255, 255, 255, 0.85)",
7793
+ animation: "sc-spin 0.8s linear infinite"
7794
+ }
7795
+ }),
7796
+ /* @__PURE__ */ jsx2("div", {
7797
+ style: {
7798
+ width: "7px",
7799
+ height: "7px",
7800
+ borderRadius: "50%",
7801
+ background: "#ff0000",
7802
+ boxShadow: "0 0 10px rgba(255, 0, 0, 0.65)"
7803
+ }
7804
+ })
7805
+ ]
7762
7806
  }),
7763
7807
  showLicenseWarning && /* @__PURE__ */ jsxs2("div", {
7764
7808
  style: {
@@ -7994,7 +8038,8 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7994
8038
  /* @__PURE__ */ jsxs2("div", {
7995
8039
  style: {
7996
8040
  display: "flex",
7997
- alignItems: "center"
8041
+ alignItems: "center",
8042
+ paddingRight: "".concat(6 * responsiveScale, "px")
7998
8043
  },
7999
8044
  onMouseEnter: function onMouseEnter() {
8000
8045
  return setShowVolumeSlider(true);
@@ -8025,13 +8070,13 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8025
8070
  }),
8026
8071
  /* @__PURE__ */ jsx2("div", {
8027
8072
  style: {
8028
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8073
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8029
8074
  overflow: "hidden",
8030
8075
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8031
8076
  display: "flex",
8032
8077
  alignItems: "center",
8033
- paddingLeft: showVolumeSlider ? "2px" : "0",
8034
- paddingRight: showVolumeSlider ? "4px" : "0"
8078
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8079
+ paddingRight: showVolumeSlider ? "".concat(8 * responsiveScale, "px") : "0"
8035
8080
  },
8036
8081
  children: /* @__PURE__ */ jsxs2("div", {
8037
8082
  style: {
@@ -8278,7 +8323,8 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8278
8323
  alignItems: "center",
8279
8324
  background: "rgba(0, 0, 0, 0.6)",
8280
8325
  borderRadius: "".concat(18 * responsiveScale, "px"),
8281
- padding: "2px"
8326
+ padding: "2px",
8327
+ paddingRight: "".concat(8 * responsiveScale, "px")
8282
8328
  },
8283
8329
  onMouseEnter: function onMouseEnter() {
8284
8330
  return setShowVolumeSlider(true);
@@ -8307,13 +8353,13 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8307
8353
  }),
8308
8354
  /* @__PURE__ */ jsx2("div", {
8309
8355
  style: {
8310
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8356
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8311
8357
  overflow: "hidden",
8312
8358
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8313
8359
  display: "flex",
8314
8360
  alignItems: "center",
8315
- paddingLeft: showVolumeSlider ? "2px" : "0",
8316
- paddingRight: showVolumeSlider ? "6px" : "0"
8361
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8362
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
8317
8363
  },
8318
8364
  children: /* @__PURE__ */ jsxs2("div", {
8319
8365
  style: {