stormcloud-video-player 0.8.19 → 0.8.20

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 (39) hide show
  1. package/dist/stormcloud-vp.min.js +1 -1
  2. package/lib/index.cjs +53 -9
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.js +53 -9
  5. package/lib/index.js.map +1 -1
  6. package/lib/player/AdBreakOrchestrator.d.cts +1 -1
  7. package/lib/player/AdConfigManager.cjs +60 -5
  8. package/lib/player/AdConfigManager.cjs.map +1 -1
  9. package/lib/player/AdConfigManager.d.cts +1 -1
  10. package/lib/player/AdPreloadPool.d.cts +1 -1
  11. package/lib/player/AdTimingService.d.cts +1 -1
  12. package/lib/player/HlsEngine.d.cts +1 -1
  13. package/lib/player/PlayerControls.d.cts +1 -1
  14. package/lib/player/Scte35CueManager.d.cts +1 -1
  15. package/lib/player/Scte35Parser.d.cts +1 -1
  16. package/lib/player/StormcloudVideoPlayer.cjs +53 -9
  17. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  18. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  19. package/lib/player/playerTypes.d.cts +1 -1
  20. package/lib/players/HlsPlayer.cjs +53 -9
  21. package/lib/players/HlsPlayer.cjs.map +1 -1
  22. package/lib/players/HlsPlayer.d.cts +1 -1
  23. package/lib/players/index.cjs +53 -9
  24. package/lib/players/index.cjs.map +1 -1
  25. package/lib/sdk/hlsAdPlayer.cjs +5 -4
  26. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  27. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  28. package/lib/types-BAP8n5mE.d.cts +126 -0
  29. package/lib/ui/StormcloudVideoPlayer.cjs +53 -9
  30. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  31. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  32. package/lib/utils/ctvVastSignals.cjs +12 -1
  33. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  34. package/lib/utils/tracking.d.cts +1 -1
  35. package/lib/utils/vastEnvironmentSignals.cjs +12 -1
  36. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  37. package/lib/utils/vastMacros.cjs +48 -0
  38. package/lib/utils/vastMacros.cjs.map +1 -1
  39. package/package.json +1 -1
package/lib/index.cjs CHANGED
@@ -1011,6 +1011,7 @@ function createHlsAdPlayer(contentVideo, options) {
1011
1011
  handleAdComplete();
1012
1012
  });
