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.js CHANGED
@@ -797,6 +797,7 @@ function createHlsAdPlayer(contentVideo, options) {
797
797
  handleAdComplete();
798
798
  });
799
799
  adVideoElement.addEventListener("error", function(e) {
800
+ if (!adPlaying) return;
800
801
  console.error("[HlsAdPlayer] Ad video error:", e);
801
802
  if (currentAd) {
802
803
  fireTrackingPixels(currentAd.trackingUrls.error);
@@ -998,15 +999,15 @@ function createHlsAdPlayer(contentVideo, options) {
998
999
  adVideoElement.muted = originalMutedState;
999
1000
  console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
1000
1001
  }
1002
+ mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1003
+ if (!mediaFile) {
1004
+ throw new Error("No media file available for ad");
1005
+ }
1001
1006
  if (adContainerEl) {
1002
1007
  adContainerEl.style.display = "flex";
1003
1008
  adContainerEl.style.pointerEvents = "auto";
1004
1009
  }
1005
1010
  emit("content_pause");
1006
- mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1007
- if (!mediaFile) {
1008
- throw new Error("No media file available for ad");
1009
- }
1010
1011
  isHlsAd = isHlsMediaFile(mediaFile);
1011
1012
  console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
1012
1013
  if (isHlsAd && Hls.isSupported()) {
@@ -2320,9 +2321,20 @@ function initializePolyfills() {
2320
2321
  }
2321
2322
  // src/utils/vastEnvironmentSignals.ts
2322
2323
  var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2324
+ var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2325
+ var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2326
+ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2323
2327
  var AIRY_APP_NAME = "AiryTV Movies & TV";
2324
2328
  var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2325
2329
  var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2330
+ function getDefaultAppId() {
2331
+ if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2332
+ var ua = navigator.userAgent;
2333
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2334
+ if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2335
+ if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2336
+ return AIRY_ANDROID_APP_ID;
2337
+ }
2326
2338
  var DEVICE_ID_STORAGE_KEYS = [
2327
2339
  "rdid",
2328
2340
  "ifa",
@@ -2349,7 +2361,7 @@ function resolveVastEnvironmentSignals(isCtv) {
2349
2361
  return _object_spread_props(_object_spread({
2350
2362
  isCtv: true,
2351
2363
  contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || AIRY_DEFAULT_CONTENT_URL,
2352
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || AIRY_ANDROID_APP_ID,
2364
+ appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || getDefaultAppId(),
2353
2365
  appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || AIRY_APP_NAME,
2354
2366
  sessionId: getOrCreateCtvSessionId()
2355
2367
  }, deviceId ? {
@@ -2895,6 +2907,29 @@ function normalizeVastTagUrl(raw) {
2895
2907
  if (!raw) return raw;
2896
2908
  try {
2897
2909
  var url = new URL(raw);
2910
+ var anValue = url.searchParams.get("an");
2911
+ if (anValue !== null) {
2912
+ var orphanFragments = [];
2913
+ url.searchParams.forEach(function(_value, key) {
2914
+ if (key && INVALID_VAST_PARAM_KEY.test(key)) {
2915
+ orphanFragments.push(key.trim());
2916
+ }
2917
+ });
2918
+ if (orphanFragments.length > 0) {
2919
+ var reconstructed = [
2920
+ anValue.trimEnd()
2921
+ ].concat(_to_consumable_array(orphanFragments)).filter(Boolean).join(" & ");
2922
+ url.searchParams.forEach(function(_value, key) {
2923
+ if (key && INVALID_VAST_PARAM_KEY.test(key)) {
2924
+ url.searchParams.delete(key);
2925
+ }
2926
+ });
2927
+ url.searchParams.set("an", reconstructed);
2928
+ return url.toString().replace(/([?&]an=)([^&]*)/, function(_match, prefix, val) {
2929
+ return prefix + val.replace(/\+/g, "%20");
2930
+ });
2931
+ }
2932
+ }
2898
2933
  removeBrokenAppNameOrphans(url.searchParams);
2899
2934
  return url.toString();
2900
2935
  } catch (unused) {
@@ -4328,7 +4363,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
4328
4363
  key: "fetchAdConfiguration",
4329
4364
  value: function fetchAdConfiguration() {
4330
4365
  return _async_to_generator(function() {
4331
- 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;
4366
+ 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;
4332
4367
  return _ts_generator(this, function(_state) {
4333
4368
  switch(_state.label){
4334
4369
  case 0:
@@ -4412,9 +4447,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
4412
4447
  data = _state.sent();
4413
4448
  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;
4414
4449
  if (imaPayload) {
4415
- this.apiVastTagUrl = normalizeVastTagUrl(imaPayload);
4450
+ decodedPayload = imaPayload;
4451
+ try {
4452
+ decodedPayload = decodeURIComponent(imaPayload);
4453
+ } catch (unused) {
4454
+ console.warn("[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:", imaPayload);
4455
+ }
4456
+ console.log("[StormcloudVideoPlayer] Raw VAST tag URL (from API):", decodedPayload);
4457
+ this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);
4416
4458
  if (this.debug) {
4417
- console.log("[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:", this.apiVastTagUrl);
4459
+ console.log("[StormcloudVideoPlayer] Normalized VAST tag URL:", this.apiVastTagUrl);
4418
4460
  }
4419
4461
  } else {
4420
4462
  if (this.debug) {
@@ -4748,7 +4790,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
4748
4790
  adTest: this.config.adTest,
4749
4791
  consent: this.consentSignals
4750
4792
  });
4751
- urls.push(palNonce.injectNonce(urlWithMacros));
4793
+ var finalUrl = palNonce.injectNonce(urlWithMacros);
4794
+ console.log("[StormcloudVideoPlayer] Resolved ad request URL (pod=".concat(this.podCounter, ", pos=").concat(this.adRequestPositionInBreak, "):"), finalUrl);
4795
+ urls.push(finalUrl);
4752
4796
  }
4753
4797
  return urls;
4754
4798
  }