stormcloud-video-player 0.8.22 → 0.8.23

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.
@@ -2354,12 +2354,14 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
2354
2354
  "adid"
2355
2355
  ]);
2356
2356
  function resolveVastEnvironmentSignals(isCtv) {
2357
- var _ref, _bridgeSignals_limitAdTracking;
2357
+ var _ref;
2358
2358
  var bridgeSignals = readNativeBridgeSignals();
2359
+ var platformDevice = readPlatformNativeDeviceId();
2359
2360
  var lg = isCtv && isLgWebOS();
2360
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || (lg ? getLgTestDeviceId() : void 0);
2361
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2362
- var limitAdTracking = deviceId != null ? (_ref = (_bridgeSignals_limitAdTracking = bridgeSignals.limitAdTracking) !== null && _bridgeSignals_limitAdTracking !== void 0 ? _bridgeSignals_limitAdTracking : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2361
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2362
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2363
+ var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2364
+ var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2363
2365
  if (isCtv) {
2364
2366
  return _object_spread_props(_object_spread({
2365
2367
  isCtv: true,
@@ -2430,6 +2432,72 @@ function createUuid() {
2430
2432
  return nibble.toString(16);
2431
2433
  });
2432
2434
  }
2435
+ function readPlatformNativeDeviceId() {
2436
+ if (typeof window === "undefined") return {};
2437
+ try {
2438
+ var _window_webapis;
2439
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
2440
+ if (adinfo) {
2441
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
2442
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
2443
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
2444
+ return _object_spread({
2445
+ deviceId: tifa,
2446
+ deviceIdType: "tifa"
2447
+ }, typeof lat === "boolean" ? {
2448
+ limitAdTracking: lat
2449
+ } : {});
2450
+ }
2451
+ }
2452
+ } catch (unused) {}
2453
+ try {
2454
+ var webOSDev = window.webOSDev;
2455
+ if (webOSDev) {
2456
+ var _webOSDev_lgudid;
2457
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
2458
+ if (typeof lgudid === "string" && lgudid) {
2459
+ if (isZeroedAdId(lgudid)) {
2460
+ return {
2461
+ deviceIdType: "lgudid",
2462
+ limitAdTracking: true
2463
+ };
2464
+ }
2465
+ if (!isMacroPlaceholder(lgudid)) {
2466
+ return {
2467
+ deviceId: lgudid,
2468
+ deviceIdType: "lgudid",
2469
+ limitAdTracking: false
2470
+ };
2471
+ }
2472
+ }
2473
+ }
2474
+ } catch (unused) {}
2475
+ try {
2476
+ var roku = window.Roku;
2477
+ if (roku) {
2478
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
2479
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
2480
+ return {
2481
+ deviceId: rida,
2482
+ deviceIdType: "rida",
2483
+ limitAdTracking: false
2484
+ };
2485
+ }
2486
+ }
2487
+ } catch (unused) {}
2488
+ return {};
2489
+ }
2490
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
2491
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
2492
+ "00000000-0000-0000-0000-000000000000"
2493
+ ]);
2494
+ function isMacroPlaceholder(value) {
2495
+ var t = value.trim();
2496
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2497
+ }
2498
+ function isZeroedAdId(value) {
2499
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2500
+ }
2433
2501
  function readNativeBridgeSignals() {
2434
2502
  if (typeof window === "undefined") {
2435
2503
  return {};
@@ -2770,7 +2838,7 @@ var INLINE_DEVICE_MACRO_REPLACEMENTS = [
2770
2838
  }
2771
2839
  }
2772
2840
  ];