1013
1013
  adVideoElement.addEventListener("error", function(e) {
1014
+ if (!adPlaying) return;
1014
1015
  console.error("[HlsAdPlayer] Ad video error:", e);
1015
1016
  if (currentAd) {
1016
1017
  fireTrackingPixels(currentAd.trackingUrls.error);
@@ -1212,15 +1213,15 @@ function createHlsAdPlayer(contentVideo, options) {
1212
1213
  adVideoElement.muted = originalMutedState;
1213
1214
  console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
1214
1215
  }
1216
+ mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1217
+ if (!mediaFile) {
1218
+ throw new Error("No media file available for ad");
1219
+ }
1215
1220
  if (adContainerEl) {
1216
1221
  adContainerEl.style.display = "flex";
1217
1222
  adContainerEl.style.pointerEvents = "auto";
1218
1223
  }
1219
1224
  emit("content_pause");
1220
- mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1221
- if (!mediaFile) {
1222
- throw new Error("No media file available for ad");
1223
- }
1224
1225
  isHlsAd = isHlsMediaFile(mediaFile);
1225
1226
  console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
1226
1227
  if (isHlsAd && import_hls.default.isSupported()) {
@@ -2532,9 +2533,20 @@ function initializePolyfills() {
2532
2533
  }
2533
2534
  // src/utils/vastEnvironmentSignals.ts
2534
2535
  var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2536
+ var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2537
+ var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2538
+ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2535
2539
  var AIRY_APP_NAME = "AiryTV Movies & TV";
2536
2540
  var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2537
2541
  var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2542
+ function getDefaultAppId() {
2543
+ if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2544
+ var ua = navigator.userAgent;
2545
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2546
+ if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2547
+ if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2548
+ return AIRY_ANDROID_APP_ID;
2549
+ }
2538
2550
  var DEVICE_ID_STORAGE_KEYS = [
2539
2551
  "rdid",
2540
2552
  "ifa",
@@ -2561,7 +2573,7 @@ function resolveVastEnvironmentSignals(isCtv) {
2561
2573
  return _object_spread_props(_object_spread({
2562
2574
  isCtv: true,
2563
2575
  contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || AIRY_DEFAULT_CONTENT_URL,
2564
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || AIRY_ANDROID_APP_ID,
2576
+ appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || getDefaultAppId(),
2565
2577
  appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || AIRY_APP_NAME,
2566
2578
  sessionId: getOrCreateCtvSessionId()
2567
2579
  }, deviceId ? {
@@ -3107,6 +3119,29 @@ function normalizeVastTagUrl(raw) {
3107
3119
  if (!raw) return raw;
3108
3120
  try {
3109
3121
  var url = new URL(raw);
3122
+ var anValue = url.searchParams.get("an");
3123
+ if (anValue !== null) {
3124
+ var orphanFragments = [];
3125
+ url.searchParams.forEach(function(_value, key) {
3126
+ if (key && INVALID_VAST_PARAM_KEY.test(key)) {
3127
+ orphanFragments.push(key.trim());
3128
+ }
3129
+ });
3130
+ if (orphanFragments.length > 0) {
3131
+ var reconstructed = [
3132
+ anValue.trimEnd()
3133
+ ].concat(_to_consumable_array(orphanFragments)).filter(Boolean).join(" & ");
3134
+ url.searchParams.forEach(function(_value, key) {
3135
+ if (key && INVALID_VAST_PARAM_KEY.test(key)) {
3136
+ url.searchParams.delete(key);
3137
+ }
3138
+ });
3139
+ url.searchParams.set("an", reconstructed);
3140
+ return url.toString().replace(/([?&]an=)([^&]*)/, function(_match, prefix, val) {
3141
+ return prefix + val.replace(/\+/g, "%20");
3142
+ });
3143
+ }
3144
+ }
3110
3145
  removeBrokenAppNameOrphans(url.searchParams);
3111
3146
  return url.toString();
3112
3147
  } catch (unused) {
@@ -4537,7 +4572,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
4537
4572
  key: "fetchAdConfiguration",
4538
4573
  value: function fetchAdConfiguration() {
4539
4574
  return _async_to_generator(function() {
4540
- var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, numberAds;
4575
+ var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
4541
4576
  return _ts_generator(this, function(_state) {
4542
4577
  switch(_state.label){
4543
4578
  case 0:
@@ -4621,9 +4656,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
4621
4656
  data = _state.sent();
4622
4657
  imaPayload = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : (_data_response_ima = _data_response.ima) === null || _data_response_ima === void 0 ? void 0 : (_data_response_ima_publisherdeskima = _data_response_ima["publisherdesk.ima"]) === null || _data_response_ima_publisherdeskima === void 0 ? void 0 : _data_response_ima_publisherdeskima.payload;
4623
4658
  if (imaPayload) {
4624
- this.apiVastTagUrl = normalizeVastTagUrl(imaPayload);
4659
+ decodedPayload = imaPayload;
4660
+ try {
4661
+ decodedPayload = decodeURIComponent(imaPayload);
4662
+ } catch (unused) {
4663
+ console.warn("[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:", imaPayload);
4664
+ }
4665
+ console.log("[StormcloudVideoPlayer] Raw VAST tag URL (from API):", decodedPayload);
4666
+ this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);
4625
4667
  if (this.debug) {
4626
- console.log("[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:", this.apiVastTagUrl);
4668
+ console.log("[StormcloudVideoPlayer] Normalized VAST tag URL:", this.apiVastTagUrl);
4627
4669
  }
4628
4670
  } else {
4629
4671
  if (this.debug) {
@@ -4957,7 +4999,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
4957
4999
  adTest: this.config.adTest,
4958
5000
  consent: this.consentSignals
4959
5001
  });
4960
- urls.push(palNonce.injectNonce(urlWithMacros));
5002
+ var finalUrl = palNonce.injectNonce(urlWithMacros);
5003
+ console.log("[StormcloudVideoPlayer] Resolved ad request URL (pod=".concat(this.podCounter, ", pos=").concat(this.adRequestPositionInBreak, "):"), finalUrl);
5004
+ urls.push(finalUrl);
4961
5005
  }
4962
5006
  return urls;
4963
5007
  }