stormcloud-video-player 0.8.57 → 0.8.59

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.
Files changed (42) hide show
  1. package/dist/stormcloud-vp.min.js +1 -1
  2. package/lib/index.cjs +57 -81
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.d.cts +1 -0
  5. package/lib/index.d.ts +1 -0
  6. package/lib/index.js +57 -81
  7. package/lib/index.js.map +1 -1
  8. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  9. package/lib/player/AdBreakOrchestrator.d.cts +1 -1
  10. package/lib/player/AdConfigManager.cjs +47 -76
  11. package/lib/player/AdConfigManager.cjs.map +1 -1
  12. package/lib/player/AdConfigManager.d.cts +2 -1
  13. package/lib/player/AdTimingService.d.cts +1 -1
  14. package/lib/player/HlsEngine.d.cts +1 -1
  15. package/lib/player/PlayerControls.d.cts +1 -1
  16. package/lib/player/Scte35CueManager.d.cts +1 -1
  17. package/lib/player/Scte35Parser.d.cts +1 -1
  18. package/lib/player/StormcloudVideoPlayer.cjs +53 -79
  19. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  20. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  21. package/lib/player/playerTypes.d.cts +1 -1
  22. package/lib/players/HlsPlayer.cjs +53 -79
  23. package/lib/players/HlsPlayer.cjs.map +1 -1
  24. package/lib/players/HlsPlayer.d.cts +1 -1
  25. package/lib/players/index.cjs +53 -79
  26. package/lib/players/index.cjs.map +1 -1
  27. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  28. package/lib/{types-cTqIKw_D.d.cts → types-52ASml2N.d.cts} +1 -0
  29. package/lib/ui/StormcloudVideoPlayer.cjs +57 -81
  30. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  31. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  32. package/lib/utils/ctvVastSignals.cjs +30 -36
  33. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  34. package/lib/utils/tracking.cjs.map +1 -1
  35. package/lib/utils/tracking.d.cts +1 -1
  36. package/lib/utils/vastEnvironmentSignals.cjs +16 -36
  37. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  38. package/lib/utils/vastEnvironmentSignals.d.cts +0 -3
  39. package/lib/utils/vastMacros.cjs +13 -34
  40. package/lib/utils/vastMacros.cjs.map +1 -1
  41. package/lib/utils/vastMacros.d.cts +1 -3
  42. package/package.json +1 -1
package/lib/index.d.cts CHANGED
@@ -42,6 +42,7 @@ interface StormcloudVideoPlayerConfig {
42
42
  minSegmentsBeforePlay?: number;
43
43
  ctvAdRequest?: boolean;
44
44
  adTest?: boolean;
45
+ programTitle?: string;
45
46
  podMaxAds?: number;
46
47
  podMaxDurationMs?: number;
47
48
  podExactDuration?: boolean;
package/lib/index.d.ts CHANGED
@@ -42,6 +42,7 @@ interface StormcloudVideoPlayerConfig {
42
42
  minSegmentsBeforePlay?: number;
43
43
  ctvAdRequest?: boolean;
44
44
  adTest?: boolean;
45
+ programTitle?: string;
45
46
  podMaxAds?: number;
46
47
  podMaxDurationMs?: number;
47
48
  podExactDuration?: boolean;
package/lib/index.js CHANGED
@@ -2543,34 +2543,8 @@ function ingestPlayerTracking(licenseKey, channel, body) {
2543
2543
  })();
2544
2544
  }
2545
2545
  // src/utils/vastEnvironmentSignals.ts
2546
- var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2547
- var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2548
- var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2549
- var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2550
- var AIRY_APP_NAME = "AiryTV Movies & TV";
2551
- var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2552
2546
  var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2553
2547
  var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
