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.
@@ -980,6 +980,7 @@ function createVastAdLayer(contentVideo, options) {
980
980
  var tornDown = false;
981
981
  var trackingFired = createEmptyTrackingState();
982
982
  var adStallTimerId;
983
+ var savedContentVideoStyles;
983
984
  var currentAdEventHandlers;
984
985
  var preloadSlots = /* @__PURE__ */ new Map();
985
986
  function emit(event, payload) {
@@ -1096,7 +1097,7 @@ function createVastAdLayer(contentVideo, options) {
1096
1097
  video.style.top = "0";
1097
1098
  video.style.width = "100%";
1098
1099
  video.style.height = "100%";
1099
- video.style.objectFit = "contain";
1100
+ video.style.objectFit = "cover";
1100
1101
  video.style.backgroundColor = "#000";
1101
1102
  video.playsInline = true;
1102
1103
  video.muted = false;
@@ -1211,12 +1212,31 @@ function createVastAdLayer(contentVideo, options) {
1211
1212
  delete contentVideo.dataset.stormcloudAdPlaying;
1212
1213
  }
1213
1214
  }
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
+ }
1214
1233
  function handleAdComplete() {
1215
1234
  if (tornDown) return;
1216
1235
  clearAdStallTimer();
1217
1236
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
1218
1237
  adPlaying = false;
1219
1238
  setAdPlayingFlag(false);
1239
+ restoreContentVideoStyles();
1220
1240
  if (adContainerEl) {
1221
1241
  adContainerEl.style.display = "none";
1222
1242
  adContainerEl.style.pointerEvents = "none";
@@ -1231,6 +1251,7 @@ function createVastAdLayer(contentVideo, options) {
1231
1251
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1232
1252
  adPlaying = false;
1233
1253
  setAdPlayingFlag(false);
1254
+ restoreContentVideoStyles();
1234
1255
  if (adContainerEl) {
1235
1256
  adContainerEl.style.display = "none";
1236
1257
  adContainerEl.style.pointerEvents = "none";
@@ -1401,6 +1422,7 @@ function createVastAdLayer(contentVideo, options) {
1401
1422
  ];
1402
1423
  contentVideo.style.visibility = "visible";
1403
1424
  contentVideo.style.opacity = "1";
1425
+ applyContentVideoAdCoverStyles();
1404
1426
  emit("content_pause");
1405
1427
  setupAdEventListeners();
1406
1428
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1639,6 +1661,7 @@ function createVastAdLayer(contentVideo, options) {
1639
1661
  ];
1640
1662
  contentVideo.style.visibility = "visible";
1641
1663
  contentVideo.style.opacity = "1";
1664
+ applyContentVideoAdCoverStyles();
1642
1665
  emit("content_pause");
1643
1666
  setupAdEventListeners();
1644
1667
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1789,6 +1812,7 @@ function createVastAdLayer(contentVideo, options) {
1789
1812
  if (debug) console.log("".concat(LOG, " Stopping ad"));
1790
1813
  adPlaying = false;
1791
1814
  setAdPlayingFlag(false);
1815
+ restoreContentVideoStyles();
1792
1816
  contentVideo.muted = originalMutedState;
1793
1817
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1794
1818
  contentVideo.style.visibility = "visible";
@@ -1827,6 +1851,7 @@ function createVastAdLayer(contentVideo, options) {
1827
1851
  destroyed = true;
1828
1852
  adPlaying = false;
1829
1853
  setAdPlayingFlag(false);
1854
+ restoreContentVideoStyles();
1830
1855
  contentVideo.muted = originalMutedState;
1831
1856
  contentVideo.volume = originalVolume;
1832
1857
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -6066,6 +6091,7 @@ var CRITICAL_PROPS = [
6066
6091
  "driftToleranceMs"
6067
6092
  ];
6068
6093
  var CONTROLS_HIDE_DELAY = 3e3;
6094
+ var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
6069
6095
  var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6070
6096
  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, [
6071
6097
  "src",
@@ -6123,6 +6149,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6123
6149
  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];
6124
6150
  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];
6125
6151
  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];
6152
+ 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];
6126
6153
  var getResponsiveScale = function getResponsiveScale() {
6127
6154
  if (viewportWidth < 480) return 0.7;
6128
6155
  if (viewportWidth < 768) return 0.8;
@@ -6364,6 +6391,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6364
6391
  }, []);
6365
6392
  (0, import_react.useEffect)(function() {
6366
6393
  if (!videoRef.current) return;
6394
+ var handleLoadedMetadata = function handleLoadedMetadata() {
6395
+ var video2 = videoRef.current;
6396
+ if (!video2) return;
6397
+ if (video2.videoWidth > 0 && video2.videoHeight > 0) {
6398
+ setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);
6399
+ }
6400
+ };
6367
6401
  var handleCanPlay = function handleCanPlay() {
6368
6402
  setIsLoading(false);
6369
6403
  if (bufferingTimeoutRef.current) {
@@ -6410,6 +6444,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6410
6444
  setShowCenterPlay(true);
6411
6445
  };
6412
6446
  var video = videoRef.current;
6447
+ handleLoadedMetadata();
6448
+ video.addEventListener("loadedmetadata", handleLoadedMetadata);
6413
6449
  video.addEventListener("canplay", handleCanPlay);
6414
6450
  video.addEventListener("canplaythrough", handleCanPlayThrough);
6415
6451
  video.addEventListener("waiting", handleWaiting);
@@ -6424,6 +6460,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6424
6460
  clearTimeout(bufferingTimeoutRef.current);
6425
6461
  bufferingTimeoutRef.current = null;
6426
6462
  }
6463
+ video.removeEventListener("loadedmetadata", handleLoadedMetadata);
6427
6464
  video.removeEventListener("canplay", handleCanPlay);
6428
6465
  video.removeEventListener("canplaythrough", handleCanPlayThrough);
6429
6466
  video.removeEventListener("waiting", handleWaiting);
@@ -6434,6 +6471,11 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6434
6471
  }, [
6435
6472
  debugAdTiming
6436
6473
  ]);
6474
+ (0, import_react.useEffect)(function() {
6475
+ setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);
6476
+ }, [
6477
+ src
6478
+ ]);
6437
6479
  (0, import_react.useEffect)(function() {
6438
6480
  return function() {
6439
6481
  if (controlsTimerRef.current) {
@@ -6459,7 +6501,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6459
6501
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
6460
6502
  children: [
6461
6503
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", {
6462
- 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 "
6504
+ 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 "
6463
6505
  }),
6464
6506
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6465
6507
  ref: wrapperRef,
@@ -6477,6 +6519,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6477
6519
  width: isFullscreen ? "100vw" : "100%",
6478
6520
  height: isFullscreen ? "100vh" : "auto",
6479
6521
  minHeight: isFullscreen ? "100vh" : "auto",
6522
+ aspectRatio: isFullscreen ? void 0 : playerAspectRatio,
6480
6523
  maxWidth: isFullscreen ? "100vw" : "100%",
6481
6524
  maxHeight: isFullscreen ? "100vh" : "none",
6482
6525
  zIndex: isFullscreen ? 999999 : void 0,
@@ -6491,7 +6534,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6491
6534
  style: _object_spread({
6492
6535
  display: "block",
6493
6536
  width: "100%",
6494
- height: isFullscreen ? "100%" : "auto",
6537
+ height: "100%",
6495
6538
  maxWidth: "100%",
6496
6539
  maxHeight: isFullscreen ? "100%" : "none",
6497
6540
  objectFit: isFullscreen ? "cover" : "contain",
@@ -6505,18 +6548,44 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6505
6548
  }, restVideoAttrs), {
6506
6549
  children: children
6507
6550
  })),
6508
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaSpinner, {
6551
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6509
6552
  className: "sc-loading-indicator",
6510
- size: 40,
6511
- color: "rgba(255, 255, 255, 0.85)",
6512
6553
  style: {
6513
6554
  position: "absolute",
6514
- top: "calc(50% - 20px)",
6515
- left: "calc(50% - 20px)",
6555
+ top: "50%",
6556
+ left: "50%",
6557
+ transform: "translate(-50%, -50%)",
6516
6558
  zIndex: 20,
6517
- animation: "sc-spin 0.9s linear infinite",
6518
- filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
6519
- }
6559
+ width: "".concat(Math.max(34, 38 * responsiveScale), "px"),
6560
+ height: "".concat(Math.max(34, 38 * responsiveScale), "px"),
6561
+ display: "flex",
6562
+ alignItems: "center",
6563
+ justifyContent: "center",
6564
+ animation: "sc-loading-glow 1.4s ease-in-out infinite",
6565
+ filter: "drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))"
6566
+ },
6567
+ children: [
6568
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6569
+ style: {
6570
+ position: "absolute",
6571
+ inset: 0,
6572
+ borderRadius: "50%",
6573
+ border: "3px solid rgba(255, 255, 255, 0.25)",
6574
+ borderTopColor: "#ff0000",
6575
+ borderRightColor: "rgba(255, 255, 255, 0.85)",
6576
+ animation: "sc-spin 0.8s linear infinite"
6577
+ }
6578
+ }),
6579
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6580
+ style: {
6581
+ width: "7px",
6582
+ height: "7px",
6583
+ borderRadius: "50%",
6584
+ background: "#ff0000",
6585
+ boxShadow: "0 0 10px rgba(255, 0, 0, 0.65)"
6586
+ }
6587
+ })
6588
+ ]
6520
6589
  }),