2773
- function isMacroPlaceholder(value) {
2841
+ function isMacroPlaceholder2(value) {
2774
2842
  if (value == null) return true;
2775
2843
  var trimmed = value.trim();
2776
2844
  if (!trimmed) return true;
@@ -2829,11 +2897,11 @@ function applyDeviceIdentityParams(params, ctx) {
2829
2897
  if (runtimeId) {
2830
2898
  params.set("rdid", runtimeId);
2831
2899
  params.set("idtype", runtimeType || tagType || "aaid");
2832
- params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder(tagLat) ? "0" : tagLat);
2900
+ params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder2(tagLat) ? "0" : tagLat);
2833
2901
  return;
2834
2902
  }
2835
- var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));
2836
- var tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));
2903
+ var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));
2904
+ var tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));
2837
2905
  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {
2838
2906
  params.delete("rdid");
2839
2907
  params.delete("idtype");
@@ -2841,10 +2909,10 @@ function applyDeviceIdentityParams(params, ctx) {
2841
2909
  return;
2842
2910
  }
2843
2911
  if (tagRdidValid) {
2844
- if (isMacroPlaceholder(tagType) && runtimeType) {
2912
+ if (isMacroPlaceholder2(tagType) && runtimeType) {
2845
2913
  params.set("idtype", runtimeType);
2846
2914
  }
2847
- if (isMacroPlaceholder(tagLat)) {
2915
+ if (isMacroPlaceholder2(tagLat)) {
2848
2916
  params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : "0");
2849
2917
  }
2850
2918
  return;
@@ -3030,7 +3098,7 @@ function applyVastMacros(baseUrl, ctx) {
3030
3098
  }
3031
3099
  var staleKeys = [];
3032
3100
  params.forEach(function(value, key) {
3033
- if (isMacroPlaceholder(value)) {
3101
+ if (isMacroPlaceholder2(value)) {
3034
3102
  staleKeys.push(key);
3035
3103
  }
3036
3104
  });
@@ -5979,7 +6047,7 @@ var HlsEngine = /*#__PURE__*/ function() {
5979
6047
  key: "setupNativeHls",
5980
6048
  value: function setupNativeHls() {
5981
6049
  return _async_to_generator(function() {
5982
- var _this_config_isLiveStream, _this_config_lowLatencyMode, _this_video_play;
6050
+ var _this_config_isLiveStream, _this_config_lowLatencyMode, adBehavior, _this_video_play;
5983
6051
  return _ts_generator(this, function(_state) {
5984
6052
  switch(_state.label){
5985
6053
  case 0:
@@ -5988,10 +6056,11 @@ var HlsEngine = /*#__PURE__*/ function() {
5988
6056
  this.video.src = this.config.src;
5989
6057
  this.isLiveStream = (_this_config_isLiveStream = this.config.isLiveStream) !== null && _this_config_isLiveStream !== void 0 ? _this_config_isLiveStream : (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false;
5990
6058
  if (this.debug) {
5991
- console.log("[StormcloudVideoPlayer] Using native HLS playback - VOD mode:", {
6059
+ adBehavior = this.isLiveStream ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
6060
+ console.log("[StormcloudVideoPlayer] Using native HLS playback:", {
5992
6061
  isLive: this.isLiveStream,
5993
6062
  allowNativeHls: this.config.allowNativeHls,
5994
- adBehavior: "vod (main video pauses during ads)"
6063
+ adBehavior: adBehavior
5995
6064
  });
5996
6065
  }
5997
6066
  if (!this.config.autoplay) return [
@@ -6400,6 +6469,14 @@ var HlsEngine = /*#__PURE__*/ function() {
6400
6469
  });
6401
6470
  }
6402
6471
  },
6472
+ {
6473
+ key: "getLiveSyncPosition",
6474
+ value: function getLiveSyncPosition() {
6475
+ var _this_hls;
6476
+ var pos = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.liveSyncPosition;
6477
+ return typeof pos === "number" && Number.isFinite(pos) ? pos : void 0;
6478
+ }
6479
+ },
6403
6480
  {
6404
6481
  key: "destroy",
6405
6482
  value: function destroy() {
@@ -7974,6 +8051,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
7974
8051
  this.host.video.volume = restoredVolume;
7975
8052
  }
7976
8053
  if (this.host.shouldContinueLiveStreamDuringAds()) {
8054
+ var liveSyncPos = this.host.getLiveSyncPosition();
8055
+ if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
8056
+ if (this.debug) {
8057
+ console.log("[StormcloudVideoPlayer] Live break end — snapping to live edge: ".concat(this.host.video.currentTime.toFixed(2), "s → ").concat(liveSyncPos.toFixed(2), "s"));
8058
+ }
8059
+ this.host.video.currentTime = liveSyncPos;
8060
+ }
7977
8061
  if (this.host.video.paused) {
7978
8062
  var _this_host_video_play;
7979
8063
  if (this.debug) console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
@@ -8116,6 +8200,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8116
8200
  shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
8117
8201
  return _this.shouldContinueLiveStreamDuringAds();
8118
8202
  },
8203
+ getLiveSyncPosition: function getLiveSyncPosition() {
8204
+ return _this.hlsEngine.getLiveSyncPosition();
8205
+ },
8119
8206
  generateVastUrls: function generateVastUrls(base, count) {
8120
8207
  return _this.generateVastUrls(base, count);
8121
8208
  }
@@ -8157,7 +8244,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8157
8244
  // ───────────────────────────────────────────────────────────────
8158
8245
  function load() {
8159
8246
  return _async_to_generator(function() {
8160
- var _this, _this_config_lowLatencyMode, error;
8247
+ var _this, _this_config_lowLatencyMode, error, continueLiveStreamDuringAds;
8161
8248
  return _ts_generator(this, function(_state) {
8162
8249
  switch(_state.label){
8163
8250
  case 0:
@@ -8211,15 +8298,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8211
8298
  3,
8212
8299
  6
8213
8300
  ];
8214
- this.adPlayer.destroy();
8215
- this.adPlayer = this.createAdPlayer(false);
8216
- this.adPlayer.initialize();
8217
8301
  return [
8218
8302
  4,
8219
8303
  this.hlsEngine.setupNativeHls()
8220
8304
  ];
8221
8305
  case 5:
8222
8306
  _state.sent();
8307
+ continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
8308
+ if (this.debug) {
8309
+ console.log("[StormcloudVideoPlayer] Native HLS ad behavior:", {
8310
+ isLive: this.hlsEngine.isLiveStream,
8311
+ continueLiveStreamDuringAds: continueLiveStreamDuringAds
8312
+ });
8313
+ }
8314
+ this.adPlayer.destroy();
8315
+ this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);
8316
+ this.adPlayer.initialize();
8223
8317
  return [
8224
8318
  2
8225
8319
  ];
@@ -8327,9 +8421,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8327
8421
  {
8328
8422
  key: "shouldContinueLiveStreamDuringAds",
8329
8423
  value: function shouldContinueLiveStreamDuringAds() {
8330
- if (this.config.allowNativeHls) return false;
8331
- if (!this.hlsEngine.isLiveStream) return false;
8332
- return true;
8424
+ if (this.hlsEngine.isLiveStream) {
8425
+ return true;
8426
+ }
8427
+ var duration = this.video.duration;
8428
+ if (!Number.isFinite(duration) || duration === Infinity) {
8429
+ return true;
8430
+ }
8431
+ return false;
8333
8432
  }
8334
8433
  },
8335
8434
  {
@@ -8627,9 +8726,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8627
8726
  this.adBreak.showAds = true;
8628
8727
  this.adBreak.inAdBreak = true;
8629
8728
  this.timing.currentAdBreakStartWallClockMs = Date.now();
8630
- if (!this.video.paused) {
8631
- this.video.pause();
8632
- }
8633
8729
  _state.label = 1;
8634
8730
  case 1:
8635
8731
  _state.trys.push([
@@ -9003,7 +9099,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
9003
9099
  setShowSpeedMenu(false);
9004
9100
  };
9005
9101
  var isHlsStream = (src === null || src === void 0 ? void 0 : src.toLowerCase().includes(".m3u8")) || (src === null || src === void 0 ? void 0 : src.toLowerCase().includes("/hls/"));
9006
- var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls || isLiveStream === false : true);
9102
+ var isLiveUiMode = isLiveStream === true;
9103
+ var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? !isLiveUiMode : true);
9007
9104
  var criticalPropsKey = (0, import_react.useMemo)(function() {
9008
9105
  return CRITICAL_PROPS.map(function(prop) {
9009
9106
  return "".concat(prop, ":").concat(props[prop]);