2554
- var LG_TEST_APP_ID = "com.hulu.plus";
2555
- var LG_TEST_APP_NAME = "Hulu";
2556
- var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
2557
- var _lgTestDeviceId;
2558
- function getLgTestDeviceId() {
2559
- if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
2560
- return _lgTestDeviceId;
2561
- }
2562
- function isLgWebOS() {
2563
- if (typeof navigator === "undefined") return false;
2564
- return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
2565
- }
2566
- function getDefaultAppId() {
2567
- if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2568
- var ua = navigator.userAgent;
2569
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2570
- if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2571
- if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2572
- return AIRY_ANDROID_APP_ID;
2573
- }
2574
2548
  var DEVICE_ID_STORAGE_KEYS = [
2575
2549
  "rdid",
2576
2550
  "ifa",
@@ -2591,23 +2565,29 @@ function resolveVastEnvironmentSignals(isCtv) {
2591
2565
  var _ref;
2592
2566
  var bridgeSignals = readNativeBridgeSignals();
2593
2567
  var platformDevice = readPlatformNativeDeviceId();
2594
- var lg = isCtv && isLgWebOS();
2595
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2596
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2568
+ var realDeviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
2569
+ var deviceId = realDeviceId;
2570
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
2597
2571
  var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2598
2572
  var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2573
+ if (!deviceId && isCtv) {
2574
+ var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
2575
+ if (dpid) {
2576
+ var _ref1;
2577
+ deviceId = dpid;
2578
+ deviceIdType = "dpid";
2579
+ limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
2580
+ }
2581
+ }
2599
2582
  if (isCtv) {
2600
2583
  return _object_spread_props(_object_spread({
2601
2584
  isCtv: true,
2602
- contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
2603
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
2604
- appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
2605
2585
  sessionId: getOrCreateCtvSessionId()
2606
2586
  }, deviceId ? {
2607
2587
  deviceId: deviceId
2608
- } : {}, deviceIdType ? {
2588
+ } : {}, deviceId && deviceIdType ? {
2609
2589
  deviceIdType: deviceIdType
2610
- } : {}, limitAdTracking != null ? {
2590
+ } : {}, deviceId && limitAdTracking != null ? {
2611
2591
  limitAdTracking: limitAdTracking
2612
2592
  } : {}), {
2613
2593
  deviceTypeHint: 5
@@ -2617,9 +2597,9 @@ function resolveVastEnvironmentSignals(isCtv) {
2617
2597
  isCtv: false
2618
2598
  }, deviceId ? {
2619
2599
  deviceId: deviceId
2620
- } : {}, deviceIdType ? {
2600
+ } : {}, deviceId && deviceIdType ? {
2621
2601
  deviceIdType: deviceIdType
2622
- } : {}, limitAdTracking != null ? {
2602
+ } : {}, deviceId && limitAdTracking != null ? {
2623
2603
  limitAdTracking: limitAdTracking
2624
2604
  } : {});
2625
2605
  }
@@ -3881,7 +3861,6 @@ var UNEXPANDED_MACRO_PATTERN = /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/;
3881
3861
  var INVALID_VAST_PARAM_KEY = /^\s|\s$/;
3882
3862
  var EXAMPLE_COM_URL = /example\.com/i;
3883
3863
  var CTV_UNSUPPORTED_PARAMS = [
3884
- "description_url",
3885
3864
  "tfcd",
3886
3865
  "npa",
3887
3866
  "min_ad_duration",
@@ -3972,18 +3951,6 @@ var INLINE_DEVICE_MACRO_REPLACEMENTS = [
3972
3951
  return ctx.limitAdTracking != null ? ctx.limitAdTracking ? "1" : "0" : void 0;
3973
3952
  }
3974
3953
  },
3975
- {
3976
- pattern: /%%MSID%%/gi,
3977
- getValue: function getValue(ctx) {
3978
- return ctx.appId;
3979
- }
3980
- },
3981
- {
3982
- pattern: /%%APP_NAME%%/gi,
3983
- getValue: function getValue(ctx) {
3984
- return ctx.appName;
3985
- }
3986
- },
3987
3954
  {
3988
3955
  pattern: /%%SESSION_ID%%/gi,
3989
3956
  getValue: function getValue(ctx) {
@@ -4174,7 +4141,7 @@ function applyVastMacros(baseUrl, ctx) {
4174
4141
  return replaceCorrelatorFallback(expandedUrl, ctx.correlator);
4175
4142
  }
4176
4143
  var params = url.searchParams;
4177
- removeBrokenAppNameOrphans(params, ctx.appName);
4144
+ removeBrokenAppNameOrphans(params);
4178
4145
  params.set("correlator", ctx.correlator);
4179
4146
  params.set("scor", ctx.streamCorrelator);
4180
4147
  if (ctx.isCtv) {
@@ -4213,18 +4180,14 @@ function applyVastMacros(baseUrl, ctx) {
4213
4180
  if (ctx.podMaxAds != null) {
4214
4181
  params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
4215
4182
  }
4216
- var requestUrl = ctx.contentUrl || ctx.pageUrl;
4217
- if (requestUrl) {
4218
- params.set("url", requestUrl);
4219
- if (!ctx.isCtv) {
4220
- params.set("description_url", requestUrl);
4221
- }
4222
- } else {
4223
- var existingUrl = params.get("url") || "";
4224
- if (EXAMPLE_COM_URL.test(existingUrl)) {
4225
- params.delete("url");
4226
- params.delete("description_url");
4227
- }
4183
+ if (!ctx.isCtv && ctx.pageUrl) {
4184
+ params.set("url", ctx.pageUrl);
4185
+ params.set("description_url", ctx.pageUrl);
4186
+ }
4187
+ var existingUrl = params.get("url") || "";
4188
+ if (EXAMPLE_COM_URL.test(existingUrl)) {
4189
+ params.delete("url");
4190
+ params.delete("description_url");
4228
4191
  }
4229
4192
  if (ctx.adWillPlayMuted != null) {
4230
4193
  params.set("vpmute", ctx.adWillPlayMuted ? "1" : "0");
@@ -4232,13 +4195,6 @@ function applyVastMacros(baseUrl, ctx) {
4232
4195
  if (ctx.adWillAutoPlay != null) {
4233
4196
  params.set("vpa", ctx.adWillAutoPlay ? "auto" : "click");
4234
4197
  }
4235
- if (ctx.appId) {
4236
- params.set("msid", ctx.appId);
4237
- }
4238
- if (ctx.appName) {
4239
- removeBrokenAppNameOrphans(params, ctx.appName);
4240
- params.set("an", ctx.appName);
4241
- }
4242
4198
  if (ctx.sessionId) {
4243
4199
  params.set("sid", ctx.sessionId);
4244
4200
  }
@@ -4263,6 +4219,9 @@ function applyVastMacros(baseUrl, ctx) {
4263
4219
  if (ctx.adTest) {
4264
4220
  params.set("adtest", "on");
4265
4221
  }
4222
+ if (ctx.programTitle) {
4223
+ params.set("ct_ti", ctx.programTitle);
4224
+ }
4266
4225
  var staleKeys = [];
4267
4226
  params.forEach(function(value, key) {
4268
4227
  if (isMacroPlaceholder2(value)) {
@@ -4289,7 +4248,7 @@ function applyVastMacros(baseUrl, ctx) {
4289
4248
  }
4290
4249
  }
4291
4250
  }
4292
- removeBrokenAppNameOrphans(params, ctx.appName);
4251
+ removeBrokenAppNameOrphans(params);
4293
4252
  return url.toString();
4294
4253
  }
4295
4254
  function replaceCorrelatorFallback(baseUrl, correlator) {
@@ -5823,13 +5782,25 @@ var AdConfigManager = /*#__PURE__*/ function() {
5823
5782
  };
5824
5783
  }
5825
5784
  },
5785
+ {
5786
+ key: "getPalDescriptionUrl",
5787
+ value: function getPalDescriptionUrl() {
5788
+ if (!this.apiVastTagUrl) return void 0;
5789
+ try {
5790
+ var params = new URL(this.apiVastTagUrl).searchParams;
5791
+ return params.get("description_url") || params.get("url") || void 0;
5792
+ } catch (unused) {
5793
+ return void 0;
5794
+ }
5795
+ }
5796
+ },
5826
5797
  {
5827
5798
  key: "generatePodVastUrl",
5828
5799
  value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
5829
5800
  var _podParams_maxDurationMs;
5830
5801
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
5831
5802
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
5832
- var urlWithMacros = applyVastMacros(baseUrl, {
5803
+ var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
5833
5804
  correlator: this.viewCorrelator,
5834
5805
  streamCorrelator: this.streamCorrelator,
5835
5806
  pod: this.podCounter > 0 ? this.podCounter : void 0,
@@ -5837,20 +5808,20 @@ var AdConfigManager = /*#__PURE__*/ function() {
5837
5808
  podMinDurationMs: podParams.minDurationMs,
5838
5809
  podMaxDurationMs: podParams.maxDurationMs,
5839
5810
  isCtv: envSignals.isCtv,
5840
- contentUrl: envSignals.contentUrl,
5841
5811
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
5842
5812
  adWillPlayMuted: adWillPlayMuted,
5843
5813
  adWillAutoPlay: !!this.config.autoplay,
5844
- appId: envSignals.appId,
5845
- appName: envSignals.appName,
5846
5814
  sessionId: envSignals.sessionId,
5847
5815
  deviceId: envSignals.deviceId,
5848
5816
  deviceIdType: envSignals.deviceIdType,
5849
5817
  limitAdTracking: envSignals.limitAdTracking,
5850
5818
  deviceTypeHint: envSignals.deviceTypeHint,
5851
- adTest: this.config.adTest,
5819
+ adTest: this.config.adTest
5820
+ }, this.config.programTitle ? {
5821
+ programTitle: this.config.programTitle
5822
+ } : {}), {
5852
5823
  consent: this.consentSignals
5853
- });
5824
+ }));
5854
5825
  var finalUrl = palNonce.injectNonce(urlWithMacros);
5855
5826
  console.log("[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=".concat(this.podCounter, ", pmad=").concat(podParams.maxAds, ", pmnd=").concat(podParams.minDurationMs, ", pmxd=").concat((_podParams_maxDurationMs = podParams.maxDurationMs) !== null && _podParams_maxDurationMs !== void 0 ? _podParams_maxDurationMs : "?", "):"), finalUrl);
5856
5827
  return finalUrl;
@@ -8961,7 +8932,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8961
8932
  // ───────────────────────────────────────────────────────────────
8962
8933
  function load() {
8963
8934
  return _async_to_generator(function() {
8964
- var _this, _this_config_lowLatencyMode, error, continueLiveStreamDuringAds;
8935
+ var _this, _this_config_lowLatencyMode, error, palDescriptionUrl, continueLiveStreamDuringAds;
8965
8936
  return _ts_generator(this, function(_state) {
8966
8937
  switch(_state.label){
8967
8938
  case 0:
@@ -8997,14 +8968,17 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8997
8968
  4
8998
8969
  ];
8999
8970
  case 4:
9000
- this.palNonce.generateNonce({
8971
+ palDescriptionUrl = this.adConfig.getPalDescriptionUrl();
8972
+ this.palNonce.generateNonce(_object_spread({
9001
8973
  videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,
9002
8974
  videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,
9003
8975
  adWillAutoPlay: !!this.config.autoplay,
9004
8976
  adWillPlayMuted: true,
9005
8977
  playerVolume: 0,
9006
8978
  continuousPlayback: (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
9007
- }).catch(function() {});
8979
+ }, palDescriptionUrl ? {
8980
+ descriptionUrl: palDescriptionUrl
8981
+ } : {})).catch(function() {});
9008
8982
  fetchConsentSignals().then(function(signals) {
9009
8983
  _this.adConfig.consentSignals = signals;
9010
8984
  }).catch(function() {});
@@ -9728,7 +9702,7 @@ var CRITICAL_PROPS = [
9728
9702
  var CONTROLS_HIDE_DELAY = 3e3;
9729
9703
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
9730
9704
  var StormcloudVideoPlayerComponent = React.memo(function(props) {
9731
- var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, 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, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, restVideoAttrs = _object_without_properties(props, [
9705
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, 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, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, restVideoAttrs = _object_without_properties(props, [
9732
9706
  "src",
9733
9707
  "autoplay",
9734
9708
  "muted",
@@ -9759,7 +9733,8 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
9759
9733
  "isVmap",
9760
9734
  "vmapUrl",
9761
9735
  "minSegmentsBeforePlay",
9762
- "ctvAdRequest"
9736
+ "ctvAdRequest",
9737
+ "programTitle"
9763
9738
  ]);
9764
9739
  var videoRef = useRef(null);
9765
9740
  var playerRef = useRef(null);
@@ -9950,6 +9925,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
9950
9925
  if (vmapUrl !== void 0) cfg.vmapUrl = vmapUrl;
9951
9926
  if (minSegmentsBeforePlay !== void 0) cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
9952
9927
  if (ctvAdRequest !== void 0) cfg.ctvAdRequest = ctvAdRequest;
9928
+ if (programTitle !== void 0) cfg.programTitle = programTitle;
9953
9929
  var player = new StormcloudVideoPlayer(cfg);
9954
9930
  playerRef.current = player;
9955
9931
  player.load().then(function() {