stormcloud-video-player 0.6.5 → 0.6.7

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
@@ -1124,6 +1124,7 @@ function createVastAdLayer(contentVideo, options) {
1124
1124
  var tornDown = false;
1125
1125
  var trackingFired = createEmptyTrackingState();
1126
1126
  var adStallTimerId;
1127
+ var savedContentVideoStyles;
1127
1128
  var currentAdEventHandlers;
1128
1129
  var preloadSlots = /* @__PURE__ */ new Map();
1129
1130
  function emit(event, payload) {
@@ -1240,7 +1241,7 @@ function createVastAdLayer(contentVideo, options) {
1240
1241
  video.style.top = "0";
1241
1242
  video.style.width = "100%";
1242
1243
  video.style.height = "100%";
1243
- video.style.objectFit = "contain";
1244
+ video.style.objectFit = "cover";
1244
1245
  video.style.backgroundColor = "#000";
1245
1246
  video.playsInline = true;
1246
1247
  video.muted = false;
@@ -1355,12 +1356,31 @@ function createVastAdLayer(contentVideo, options) {
1355
1356
  delete contentVideo.dataset.stormcloudAdPlaying;
1356
1357
  }
1357
1358
  }
1359
+ function applyContentVideoAdCoverStyles() {
1360
+ if (!singleElementMode) return;
1361
+ savedContentVideoStyles = {
1362
+ objectFit: contentVideo.style.objectFit,
1363
+ width: contentVideo.style.width,
1364
+ height: contentVideo.style.height
1365
+ };
1366
+ contentVideo.style.objectFit = "cover";
1367
+ contentVideo.style.width = "100%";
1368
+ contentVideo.style.height = "100%";
1369
+ }
1370
+ function restoreContentVideoStyles() {
1371
+ if (!singleElementMode || !savedContentVideoStyles) return;
1372
+ contentVideo.style.objectFit = savedContentVideoStyles.objectFit;
1373
+ contentVideo.style.width = savedContentVideoStyles.width;
1374
+ contentVideo.style.height = savedContentVideoStyles.height;
1375
+ savedContentVideoStyles = void 0;
1376
+ }
1358
1377
  function handleAdComplete() {
1359
1378
  if (tornDown) return;
1360
1379
  clearAdStallTimer();
1361
1380
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
1362
1381
  adPlaying = false;
1363
1382
  setAdPlayingFlag(false);
1383
+ restoreContentVideoStyles();
1364
1384
  if (adContainerEl) {
1365
1385
  adContainerEl.style.display = "none";
1366
1386
  adContainerEl.style.pointerEvents = "none";
@@ -1375,6 +1395,7 @@ function createVastAdLayer(contentVideo, options) {
1375
1395
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1376
1396
  adPlaying = false;
1377
1397
  setAdPlayingFlag(false);
1398
+ restoreContentVideoStyles();
1378
1399
  if (adContainerEl) {
1379
1400
  adContainerEl.style.display = "none";
1380
1401
  adContainerEl.style.pointerEvents = "none";
@@ -1545,6 +1566,7 @@ function createVastAdLayer(contentVideo, options) {
1545
1566
  ];
1546
1567
  contentVideo.style.visibility = "visible";
1547
1568
  contentVideo.style.opacity = "1";
1569
+ applyContentVideoAdCoverStyles();
1548
1570
  emit("content_pause");
1549
1571
  setupAdEventListeners();
1550
1572
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1783,6 +1805,7 @@ function createVastAdLayer(contentVideo, options) {
1783
1805
  ];
1784
1806
  contentVideo.style.visibility = "visible";
1785
1807
  contentVideo.style.opacity = "1";
1808
+ applyContentVideoAdCoverStyles();
1786
1809
  emit("content_pause");
1787
1810
  setupAdEventListeners();
1788
1811
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1933,6 +1956,7 @@ function createVastAdLayer(contentVideo, options) {
1933
1956
  if (debug) console.log("".concat(LOG, " Stopping ad"));
1934
1957
  adPlaying = false;
1935
1958
  setAdPlayingFlag(false);
1959
+ restoreContentVideoStyles();
1936
1960
  contentVideo.muted = originalMutedState;
1937
1961
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1938
1962
  contentVideo.style.visibility = "visible";
@@ -1971,6 +1995,7 @@ function createVastAdLayer(contentVideo, options) {
1971
1995
  destroyed = true;
1972
1996
  adPlaying = false;
1973
1997
  setAdPlayingFlag(false);
1998
+ restoreContentVideoStyles();
1974
1999
  contentVideo.muted = originalMutedState;
1975
2000
  contentVideo.volume = originalVolume;
1976
2001
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -6235,6 +6260,7 @@ var CRITICAL_PROPS = [
6235
6260
  "driftToleranceMs"
6236
6261
  ];
6237
6262
  var CONTROLS_HIDE_DELAY = 3e3;
6263
+ var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
6238
6264
  var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6239
6265
  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, restVideoAttrs = _object_without_properties(props, [
6240
6266
  "src",
@@ -6292,6 +6318,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6292
6318
  var _import_react_default_useState15 = _sliced_to_array(import_react.default.useState(true), 2), controlsVisible = _import_react_default_useState15[0], setControlsVisible = _import_react_default_useState15[1];
6293
6319
  var _import_react_default_useState16 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _import_react_default_useState16[0], setViewportWidth = _import_react_default_useState16[1];
6294
6320
  var _import_react_default_useState17 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _import_react_default_useState17[0], setIsPortrait = _import_react_default_useState17[1];
6321
+ var _import_react_default_useState18 = _sliced_to_array(import_react.default.useState(DEFAULT_PLAYER_ASPECT_RATIO), 2), playerAspectRatio = _import_react_default_useState18[0], setPlayerAspectRatio = _import_react_default_useState18[1];
6295
6322
  var getResponsiveScale = function getResponsiveScale() {
6296
6323
  if (viewportWidth < 480) return 0.7;
6297
6324
  if (viewportWidth < 768) return 0.8;
@@ -6533,6 +6560,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6533
6560
  }, []);
6534
6561
  (0, import_react.useEffect)(function() {
6535
6562
  if (!videoRef.current) return;
6563
+ var handleLoadedMetadata = function handleLoadedMetadata() {
6564
+ var video2 = videoRef.current;
6565
+ if (!video2) return;
6566
+ if (video2.videoWidth > 0 && video2.videoHeight > 0) {
6567
+ setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);
6568
+ }
6569
+ };
6536
6570
  var handleCanPlay = function handleCanPlay() {
6537
6571
  setIsLoading(false);
6538
6572
  if (bufferingTimeoutRef.current) {
@@ -6579,6 +6613,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6579
6613
  setShowCenterPlay(true);
6580
6614
  };
6581
6615
  var video = videoRef.current;
6616
+ handleLoadedMetadata();
6617
+ video.addEventListener("loadedmetadata", handleLoadedMetadata);
6582
6618
  video.addEventListener("canplay", handleCanPlay);
6583
6619
  video.addEventListener("canplaythrough", handleCanPlayThrough);
6584
6620
  video.addEventListener("waiting", handleWaiting);
@@ -6593,6 +6629,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6593
6629
  clearTimeout(bufferingTimeoutRef.current);
6594
6630
  bufferingTimeoutRef.current = null;
6595
6631
  }
6632
+ video.removeEventListener("loadedmetadata", handleLoadedMetadata);
6596
6633
  video.removeEventListener("canplay", handleCanPlay);
6597
6634
  video.removeEventListener("canplaythrough", handleCanPlayThrough);
6598
6635
  video.removeEventListener("waiting", handleWaiting);
@@ -6603,6 +6640,11 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6603
6640
  }, [
6604
6641
  debugAdTiming
6605
6642
  ]);
6643
+ (0, import_react.useEffect)(function() {
6644
+ setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);
6645
+ }, [
6646
+ src
6647
+ ]);
6606
6648
  (0, import_react.useEffect)(function() {
6607
6649
  return function() {
6608
6650
  if (controlsTimerRef.current) {
@@ -6628,7 +6670,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6628
6670
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
6629
6671
  children: [
6630
6672
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", {
6631
- 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 "
6673
+ 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 "
6632
6674
  }),
6633
6675
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6634
6676
  ref: wrapperRef,
@@ -6646,6 +6688,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6646
6688
  width: isFullscreen ? "100vw" : "100%",
6647
6689
  height: isFullscreen ? "100vh" : "auto",
6648
6690
  minHeight: isFullscreen ? "100vh" : "auto",
6691
+ aspectRatio: isFullscreen ? void 0 : playerAspectRatio,
6649
6692
  maxWidth: isFullscreen ? "100vw" : "100%",
6650
6693
  maxHeight: isFullscreen ? "100vh" : "none",
6651
6694
  zIndex: isFullscreen ? 999999 : void 0,
@@ -6660,7 +6703,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6660
6703
  style: _object_spread({
6661
6704
  display: "block",
6662
6705
  width: "100%",
6663
- height: isFullscreen ? "100%" : "auto",
6706
+ height: "100%",
6664
6707
  maxWidth: "100%",
6665
6708
  maxHeight: isFullscreen ? "100%" : "none",
6666
6709
  objectFit: isFullscreen ? "cover" : "contain",
@@ -6674,18 +6717,44 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6674
6717
  }, restVideoAttrs), {
6675
6718
  children: children
6676
6719
  })),
6677
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaSpinner, {
6720
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6678
6721
  className: "sc-loading-indicator",
6679
- size: 40,
6680
- color: "rgba(255, 255, 255, 0.85)",
6681
6722
  style: {
6682
6723
  position: "absolute",
6683
- top: "calc(50% - 20px)",
6684
- left: "calc(50% - 20px)",
6724
+ top: "50%",
6725
+ left: "50%",
6726
+ transform: "translate(-50%, -50%)",
6685
6727
  zIndex: 20,
6686
- animation: "sc-spin 0.9s linear infinite",
6687
- filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
6688
- }
6728
+ width: "".concat(Math.max(34, 38 * responsiveScale), "px"),
6729
+ height: "".concat(Math.max(34, 38 * responsiveScale), "px"),
6730
+ display: "flex",
6731
+ alignItems: "center",
6732
+ justifyContent: "center",
6733
+ animation: "sc-loading-glow 1.4s ease-in-out infinite",
6734
+ filter: "drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))"
6735
+ },
6736
+ children: [
6737
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6738
+ style: {
6739
+ position: "absolute",
6740
+ inset: 0,
6741
+ borderRadius: "50%",
6742
+ border: "3px solid rgba(255, 255, 255, 0.25)",
6743
+ borderTopColor: "#ff0000",
6744
+ borderRightColor: "rgba(255, 255, 255, 0.85)",
6745
+ animation: "sc-spin 0.8s linear infinite"
6746
+ }
6747
+ }),
6748
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6749
+ style: {
6750
+ width: "7px",
6751
+ height: "7px",
6752
+ borderRadius: "50%",
6753
+ background: "#ff0000",
6754
+ boxShadow: "0 0 10px rgba(255, 0, 0, 0.65)"
6755
+ }
6756
+ })
6757
+ ]
6689
6758
  }),
6690
6759
  showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6691
6760
  style: {
@@ -6921,7 +6990,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6921
6990
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6922
6991
  style: {
6923
6992
  display: "flex",
6924
- alignItems: "center"
6993
+ alignItems: "center",
6994
+ paddingRight: "".concat(6 * responsiveScale, "px")
6925
6995
  },
6926
6996
  onMouseEnter: function onMouseEnter() {
6927
6997
  return setShowVolumeSlider(true);
@@ -6952,13 +7022,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6952
7022
  }),
6953
7023
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6954
7024
  style: {
6955
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
7025
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
6956
7026
  overflow: "hidden",
6957
7027
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
6958
7028
  display: "flex",
6959
7029
  alignItems: "center",
6960
- paddingLeft: showVolumeSlider ? "2px" : "0",
6961
- paddingRight: showVolumeSlider ? "4px" : "0"
7030
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
7031
+ paddingRight: showVolumeSlider ? "".concat(8 * responsiveScale, "px") : "0"
6962
7032
  },
6963
7033
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6964
7034
  style: {
@@ -7205,7 +7275,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7205
7275
  alignItems: "center",
7206
7276
  background: "rgba(0, 0, 0, 0.6)",
7207
7277
  borderRadius: "".concat(18 * responsiveScale, "px"),
7208
- padding: "2px"
7278
+ padding: "2px",
7279
+ paddingRight: "".concat(8 * responsiveScale, "px")
7209
7280
  },
7210
7281
  onMouseEnter: function onMouseEnter() {
7211
7282
  return setShowVolumeSlider(true);
@@ -7234,13 +7305,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7234
7305
  }),
7235
7306
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7236
7307
  style: {
7237
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
7308
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
7238
7309
  overflow: "hidden",
7239
7310
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
7240
7311
  display: "flex",
7241
7312
  alignItems: "center",
7242
- paddingLeft: showVolumeSlider ? "2px" : "0",
7243
- paddingRight: showVolumeSlider ? "6px" : "0"
7313
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
7314
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
7244
7315
  },
7245
7316
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7246
7317
  style: {