stormcloud-video-player 0.6.5 → 0.7.0

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
@@ -367,7 +367,7 @@ function _ts_values(o) {
367
367
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
368
368
  }
369
369
  // src/ui/StormcloudVideoPlayer.tsx
370
- import React, { useEffect, useRef, useMemo, useCallback } from "react";
370
+ import React2, { useEffect as useEffect2, useRef as useRef2, useMemo, useCallback as useCallback2 } from "react";
371
371
  // src/player/StormcloudVideoPlayer.ts
372
372
  import Hls2 from "hls.js";
373
373
  // src/sdk/vastParser.ts
@@ -964,6 +964,7 @@ function createVastAdLayer(contentVideo, options) {
964
964
  var tornDown = false;
965
965
  var trackingFired = createEmptyTrackingState();
966
966
  var adStallTimerId;
967
+ var savedContentVideoStyles;
967
968
  var currentAdEventHandlers;
968
969
  var preloadSlots = /* @__PURE__ */ new Map();
969
970
  function emit(event, payload) {
@@ -1080,7 +1081,7 @@ function createVastAdLayer(contentVideo, options) {
1080
1081
  video.style.top = "0";
1081
1082
  video.style.width = "100%";
1082
1083
  video.style.height = "100%";
1083
- video.style.objectFit = "contain";
1084
+ video.style.objectFit = "cover";
1084
1085
  video.style.backgroundColor = "#000";
1085
1086
  video.playsInline = true;
1086
1087
  video.muted = false;
@@ -1195,12 +1196,31 @@ function createVastAdLayer(contentVideo, options) {
1195
1196
  delete contentVideo.dataset.stormcloudAdPlaying;
1196
1197
  }
1197
1198
  }
1199
+ function applyContentVideoAdCoverStyles() {
1200
+ if (!singleElementMode) return;
1201
+ savedContentVideoStyles = {
1202
+ objectFit: contentVideo.style.objectFit,
1203
+ width: contentVideo.style.width,
1204
+ height: contentVideo.style.height
1205
+ };
1206
+ contentVideo.style.objectFit = "cover";
1207
+ contentVideo.style.width = "100%";
1208
+ contentVideo.style.height = "100%";
1209
+ }
1210
+ function restoreContentVideoStyles() {
1211
+ if (!singleElementMode || !savedContentVideoStyles) return;
1212
+ contentVideo.style.objectFit = savedContentVideoStyles.objectFit;
1213
+ contentVideo.style.width = savedContentVideoStyles.width;
1214
+ contentVideo.style.height = savedContentVideoStyles.height;
1215
+ savedContentVideoStyles = void 0;
1216
+ }
1198
1217
  function handleAdComplete() {
1199
1218
  if (tornDown) return;
1200
1219
  clearAdStallTimer();
1201
1220
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
1202
1221
  adPlaying = false;
1203
1222
  setAdPlayingFlag(false);
1223
+ restoreContentVideoStyles();
1204
1224
  if (adContainerEl) {
1205
1225
  adContainerEl.style.display = "none";
1206
1226
  adContainerEl.style.pointerEvents = "none";
@@ -1215,6 +1235,7 @@ function createVastAdLayer(contentVideo, options) {
1215
1235
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1216
1236
  adPlaying = false;
1217
1237
  setAdPlayingFlag(false);
1238
+ restoreContentVideoStyles();
1218
1239
  if (adContainerEl) {
1219
1240
  adContainerEl.style.display = "none";
1220
1241
  adContainerEl.style.pointerEvents = "none";
@@ -1385,6 +1406,7 @@ function createVastAdLayer(contentVideo, options) {
1385
1406
  ];
1386
1407
  contentVideo.style.visibility = "visible";
1387
1408
  contentVideo.style.opacity = "1";
1409
+ applyContentVideoAdCoverStyles();
1388
1410
  emit("content_pause");
1389
1411
  setupAdEventListeners();
1390
1412
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1623,6 +1645,7 @@ function createVastAdLayer(contentVideo, options) {
1623
1645
  ];
1624
1646
  contentVideo.style.visibility = "visible";
1625
1647
  contentVideo.style.opacity = "1";
1648
+ applyContentVideoAdCoverStyles();
1626
1649
  emit("content_pause");
1627
1650
  setupAdEventListeners();
1628
1651
  adVolume2 = originalMutedState ? 1 : originalVolume;
@@ -1773,6 +1796,7 @@ function createVastAdLayer(contentVideo, options) {
1773
1796
  if (debug) console.log("".concat(LOG, " Stopping ad"));
1774
1797
  adPlaying = false;
1775
1798
  setAdPlayingFlag(false);
1799
+ restoreContentVideoStyles();
1776
1800
  contentVideo.muted = originalMutedState;
1777
1801
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1778
1802
  contentVideo.style.visibility = "visible";
@@ -1811,6 +1835,7 @@ function createVastAdLayer(contentVideo, options) {
1811
1835
  destroyed = true;
1812
1836
  adPlaying = false;
1813
1837
  setAdPlayingFlag(false);
1838
+ restoreContentVideoStyles();
1814
1839
  contentVideo.muted = originalMutedState;
1815
1840
  contentVideo.volume = originalVolume;
1816
1841
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -6007,6 +6032,46 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6007
6032
  return this.isLiveStream;
6008
6033
  }
6009
6034
  },
6035
+ {
6036
+ key: "getMinHlsResolution",
6037
+ value: function getMinHlsResolution() {
6038
+ var _this_hls;
6039
+ var levels = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.levels;
6040
+ if (!levels || levels.length === 0) return null;
6041
+ var min = null;
6042
+ var minPixels = Infinity;
6043
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
6044
+ try {
6045
+ for(var _iterator = levels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
6046
+ var level = _step.value;
6047
+ if (level.width && level.height) {
6048
+ var pixels = level.width * level.height;
6049
+ if (pixels < minPixels) {
6050
+ minPixels = pixels;
6051
+ min = {
6052
+ width: level.width,
6053
+ height: level.height
6054
+ };
6055
+ }
6056
+ }
6057
+ }
6058
+ } catch (err) {
6059
+ _didIteratorError = true;
6060
+ _iteratorError = err;
6061
+ } finally{
6062
+ try {
6063
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
6064
+ _iterator.return();
6065
+ }
6066
+ } finally{
6067
+ if (_didIteratorError) {
6068
+ throw _iteratorError;
6069
+ }
6070
+ }
6071
+ }
6072
+ return min;
6073
+ }
6074
+ },
6010
6075
  {
6011
6076
  key: "videoElement",
6012
6077
  get: function get() {
@@ -6069,7 +6134,322 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6069
6134
  }();
6070
6135
  // src/ui/StormcloudVideoPlayer.tsx
6071
6136
  import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress, FaSpinner } from "react-icons/fa";
6137
+ // src/ui/OverlayRenderer.tsx
6138
+ import { useEffect, useRef, useState, useCallback } from "react";
6139
+ // src/utils/overlays.ts
6140
+ var OVERLAY_API_BASE = "https://adstorm.co/api-adstorm-dev";
6141
+ function timeStringToSeconds(timeStr) {
6142
+ if (!timeStr) return 0;
6143
+ var parts = timeStr.split(":");
6144
+ if (parts.length >= 3) {
6145
+ var _parts_, _parts_1, _parts_2;
6146
+ var hours = parseInt((_parts_ = parts[0]) !== null && _parts_ !== void 0 ? _parts_ : "0", 10) || 0;
6147
+ var minutes = parseInt((_parts_1 = parts[1]) !== null && _parts_1 !== void 0 ? _parts_1 : "0", 10) || 0;
6148
+ var secStr = (_parts_2 = parts[2]) !== null && _parts_2 !== void 0 ? _parts_2 : "0";
6149
+ var dotIdx = secStr.indexOf(".");
6150
+ var seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;
6151
+ var msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : "";
6152
+ var ms = msFrag ? parseInt(msFrag.padEnd(3, "0").substring(0, 3), 10) || 0 : 0;
6153
+ return hours * 3600 + minutes * 60 + seconds + ms / 1e3;
6154
+ }
6155
+ if (parts.length === 2) {
6156
+ var _parts_3, _parts_4;
6157
+ var minutes1 = parseInt((_parts_3 = parts[0]) !== null && _parts_3 !== void 0 ? _parts_3 : "0", 10) || 0;
6158
+ var secStr1 = (_parts_4 = parts[1]) !== null && _parts_4 !== void 0 ? _parts_4 : "0";
6159
+ var dotIdx1 = secStr1.indexOf(".");
6160
+ var seconds1 = parseInt(dotIdx1 >= 0 ? secStr1.substring(0, dotIdx1) : secStr1, 10) || 0;
6161
+ var msFrag1 = dotIdx1 >= 0 ? secStr1.substring(dotIdx1 + 1) : "";
6162
+ var ms1 = msFrag1 ? parseInt(msFrag1.padEnd(3, "0").substring(0, 3), 10) || 0 : 0;
6163
+ return minutes1 * 60 + seconds1 + ms1 / 1e3;
6164
+ }
6165
+ var num = parseFloat(timeStr);
6166
+ return isFinite(num) ? Math.max(0, num) : 0;
6167
+ }
6168
+ function isOverlayActive(overlay, currentTime) {
6169
+ if (!overlay.visible) return false;
6170
+ var startSec = timeStringToSeconds(overlay.start_time);
6171
+ var durationSec = timeStringToSeconds(overlay.duration);
6172
+ if (durationSec <= 0) return false;
6173
+ return currentTime >= startSec && currentTime < startSec + durationSec;
6174
+ }
6175
+ function fetchProjectOverlays(_0) {
6176
+ return _async_to_generator(function(projectId) {
6177
+ var apiBaseUrl, response, data;
6178
+ var _arguments = arguments;
6179
+ return _ts_generator(this, function(_state) {
6180
+ switch(_state.label){
6181
+ case 0:
6182
+ apiBaseUrl = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : OVERLAY_API_BASE;
6183
+ return [
6184
+ 4,
6185
+ fetch("".concat(apiBaseUrl, "/adstorm/swirl/projects/").concat(projectId, "/overlays"))
6186
+ ];
6187
+ case 1:
6188
+ response = _state.sent();
6189
+ if (!response.ok) {
6190
+ throw new Error("Failed to fetch overlays: ".concat(response.status, " ").concat(response.statusText));
6191
+ }
6192
+ return [
6193
+ 4,
6194
+ response.json()
6195
+ ];
6196
+ case 2:
6197
+ data = _state.sent();
6198
+ return [
6199
+ 2,
6200
+ Array.isArray(data) ? data : []
6201
+ ];
6202
+ }
6203
+ });
6204
+ }).apply(this, arguments);
6205
+ }
6206
+ function resolveImageUrl(imageUrl) {
6207
+ var apiBaseUrl = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : OVERLAY_API_BASE;
6208
+ if (!imageUrl) return "";
6209
+ if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
6210
+ return imageUrl;
6211
+ }
6212
+ if (imageUrl.startsWith("/")) {
6213
+ try {
6214
+ var url = new URL(apiBaseUrl);
6215
+ return "".concat(url.origin).concat(imageUrl);
6216
+ } catch (unused) {
6217
+ return imageUrl;
6218
+ }
6219
+ }
6220
+ return "".concat(apiBaseUrl, "/").concat(imageUrl);
6221
+ }
6222
+ // src/ui/OverlayRenderer.tsx
6072
6223
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6224
+ function computeVideoDimensions(video) {
6225
+ var nativeWidth = video.videoWidth;
6226
+ var nativeHeight = video.videoHeight;
6227
+ if (!nativeWidth || !nativeHeight) return null;
6228
+ var displayWidth = video.offsetWidth;
6229
+ var displayHeight = video.offsetHeight;
6230
+ if (!displayWidth || !displayHeight) return null;
6231
+ var videoAspect = nativeWidth / nativeHeight;
6232
+ var displayAspect = displayWidth / displayHeight;
6233
+ var renderWidth;
6234
+ var renderHeight;
6235
+ var offsetX;
6236
+ var offsetY;
6237
+ if (videoAspect > displayAspect) {
6238
+ renderWidth = displayWidth;
6239
+ renderHeight = displayWidth / videoAspect;
6240
+ offsetX = 0;
6241
+ offsetY = (displayHeight - renderHeight) / 2;
6242
+ } else {
6243
+ renderHeight = displayHeight;
6244
+ renderWidth = displayHeight * videoAspect;
6245
+ offsetX = (displayWidth - renderWidth) / 2;
6246
+ offsetY = 0;
6247
+ }
6248
+ return {
6249
+ nativeWidth: nativeWidth,
6250
+ nativeHeight: nativeHeight,
6251
+ displayWidth: renderWidth,
6252
+ displayHeight: renderHeight,
6253
+ offsetX: offsetX,
6254
+ offsetY: offsetY,
6255
+ scaleX: renderWidth / nativeWidth,
6256
+ scaleY: renderHeight / nativeHeight
6257
+ };
6258
+ }
6259
+ function ImageOverlay(param) {
6260
+ var overlay = param.overlay;
6261
+ var src = resolveImageUrl(overlay.image_url || "");
6262
+ if (!src) return null;
6263
+ return /* @__PURE__ */ jsx("img", {
6264
+ src: src,
6265
+ alt: overlay.name,
6266
+ draggable: false,
6267
+ style: {
6268
+ width: "100%",
6269
+ height: "100%",
6270
+ objectFit: "contain",
6271
+ display: "block",
6272
+ pointerEvents: "none",
6273
+ userSelect: "none"
6274
+ }
6275
+ });
6276
+ }
6277
+ function TextOverlay(param) {
6278
+ var overlay = param.overlay;
6279
+ var text = overlay.content || "";
6280
+ return /* @__PURE__ */ jsx("div", {
6281
+ style: {
6282
+ width: "100%",
6283
+ height: "100%",
6284
+ display: "flex",
6285
+ alignItems: "center",
6286
+ justifyContent: "center",
6287
+ color: "#ffffff",
6288
+ fontSize: "clamp(10px, 1.4vw, 20px)",
6289
+ fontFamily: "Roboto, 'Segoe UI', Arial, sans-serif",
6290
+ fontWeight: 600,
6291
+ textAlign: "center",
6292
+ padding: "4px 8px",
6293
+ boxSizing: "border-box",
6294
+ wordBreak: "break-word",
6295
+ textShadow: "0 1px 4px rgba(0,0,0,0.7)",
6296
+ pointerEvents: "none",
6297
+ userSelect: "none",
6298
+ lineHeight: 1.3
6299
+ },
6300
+ children: text
6301
+ });
6302
+ }
6303
+ function ScrollerOverlay(param) {
6304
+ var overlay = param.overlay;
6305
+ var _ref, _ref1, _ref2, _ref3, _ref4;
6306
+ var cfg = overlay.scroller_config;
6307
+ var text = (cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && cfg.custom_text ? cfg.custom_text : overlay.content || (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text) || "";
6308
+ var scrollSpeed = (_ref = cfg === null || cfg === void 0 ? void 0 : cfg.scroll_speed) !== null && _ref !== void 0 ? _ref : 50;
6309
+ var direction = (_ref1 = cfg === null || cfg === void 0 ? void 0 : cfg.direction) !== null && _ref1 !== void 0 ? _ref1 : "left";
6310
+ var fontSize = (cfg === null || cfg === void 0 ? void 0 : cfg.font_size) ? "".concat(cfg.font_size, "px") : "clamp(10px, 1.2vw, 18px)";
6311
+ var fontFamily = (cfg === null || cfg === void 0 ? void 0 : cfg.font_family) || "Roboto, 'Segoe UI', Arial, sans-serif";
6312
+ var fontWeight = (cfg === null || cfg === void 0 ? void 0 : cfg.font_weight) || "600";
6313
+ var textColor = (cfg === null || cfg === void 0 ? void 0 : cfg.text_color) || "#ffffff";
6314
+ var bgColor = (cfg === null || cfg === void 0 ? void 0 : cfg.background_color) || "transparent";
6315
+ var bgOpacity = (cfg === null || cfg === void 0 ? void 0 : cfg.background_opacity) !== void 0 ? cfg.background_opacity / 100 : 0;
6316
+ var borderColor = (cfg === null || cfg === void 0 ? void 0 : cfg.border_color) || "transparent";
6317
+ var borderWidth = (_ref2 = cfg === null || cfg === void 0 ? void 0 : cfg.border_width) !== null && _ref2 !== void 0 ? _ref2 : 0;
6318
+ var borderRadius = (_ref3 = cfg === null || cfg === void 0 ? void 0 : cfg.border_radius) !== null && _ref3 !== void 0 ? _ref3 : 0;
6319
+ var padding = (_ref4 = cfg === null || cfg === void 0 ? void 0 : cfg.padding) !== null && _ref4 !== void 0 ? _ref4 : 4;
6320
+ var isVertical = direction === "up" || direction === "down";
6321
+ var isReverse = direction === "right" || direction === "down";
6322
+ var durationSec = Math.max(3, 120 - scrollSpeed);
6323
+ var animId = "sc-scroller-".concat(overlay.id);
6324
+ var keyframes = isVertical ? "@keyframes ".concat(animId, " {\n 0% { transform: translateY(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateY(").concat(isReverse ? "100%" : "-100%", "); }\n }") : "@keyframes ".concat(animId, " {\n 0% { transform: translateX(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateX(").concat(isReverse ? "100%" : "-100%", "); }\n }");
6325
+ return /* @__PURE__ */ jsxs(Fragment, {
6326
+ children: [
6327
+ /* @__PURE__ */ jsx("style", {
6328
+ children: keyframes
6329
+ }),
6330
+ /* @__PURE__ */ jsx("div", {
6331
+ style: {
6332
+ width: "100%",
6333
+ height: "100%",
6334
+ overflow: "hidden",
6335
+ display: "flex",
6336
+ alignItems: "center",
6337
+ backgroundColor: bgOpacity > 0 ? "rgba(".concat(hexToRgb(bgColor), ", ").concat(bgOpacity, ")") : void 0,
6338
+ border: borderWidth > 0 ? "".concat(borderWidth, "px solid ").concat(borderColor) : void 0,
6339
+ borderRadius: borderRadius > 0 ? "".concat(borderRadius, "px") : void 0,
6340
+ padding: "".concat(padding, "px"),
6341
+ boxSizing: "border-box",
6342
+ pointerEvents: "none"
6343
+ },
6344
+ children: /* @__PURE__ */ jsx("div", {
6345
+ style: {
6346
+ whiteSpace: "nowrap",
6347
+ fontSize: fontSize,
6348
+ fontFamily: fontFamily,
6349
+ fontWeight: fontWeight,
6350
+ color: textColor,
6351
+ animation: "".concat(animId, " ").concat(durationSec, "s linear infinite"),
6352
+ textShadow: "0 1px 4px rgba(0,0,0,0.5)",
6353
+ userSelect: "none"
6354
+ },
6355
+ children: text
6356
+ })
6357
+ })
6358
+ ]
6359
+ });
6360
+ }
6361
+ function hexToRgb(hex) {
6362
+ if (!hex || !hex.startsWith("#")) return "0,0,0";
6363
+ var clean = hex.slice(1);
6364
+ var num = parseInt(clean.length === 3 ? clean.replace(/./g, "$&$&") : clean, 16);
6365
+ return "".concat(num >> 16 & 255, ",").concat(num >> 8 & 255, ",").concat(num & 255);
6366
+ }
6367
+ var OverlayRenderer = function OverlayRenderer(param) {
6368
+ var overlays = param.overlays, currentTime = param.currentTime, videoRef = param.videoRef, coordinateSpace = param.coordinateSpace;
6369
+ var _useState = _sliced_to_array(useState(null), 2), dims = _useState[0], setDims = _useState[1];
6370
+ var rafRef = useRef(null);
6371
+ var updateDims = useCallback(function() {
6372
+ var video = videoRef.current;
6373
+ if (video) {
6374
+ var computed = computeVideoDimensions(video);
6375
+ setDims(function(prev) {
6376
+ if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {
6377
+ return prev;
6378
+ }
6379
+ return computed;
6380
+ });
6381
+ }
6382
+ }, [
6383
+ videoRef
6384
+ ]);
6385
+ useEffect(function() {
6386
+ updateDims();
6387
+ var interval = setInterval(updateDims, 500);
6388
+ var handleResize = function handleResize() {
6389
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
6390
+ rafRef.current = requestAnimationFrame(updateDims);
6391
+ };
6392
+ window.addEventListener("resize", handleResize);
6393
+ return function() {
6394
+ clearInterval(interval);
6395
+ window.removeEventListener("resize", handleResize);
6396
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
6397
+ };
6398
+ }, [
6399
+ updateDims
6400
+ ]);
6401
+ var activeOverlays = overlays.filter(function(o) {
6402
+ return isOverlayActive(o, currentTime);
6403
+ });
6404
+ if (!dims || activeOverlays.length === 0) return null;
6405
+ return /* @__PURE__ */ jsx("div", {
6406
+ "aria-hidden": "true",
6407
+ style: {
6408
+ position: "absolute",
6409
+ left: "".concat(dims.offsetX, "px"),
6410
+ top: "".concat(dims.offsetY, "px"),
6411
+ width: "".concat(dims.displayWidth, "px"),
6412
+ height: "".concat(dims.displayHeight, "px"),
6413
+ pointerEvents: "none",
6414
+ overflow: "hidden",
6415
+ zIndex: 8
6416
+ },
6417
+ children: activeOverlays.map(function(overlay) {
6418
+ var scaleX = (coordinateSpace === null || coordinateSpace === void 0 ? void 0 : coordinateSpace.width) ? dims.displayWidth / coordinateSpace.width : dims.scaleX;
6419
+ var scaleY = (coordinateSpace === null || coordinateSpace === void 0 ? void 0 : coordinateSpace.height) ? dims.displayHeight / coordinateSpace.height : dims.scaleY;
6420
+ var left = overlay.x * scaleX;
6421
+ var top = overlay.y * scaleY;
6422
+ var width = overlay.width * scaleX;
6423
+ var height = overlay.height * scaleY;
6424
+ var opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;
6425
+ return /* @__PURE__ */ jsxs("div", {
6426
+ style: {
6427
+ position: "absolute",
6428
+ left: "".concat(left, "px"),
6429
+ top: "".concat(top, "px"),
6430
+ width: "".concat(width, "px"),
6431
+ height: "".concat(height, "px"),
6432
+ opacity: opacity,
6433
+ zIndex: overlay.z_index,
6434
+ overflow: "hidden"
6435
+ },
6436
+ children: [
6437
+ overlay.type === "image" && /* @__PURE__ */ jsx(ImageOverlay, {
6438
+ overlay: overlay
6439
+ }),
6440
+ overlay.type === "text" && /* @__PURE__ */ jsx(TextOverlay, {
6441
+ overlay: overlay
6442
+ }),
6443
+ overlay.type === "scroller" && /* @__PURE__ */ jsx(ScrollerOverlay, {
6444
+ overlay: overlay
6445
+ })
6446
+ ]
6447
+ }, overlay.id);
6448
+ })
6449
+ });
6450
+ };
6451
+ // src/ui/StormcloudVideoPlayer.tsx
6452
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
6073
6453
  var CRITICAL_PROPS = [
6074
6454
  "src",
6075
6455
  "allowNativeHls",
@@ -6078,8 +6458,8 @@ var CRITICAL_PROPS = [
6078
6458
  "driftToleranceMs"
6079
6459
  ];
6080
6460
  var CONTROLS_HIDE_DELAY = 3e3;
6081
- var StormcloudVideoPlayerComponent = React.memo(function(props) {
6082
- 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, [
6461
+ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
6462
+ 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, [
6083
6463
  "src",
6084
6464
  "autoplay",
6085
6465
  "muted",
@@ -6106,35 +6486,38 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6106
6486
  "licenseKey",
6107
6487
  "minSegmentsBeforePlay",
6108
6488
  "disableAds",
6109
- "disableFiller"
6489
+ "disableFiller",
6490
+ "swirlProjectId"
6110
6491
  ]);
6111
- var videoRef = useRef(null);
6112
- var playerRef = useRef(null);
6113
- var bufferingTimeoutRef = useRef(null);
6114
- var controlsTimerRef = useRef(null);
6115
- var wrapperRef = useRef(null);
6116
- var _React_useState = _sliced_to_array(React.useState({
6492
+ var videoRef = useRef2(null);
6493
+ var playerRef = useRef2(null);
6494
+ var bufferingTimeoutRef = useRef2(null);
6495
+ var controlsTimerRef = useRef2(null);
6496
+ var wrapperRef = useRef2(null);
6497
+ var _React2_useState = _sliced_to_array(React2.useState({
6117
6498
  showAds: false,
6118
6499
  currentIndex: 0,
6119
6500
  totalAds: 0
6120
- }), 2), adStatus = _React_useState[0], setAdStatus = _React_useState[1];
6121
- var _React_useState1 = _sliced_to_array(React.useState(true), 2), shouldShowNativeControls = _React_useState1[0], setShouldShowNativeControls = _React_useState1[1];
6122
- var _React_useState2 = _sliced_to_array(React.useState(false), 2), isMuted = _React_useState2[0], setIsMuted = _React_useState2[1];
6123
- var _React_useState3 = _sliced_to_array(React.useState(false), 2), isFullscreen = _React_useState3[0], setIsFullscreen = _React_useState3[1];
6124
- var _React_useState4 = _sliced_to_array(React.useState(false), 2), isPlaying = _React_useState4[0], setIsPlaying = _React_useState4[1];
6125
- var _React_useState5 = _sliced_to_array(React.useState(0), 2), currentTime = _React_useState5[0], setCurrentTime = _React_useState5[1];
6126
- var _React_useState6 = _sliced_to_array(React.useState(0), 2), duration = _React_useState6[0], setDuration = _React_useState6[1];
6127
- var _React_useState7 = _sliced_to_array(React.useState(1), 2), volume = _React_useState7[0], setVolume = _React_useState7[1];
6128
- var _React_useState8 = _sliced_to_array(React.useState(1), 2), playbackRate = _React_useState8[0], setPlaybackRate = _React_useState8[1];
6129
- var _React_useState9 = _sliced_to_array(React.useState(false), 2), showVolumeSlider = _React_useState9[0], setShowVolumeSlider = _React_useState9[1];
6130
- var _React_useState10 = _sliced_to_array(React.useState(false), 2), showSpeedMenu = _React_useState10[0], setShowSpeedMenu = _React_useState10[1];
6131
- var _React_useState11 = _sliced_to_array(React.useState(true), 2), isLoading = _React_useState11[0], setIsLoading = _React_useState11[1];
6132
- var _React_useState12 = _sliced_to_array(React.useState(false), 2), isBuffering = _React_useState12[0], setIsBuffering = _React_useState12[1];
6133
- var _React_useState13 = _sliced_to_array(React.useState(false), 2), showCenterPlay = _React_useState13[0], setShowCenterPlay = _React_useState13[1];
6134
- var _React_useState14 = _sliced_to_array(React.useState(false), 2), showLicenseWarning = _React_useState14[0], setShowLicenseWarning = _React_useState14[1];
6135
- var _React_useState15 = _sliced_to_array(React.useState(true), 2), controlsVisible = _React_useState15[0], setControlsVisible = _React_useState15[1];
6136
- var _React_useState16 = _sliced_to_array(React.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _React_useState16[0], setViewportWidth = _React_useState16[1];
6137
- var _React_useState17 = _sliced_to_array(React.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _React_useState17[0], setIsPortrait = _React_useState17[1];
6501
+ }), 2), adStatus = _React2_useState[0], setAdStatus = _React2_useState[1];
6502
+ var _React2_useState1 = _sliced_to_array(React2.useState(true), 2), shouldShowNativeControls = _React2_useState1[0], setShouldShowNativeControls = _React2_useState1[1];
6503
+ var _React2_useState2 = _sliced_to_array(React2.useState(false), 2), isMuted = _React2_useState2[0], setIsMuted = _React2_useState2[1];
6504
+ var _React2_useState3 = _sliced_to_array(React2.useState(false), 2), isFullscreen = _React2_useState3[0], setIsFullscreen = _React2_useState3[1];
6505
+ var _React2_useState4 = _sliced_to_array(React2.useState(false), 2), isPlaying = _React2_useState4[0], setIsPlaying = _React2_useState4[1];
6506
+ var _React2_useState5 = _sliced_to_array(React2.useState(0), 2), currentTime = _React2_useState5[0], setCurrentTime = _React2_useState5[1];
6507
+ var _React2_useState6 = _sliced_to_array(React2.useState(0), 2), duration = _React2_useState6[0], setDuration = _React2_useState6[1];
6508
+ var _React2_useState7 = _sliced_to_array(React2.useState(1), 2), volume = _React2_useState7[0], setVolume = _React2_useState7[1];
6509
+ var _React2_useState8 = _sliced_to_array(React2.useState(1), 2), playbackRate = _React2_useState8[0], setPlaybackRate = _React2_useState8[1];
6510
+ var _React2_useState9 = _sliced_to_array(React2.useState(false), 2), showVolumeSlider = _React2_useState9[0], setShowVolumeSlider = _React2_useState9[1];
6511
+ var _React2_useState10 = _sliced_to_array(React2.useState(false), 2), showSpeedMenu = _React2_useState10[0], setShowSpeedMenu = _React2_useState10[1];
6512
+ var _React2_useState11 = _sliced_to_array(React2.useState(true), 2), isLoading = _React2_useState11[0], setIsLoading = _React2_useState11[1];
6513
+ var _React2_useState12 = _sliced_to_array(React2.useState(false), 2), isBuffering = _React2_useState12[0], setIsBuffering = _React2_useState12[1];
6514
+ var _React2_useState13 = _sliced_to_array(React2.useState(false), 2), showCenterPlay = _React2_useState13[0], setShowCenterPlay = _React2_useState13[1];
6515
+ var _React2_useState14 = _sliced_to_array(React2.useState(false), 2), showLicenseWarning = _React2_useState14[0], setShowLicenseWarning = _React2_useState14[1];
6516
+ var _React2_useState15 = _sliced_to_array(React2.useState(true), 2), controlsVisible = _React2_useState15[0], setControlsVisible = _React2_useState15[1];
6517
+ var _React2_useState16 = _sliced_to_array(React2.useState([]), 2), overlays = _React2_useState16[0], setOverlays = _React2_useState16[1];
6518
+ var _React2_useState17 = _sliced_to_array(React2.useState(null), 2), overlayCoordSpace = _React2_useState17[0], setOverlayCoordSpace = _React2_useState17[1];
6519
+ var _React2_useState18 = _sliced_to_array(React2.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _React2_useState18[0], setViewportWidth = _React2_useState18[1];
6520
+ 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];
6138
6521
  var getResponsiveScale = function getResponsiveScale() {
6139
6522
  if (viewportWidth < 480) return 0.7;
6140
6523
  if (viewportWidth < 768) return 0.8;
@@ -6142,7 +6525,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6142
6525
  return 1;
6143
6526
  };
6144
6527
  var responsiveScale = getResponsiveScale();
6145
- var resetControlsTimer = useCallback(function() {
6528
+ var resetControlsTimer = useCallback2(function() {
6146
6529
  if (controlsTimerRef.current) {
6147
6530
  clearTimeout(controlsTimerRef.current);
6148
6531
  }
@@ -6230,7 +6613,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6230
6613
  lowLatencyMode,
6231
6614
  driftToleranceMs
6232
6615
  ]);
6233
- useEffect(function() {
6616
+ useEffect2(function() {
6234
6617
  if (typeof window === "undefined") return;
6235
6618
  var el = videoRef.current;
6236
6619
  if (!el || !src) return;
@@ -6285,7 +6668,50 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6285
6668
  }, [
6286
6669
  criticalPropsKey
6287
6670
  ]);
6288
- useEffect(function() {
6671
+ useEffect2(function() {
6672
+ if (!swirlProjectId) {
6673
+ setOverlays([]);
6674
+ setOverlayCoordSpace(null);
6675
+ return;
6676
+ }
6677
+ var cancelled = false;
6678
+ fetchProjectOverlays(swirlProjectId).then(function(data) {
6679
+ if (!cancelled) setOverlays(data);
6680
+ }).catch(function(err) {
6681
+ if (!cancelled) {
6682
+ console.warn("[StormcloudVideoPlayer] Failed to fetch overlays:", err);
6683
+ }
6684
+ });
6685
+ return function() {
6686
+ cancelled = true;
6687
+ };
6688
+ }, [
6689
+ swirlProjectId
6690
+ ]);
6691
+ useEffect2(function() {
6692
+ if (!swirlProjectId) return;
6693
+ var player = playerRef.current;
6694
+ if (!player) return;
6695
+ var tryResolve = function tryResolve() {
6696
+ var res = player.getMinHlsResolution();
6697
+ if (res) {
6698
+ setOverlayCoordSpace(res);
6699
+ return true;
6700
+ }
6701
+ return false;
6702
+ };
6703
+ if (tryResolve()) return;
6704
+ var interval = setInterval(function() {
6705
+ if (tryResolve()) clearInterval(interval);
6706
+ }, 300);
6707
+ return function() {
6708
+ return clearInterval(interval);
6709
+ };
6710
+ }, [
6711
+ swirlProjectId,
6712
+ criticalPropsKey
6713
+ ]);
6714
+ useEffect2(function() {
6289
6715
  if (!playerRef.current) return;
6290
6716
  try {
6291
6717
  if (autoplay !== void 0 && playerRef.current.videoElement) {
@@ -6301,7 +6727,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6301
6727
  autoplay,
6302
6728
  muted
6303
6729
  ]);
6304
- useEffect(function() {
6730
+ useEffect2(function() {
6305
6731
  if (!playerRef.current) return;
6306
6732
  var checkAdStatus = function checkAdStatus() {
6307
6733
  if (playerRef.current) {
@@ -6331,7 +6757,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6331
6757
  return clearInterval(interval);
6332
6758
  };
6333
6759
  }, []);
6334
- useEffect(function() {
6760
+ useEffect2(function() {
6335
6761
  if (typeof window === "undefined" || !playerRef.current) return;
6336
6762
  var handleResize = function handleResize() {
6337
6763
  if (playerRef.current && videoRef.current) {
@@ -6347,7 +6773,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6347
6773
  return window.removeEventListener("resize", handleResize);
6348
6774
  };
6349
6775
  }, []);
6350
- useEffect(function() {
6776
+ useEffect2(function() {
6351
6777
  if (!playerRef.current || !videoRef.current) return;
6352
6778
  var updateStates = function updateStates() {
6353
6779
  if (playerRef.current && videoRef.current) {
@@ -6374,7 +6800,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6374
6800
  document.removeEventListener("fullscreenchange", handleFullscreenChange);
6375
6801
  };
6376
6802
  }, []);
6377
- useEffect(function() {
6803
+ useEffect2(function() {
6378
6804
  if (!videoRef.current) return;
6379
6805
  var handleCanPlay = function handleCanPlay() {
6380
6806
  setIsLoading(false);
@@ -6446,19 +6872,19 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6446
6872
  }, [
6447
6873
  debugAdTiming
6448
6874
  ]);
6449
- useEffect(function() {
6875
+ useEffect2(function() {
6450
6876
  return function() {
6451
6877
  if (controlsTimerRef.current) {
6452
6878
  clearTimeout(controlsTimerRef.current);
6453
6879
  }
6454
6880
  };
6455
6881
  }, []);
6456
- var handleWrapperMouseMove = useCallback(function() {
6882
+ var handleWrapperMouseMove = useCallback2(function() {
6457
6883
  resetControlsTimer();
6458
6884
  }, [
6459
6885
  resetControlsTimer
6460
6886
  ]);
6461
- var handleWrapperMouseLeave = useCallback(function() {
6887
+ var handleWrapperMouseLeave = useCallback2(function() {
6462
6888
  if (!showVolumeSlider && !showSpeedMenu) {
6463
6889
  setControlsVisible(false);
6464
6890
  }
@@ -6468,12 +6894,12 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6468
6894
  ]);
6469
6895
  var progressPercent = duration > 0 ? currentTime / duration * 100 : 0;
6470
6896
  var VolumeIcon = isMuted || volume === 0 ? FaVolumeMute : volume < 0.5 ? FaVolumeDown : FaVolumeUp;
6471
- return /* @__PURE__ */ jsxs(Fragment, {
6897
+ return /* @__PURE__ */ jsxs2(Fragment2, {
6472
6898
  children: [
6473
- /* @__PURE__ */ jsx("style", {
6899
+ /* @__PURE__ */ jsx2("style", {
6474
6900
  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 "
6475
6901
  }),
6476
- /* @__PURE__ */ jsxs("div", {
6902
+ /* @__PURE__ */ jsxs2("div", {
6477
6903
  ref: wrapperRef,
6478
6904
  className: "sc-wrapper ".concat(wrapperClassName || ""),
6479
6905
  onMouseMove: handleWrapperMouseMove,
@@ -6497,10 +6923,12 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6497
6923
  boxShadow: isFullscreen ? "none" : void 0
6498
6924
  }, wrapperStyle),
6499
6925
  children: [
6500
- /* @__PURE__ */ jsx("video", _object_spread_props(_object_spread({
6926
+ /* @__PURE__ */ jsx2("video", _object_spread_props(_object_spread({
6501
6927
  ref: videoRef,
6502
6928
  className: className,
6503
6929
  style: _object_spread({
6930
+ position: "relative",
6931
+ zIndex: 1,
6504
6932
  display: "block",
6505
6933
  width: "100%",
6506
6934
  height: isFullscreen ? "100%" : "auto",
@@ -6517,7 +6945,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6517
6945
  }, restVideoAttrs), {
6518
6946
  children: children
6519
6947
  })),
6520
- (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsx(FaSpinner, {
6948
+ overlays.length > 0 && !adStatus.showAds && /* @__PURE__ */ jsx2(OverlayRenderer, {
6949
+ overlays: overlays,
6950
+ currentTime: currentTime,
6951
+ videoRef: videoRef,
6952
+ coordinateSpace: overlayCoordSpace
6953
+ }),
6954
+ (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ jsx2(FaSpinner, {
6521
6955
  className: "sc-loading-indicator",
6522
6956
  size: 40,
6523
6957
  color: "rgba(255, 255, 255, 0.85)",
@@ -6530,7 +6964,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6530
6964
  filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
6531
6965
  }
6532
6966
  }),
6533
- showLicenseWarning && /* @__PURE__ */ jsxs("div", {
6967
+ showLicenseWarning && /* @__PURE__ */ jsxs2("div", {
6534
6968
  style: {
6535
6969
  position: "absolute",
6536
6970
  top: "50%",
@@ -6549,7 +6983,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6549
6983
  margin: "0 16px"
6550
6984
  },
6551
6985
  children: [
6552
- /* @__PURE__ */ jsx("div", {
6986
+ /* @__PURE__ */ jsx2("div", {
6553
6987
  style: {
6554
6988
  fontSize: "18px",
6555
6989
  fontWeight: "700",
@@ -6558,7 +6992,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6558
6992
  },
6559
6993
  children: "License Key Required"
6560
6994
  }),
6561
- /* @__PURE__ */ jsxs("div", {
6995
+ /* @__PURE__ */ jsxs2("div", {
6562
6996
  style: {
6563
6997
  fontSize: "13px",
6564
6998
  lineHeight: "1.6",
@@ -6566,13 +7000,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6566
7000
  },
6567
7001
  children: [
6568
7002
  "Please provide a valid license key to use the Stormcloud Video Player.",
6569
- /* @__PURE__ */ jsx("br", {}),
7003
+ /* @__PURE__ */ jsx2("br", {}),
6570
7004
  "Contact your administrator for licensing information."
6571
7005
  ]
6572
7006
  })
6573
7007
  ]
6574
7008
  }),
6575
- showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ jsx("div", {
7009
+ showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ jsx2("div", {
6576
7010
  onClick: handleCenterPlayClick,
6577
7011
  style: {
6578
7012
  position: "absolute",
@@ -6607,7 +7041,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6607
7041
  el.style.transform = "translate(-50%, -50%) scale(1)";
6608
7042
  },
6609
7043
  title: "Play",
6610
- children: /* @__PURE__ */ jsx(FaPlay, {
7044
+ children: /* @__PURE__ */ jsx2(FaPlay, {
6611
7045
  size: Math.max(22, 28 * responsiveScale),
6612
7046
  color: "white",
6613
7047
  style: {
@@ -6616,7 +7050,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6616
7050
  }
6617
7051
  })
6618
7052
  }),
6619
- adStatus.showAds && /* @__PURE__ */ jsxs("div", {
7053
+ adStatus.showAds && /* @__PURE__ */ jsxs2("div", {
6620
7054
  style: {
6621
7055
  position: "absolute",
6622
7056
  top: "".concat(12 * responsiveScale, "px"),
@@ -6628,7 +7062,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6628
7062
  animation: "sc-fade-in 0.3s ease"
6629
7063
  },
6630
7064
  children: [
6631
- /* @__PURE__ */ jsx("div", {
7065
+ /* @__PURE__ */ jsx2("div", {
6632
7066
  style: {
6633
7067
  background: "rgba(234, 179, 8, 0.9)",
6634
7068
  backdropFilter: "blur(12px)",
@@ -6643,7 +7077,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6643
7077
  },
6644
7078
  children: "Ad"
6645
7079
  }),
6646
- adStatus.currentIndex > 0 && /* @__PURE__ */ jsxs("div", {
7080
+ adStatus.currentIndex > 0 && /* @__PURE__ */ jsxs2("div", {
6647
7081
  style: {
6648
7082
  background: "rgba(0, 0, 0, 0.5)",
6649
7083
  backdropFilter: "blur(12px)",
@@ -6662,7 +7096,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6662
7096
  })
6663
7097
  ]
6664
7098
  }),
6665
- shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ jsxs("div", {
7099
+ shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ jsxs2("div", {
6666
7100
  className: "sc-controls-bar",
6667
7101
  style: {
6668
7102
  position: "absolute",
@@ -6677,7 +7111,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6677
7111
  pointerEvents: controlsVisible || adStatus.showAds ? "auto" : "none"
6678
7112
  },
6679
7113
  children: [
6680
- /* @__PURE__ */ jsxs("div", {
7114
+ /* @__PURE__ */ jsxs2("div", {
6681
7115
  className: "sc-progress-track",
6682
7116
  style: {
6683
7117
  width: "100%",
@@ -6697,7 +7131,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6697
7131
  e.currentTarget.style.height = "3px";
6698
7132
  },
6699
7133
  children: [
6700
- /* @__PURE__ */ jsx("div", {
7134
+ /* @__PURE__ */ jsx2("div", {
6701
7135
  style: {
6702
7136
  position: "absolute",
6703
7137
  top: 0,
@@ -6709,7 +7143,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6709
7143
  transition: "width 0.15s linear"
6710
7144
  }
6711
7145
  }),
6712
- /* @__PURE__ */ jsx("div", {
7146
+ /* @__PURE__ */ jsx2("div", {
6713
7147
  className: "sc-progress-thumb",
6714
7148
  style: {
6715
7149
  position: "absolute",
@@ -6726,7 +7160,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6726
7160
  })
6727
7161
  ]
6728
7162
  }),
6729
- /* @__PURE__ */ jsxs("div", {
7163
+ /* @__PURE__ */ jsxs2("div", {
6730
7164
  style: {
6731
7165
  display: "flex",
6732
7166
  alignItems: "center",
@@ -6735,14 +7169,14 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6735
7169
  gap: "".concat(8 * responsiveScale, "px")
6736
7170
  },
6737
7171
  children: [
6738
- /* @__PURE__ */ jsxs("div", {
7172
+ /* @__PURE__ */ jsxs2("div", {
6739
7173
  style: {
6740
7174
  display: "flex",
6741
7175
  alignItems: "center",
6742
7176
  gap: "".concat(8 * responsiveScale, "px")
6743
7177
  },
6744
7178
  children: [
6745
- /* @__PURE__ */ jsx("button", {
7179
+ /* @__PURE__ */ jsx2("button", {
6746
7180
  className: "sc-ctrl-btn",
6747
7181
  onClick: handlePlayPause,
6748
7182
  style: {
@@ -6752,16 +7186,16 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6752
7186
  minHeight: "".concat(36 * responsiveScale, "px")
6753
7187
  },
6754
7188
  title: isPlaying ? "Pause" : "Play",
6755
- children: isPlaying ? /* @__PURE__ */ jsx(FaPause, {
7189
+ children: isPlaying ? /* @__PURE__ */ jsx2(FaPause, {
6756
7190
  size: Math.max(14, 18 * responsiveScale)
6757
- }) : /* @__PURE__ */ jsx(FaPlay, {
7191
+ }) : /* @__PURE__ */ jsx2(FaPlay, {
6758
7192
  size: Math.max(14, 18 * responsiveScale),
6759
7193
  style: {
6760
7194
  marginLeft: "2px"
6761
7195
  }
6762
7196
  })
6763
7197
  }),
6764
- /* @__PURE__ */ jsxs("div", {
7198
+ /* @__PURE__ */ jsxs2("div", {
6765
7199
  style: {
6766
7200
  display: "flex",
6767
7201
  alignItems: "center"
@@ -6773,7 +7207,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6773
7207
  return setShowVolumeSlider(false);
6774
7208
  },
6775
7209
  children: [
6776
- /* @__PURE__ */ jsx("button", {
7210
+ /* @__PURE__ */ jsx2("button", {
6777
7211
  className: "sc-ctrl-btn",
6778
7212
  onClick: function onClick() {
6779
7213
  if (playerRef.current) {
@@ -6789,11 +7223,11 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6789
7223
  minHeight: "".concat(36 * responsiveScale, "px")
6790
7224
  },
6791
7225
  title: isMuted ? "Unmute" : "Mute",
6792
- children: /* @__PURE__ */ jsx(VolumeIcon, {
7226
+ children: /* @__PURE__ */ jsx2(VolumeIcon, {
6793
7227
  size: Math.max(14, 18 * responsiveScale)
6794
7228
  })
6795
7229
  }),
6796
- /* @__PURE__ */ jsx("div", {
7230
+ /* @__PURE__ */ jsx2("div", {
6797
7231
  style: {
6798
7232
  width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
6799
7233
  overflow: "hidden",
@@ -6803,7 +7237,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6803
7237
  paddingLeft: showVolumeSlider ? "2px" : "0",
6804
7238
  paddingRight: showVolumeSlider ? "4px" : "0"
6805
7239
  },
6806
- children: /* @__PURE__ */ jsxs("div", {
7240
+ children: /* @__PURE__ */ jsxs2("div", {
6807
7241
  style: {
6808
7242
  position: "relative",
6809
7243
  width: "".concat(56 * responsiveScale, "px"),
@@ -6833,7 +7267,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6833
7267
  handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
6834
7268
  },
6835
7269
  children: [
6836
- /* @__PURE__ */ jsx("div", {
7270
+ /* @__PURE__ */ jsx2("div", {
6837
7271
  style: {
6838
7272
  position: "absolute",
6839
7273
  inset: 0,
@@ -6841,7 +7275,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6841
7275
  borderRadius: "1.5px"
6842
7276
  }
6843
7277
  }),
6844
- /* @__PURE__ */ jsx("div", {
7278
+ /* @__PURE__ */ jsx2("div", {
6845
7279
  style: {
6846
7280
  position: "absolute",
6847
7281
  top: 0,
@@ -6853,7 +7287,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6853
7287
  transition: "width 0.1s ease-out"
6854
7288
  }
6855
7289
  }),
6856
- /* @__PURE__ */ jsx("div", {
7290
+ /* @__PURE__ */ jsx2("div", {
6857
7291
  style: {
6858
7292
  position: "absolute",
6859
7293
  top: "50%",
@@ -6872,7 +7306,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6872
7306
  })
6873
7307
  ]
6874
7308
  }),
6875
- /* @__PURE__ */ jsxs("div", {
7309
+ /* @__PURE__ */ jsxs2("div", {
6876
7310
  style: {
6877
7311
  fontSize: "".concat(13 * responsiveScale, "px"),
6878
7312
  fontFamily: "Roboto, 'Segoe UI', Arial, sans-serif",
@@ -6885,7 +7319,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6885
7319
  children: [
6886
7320
  formatTime(currentTime),
6887
7321
  " ",
6888
- /* @__PURE__ */ jsx("span", {
7322
+ /* @__PURE__ */ jsx2("span", {
6889
7323
  style: {
6890
7324
  color: "rgba(255,255,255,0.5)"
6891
7325
  },
@@ -6897,20 +7331,20 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6897
7331
  })
6898
7332
  ]
6899
7333
  }),
6900
- /* @__PURE__ */ jsxs("div", {
7334
+ /* @__PURE__ */ jsxs2("div", {
6901
7335
  style: {
6902
7336
  display: "flex",
6903
7337
  alignItems: "center",
6904
7338
  gap: "".concat(8 * responsiveScale, "px")
6905
7339
  },
6906
7340
  children: [
6907
- /* @__PURE__ */ jsxs("div", {
7341
+ /* @__PURE__ */ jsxs2("div", {
6908
7342
  style: {
6909
7343
  position: "relative",
6910
7344
  display: viewportWidth < 600 ? "none" : "block"
6911
7345
  },
6912
7346
  children: [
6913
- /* @__PURE__ */ jsxs("button", {
7347
+ /* @__PURE__ */ jsxs2("button", {
6914
7348
  className: "sc-ctrl-btn",
6915
7349
  onClick: function onClick() {
6916
7350
  setShowSpeedMenu(!showSpeedMenu);
@@ -6930,7 +7364,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6930
7364
  "x"
6931
7365
  ]
6932
7366
  }),
6933
- showSpeedMenu && /* @__PURE__ */ jsx("div", {
7367
+ showSpeedMenu && /* @__PURE__ */ jsx2("div", {
6934
7368
  style: {
6935
7369
  position: "absolute",
6936
7370
  bottom: "100%",
@@ -6956,7 +7390,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6956
7390
  1.75,
6957
7391
  2
6958
7392
  ].map(function(speed) {
6959
- return /* @__PURE__ */ jsxs("button", {
7393
+ return /* @__PURE__ */ jsxs2("button", {
6960
7394
  onClick: function onClick() {
6961
7395
  return handlePlaybackRateChange(speed);
6962
7396
  },
@@ -6995,7 +7429,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
6995
7429
  })
6996
7430
  ]
6997
7431
  }),
6998
- /* @__PURE__ */ jsx("button", {
7432
+ /* @__PURE__ */ jsx2("button", {
6999
7433
  className: "sc-ctrl-btn",
7000
7434
  onClick: function onClick() {
7001
7435
  if (onFullscreenToggle) {
@@ -7016,9 +7450,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7016
7450
  minHeight: "".concat(36 * responsiveScale, "px")
7017
7451
  },
7018
7452
  title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
7019
- children: isFullscreen ? /* @__PURE__ */ jsx(FaCompress, {
7453
+ children: isFullscreen ? /* @__PURE__ */ jsx2(FaCompress, {
7020
7454
  size: Math.max(14, 18 * responsiveScale)
7021
- }) : /* @__PURE__ */ jsx(FaExpand, {
7455
+ }) : /* @__PURE__ */ jsx2(FaExpand, {
7022
7456
  size: Math.max(14, 18 * responsiveScale)
7023
7457
  })
7024
7458
  })
@@ -7027,7 +7461,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7027
7461
  ]
7028
7462
  })
7029
7463
  ]
7030
- }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ jsxs("div", {
7464
+ }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ jsxs2("div", {
7031
7465
  className: "sc-controls-bar",
7032
7466
  style: {
7033
7467
  position: "absolute",
@@ -7042,7 +7476,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7042
7476
  pointerEvents: controlsVisible ? "auto" : "none"
7043
7477
  },
7044
7478
  children: [
7045
- /* @__PURE__ */ jsxs("div", {
7479
+ /* @__PURE__ */ jsxs2("div", {
7046
7480
  style: {
7047
7481
  display: "flex",
7048
7482
  alignItems: "center",
@@ -7057,7 +7491,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7057
7491
  return setShowVolumeSlider(false);
7058
7492
  },
7059
7493
  children: [
7060
- /* @__PURE__ */ jsx("button", {
7494
+ /* @__PURE__ */ jsx2("button", {
7061
7495
  className: "sc-ctrl-btn",
7062
7496
  onClick: function onClick() {
7063
7497
  if (playerRef.current) playerRef.current.toggleMute();
@@ -7071,11 +7505,11 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7071
7505
  minHeight: "".concat(36 * responsiveScale, "px")
7072
7506
  },
7073
7507
  title: isMuted ? "Unmute" : "Mute",
7074
- children: /* @__PURE__ */ jsx(VolumeIcon, {
7508
+ children: /* @__PURE__ */ jsx2(VolumeIcon, {
7075
7509
  size: Math.max(14, 18 * responsiveScale)
7076
7510
  })
7077
7511
  }),
7078
- /* @__PURE__ */ jsx("div", {
7512
+ /* @__PURE__ */ jsx2("div", {
7079
7513
  style: {
7080
7514
  width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
7081
7515
  overflow: "hidden",
@@ -7085,7 +7519,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7085
7519
  paddingLeft: showVolumeSlider ? "2px" : "0",
7086
7520
  paddingRight: showVolumeSlider ? "6px" : "0"
7087
7521
  },
7088
- children: /* @__PURE__ */ jsxs("div", {
7522
+ children: /* @__PURE__ */ jsxs2("div", {
7089
7523
  style: {
7090
7524
  position: "relative",
7091
7525
  width: "".concat(56 * responsiveScale, "px"),
@@ -7115,7 +7549,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7115
7549
  handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
7116
7550
  },
7117
7551
  children: [
7118
- /* @__PURE__ */ jsx("div", {
7552
+ /* @__PURE__ */ jsx2("div", {
7119
7553
  style: {
7120
7554
  position: "absolute",
7121
7555
  inset: 0,
@@ -7123,7 +7557,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7123
7557
  borderRadius: "1.5px"
7124
7558
  }
7125
7559
  }),
7126
- /* @__PURE__ */ jsx("div", {
7560
+ /* @__PURE__ */ jsx2("div", {
7127
7561
  style: {
7128
7562
  position: "absolute",
7129
7563
  top: 0,
@@ -7135,7 +7569,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7135
7569
  transition: "width 0.1s ease-out"
7136
7570
  }
7137
7571
  }),
7138
- /* @__PURE__ */ jsx("div", {
7572
+ /* @__PURE__ */ jsx2("div", {
7139
7573
  style: {
7140
7574
  position: "absolute",
7141
7575
  top: "50%",
@@ -7154,7 +7588,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7154
7588
  })
7155
7589
  ]
7156
7590
  }),
7157
- /* @__PURE__ */ jsx("button", {
7591
+ /* @__PURE__ */ jsx2("button", {
7158
7592
  className: "sc-ctrl-btn",
7159
7593
  onClick: function onClick() {
7160
7594
  if (onFullscreenToggle) {
@@ -7176,15 +7610,15 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7176
7610
  background: "rgba(0, 0, 0, 0.6)"
7177
7611
  },
7178
7612
  title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
7179
- children: isFullscreen ? /* @__PURE__ */ jsx(FaCompress, {
7613
+ children: isFullscreen ? /* @__PURE__ */ jsx2(FaCompress, {
7180
7614
  size: Math.max(14, 18 * responsiveScale)
7181
- }) : /* @__PURE__ */ jsx(FaExpand, {
7615
+ }) : /* @__PURE__ */ jsx2(FaExpand, {
7182
7616
  size: Math.max(14, 18 * responsiveScale)
7183
7617
  })
7184
7618
  })
7185
7619
  ]
7186
7620
  }),
7187
- onControlClick && /* @__PURE__ */ jsx("div", {
7621
+ onControlClick && /* @__PURE__ */ jsx2("div", {
7188
7622
  onClick: onControlClick,
7189
7623
  style: {
7190
7624
  position: "absolute",
@@ -7235,7 +7669,8 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7235
7669
  "playsInline",
7236
7670
  "preload",
7237
7671
  "poster",
7238
- "children"
7672
+ "children",
7673
+ "swirlProjectId"
7239
7674
  ];
7240
7675
  var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
7241
7676
  try {
@@ -7290,7 +7725,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
7290
7725
  return true;
7291
7726
  });
7292
7727
  // src/StormcloudPlayer.tsx
7293
- import React3, { Component as Component4, Suspense } from "react";
7728
+ import React4, { Component as Component4, Suspense } from "react";
7294
7729
  // src/props.ts
7295
7730
  var noop = function noop() {};
7296
7731
  var defaultProps = {
@@ -7971,7 +8406,7 @@ var players = [
7971
8406
  ];
7972
8407
  var players_default = players;
7973
8408
  // src/Player.tsx
7974
- import React2, { Component as Component3 } from "react";
8409
+ import React3, { Component as Component3 } from "react";
7975
8410
  var SEEK_ON_PLAY_EXPIRY = 5e3;
7976
8411
  var Player = /*#__PURE__*/ function(Component3) {
7977
8412
  "use strict";
@@ -8220,7 +8655,7 @@ var Player = /*#__PURE__*/ function(Component3) {
8220
8655
  if (!Player2) {
8221
8656
  return null;
8222
8657
  }
8223
- return React2.createElement(Player2, _object_spread_props(_object_spread({}, this.props), {
8658
+ return React3.createElement(Player2, _object_spread_props(_object_spread({}, this.props), {
8224
8659
  onMount: this.handlePlayerMount,
8225
8660
  onReady: this.handleReady,
8226
8661
  onPlay: this.handlePlay,
@@ -8367,7 +8802,7 @@ var createStormcloudPlayer = function createStormcloudPlayer(playerList, fallbac
8367
8802
  if (!src) return null;
8368
8803
  var activePlayer = _this.getActivePlayer(src);
8369
8804
  if (!activePlayer) return null;
8370
- return React3.createElement(Player, _object_spread_props(_object_spread({}, _this.props), {
8805
+ return React4.createElement(Player, _object_spread_props(_object_spread({}, _this.props), {
8371
8806
  key: activePlayer.key,
8372
8807
  ref: _this.references.player,
8373
8808
  activePlayer: activePlayer.lazyPlayer || activePlayer,
@@ -8383,13 +8818,13 @@ var createStormcloudPlayer = function createStormcloudPlayer(playerList, fallbac
8383
8818
  var _this_props = this.props, src = _this_props.src, style = _this_props.style, width = _this_props.width, height = _this_props.height, fallbackElement = _this_props.fallback, Wrapper = _this_props.wrapper;
8384
8819
  var attributes = this.getAttributes(src);
8385
8820
  var wrapperRef = typeof Wrapper === "string" ? this.references.wrapper : void 0;
8386
- return React3.createElement(Wrapper, _object_spread({
8821
+ return React4.createElement(Wrapper, _object_spread({
8387
8822
  ref: wrapperRef,
8388
8823
  style: _object_spread_props(_object_spread({}, style), {
8389
8824
  width: width,
8390
8825
  height: height
8391
8826
  })
8392
- }, attributes), React3.createElement(UniversalSuspense, {
8827
+ }, attributes), React4.createElement(UniversalSuspense, {
8393
8828
  fallback: fallbackElement
8394
8829
  }, this.renderActivePlayer(src)));
8395
8830
  }
@@ -8455,5 +8890,5 @@ var createStormcloudPlayer = function createStormcloudPlayer(playerList, fallbac
8455
8890
  };
8456
8891
  var StormcloudPlayer = createStormcloudPlayer(players_default, players_default[players_default.length - 1]);
8457
8892
  var StormcloudPlayer_default = StormcloudPlayer;
8458
- export { IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, canPlay, createStormcloudPlayer, createVastAdLayer, createVastManager, StormcloudVideoPlayerComponent as default, detectBrowser, getBrowserConfigOverrides, getBrowserID, getClientInfo, initializePolyfills, isMediaStream, lazy, logBrowserInfo, merge, omit, parseQuery, players_default as players, randomString, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode };
8893
+ export { IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, canPlay, createStormcloudPlayer, createVastAdLayer, createVastManager, StormcloudVideoPlayerComponent as default, detectBrowser, fetchProjectOverlays, getBrowserConfigOverrides, getBrowserID, getClientInfo, initializePolyfills, isMediaStream, isOverlayActive, lazy, logBrowserInfo, merge, omit, parseQuery, players_default as players, randomString, resolveImageUrl, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode, timeStringToSeconds };
8459
8894
  //# sourceMappingURL=index.js.map