stormcloud-video-player 0.7.49 → 0.7.51

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.js CHANGED
@@ -1699,6 +1699,126 @@ function createAdStormPlayer(contentVideo, options) {
1699
1699
  }
1700
1700
  };
1701
1701
  }
1702
+ // src/utils/mqttClient.ts
1703
+ import mqtt from "mqtt";
1704
+ // src/utils/mqttConfig.ts
1705
+ var MQTT_CA_CERT_FILE = "src/certs/emqxsl-ca.crt";
1706
+ var DEFAULT_MQTT_CONFIG = {
1707
+ enabled: true,
1708
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
1709
+ brokerPort: 8883,
1710
+ wsPort: 8084,
1711
+ username: "for-sonifi",
1712
+ password: "sonifi-mqtt",
1713
+ topicPrefix: "adstorm/players",
1714
+ qos: 1
1715
+ };
1716
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
1717
+ function applyMQTTConfig(overrides) {
1718
+ Object.assign(mqttConfig, overrides);
1719
+ }
1720
+ function isMQTTEnabled() {
1721
+ return mqttConfig.enabled;
1722
+ }
1723
+ function buildMQTTBrokerUrl() {
1724
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
1725
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
1726
+ }
1727
+ function buildPlayerTopic(licenseKey, channel) {
1728
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
1729
+ }
1730
+ // src/utils/mqttClient.ts
1731
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
1732
+ var client = null;
1733
+ var status = "disconnected";
1734
+ function getMQTTStatus() {
1735
+ return status;
1736
+ }
1737
+ function isMQTTConnected() {
1738
+ return status === "connected" && client !== null && client.connected;
1739
+ }
1740
+ function isMQTTConfigured() {
1741
+ return isMQTTEnabled();
1742
+ }
1743
+ function configureMQTT(overrides) {
1744
+ applyMQTTConfig(overrides);
1745
+ disconnectMQTT();
1746
+ }
1747
+ function initMQTTClient() {
1748
+ if (client || !isMQTTEnabled()) return;
1749
+ var url = buildMQTTBrokerUrl();
1750
+ status = "connecting";
1751
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
1752
+ try {
1753
+ client = mqtt.connect(url, {
1754
+ clientId: clientId,
1755
+ username: mqttConfig.username,
1756
+ password: mqttConfig.password,
1757
+ keepalive: 60,
1758
+ clean: true,
1759
+ reconnectPeriod: 5e3,
1760
+ connectTimeout: 1e4,
1761
+ queueQoSZero: false
1762
+ });
1763
+ } catch (err) {
1764
+ status = "error";
1765
+ console.warn("".concat(LOG, " connect() threw:"), err);
1766
+ return;
1767
+ }
1768
+ client.on("connect", function() {
1769
+ status = "connected";
1770
+ console.info("".concat(LOG, " connected to ").concat(url));
1771
+ });
1772
+ client.on("reconnect", function() {
1773
+ status = "connecting";
1774
+ console.info("".concat(LOG, " reconnecting..."));
1775
+ });
1776
+ client.on("offline", function() {
1777
+ if (status !== "error") {
1778
+ status = "disconnected";
1779
+ }
1780
+ console.warn("".concat(LOG, " offline"));
1781
+ });
1782
+ client.on("error", function(err) {
1783
+ status = "error";
1784
+ console.warn("".concat(LOG, " error:"), err.message);
1785
+ });
1786
+ client.on("close", function() {
1787
+ if (status === "connected" || status === "connecting") {
1788
+ status = "disconnected";
1789
+ }
1790
+ });
1791
+ }
1792
+ function ensureMQTTClient() {
1793
+ if (isMQTTEnabled() && !client) {
1794
+ initMQTTClient();
1795
+ }
1796
+ }
1797
+ function publishMQTT(topic, payload) {
1798
+ if (!isMQTTEnabled()) {
1799
+ return false;
1800
+ }
1801
+ ensureMQTTClient();
1802
+ if (!client) {
1803
+ return false;
1804
+ }
1805
+ try {
1806
+ client.publish(topic, JSON.stringify(payload), {
1807
+ qos: mqttConfig.qos
1808
+ });
1809
+ return true;
1810
+ } catch (err) {
1811
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
1812
+ return false;
1813
+ }
1814
+ }
1815
+ function disconnectMQTT() {
1816
+ if (client) {
1817
+ client.end(true);
1818
+ client = null;
1819
+ status = "disconnected";
1820
+ }
1821
+ }
1702
1822
  // src/utils/tracking.ts
