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.
package/lib/index.cjs CHANGED
@@ -2576,12 +2576,14 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
2576
2576
  "adid"
2577
2577
  ]);
2578
2578
  function resolveVastEnvironmentSignals(isCtv) {
2579
- var _ref, _bridgeSignals_limitAdTracking;
2579
+ var _ref;
2580
2580
  var bridgeSignals = readNativeBridgeSignals();
2581
+ var platformDevice = readPlatformNativeDeviceId();
2581
2582
  var lg = isCtv && isLgWebOS();
2582
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || (lg ? getLgTestDeviceId() : void 0);
2583
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2584
- 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;
2583
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2584
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2585
+ var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2586
+ var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2585
2587
  if (isCtv) {
2586
2588
  return _object_spread_props(_object_spread({
2587
2589
  isCtv: true,
@@ -2652,6 +2654,72 @@ function createUuid() {
2652
2654
  return nibble.toString(16);
2653
2655
  });
2654
2656
  }
2657
+ function readPlatformNativeDeviceId() {
2658
+ if (typeof window === "undefined") return {};
2659
+ try {
2660
+ var _window_webapis;
2661
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
2662
+ if (adinfo) {
2663
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
2664
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
2665
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
2666
+ return _object_spread({
2667
+ deviceId: tifa,
2668
+ deviceIdType: "tifa"
2669
+ }, typeof lat === "boolean" ? {
2670
+ limitAdTracking: lat
2671
+ } : {});
2672
+ }
2673
+ }
2674
+ } catch (unused) {}
2675
+ try {
2676
+ var webOSDev = window.webOSDev;
2677
+ if (webOSDev) {
2678
+ var _webOSDev_lgudid;
2679
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
2680
+ if (typeof lgudid === "string" && lgudid) {
2681
+ if (isZeroedAdId(lgudid)) {
2682
+ return {
2683
+ deviceIdType: "lgudid",
2684
+ limitAdTracking: true
2685
+ };
2686
+ }
2687
+ if (!isMacroPlaceholder(lgudid)) {
2688
+ return {
2689
+ deviceId: lgudid,
2690
+ deviceIdType: "lgudid",
2691
+ limitAdTracking: false
2692
+ };
2693
+ }
2694
+ }
2695
+ }
2696
+ } catch (unused) {}
2697
+ try {
2698
+ var roku = window.Roku;
2699
+ if (roku) {
2700
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
2701
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
2702
+ return {
2703
+ deviceId: rida,
2704
+ deviceIdType: "rida",
2705
+ limitAdTracking: false
2706
+ };
2707
+ }
2708
+ }
2709
+ } catch (unused) {}
2710
+ return {};
2711
+ }
2712
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
2713
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
2714
+ "00000000-0000-0000-0000-000000000000"
2715
+ ]);
2716
+ function isMacroPlaceholder(value) {
2717
+ var t = value.trim();
2718
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2719
+ }
2720
+ function isZeroedAdId(value) {
2721
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2722
+ }
2655
2723
  function readNativeBridgeSignals() {
2656
2724
  if (typeof window === "undefined") {
2657
2725
  return {};
@@ -2992,7 +3060,7 @@ var INLINE_DEVICE_MACRO_REPLACEMENTS = [
2992
3060
  }
2993
3061
  }
2994
3062
  ];
