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.
@@ -980,7 +980,6 @@ function createVastAdLayer(contentVideo, options) {
980
980
  var tornDown = false;
981
981
  var trackingFired = createEmptyTrackingState();
982
982
  var adStallTimerId;
983
- var savedContentVideoStyles;
984
983
  var currentAdEventHandlers;
985
984
  var preloadSlots = /* @__PURE__ */ new Map();
986
985
  function emit(event, payload) {
@@ -1097,7 +1096,7 @@ function createVastAdLayer(contentVideo, options) {
1097
1096
  video.style.top = "0";
1098
1097
  video.style.width = "100%";
1099
1098
  video.style.height = "100%";
1100
- video.style.objectFit = "cover";
1099
+ video.style.objectFit = "contain";
1101
1100
  video.style.backgroundColor = "#000";
1102
1101
  video.playsInline = true;
1103
1102
  video.muted = false;
@@ -1212,31 +1211,12 @@ function createVastAdLayer(contentVideo, options) {
1212
1211
  delete contentVideo.dataset.stormcloudAdPlaying;
1213
1212
  }
1214
1213
  }
1215
- function applyContentVideoAdCoverStyles() {
1216
- if (!singleElementMode) return;
1217
- savedContentVideoStyles = {
1218
- objectFit: contentVideo.style.objectFit,
1219
- width: contentVideo.style.width,
1220
- height: contentVideo.style.height
1221
- };
1222
- contentVideo.style.objectFit = "cover";
1223
- contentVideo.style.width = "100%";
1224
- contentVideo.style.height = "100%";
1225
- }
1226
- function restoreContentVideoStyles() {
1227
- if (!singleElementMode || !savedContentVideoStyles) return;
1228
- contentVideo.style.objectFit = savedContentVideoStyles.objectFit;
1229
- contentVideo.style.width = savedContentVideoStyles.width;
1230
- contentVideo.style.height = savedContentVideoStyles.height;
1231
- savedContentVideoStyles = void 0;
1232
- }
1233
1214
  function handleAdComplete() {
1234
1215
  if (tornDown) return;
1235
1216
  clearAdStallTimer();
1236
1217
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
1237
1218
  adPlaying = false;
1238
1219
  setAdPlayingFlag(false);
1239
- restoreContentVideoStyles();
1240
1220
  if (adContainerEl) {
1241
1221
  adContainerEl.style.display = "none";
1242
1222
  adContainerEl.style.pointerEvents = "none";
@@ -1251,7 +1231,6 @@ function createVastAdLayer(contentVideo, options) {
1251
1231
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1252
1232
  adPlaying = false;
1253
1233
  setAdPlayingFlag(false);
1254
- restoreContentVideoStyles();
1255
1234
  if (adContainerEl) {
1256
1235
  adContainerEl.style.display = "none";
1257
1236
  adContainerEl.style.pointerEvents = "none";
@@ -1422,7 +1401,6 @@ function createVastAdLayer(contentVideo, options) {
1422
1401
  ];
1423
1402
  contentVideo.style.visibility = "visible";
1424
1403
  contentVideo.style.opacity = "1";
1425
- applyContentVideoAdCoverStyles();
1426
1404
  emit("content_pause");
1427
1405
  setupAdEventListeners();
1428
1406
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1661,7 +1639,6 @@ function createVastAdLayer(contentVideo, options) {
1661
1639
  ];
1662
1640
  contentVideo.style.visibility = "visible";
1663
1641
  contentVideo.style.opacity = "1";
1664
- applyContentVideoAdCoverStyles();
1665
1642
  emit("content_pause");
1666
1643
  setupAdEventListeners();
1667
1644
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1812,7 +1789,6 @@ function createVastAdLayer(contentVideo, options) {
1812
1789
  if (debug) console.log("".concat(LOG, " Stopping ad"));
1813
1790
  adPlaying = false;
1814
1791
  setAdPlayingFlag(false);
1815
- restoreContentVideoStyles();
1816
1792
  contentVideo.muted = originalMutedState;
1817
1793
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1818
1794
  contentVideo.style.visibility = "visible";
@@ -1851,7 +1827,6 @@ function createVastAdLayer(contentVideo, options) {
1851
1827
  destroyed = true;
1852
1828
  adPlaying = false;
1853
1829
  setAdPlayingFlag(false);
1854
- restoreContentVideoStyles();
1855
1830
  contentVideo.muted = originalMutedState;
1856
1831
  contentVideo.volume = originalVolume;
1857
1832
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -7231,6 +7206,7 @@ var CRITICAL_PROPS = [
7231
7206
  "driftToleranceMs"
7232
7207
  ];
7233
7208
  var CONTROLS_HIDE_DELAY = 3e3;
7209
+ var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
7234
7210
  var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props) {
7235
7211
  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, [
7236
7212
  "src",
@@ -7291,6 +7267,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7291
7267
  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];
7292
7268
  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];
7293
7269
  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];
7270
+ 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];
7294
7271
  var getResponsiveScale = function getResponsiveScale() {
7295
7272
  if (viewportWidth < 480) return 0.7;
7296
7273
  if (viewportWidth < 768) return 0.8;
@@ -7586,6 +7563,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7586
7563
  }, []);
7587
7564
  (0, import_react2.useEffect)(function() {
7588
7565
  if (!videoRef.current) return;
7566
+ var handleLoadedMetadata = function handleLoadedMetadata() {
7567
+ var video2 = videoRef.current;
7568
+ if (!video2) return;
7569
+ if (video2.videoWidth > 0 && video2.videoHeight > 0) {
7570
+ setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);
7571
+ }
7572
+ };
7589
7573
  var handleCanPlay = function handleCanPlay() {
7590
7574
  setIsLoading(false);
7591
7575
  if (bufferingTimeoutRef.current) {
@@ -7632,6 +7616,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7632
7616
  setShowCenterPlay(true);
7633
7617
  };
7634
7618
  var video = videoRef.current;
7619
+ handleLoadedMetadata();
7620
+ video.addEventListener("loadedmetadata", handleLoadedMetadata);
7635
7621
  video.addEventListener("canplay", handleCanPlay);
7636
7622
  video.addEventListener("canplaythrough", handleCanPlayThrough);
7637
7623
  video.addEventListener("waiting", handleWaiting);
@@ -7646,6 +7632,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7646
7632
  clearTimeout(bufferingTimeoutRef.current);
7647
7633
  bufferingTimeoutRef.current = null;
7648
7634
  }
7635
+ video.removeEventListener("loadedmetadata", handleLoadedMetadata);
7649
7636
  video.removeEventListener("canplay", handleCanPlay);
7650
7637
  video.removeEventListener("canplaythrough", handleCanPlayThrough);
7651
7638
  video.removeEventListener("waiting", handleWaiting);
@@ -7656,6 +7643,11 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7656
7643
  }, [
7657
7644
  debugAdTiming
7658
7645
  ]);
7646
+ (0, import_react2.useEffect)(function() {
7647
+ setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);
7648
+ }, [
7649
+ src
7650
+ ]);
7659
7651
  (0, import_react2.useEffect)(function() {
7660
7652
  return function() {
7661
7653
  if (controlsTimerRef.current) {
@@ -7681,7 +7673,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7681
7673
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, {
7682
7674
  children: [
7683
7675
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", {
7684
- 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 "
7676
+ 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 "
7685
7677
  }),
7686
7678
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7687
7679
  ref: wrapperRef,
@@ -7699,6 +7691,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7699
7691
  width: isFullscreen ? "100vw" : "100%",
7700
7692
  height: isFullscreen ? "100vh" : "auto",
7701
7693
  minHeight: isFullscreen ? "100vh" : "auto",
7694
+ aspectRatio: isFullscreen ? void 0 : playerAspectRatio,
7702
7695
  maxWidth: isFullscreen ? "100vw" : "100%",
7703
7696
  maxHeight: isFullscreen ? "100vh" : "none",
7704
7697
  zIndex: isFullscreen ? 999999 : void 0,
@@ -7715,7 +7708,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7715
7708
  zIndex: 1,
7716
7709
  display: "block",
7717
7710
  width: "100%",
7718
- height: isFullscreen ? "100%" : "auto",
7711
+ height: "100%",
7719
7712
  maxWidth: "100%",
7720
7713
  maxHeight: isFullscreen ? "100%" : "none",
7721
7714
  objectFit: isFullscreen ? "cover" : "contain",
@@ -7735,18 +7728,44 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7735
7728
  videoRef: videoRef,
7736
7729
  coordinateSpace: overlayCoordSpace
7737
7730
  }),
7738
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_fa.FaSpinner, {
7731
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7739
7732
  className: "sc-loading-indicator",
7740
- size: 40,
7741
- color: "rgba(255, 255, 255, 0.85)",
7742
7733
  style: {
7743
7734
  position: "absolute",
7744
- top: "calc(50% - 20px)",
7745
- left: "calc(50% - 20px)",
7735
+ top: "50%",
7736
+ left: "50%",
7737
+ transform: "translate(-50%, -50%)",
7746
7738
  zIndex: 20,
7747
- animation: "sc-spin 0.9s linear infinite",
7748
- filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
7749
- }
7739
+ width: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7740
+ height: "".concat(Math.max(34, 38 * responsiveScale), "px"),
7741
+ display: "flex",
7742
+ alignItems: "center",
7743
+ justifyContent: "center",
7744
+ animation: "sc-loading-glow 1.4s ease-in-out infinite",
7745
+ filter: "drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))"
7746
+ },
7747
+ children: [
7748
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
7749
+ style: {
7750
+ position: "absolute",
7751
+ inset: 0,
7752
+ borderRadius: "50%",
7753
+ border: "3px solid rgba(255, 255, 255, 0.25)",
7754
+ borderTopColor: "#ff0000",
7755
+ borderRightColor: "rgba(255, 255, 255, 0.85)",
7756
+ animation: "sc-spin 0.8s linear infinite"
7757
+ }
7758
+ }),
7759
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
7760
+ style: {
7761
+ width: "7px",
7762
+ height: "7px",
7763
+ borderRadius: "50%",
7764
+ background: "#ff0000",
7765
+ boxShadow: "0 0 10px rgba(255, 0, 0, 0.65)"
7766
+ }
7767
+ })
7768
+ ]
7750
7769
  }),