1703
1823
  var cachedBrowserId = null;
1704
1824
  function getClientInfo() {
@@ -1929,139 +2049,164 @@ function getBrowserID(clientInfo) {
1929
2049
  });
1930
2050
  })();
1931
2051
  }
1932
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
1933
- function sendTrackRequest(licenseKey, body) {
2052
+ function canPublish(licenseKey) {
2053
+ return Boolean(isMQTTEnabled() && licenseKey);
2054
+ }
2055
+ function buildPlayerMetricEvent() {
1934
2056
  return _async_to_generator(function() {
1935
- var headers, response;
2057
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2058
+ var _arguments = arguments;
1936
2059
  return _ts_generator(this, function(_state) {
1937
2060
  switch(_state.label){
1938
2061
  case 0:
1939
- headers = {
1940
- "Content-Type": "application/json"
1941
- };
1942
- if (licenseKey) {
1943
- headers["Authorization"] = "Bearer ".concat(licenseKey);
1944
- }
2062
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2063
+ clientInfo = getClientInfo();
1945
2064
  return [
1946
2065
  4,
1947
- fetch(TRACK_URL, {
1948
- method: "POST",
1949
- headers: headers,
1950
- body: JSON.stringify(body)
1951
- })
2066
+ getBrowserID(clientInfo)
1952
2067
  ];
1953
2068
  case 1:
1954
- response = _state.sent();
1955
- if (!response.ok) {
1956
- throw new Error("HTTP error! status: ".concat(response.status));
1957
- }
2069
+ playerId = _state.sent();
2070
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2071
+ return [
2072
+ 2,
2073
+ _object_spread({
2074
+ player_id: playerId,
2075
+ device_type: clientInfo.deviceType,
2076
+ os: clientInfo.os.toLowerCase(),
2077
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2078
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2079
+ capture_at: captureAt
2080
+ }, context.inputStreamType ? {
2081
+ input_stream_type: context.inputStreamType
2082
+ } : {})
2083
+ ];
2084
+ }
2085
+ });
2086
+ }).apply(this, arguments);
2087
+ }
2088
+ function publishTracking(licenseKey, channel, body) {
2089
+ ensureMQTTClient();
2090
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2091
+ }
2092
+ function sendInitialTracking(_0) {
2093
+ return _async_to_generator(function(licenseKey) {
2094
+ var context, metricEvent, error;
2095
+ var _arguments = arguments;
2096
+ return _ts_generator(this, function(_state) {
2097
+ switch(_state.label){
2098
+ case 0:
2099
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2100
+ if (!canPublish(licenseKey)) return [
2101
+ 2
2102
+ ];
2103
+ _state.label = 1;
2104
+ case 1:
2105
+ _state.trys.push([
2106
+ 1,
2107
+ 3,
2108
+ ,
2109
+ 4
2110
+ ]);
1958
2111
  return [
1959
2112
  4,
1960
- response.json()
2113
+ buildPlayerMetricEvent(context, {
2114
+ adLoaded: false,
2115
+ adDetect: false
2116
+ })
1961
2117
  ];
1962
2118
  case 2:
1963
- _state.sent();
2119
+ metricEvent = _state.sent();
2120
+ publishTracking(licenseKey, "metrics", {
2121
+ events: [
2122
+ metricEvent
2123
+ ]
2124
+ });
2125
+ return [
2126
+ 3,
2127
+ 4
2128
+ ];
2129
+ case 3:
2130
+ error = _state.sent();
2131
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2132
+ return [
2133
+ 3,
2134
+ 4
2135
+ ];
2136
+ case 4:
1964
2137
  return [
1965
2138
  2
1966
2139
  ];
1967
2140
  }
1968
2141
  });
1969
- })();
2142
+ }).apply(this, arguments);
1970
2143
  }