2995
- function isMacroPlaceholder(value) {
3063
+ function isMacroPlaceholder2(value) {
2996
3064
  if (value == null) return true;
2997
3065
  var trimmed = value.trim();
2998
3066
  if (!trimmed) return true;
@@ -3051,11 +3119,11 @@ function applyDeviceIdentityParams(params, ctx) {
3051
3119
  if (runtimeId) {
3052
3120
  params.set("rdid", runtimeId);
3053
3121
  params.set("idtype", runtimeType || tagType || "aaid");
3054
- params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder(tagLat) ? "0" : tagLat);
3122
+ params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder2(tagLat) ? "0" : tagLat);
3055
3123
  return;
3056
3124
  }
3057
- var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));
3058
- var tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));
3125
+ var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));
3126
+ var tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));
3059
3127
  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {
3060
3128
  params.delete("rdid");
3061
3129
  params.delete("idtype");
@@ -3063,10 +3131,10 @@ function applyDeviceIdentityParams(params, ctx) {
3063
3131
  return;
3064
3132
  }
3065
3133
  if (tagRdidValid) {
3066
- if (isMacroPlaceholder(tagType) && runtimeType) {
3134
+ if (isMacroPlaceholder2(tagType) && runtimeType) {
3067
3135
  params.set("idtype", runtimeType);
3068
3136
  }
3069
- if (isMacroPlaceholder(tagLat)) {
3137
+ if (isMacroPlaceholder2(tagLat)) {
3070
3138
  params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : "0");
3071
3139
  }
3072
3140
  return;
@@ -3252,7 +3320,7 @@ function applyVastMacros(baseUrl, ctx) {
3252
3320
  }
3253
3321
  var staleKeys = [];
3254
3322
  params.forEach(function(value, key) {
3255
- if (isMacroPlaceholder(value)) {
3323
+ if (isMacroPlaceholder2(value)) {
3256
3324
  staleKeys.push(key);
3257
3325
  }
3258
3326
  });
@@ -6224,7 +6292,7 @@ var HlsEngine = /*#__PURE__*/ function() {
6224
6292
  key: "setupNativeHls",
6225
6293
  value: function setupNativeHls() {
6226
6294
  return _async_to_generator(function() {
6227
- var _this_config_isLiveStream, _this_config_lowLatencyMode, _this_video_play;
6295
+ var _this_config_isLiveStream, _this_config_lowLatencyMode, adBehavior, _this_video_play;
6228
6296
  return _ts_generator(this, function(_state) {
6229
6297
  switch(_state.label){
6230
6298
  case 0:
@@ -6233,10 +6301,11 @@ var HlsEngine = /*#__PURE__*/ function() {
6233
6301
  this.video.src = this.config.src;
6234
6302
  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;
6235
6303
  if (this.debug) {
6236
- console.log("[StormcloudVideoPlayer] Using native HLS playback - VOD mode:", {
6304
+ adBehavior = this.isLiveStream ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
6305
+ console.log("[StormcloudVideoPlayer] Using native HLS playback:", {
6237
6306
  isLive: this.isLiveStream,
6238
6307
  allowNativeHls: this.config.allowNativeHls,
6239
- adBehavior: "vod (main video pauses during ads)"
6308
+ adBehavior: adBehavior
6240
6309
  });
6241
6310
  }
6242
6311
  if (!this.config.autoplay) return [
@@ -6645,6 +6714,14 @@ var HlsEngine = /*#__PURE__*/ function() {
6645
6714
  });
6646
6715
  }
6647
6716
  },
6717
+ {
6718
+ key: "getLiveSyncPosition",
6719
+ value: function getLiveSyncPosition() {
6720
+ var _this_hls;
6721
+ var pos = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.liveSyncPosition;
6722
+ return typeof pos === "number" && Number.isFinite(pos) ? pos : void 0;
6723
+ }
6724
+ },
6648
6725
  {
6649
6726
  key: "destroy",
6650
6727
  value: function destroy() {
@@ -8219,6 +8296,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8219
8296
  this.host.video.volume = restoredVolume;
8220
8297
  }
8221
8298
  if (this.host.shouldContinueLiveStreamDuringAds()) {
8299
+ var liveSyncPos = this.host.getLiveSyncPosition();
8300
+ if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
8301
+ if (this.debug) {
8302
+ console.log("[StormcloudVideoPlayer] Live break end — snapping to live edge: ".concat(this.host.video.currentTime.toFixed(2), "s → ").concat(liveSyncPos.toFixed(2), "s"));
8303
+ }
8304
+ this.host.video.currentTime = liveSyncPos;
8305
+ }
8222
8306
  if (this.host.video.paused) {
8223
8307
  var _this_host_video_play;
8224
8308
  if (this.debug) console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
@@ -8361,6 +8445,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8361
8445
  shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
8362
8446
  return _this.shouldContinueLiveStreamDuringAds();
8363
8447
  },
8448
+ getLiveSyncPosition: function getLiveSyncPosition() {
8449
+ return _this.hlsEngine.getLiveSyncPosition();
8450
+ },
8364
8451
  generateVastUrls: function generateVastUrls(base, count) {
8365
8452
  return _this.generateVastUrls(base, count);
8366
8453
  }
@@ -8402,7 +8489,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8402
8489
  // ───────────────────────────────────────────────────────────────
8403
8490
  function load() {
8404
8491
  return _async_to_generator(function() {
8405
- var _this, _this_config_lowLatencyMode, error;
8492
+ var _this, _this_config_lowLatencyMode, error, continueLiveStreamDuringAds;
8406
8493
  return _ts_generator(this, function(_state) {
8407
8494
  switch(_state.label){
8408
8495
  case 0:
@@ -8456,15 +8543,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8456
8543
  3,
8457
8544
  6
8458
8545
  ];
8459
- this.adPlayer.destroy();
8460
- this.adPlayer = this.createAdPlayer(false);
8461
- this.adPlayer.initialize();
8462
8546
  return [
8463
8547
  4,
8464
8548
  this.hlsEngine.setupNativeHls()
8465
8549
  ];
8466
8550
  case 5:
8467
8551
  _state.sent();
8552
+ continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
8553
+ if (this.debug) {
8554
+ console.log("[StormcloudVideoPlayer] Native HLS ad behavior:", {
8555
+ isLive: this.hlsEngine.isLiveStream,
8556
+ continueLiveStreamDuringAds: continueLiveStreamDuringAds
8557
+ });
8558
+ }
8559
+ this.adPlayer.destroy();
8560
+ this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);
8561
+ this.adPlayer.initialize();
8468
8562
  return [
8469
8563
  2
8470
8564
  ];
@@ -8572,9 +8666,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8572
8666
  {
8573
8667
  key: "shouldContinueLiveStreamDuringAds",
8574
8668
  value: function shouldContinueLiveStreamDuringAds() {
8575
- if (this.config.allowNativeHls) return false;
8576
- if (!this.hlsEngine.isLiveStream) return false;
8577
- return true;
8669
+ if (this.hlsEngine.isLiveStream) {
8670
+ return true;
8671
+ }
8672
+ var duration = this.video.duration;
8673
+ if (!Number.isFinite(duration) || duration === Infinity) {
8674
+ return true;
8675
+ }
8676
+ return false;
8578
8677
  }
8579
8678
  },
8580
8679
  {
@@ -8872,9 +8971,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8872
8971
  this.adBreak.showAds = true;
8873
8972
  this.adBreak.inAdBreak = true;
8874
8973
  this.timing.currentAdBreakStartWallClockMs = Date.now();
8875
- if (!this.video.paused) {
8876
- this.video.pause();
8877
- }
8878
8974
  _state.label = 1;
8879
8975
  case 1:
8880
8976
  _state.trys.push([
@@ -9248,7 +9344,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
9248
9344
  setShowSpeedMenu(false);
9249
9345
  };
9250
9346
  var isHlsStream = (src === null || src === void 0 ? void 0 : src.toLowerCase().includes(".m3u8")) || (src === null || src === void 0 ? void 0 : src.toLowerCase().includes("/hls/"));
9251
- var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls || isLiveStream === false : true);
9347
+ var isLiveUiMode = isLiveStream === true;
9348
+ var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? !isLiveUiMode : true);
9252
9349
  var criticalPropsKey = (0, import_react.useMemo)(function() {
9253
9350
  return CRITICAL_PROPS.map(function(prop) {
9254
9351
  return "".concat(prop, ":").concat(props[prop]);
@@ -10628,6 +10725,7 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react3_Component) {
10628
10725
  if (_this1.props.muted !== void 0) config.muted = _this1.props.muted;
10629
10726
  if (_this1.props.lowLatencyMode !== void 0) config.lowLatencyMode = _this1.props.lowLatencyMode;
10630
10727
  if (_this1.props.allowNativeHls !== void 0) config.allowNativeHls = _this1.props.allowNativeHls;
10728
+ if (_this1.props.isLiveStream !== void 0) config.isLiveStream = _this1.props.isLiveStream;
10631
10729
  if (_this1.props.driftToleranceMs !== void 0) config.driftToleranceMs = _this1.props.driftToleranceMs;
10632
10730
  if (_this1.props.immediateManifestAds !== void 0) config.immediateManifestAds = _this1.props.immediateManifestAds;
10633
10731
  if (_this1.props.debugAdTiming !== void 0) config.debugAdTiming = _this1.props.debugAdTiming;
@@ -11394,6 +11492,7 @@ var SUPPORTED_PROPS = [
11394
11492
  "wrapperStyle",
11395
11493
  "allowNativeHls",
11396
11494
  "lowLatencyMode",
11495
+ "isLiveStream",
11397
11496
  "driftToleranceMs",
11398
11497
  "immediateManifestAds",
11399
11498
  "debugAdTiming",