stormcloud-video-player 0.7.1 → 0.7.3

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
@@ -1136,7 +1136,6 @@ function createVastAdLayer(contentVideo, options) {
1136
1136
  var tornDown = false;
1137
1137
  var trackingFired = createEmptyTrackingState();
1138
1138
  var adStallTimerId;
1139
- var savedContentVideoStyles;
1140
1139
  var currentAdEventHandlers;
1141
1140
  var preloadSlots = /* @__PURE__ */ new Map();
1142
1141
  function emit(event, payload) {
@@ -1253,7 +1252,7 @@ function createVastAdLayer(contentVideo, options) {
1253
1252
  video.style.top = "0";
1254
1253
  video.style.width = "100%";
1255
1254
  video.style.height = "100%";
1256
- video.style.objectFit = "cover";
1255
+ video.style.objectFit = "contain";
1257
1256
  video.style.backgroundColor = "#000";
1258
1257
  video.playsInline = true;
1259
1258
  video.muted = false;
@@ -1368,31 +1367,12 @@ function createVastAdLayer(contentVideo, options) {
1368
1367
  delete contentVideo.dataset.stormcloudAdPlaying;
1369
1368
  }
1370
1369
  }
1371
- function applyContentVideoAdCoverStyles() {
1372
- if (!singleElementMode) return;
1373
- savedContentVideoStyles = {
1374
- objectFit: contentVideo.style.objectFit,
1375
- width: contentVideo.style.width,
1376
- height: contentVideo.style.height
1377
- };
1378
- contentVideo.style.objectFit = "cover";
1379
- contentVideo.style.width = "100%";
1380
- contentVideo.style.height = "100%";
1381
- }
1382
- function restoreContentVideoStyles() {
1383
- if (!singleElementMode || !savedContentVideoStyles) return;
1384
- contentVideo.style.objectFit = savedContentVideoStyles.objectFit;
1385
- contentVideo.style.width = savedContentVideoStyles.width;
1386
- contentVideo.style.height = savedContentVideoStyles.height;
1387
- savedContentVideoStyles = void 0;
1388
- }
1389
1370
  function handleAdComplete() {
1390
1371
  if (tornDown) return;
1391
1372
  clearAdStallTimer();
1392
1373
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
1393
1374
  adPlaying = false;
1394
1375
  setAdPlayingFlag(false);
1395
- restoreContentVideoStyles();
1396
1376
  if (adContainerEl) {
1397
1377
  adContainerEl.style.display = "none";
1398
1378
  adContainerEl.style.pointerEvents = "none";
@@ -1407,7 +1387,6 @@ function createVastAdLayer(contentVideo, options) {
1407
1387
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1408
1388
  adPlaying = false;
1409
1389
  setAdPlayingFlag(false);
1410
- restoreContentVideoStyles();
1411
1390
  if (adContainerEl) {
1412
1391
  adContainerEl.style.display = "none";
1413
1392
  adContainerEl.style.pointerEvents = "none";
@@ -1578,7 +1557,6 @@ function createVastAdLayer(contentVideo, options) {
1578
1557
  ];
1579
1558
  contentVideo.style.visibility = "visible";
1580
1559
  contentVideo.style.opacity = "1";
1581
- applyContentVideoAdCoverStyles();
1582
1560
  emit("content_pause");
1583
1561
  setupAdEventListeners();
1584
1562
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1817,7 +1795,6 @@ function createVastAdLayer(contentVideo, options) {
1817
1795
  ];
1818
1796
  contentVideo.style.visibility = "visible";
1819
1797
  contentVideo.style.opacity = "1";
1820
- applyContentVideoAdCoverStyles();
1821
1798
  emit("content_pause");
1822
1799
  setupAdEventListeners();
1823
1800
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1968,7 +1945,6 @@ function createVastAdLayer(contentVideo, options) {
1968
1945
  if (debug) console.log("".concat(LOG, " Stopping ad"));
1969
1946
  adPlaying = false;
1970
1947
  setAdPlayingFlag(false);
1971
- restoreContentVideoStyles();
1972
1948
  contentVideo.muted = originalMutedState;
1973
1949
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1974
1950
  contentVideo.style.visibility = "visible";
@@ -2007,7 +1983,6 @@ function createVastAdLayer(contentVideo, options) {
2007
1983
  destroyed = true;
2008
1984
  adPlaying = false;
2009
1985
  setAdPlayingFlag(false);
2010
- restoreContentVideoStyles();
2011
1986
  contentVideo.muted = originalMutedState;
2012
1987
  contentVideo.volume = originalVolume;
2013
1988
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -7412,6 +7387,7 @@ var CRITICAL_PROPS = [
7412
7387
  "driftToleranceMs"
7413
7388
  ];
7414
7389
  var CONTROLS_HIDE_DELAY = 3e3;
7390
+ var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
7415
7391
  var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props) {
7416
7392
  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, [
7417
7393
  "src",
@@ -7472,6 +7448,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7472
7448
  var _import_react2_default_useState17 = _sliced_to_array(import_react2.default.useState(null), 2), overlayCoordSpace = _import_react2_default_useState17[0], setOverlayCoordSpace = _import_react2_default_useState17[1];
7473
7449
  var _import_react2_default_useState18 = _sliced_to_array(import_react2.default.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _import_react2_default_useState18[0], setViewportWidth = _import_react2_default_useState18[1];
7474
7450
  var _import_react2_default_useState19 = _sliced_to_array(import_react2.default.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _import_react2_default_useState19[0], setIsPortrait = _import_react2_default_useState19[1];
7451
+ var _import_react2_default_useState20 = _sliced_to_array(import_react2.default.useState(DEFAULT_PLAYER_ASPECT_RATIO), 2), playerAspectRatio = _import_react2_default_useState20[0], setPlayerAspectRatio = _import_react2_default_useState20[1];
7475
7452
  var getResponsiveScale = function getResponsiveScale() {
7476
7453
  if (viewportWidth < 480) return 0.7;
7477
7454
  if (viewportWidth < 768) return 0.8;
@@ -7767,6 +7744,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7767
7744
  }, []);
7768
7745
  (0, import_react2.useEffect)(function() {
7769
7746
  if (!videoRef.current) return;
7747
+ var handleLoadedMetadata = function handleLoadedMetadata() {
7748
+ var video2 = videoRef.current;
7749
+ if (!video2) return;
7750
+ if (video2.videoWidth > 0 && video2.videoHeight > 0) {
7751
+ setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);
7752
+ }
7753
+ };
7770
7754
  var handleCanPlay = function handleCanPlay() {
7771
7755
  setIsLoading(false);
7772
7756
  if (bufferingTimeoutRef.current) {
@@ -7813,6 +7797,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7813
7797
  setShowCenterPlay(true);
7814
7798
  };
7815
7799
  var video = videoRef.current;
7800
+ handleLoadedMetadata();
7801
+ video.addEventListener("loadedmetadata", handleLoadedMetadata);
7816
7802
  video.addEventListener("canplay", handleCanPlay);
7817
7803
  video.addEventListener("canplaythrough", handleCanPlayThrough);
7818
7804
  video.addEventListener("waiting", handleWaiting);
@@ -7827,6 +7813,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7827
7813
  clearTimeout(bufferingTimeoutRef.current);
7828
7814
  bufferingTimeoutRef.current = null;
7829
7815
  }
7816
+ video.removeEventListener("loadedmetadata", handleLoadedMetadata);
7830
7817
  video.removeEventListener("canplay", handleCanPlay);
7831
7818
  video.removeEventListener("canplaythrough", handleCanPlayThrough);
7832
7819
  video.removeEventListener("waiting", handleWaiting);
@@ -7837,6 +7824,11 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7837
7824
  }, [
7838
7825
  debugAdTiming
7839
7826
  ]);
7827
+ (0, import_react2.useEffect)(function() {
7828
+ setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);
7829
+ }, [
7830
+ src
7831
+ ]);
7840
7832
  (0, import_react2.useEffect)(function() {
7841
7833
  return function() {
7842
7834
  if (controlsTimerRef.current) {
@@ -7862,7 +7854,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7862
7854
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, {
7863
7855
  children: [
7864
7856
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", {
7865
- 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 "
7857
+ 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 "
7866
7858
  }),
7867
7859
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7868
7860
  ref: wrapperRef,
@@ -7880,6 +7872,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7880
7872
  width: isFullscreen ? "100vw" : "100%",
7881
7873
  height: isFullscreen ? "100vh" : "auto",
7882
7874
  minHeight: isFullscreen ? "100vh" : "auto",
7875
+ aspectRatio: isFullscreen ? void 0 : playerAspectRatio,
7883
7876
  maxWidth: isFullscreen ? "100vw" : "100%",
7884
7877
  maxHeight: isFullscreen ? "100vh" : "none",
7885
7878
  zIndex: isFullscreen ? 999999 : void 0,
@@ -7896,7 +7889,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7896
7889
  zIndex: 1,
7897
7890
  display: "block",
7898
7891
  width: "100%",
7899
- height: isFullscreen ? "100%" : "auto",
7892
+ height: "100%",
7900
7893
  maxWidth: "100%",
7901
7894
  maxHeight: isFullscreen ? "100%" : "none",
7902
7895
  objectFit: isFullscreen ? "cover" : "contain",
@@ -7916,18 +7909,44 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7916
7909
  videoRef: videoRef,
7917
7910
  coordinateSpace: overlayCoordSpace
7918
7911
  }),
7919
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_fa.FaSpinner, {
7912
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7920
7913
  className: "sc-loading-indicator",
7921
- size: 40,
7922
- color: "rgba(255, 255, 255, 0.85)",
7923
7914
  style: {
7924
7915
  position: "absolute",
7925
- top: "calc(50% - 20px)",
7926
- left: "calc(50% - 20px)",
7916
+ top: "50%",
7917
+ left: "50%",
7918
+ transform: "translate(-50%, -50%)",
7927
7919
  zIndex: 20,
7928
- animation: "sc-spin 0.9s linear infinite",
7929
- filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
7930
- }
7920
+ width: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7921
+ height: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7922
+ display: "flex",
7923
+ alignItems: "center",
7924
+ justifyContent: "center",
7925
+ animation: "sc-loading-glow 1.4s ease-in-out infinite",
7926
+ filter: "drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))"
7927
+ },
7928
+ children: [
7929
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
7930
+ style: {
7931
+ position: "absolute",
7932
+ inset: 0,
7933
+ borderRadius: "50%",
7934
+ border: "3px solid rgba(255, 255, 255, 0.25)",
7935
+ borderTopColor: "#ff0000",
7936
+ borderRightColor: "rgba(255, 255, 255, 0.85)",
7937
+ animation: "sc-spin 0.8s linear infinite"
7938
+ }
7939
+ }),
7940
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
7941
+ style: {
7942
+ width: "7px",
7943
+ height: "7px",
7944
+ borderRadius: "50%",
7945
+ background: "#ff0000",
7946
+ boxShadow: "0 0 10px rgba(255, 0, 0, 0.65)"
7947
+ }
7948
+ })
7949
+ ]
7931
7950
  }),
7932
7951
  showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7933
7952
  style: {
@@ -8163,7 +8182,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8163
8182
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8164
8183
  style: {
8165
8184
  display: "flex",
8166
- alignItems: "center"
8185
+ alignItems: "center",
8186
+ paddingRight: "".concat(6 * responsiveScale, "px")
8167
8187
  },
8168
8188
  onMouseEnter: function onMouseEnter() {
8169
8189
  return setShowVolumeSlider(true);
@@ -8194,13 +8214,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8194
8214
  }),
8195
8215
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8196
8216
  style: {
8197
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8217
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8198
8218
  overflow: "hidden",
8199
8219
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8200
8220
  display: "flex",
8201
8221
  alignItems: "center",
8202
- paddingLeft: showVolumeSlider ? "2px" : "0",
8203
- paddingRight: showVolumeSlider ? "4px" : "0"
8222
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8223
+ paddingRight: showVolumeSlider ? "".concat(8 * responsiveScale, "px") : "0"
8204
8224
  },
8205
8225
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8206
8226
  style: {
@@ -8447,7 +8467,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8447
8467
  alignItems: "center",
8448
8468
  background: "rgba(0, 0, 0, 0.6)",
8449
8469
  borderRadius: "".concat(18 * responsiveScale, "px"),
8450
- padding: "2px"
8470
+ padding: "2px",
8471
+ paddingRight: "".concat(8 * responsiveScale, "px")
8451
8472
  },
8452
8473
  onMouseEnter: function onMouseEnter() {
8453
8474
  return setShowVolumeSlider(true);
@@ -8476,13 +8497,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8476
8497
  }),
8477
8498
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8478
8499
  style: {
8479
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8500
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8480
8501
  overflow: "hidden",
8481
8502
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8482
8503
  display: "flex",
8483
8504
  alignItems: "center",
8484
- paddingLeft: showVolumeSlider ? "2px" : "0",
8485
- paddingRight: showVolumeSlider ? "6px" : "0"
8505
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8506
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
8486
8507
  },
8487
8508
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8488
8509
  style: {