1971
- function sendInitialTracking(licenseKey) {
1972
- return _async_to_generator(function() {
1973
- var clientInfo, browserId, trackingData, headers, response, error;
2144
+ function sendAdDetectTracking(_0, _1) {
2145
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2146
+ var context, error;
2147
+ var _arguments = arguments;
1974
2148
  return _ts_generator(this, function(_state) {
1975
2149
  switch(_state.label){
1976
2150
  case 0:
2151
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2152
+ _state.label = 1;
2153
+ case 1:
1977
2154
  _state.trys.push([
1978
- 0,
1979
- 4,
2155
+ 1,
2156
+ 3,
1980
2157
  ,
1981
- 5
2158
+ 4
1982
2159
  ]);
1983
- clientInfo = getClientInfo();
1984
2160
  return [
1985
2161
  4,
1986
- getBrowserID(clientInfo)
1987
- ];
1988
- case 1:
1989
- browserId = _state.sent();
1990
- trackingData = _object_spread({
1991
- browserId: browserId
1992
- }, clientInfo);
1993
- headers = {
1994
- "Content-Type": "application/json"
1995
- };
1996
- if (licenseKey) {
1997
- headers["Authorization"] = "Bearer ".concat(licenseKey);
1998
- }
1999
- return [
2000
- 4,
2001
- fetch(TRACK_URL, {
2002
- method: "POST",
2003
- headers: headers,
2004
- body: JSON.stringify(trackingData)
2162
+ sendHeartbeat(licenseKey, context, {
2163
+ adDetect: true,
2164
+ captureAt: adDetectInfo.timestamp
2005
2165
  })
2006
2166
  ];
2007
2167
  case 2:
2008
- response = _state.sent();
2009
- if (!response.ok) {
2010
- throw new Error("HTTP error! status: ".concat(response.status));
2011
- }
2012
- return [
2013
- 4,
2014
- response.json()
2015
- ];
2016
- case 3:
2017
2168
  _state.sent();
2018
2169
  return [
2019
2170
  3,
2020
- 5
2171
+ 4
2021
2172
  ];
2022
- case 4:
2173
+ case 3:
2023
2174
  error = _state.sent();
2024
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2175
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2025
2176
  return [
2026
2177
  3,
2027
- 5
2178
+ 4
2028
2179
  ];
2029
- case 5:
2180
+ case 4:
2030
2181
  return [
2031
2182
  2
2032
2183
  ];
2033
2184
  }
2034
2185
  });
2035
- })();
2186
+ }).apply(this, arguments);
2036
2187
  }
2037
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2038
- return _async_to_generator(function() {
2039
- var clientInfo, browserId, trackingData, error;
2188
+ function sendAdLoadedTracking(_0, _1) {
2189
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2190
+ var context, error;
2191
+ var _arguments = arguments;
2040
2192
  return _ts_generator(this, function(_state) {
2041
2193
  switch(_state.label){
2042
2194
  case 0:
2195
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2196
+ _state.label = 1;
2197
+ case 1:
2043
2198
  _state.trys.push([
2044
- 0,
2199
+ 1,
2045
2200
  3,
2046
2201
  ,
2047
2202
  4
2048
2203
  ]);
2049
- clientInfo = getClientInfo();
2050
- return [
2051
- 4,
2052
- getBrowserID(clientInfo)
2053
- ];
2054
- case 1:
2055
- browserId = _state.sent();
2056
- trackingData = _object_spread({
2057
- browserId: browserId
2058
- }, clientInfo);
2059
2204
  return [
2060
2205
  4,
2061
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2062
- licenseKey: licenseKey,
2063
- adLoadedInfo: adLoadedInfo
2064
- }))
2206
+ sendHeartbeat(licenseKey, context, {
2207
+ adLoaded: true,
2208
+ captureAt: adLoadedInfo.timestamp
2209
+ })
2065
2210
  ];
2066
2211
  case 2:
2067
2212
  _state.sent();
@@ -2082,39 +2227,46 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2082
2227
  ];
2083
2228
  }
2084
2229
  });
2085
- })();
2230
+ }).apply(this, arguments);
2086
2231
  }