6521
6590
  showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6522
6591
  style: {
@@ -6752,7 +6821,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6752
6821
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6753
6822
  style: {
6754
6823
  display: "flex",
6755
- alignItems: "center"
6824
+ alignItems: "center",
6825
+ paddingRight: "".concat(6 * responsiveScale, "px")
6756
6826
  },
6757
6827
  onMouseEnter: function onMouseEnter() {
6758
6828
  return setShowVolumeSlider(true);
@@ -6783,13 +6853,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6783
6853
  }),
6784
6854
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
6785
6855
  style: {
6786
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
6856
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
6787
6857
  overflow: "hidden",
6788
6858
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
6789
6859
  display: "flex",
6790
6860
  alignItems: "center",
6791
- paddingLeft: showVolumeSlider ? "2px" : "0",
6792
- paddingRight: showVolumeSlider ? "4px" : "0"
6861
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
6862
+ paddingRight: showVolumeSlider ? "".concat(8 * responsiveScale, "px") : "0"
6793
6863
  },
6794
6864
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
6795
6865
  style: {
@@ -7036,7 +7106,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7036
7106
  alignItems: "center",
7037
7107
  background: "rgba(0, 0, 0, 0.6)",
7038
7108
  borderRadius: "".concat(18 * responsiveScale, "px"),
7039
- padding: "2px"
7109
+ padding: "2px",
7110
+ paddingRight: "".concat(8 * responsiveScale, "px")
7040
7111
  },
7041
7112
  onMouseEnter: function onMouseEnter() {
7042
7113
  return setShowVolumeSlider(true);
@@ -7065,13 +7136,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7065
7136
  }),
7066
7137
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7067
7138
  style: {
7068
- width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
7139
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
7069
7140
  overflow: "hidden",
7070
7141
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
7071
7142
  display: "flex",
7072
7143
  alignItems: "center",
7073
- paddingLeft: showVolumeSlider ? "2px" : "0",
7074
- paddingRight: showVolumeSlider ? "6px" : "0"
7144
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
7145
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
7075
7146
  },
7076
7147
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7077
7148
  style: {