7751
7770
  showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7752
7771
  style: {
@@ -7982,7 +8001,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7982
8001
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
7983
8002
  style: {
7984
8003
  display: "flex",
7985
- alignItems: "center"
8004
+ alignItems: "center",
8005
+ paddingRight: "".concat(6 * responsiveScale, "px")
7986
8006
  },
7987
8007
  onMouseEnter: function onMouseEnter() {
7988
8008
  return setShowVolumeSlider(true);
@@ -8013,13 +8033,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8013
8033
  }),
8014
8034
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8015
8035
  style: {
8016
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8036
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8017
8037
  overflow: "hidden",
8018
8038
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8019
8039
  display: "flex",
8020
8040
  alignItems: "center",
8021
- paddingLeft: showVolumeSlider ? "2px" : "0",
8022
- paddingRight: showVolumeSlider ? "4px" : "0"
8041
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8042
+ paddingRight: showVolumeSlider ? "".concat(8 * responsiveScale, "px") : "0"
8023
8043
  },
8024
8044
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8025
8045
  style: {
@@ -8266,7 +8286,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8266
8286
  alignItems: "center",
8267
8287
  background: "rgba(0, 0, 0, 0.6)",
8268
8288
  borderRadius: "".concat(18 * responsiveScale, "px"),
8269
- padding: "2px"
8289
+ padding: "2px",
8290
+ paddingRight: "".concat(8 * responsiveScale, "px")
8270
8291
  },
8271
8292
  onMouseEnter: function onMouseEnter() {
8272
8293
  return setShowVolumeSlider(true);
@@ -8295,13 +8316,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8295
8316
  }),
8296
8317
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8297
8318
  style: {
8298
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8319
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
8299
8320
  overflow: "hidden",
8300
8321
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8301
8322
  display: "flex",
8302
8323
  alignItems: "center",
8303
- paddingLeft: showVolumeSlider ? "2px" : "0",
8304
- paddingRight: showVolumeSlider ? "6px" : "0"
8324
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
8325
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
8305
8326
  },
8306
8327
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8307
8328
  style: {