2087
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2088
- return _async_to_generator(function() {
2089
- var clientInfo, browserId, trackingData, error;
2232
+ function sendAdImpressionTracking(_0, _1) {
2233
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2234
+ var context, metricEvent, error;
2235
+ var _arguments = arguments;
2090
2236
  return _ts_generator(this, function(_state) {
2091
2237
  switch(_state.label){
2092
2238
  case 0:
2239
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2240
+ if (!canPublish(licenseKey)) return [
2241
+ 2
2242
+ ];
2243
+ _state.label = 1;
2244
+ case 1:
2093
2245
  _state.trys.push([
2094
- 0,
2246
+ 1,
2095
2247
  3,
2096
2248
  ,
2097
2249
  4
2098
2250
  ]);
2099
- clientInfo = getClientInfo();
2100
2251
  return [
2101
2252
  4,
2102
- getBrowserID(clientInfo)
2103
- ];
2104
- case 1:
2105
- browserId = _state.sent();
2106
- trackingData = _object_spread({
2107
- browserId: browserId
2108
- }, clientInfo);
2109
- return [
2110
- 4,
2111
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2112
- licenseKey: licenseKey,
2113
- adImpressionInfo: adImpressionInfo
2114
- }))
2253
+ buildPlayerMetricEvent(context, {
2254
+ captureAt: adImpressionInfo.timestamp
2255
+ })
2115
2256
  ];
2116
2257
  case 2:
2117
- _state.sent();
2258
+ metricEvent = _state.sent();
2259
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2260
+ publishTracking(licenseKey, "impressions", {
2261
+ events: [
2262
+ {
2263
+ player_id: metricEvent.player_id,
2264
+ ad_played_count: 1,
2265
+ ad_url: adImpressionInfo.adUrl,
2266
+ capture_at: adImpressionInfo.timestamp
2267
+ }
2268
+ ]
2269
+ });
2118
2270
  return [
2119
2271
  3,
2120
2272
  4
@@ -2132,74 +2284,52 @@ function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2132
2284
  ];
2133
2285
  }
2134
2286
  });
2135
- })();
2287
+ }).apply(this, arguments);
2136
2288
  }
2137
- function sendHeartbeat(licenseKey) {
2138
- return _async_to_generator(function() {
2139
- var clientInfo, browserId, heartbeatData, headers, response, error;
2289
+ function sendHeartbeat(_0) {
2290
+ return _async_to_generator(function(licenseKey) {
2291
+ var context, flags, heartbeatData, error;
2292
+ var _arguments = arguments;
2140
2293
  return _ts_generator(this, function(_state) {
2141
2294
  switch(_state.label){
2142
2295
  case 0:
2296
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2297
+ if (!canPublish(licenseKey)) return [
2298
+ 2
2299
+ ];
2300
+ _state.label = 1;
2301
+ case 1:
2143
2302
  _state.trys.push([
2144
- 0,
2145
- 4,
2303
+ 1,
2304
+ 3,
2146
2305
  ,
2147
- 5
2306
+ 4
2148
2307
  ]);
2149
- clientInfo = getClientInfo();
2150
- return [
2151
- 4,
2152
- getBrowserID(clientInfo)
2153
- ];
2154
- case 1:
2155
- browserId = _state.sent();
2156
- heartbeatData = {
2157
- browserId: browserId,
2158
- timestamp: /* @__PURE__ */ new Date().toISOString()
2159
- };
2160
- headers = {
2161
- "Content-Type": "application/json"
2162
- };
2163
- if (licenseKey) {
2164
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2165
- }
2166
2308
  return [
2167
2309
  4,
2168
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2169
- method: "POST",
2170
- headers: headers,
2171
- body: JSON.stringify(heartbeatData)
2172
- })
2310
+ buildPlayerMetricEvent(context, flags)
2173
2311
  ];
2174
2312
  case 2:
2175
- response = _state.sent();
2176
- if (!response.ok) {
2177
- throw new Error("HTTP error! status: ".concat(response.status));
2178
- }
2179
- return [
2180
- 4,
2181
- response.json()
2182
- ];
2183
- case 3:
2184
- _state.sent();
2313
+ heartbeatData = _state.sent();
2314
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2185
2315
  return [
2186
2316
  3,
2187
- 5
2317
+ 4
2188
2318
  ];
2189
- case 4:
2319
+ case 3:
2190
2320
  error = _state.sent();
2191
2321
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2192
2322
  return [
2193
2323
  3,
2194
- 5
2324
+ 4
2195
2325
  ];
2196
- case 5:
2326
+ case 4:
2197
2327
  return [
2198
2328
  2
2199
2329
  ];
2200
2330
  }
2201
2331
  });
2202
- })();
2332
+ }).apply(this, arguments);
2203
2333
  }
2204
2334
  // src/utils/polyfills.ts
2205
2335
  function polyfillURLSearchParams() {
@@ -2789,6 +2919,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2789
2919
  this.config = _object_spread({}, browserOverrides, config);
2790
2920
  this.video = config.videoElement;
2791
2921
  this.adTransitionGapMs = (_this_config_adTransitionGapMs = this.config.adTransitionGapMs) !== null && _this_config_adTransitionGapMs !== void 0 ? _this_config_adTransitionGapMs : 100;
2922
+ if (this.config.mqttConfig) {
2923
+ configureMQTT(this.config.mqttConfig);
2924
+ }
2792
2925
  logBrowserInfo(config.debugAdTiming);
2793
2926
  var browserForAdLayer = detectBrowser();
2794
2927
  var isSinglePipeline = browserForAdLayer.isSmartTV || !!this.config.singlePipelineMode;
@@ -3156,7 +3289,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3156
3289
  source: _this.getAdSource(),
3157
3290
  adIndex: _this.currentAdIndex,
3158
3291
  timestamp: /* @__PURE__ */ new Date().toISOString()
3159
- });
3292
+ }, _this.getPlayerAnalyticsContext());
3160
3293
  }
3161
3294
  });
3162
3295
  this.adLayer.on("ad_error", function(errorPayload) {
@@ -3461,7 +3594,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3461
3594
  key: "initializeTracking",
3462
3595
  value: function initializeTracking() {
3463
3596
  var _this = this;
3464
- sendInitialTracking(this.config.licenseKey).then(function() {
3597
+ sendInitialTracking(this.config.licenseKey, this.getPlayerAnalyticsContext()).then(function() {
3465
3598
  _this.heartbeatInterval = window.setInterval(function() {
3466
3599
  _this.sendHeartbeatIfNeeded();
3467
3600
  }, 5e3);
@@ -3482,7 +3615,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3482
3615
  var now = Date.now();
3483
3616
  if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
3484
3617
  this.lastHeartbeatTime = now;
3485
- sendHeartbeat(this.config.licenseKey).catch(function(error) {
3618
+ sendHeartbeat(this.config.licenseKey, this.getPlayerAnalyticsContext()).catch(function(error) {
3486
3619
  if (_this.config.debugAdTiming) {
3487
3620
  console.warn("[StormcloudVideoPlayer] Failed to send heartbeat:", error);
3488
3621
  }
@@ -3576,6 +3709,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3576
3709
  return "other";
3577
3710
  }
3578
3711
  },
3712
+ {
3713
+ key: "getPlayerAnalyticsContext",
3714
+ value: function getPlayerAnalyticsContext() {
3715
+ return {
3716
+ inputStreamType: this.getStreamType()
3717
+ };
3718
+ }
3719
+ },
3579
3720
  {
3580
3721
  key: "shouldShowNativeControls",
3581
3722
  value: function shouldShowNativeControls() {
@@ -4230,7 +4371,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4230
4371
  sendAdLoadedTracking(_this.config.licenseKey, {
4231
4372
  source: _this.getAdSource(),
4232
4373
  timestamp: /* @__PURE__ */ new Date().toISOString()
4233
- });
4374
+ }, _this.getPlayerAnalyticsContext());
4234
4375
  }
4235
4376
  return [
4236
4377
  4,
@@ -4340,7 +4481,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4340
4481
  sendAdLoadedTracking(_this.config.licenseKey, {
4341
4482
  source: _this.getAdSource(),
4342
4483
  timestamp: /* @__PURE__ */ new Date().toISOString()
4343
- });
4484
+ }, _this.getPlayerAnalyticsContext());
4344
4485
  }
4345
4486
  return [
4346
4487
  4,
@@ -4507,7 +4648,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4507
4648
  sendAdLoadedTracking(this.config.licenseKey, {
4508
4649
  source: this.getAdSource(),
4509
4650
  timestamp: /* @__PURE__ */ new Date().toISOString()
4510
- });
4651
+ }, this.getPlayerAnalyticsContext());
4511
4652
  }
4512
4653
  _state.label = 1;
4513
4654
  case 1:
@@ -4706,7 +4847,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4706
4847
  sendAdLoadedTracking(this.config.licenseKey, {
4707
4848
  source: this.getAdSource(),
4708
4849
  timestamp: /* @__PURE__ */ new Date().toISOString()
4709
- });
4850
+ }, this.getPlayerAnalyticsContext());
4710
4851
  }
4711
4852
  return [
4712
4853
  4,
@@ -5651,6 +5792,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5651
5792
  clearInterval(this.heartbeatInterval);
5652
5793
  this.heartbeatInterval = void 0;
5653
5794
  }
5795
+ if (isMQTTEnabled()) {
5796
+ disconnectMQTT();
5797
+ }
5654
5798
  (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.destroy();
5655
5799
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
5656
5800
  this.consecutiveFailures = 0;
@@ -7251,38 +7395,44 @@ function hexToRgb(hex) {
7251
7395
  return "".concat(num >> 16 & 255, ",").concat(num >> 8 & 255, ",").concat(num & 255);
7252
7396
  }
7253
7397
  var FADE_DURATION_MS = 1e3;
7254
- var VALID_ENTER_ANIMATIONS = /* @__PURE__ */ new Set([
7255
- "fade",
7256
- "slide_left",
7257
- "slide_right",
7258
- "slide_up",
7259
- "slide_down"
7260
- ]);
7398
+ var ENTER_ANIMATION_ALIASES = {
7399
+ fade: "fade",
7400
+ slide_from_left: "slide_from_left",
7401
+ slide_from_right: "slide_from_right",
7402
+ slide_from_top: "slide_from_top",
7403
+ slide_from_bottom: "slide_from_bottom",
7404
+ slide_left: "slide_from_left",
7405
+ slide_right: "slide_from_right",
7406
+ slide_up: "slide_from_top",
7407
+ slide_down: "slide_from_bottom"
7408
+ };
7409
+ function normalizeEnterAnimation(v) {
7410
+ var _ENTER_ANIMATION_ALIASES_v;
7411
+ if (typeof v !== "string") return null;
7412
+ return (_ENTER_ANIMATION_ALIASES_v = ENTER_ANIMATION_ALIASES[v]) !== null && _ENTER_ANIMATION_ALIASES_v !== void 0 ? _ENTER_ANIMATION_ALIASES_v : null;
7413
+ }
7261
7414
  function getEnterAnimation(overlay) {
7262
7415
  var flat = overlay.enter_animation;
7263
- if (typeof flat === "string" && VALID_ENTER_ANIMATIONS.has(flat)) {
7264
- return flat;
7265
- }
7416
+ var fromFlat = normalizeEnterAnimation(flat);
7417
+ if (fromFlat) return fromFlat;
7266
7418
  if (overlay.content) {
7267
7419
  try {
7268
7420
  var parsed = JSON.parse(overlay.content);
7269
- var v = parsed === null || parsed === void 0 ? void 0 : parsed.enterAnimation;
7270
- if (typeof v === "string" && VALID_ENTER_ANIMATIONS.has(v)) {
7271
- return v;
7272
- }
7421
+ var fromContent = normalizeEnterAnimation(parsed === null || parsed === void 0 ? void 0 : parsed.enterAnimation);
7422
+ if (fromContent) return fromContent;
7273
7423
  } catch (unused) {}
7274
7424
  }
7275
7425
  return "fade";
7276
7426
  }
7277
7427
  function enterHiddenTransform(anim) {
7278
7428
  switch(anim){
7279
- case "slide_left":
7429
+ case "slide_from_left":
7280
7430
  return "translateX(-120%)";
7281
- case "slide_right":
7431
+ case "slide_from_right":
7282
7432
  return "translateX(120%)";
7283
- case "slide_up":
7433
+ case "slide_from_top":
7284
7434
  return "translateY(-120%)";
7285
- case "slide_down":
7435
+ case "slide_from_bottom":
7286
7436
  return "translateY(120%)";
7287
7437
  default:
7288
7438
  return "";
@@ -7843,7 +7993,18 @@ var CRITICAL_PROPS = [
7843
7993
  "licenseKey",
7844
7994
  "lowLatencyMode",
7845
7995
  "driftToleranceMs",
7846
- "debugAdTiming"
7996
+ "immediateManifestAds",
7997
+ "debugAdTiming",
7998
+ "showCustomControls",
7999
+ "adFailsafeTimeoutMs",
8000
+ "minSegmentsBeforePlay",
8001
+ "disableAds",
8002
+ "disableFiller",
8003
+ "singlePipelineMode",
8004
+ "mqttConfig",
8005
+ "adBreakCheckIntervalMs",
8006
+ "maxAdBreakExtensionMs",
8007
+ "adTransitionGapMs"
7847
8008
  ];
7848
8009
  var CONTROLS_HIDE_DELAY = 3e3;
7849
8010
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
@@ -7854,7 +8015,7 @@ var PANEL_BASE_RIGHT_OFFSET = 10;
7854
8015
  var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7855
8016
  var _ref;
7856
8017
  var _aiLiveContext_context;
7857
- var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, 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, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, swirlProjectId = props.swirlProjectId, swirlShowcaseDemo = props.swirlShowcaseDemo, swirlOverlayApiBaseUrl = props.swirlOverlayApiBaseUrl, swirlOverlayCoordinateSpace = props.swirlOverlayCoordinateSpace, adcisionChannelId = props.adcisionChannelId, disableOverlays = props.disableOverlays, showAdsControl = props.showAdsControl, showOverlaysControl = props.showOverlaysControl, showAiContextControl = props.showAiContextControl, showDebugControl = props.showDebugControl, restVideoAttrs = _object_without_properties(props, [
8018
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, 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, adFailsafeTimeoutMs = props.adFailsafeTimeoutMs, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, singlePipelineMode = props.singlePipelineMode, mqttConfig2 = props.mqttConfig, adBreakCheckIntervalMs = props.adBreakCheckIntervalMs, maxAdBreakExtensionMs = props.maxAdBreakExtensionMs, adTransitionGapMs = props.adTransitionGapMs, swirlProjectId = props.swirlProjectId, swirlShowcaseDemo = props.swirlShowcaseDemo, swirlOverlayApiBaseUrl = props.swirlOverlayApiBaseUrl, swirlOverlayCoordinateSpace = props.swirlOverlayCoordinateSpace, adcisionChannelId = props.adcisionChannelId, disableOverlays = props.disableOverlays, showAdsControl = props.showAdsControl, showOverlaysControl = props.showOverlaysControl, showAiContextControl = props.showAiContextControl, showDebugControl = props.showDebugControl, restVideoAttrs = _object_without_properties(props, [
7858
8019
  "src",
7859
8020
  "autoplay",
7860
8021
  "muted",
@@ -7879,9 +8040,15 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7879
8040
  "poster",
7880
8041
  "children",
7881
8042
  "licenseKey",
8043
+ "adFailsafeTimeoutMs",
7882
8044
  "minSegmentsBeforePlay",
7883
8045
  "disableAds",
7884
8046
  "disableFiller",
8047
+ "singlePipelineMode",
8048
+ "mqttConfig",
8049
+ "adBreakCheckIntervalMs",
8050
+ "maxAdBreakExtensionMs",
8051
+ "adTransitionGapMs",
7885
8052
  "swirlProjectId",
7886
8053
  "swirlShowcaseDemo",
7887
8054
  "swirlOverlayApiBaseUrl",
@@ -8122,7 +8289,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8122
8289
  var debugPanelBottomOffset = shouldShowEnhancedControls ? Math.max(74, 92 * responsiveScale) : Math.max(52, 58 * responsiveScale);
8123
8290
  var criticalPropsKey = useMemo2(function() {
8124
8291
  var baseParts = CRITICAL_PROPS.map(function(prop) {
8125
- return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(props[prop]);
8292
+ return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(JSON.stringify(props[prop]));
8126
8293
  }).join("|");
8127
8294
  return "".concat(baseParts, "|adcisionChannelId:").concat(adcisionChannelId !== null && adcisionChannelId !== void 0 ? adcisionChannelId : "");
8128
8295
  }, [
@@ -8131,8 +8298,19 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8131
8298
  licenseKey,
8132
8299
  lowLatencyMode,
8133
8300
  driftToleranceMs,
8301
+ immediateManifestAds,
8134
8302
  adcisionChannelId,
8135
- debugAdTiming
8303
+ debugAdTiming,
8304
+ showCustomControls,
8305
+ adFailsafeTimeoutMs,
8306
+ minSegmentsBeforePlay,
8307
+ disableAds,
8308
+ disableFiller,
8309
+ singlePipelineMode,
8310
+ mqttConfig2,
8311
+ adBreakCheckIntervalMs,
8312
+ maxAdBreakExtensionMs,
8313
+ adTransitionGapMs
8136
8314
  ]);
8137
8315
  useEffect2(function() {
8138
8316
  if (typeof window === "undefined") return;
@@ -8166,9 +8344,15 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8166
8344
  if (onFullscreenToggle !== void 0) cfg.onFullscreenToggle = onFullscreenToggle;
8167
8345
  if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
8168
8346
  if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
8347
+ if (adFailsafeTimeoutMs !== void 0) cfg.adFailsafeTimeoutMs = adFailsafeTimeoutMs;
8169
8348
  if (minSegmentsBeforePlay !== void 0) cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
8170
8349
  if (disableAds !== void 0) cfg.disableAds = disableAds;
8171
8350
  cfg.disableFiller = disableFiller !== null && disableFiller !== void 0 ? disableFiller : true;
8351
+ if (singlePipelineMode !== void 0) cfg.singlePipelineMode = singlePipelineMode;
8352
+ if (mqttConfig2 !== void 0) cfg.mqttConfig = mqttConfig2;
8353
+ if (adBreakCheckIntervalMs !== void 0) cfg.adBreakCheckIntervalMs = adBreakCheckIntervalMs;
8354
+ if (maxAdBreakExtensionMs !== void 0) cfg.maxAdBreakExtensionMs = maxAdBreakExtensionMs;
8355
+ if (adTransitionGapMs !== void 0) cfg.adTransitionGapMs = adTransitionGapMs;
8172
8356
  if (adcisionChannelId !== void 0) {
8173
8357
  cfg.projectId = String(adcisionChannelId);
8174
8358
  cfg.channelId = adcisionChannelId;
@@ -11309,5 +11493,5 @@ var createStormcloudPlayer = function createStormcloudPlayer(playerList, fallbac
11309
11493
  };
11310
11494
  var StormcloudPlayer = createStormcloudPlayer(players_default, players_default[players_default.length - 1]);
11311
11495
  var StormcloudPlayer_default = StormcloudPlayer;
11312
- export { IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, OVERLAY_API_BASE, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, canPlay, createAdStormPlayer, createStormcloudPlayer, StormcloudVideoPlayerComponent as default, detectBrowser, fetchProjectOverlays, getBrowserConfigOverrides, getBrowserID, getClientInfo, initializePolyfills, isMediaStream, isOverlayActive, lazy, logBrowserInfo, merge, normalizeSwirlOverlay, omit, parseQuery, players_default as players, randomString, resolveImageUrl, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode, timeStringToSeconds };
11496
+ export { DEFAULT_MQTT_CONFIG, IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, MQTT_CA_CERT_FILE, OVERLAY_API_BASE, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, applyMQTTConfig, buildMQTTBrokerUrl, buildPlayerTopic, canPlay, configureMQTT, createAdStormPlayer, createStormcloudPlayer, StormcloudVideoPlayerComponent as default, detectBrowser, disconnectMQTT, ensureMQTTClient, fetchProjectOverlays, getBrowserConfigOverrides, getBrowserID, getClientInfo, getMQTTStatus, initMQTTClient, initializePolyfills, isMQTTConfigured, isMQTTConnected, isMQTTEnabled, isMediaStream, isOverlayActive, lazy, logBrowserInfo, merge, mqttConfig, normalizeSwirlOverlay, omit, parseQuery, players_default as players, publishMQTT, randomString, resolveImageUrl, sendAdDetectTracking, sendAdImpressionTracking, sendAdLoadedTracking, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode, timeStringToSeconds };
11313
11497
  //# sourceMappingURL=index.js.map