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.cjs CHANGED
@@ -428,6 +428,9 @@ var __toCommonJS = function __toCommonJS(mod) {
428
428
  // src/index.ts
429
429
  var index_exports = {};
430
430
  __export(index_exports, {
431
+ DEFAULT_MQTT_CONFIG: function DEFAULT_MQTT_CONFIG1() {
432
+ return DEFAULT_MQTT_CONFIG;
433
+ },
431
434
  IS_BROWSER: function IS_BROWSER1() {
432
435
  return IS_BROWSER;
433
436
  },
@@ -440,6 +443,9 @@ __export(index_exports, {
440
443
  IS_SAFARI: function IS_SAFARI1() {
441
444
  return IS_SAFARI;
442
445
  },
446
+ MQTT_CA_CERT_FILE: function MQTT_CA_CERT_FILE1() {
447
+ return MQTT_CA_CERT_FILE;
448
+ },
443
449
  OVERLAY_API_BASE: function OVERLAY_API_BASE1() {
444
450
  return OVERLAY_API_BASE;
445
451
  },
@@ -458,9 +464,21 @@ __export(index_exports, {
458
464
  StormcloudVideoPlayerComponent: function StormcloudVideoPlayerComponent1() {
459
465
  return StormcloudVideoPlayerComponent;
460
466
  },
467
+ applyMQTTConfig: function applyMQTTConfig1() {
468
+ return applyMQTTConfig;
469
+ },
470
+ buildMQTTBrokerUrl: function buildMQTTBrokerUrl1() {
471
+ return buildMQTTBrokerUrl;
472
+ },
473
+ buildPlayerTopic: function buildPlayerTopic1() {
474
+ return buildPlayerTopic;
475
+ },
461
476
  canPlay: function canPlay1() {
462
477
  return canPlay;
463
478
  },
479
+ configureMQTT: function configureMQTT1() {
480
+ return configureMQTT;
481
+ },
464
482
  createAdStormPlayer: function createAdStormPlayer1() {
465
483
  return createAdStormPlayer;
466
484
  },
@@ -473,6 +491,12 @@ __export(index_exports, {
473
491
  detectBrowser: function detectBrowser1() {
474
492
  return detectBrowser;
475
493
  },
494
+ disconnectMQTT: function disconnectMQTT1() {
495
+ return disconnectMQTT;
496
+ },
497
+ ensureMQTTClient: function ensureMQTTClient1() {
498
+ return ensureMQTTClient;
499
+ },
476
500
  fetchProjectOverlays: function fetchProjectOverlays1() {
477
501
  return fetchProjectOverlays;
478
502
  },
@@ -485,9 +509,24 @@ __export(index_exports, {
485
509
  getClientInfo: function getClientInfo1() {
486
510
  return getClientInfo;
487
511
  },
512
+ getMQTTStatus: function getMQTTStatus1() {
513
+ return getMQTTStatus;
514
+ },
515
+ initMQTTClient: function initMQTTClient1() {
516
+ return initMQTTClient;
517
+ },
488
518
  initializePolyfills: function initializePolyfills1() {
489
519
  return initializePolyfills;
490
520
  },
521
+ isMQTTConfigured: function isMQTTConfigured1() {
522
+ return isMQTTConfigured;
523
+ },
524
+ isMQTTConnected: function isMQTTConnected1() {
525
+ return isMQTTConnected;
526
+ },
527
+ isMQTTEnabled: function isMQTTEnabled1() {
528
+ return isMQTTEnabled;
529
+ },
491
530
  isMediaStream: function isMediaStream1() {
492
531
  return isMediaStream;
493
532
  },
@@ -503,6 +542,9 @@ __export(index_exports, {
503
542
  merge: function merge1() {
504
543
  return merge;
505
544
  },
545
+ mqttConfig: function mqttConfig1() {
546
+ return mqttConfig;
547
+ },
506
548
  normalizeSwirlOverlay: function normalizeSwirlOverlay1() {
507
549
  return normalizeSwirlOverlay;
508
550
  },
@@ -515,12 +557,24 @@ __export(index_exports, {
515
557
  players: function players() {
516
558
  return players_default;
517
559
  },
560
+ publishMQTT: function publishMQTT1() {
561
+ return publishMQTT;
562
+ },
518
563
  randomString: function randomString1() {
519
564
  return randomString;
520
565
  },
521
566
  resolveImageUrl: function resolveImageUrl1() {
522
567
  return resolveImageUrl;
523
568
  },
569
+ sendAdDetectTracking: function sendAdDetectTracking1() {
570
+ return sendAdDetectTracking;
571
+ },
572
+ sendAdImpressionTracking: function sendAdImpressionTracking1() {
573
+ return sendAdImpressionTracking;
574
+ },
575
+ sendAdLoadedTracking: function sendAdLoadedTracking1() {
576
+ return sendAdLoadedTracking;
577
+ },
524
578
  sendHeartbeat: function sendHeartbeat1() {
525
579
  return sendHeartbeat;
526
580
  },
@@ -1874,6 +1928,126 @@ function createAdStormPlayer(contentVideo, options) {
1874
1928
  }
1875
1929
  };
1876
1930
  }
1931
+ // src/utils/mqttClient.ts
1932
+ var import_mqtt = __toESM(require("mqtt"), 1);
1933
+ // src/utils/mqttConfig.ts
1934
+ var MQTT_CA_CERT_FILE = "src/certs/emqxsl-ca.crt";
1935
+ var DEFAULT_MQTT_CONFIG = {
1936
+ enabled: true,
1937
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
1938
+ brokerPort: 8883,
1939
+ wsPort: 8084,
1940
+ username: "for-sonifi",
1941
+ password: "sonifi-mqtt",
1942
+ topicPrefix: "adstorm/players",
1943
+ qos: 1
1944
+ };
1945
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
1946
+ function applyMQTTConfig(overrides) {
1947
+ Object.assign(mqttConfig, overrides);
1948
+ }
1949
+ function isMQTTEnabled() {
1950
+ return mqttConfig.enabled;
1951
+ }
1952
+ function buildMQTTBrokerUrl() {
1953
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
1954
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
1955
+ }
1956
+ function buildPlayerTopic(licenseKey, channel) {
1957
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
1958
+ }
1959
+ // src/utils/mqttClient.ts
1960
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
1961
+ var client = null;
1962
+ var status = "disconnected";
1963
+ function getMQTTStatus() {
1964
+ return status;
1965
+ }
1966
+ function isMQTTConnected() {
1967
+ return status === "connected" && client !== null && client.connected;
1968
+ }
1969
+ function isMQTTConfigured() {
1970
+ return isMQTTEnabled();
1971
+ }
1972
+ function configureMQTT(overrides) {
1973
+ applyMQTTConfig(overrides);
1974
+ disconnectMQTT();
1975
+ }
1976
+ function initMQTTClient() {
1977
+ if (client || !isMQTTEnabled()) return;
1978
+ var url = buildMQTTBrokerUrl();
1979
+ status = "connecting";
1980
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
1981
+ try {
1982
+ client = import_mqtt.default.connect(url, {
1983
+ clientId: clientId,
1984
+ username: mqttConfig.username,
1985
+ password: mqttConfig.password,
1986
+ keepalive: 60,
1987
+ clean: true,
1988
+ reconnectPeriod: 5e3,
1989
+ connectTimeout: 1e4,
1990
+ queueQoSZero: false
1991
+ });
1992
+ } catch (err) {
1993
+ status = "error";
1994
+ console.warn("".concat(LOG, " connect() threw:"), err);
1995
+ return;
1996
+ }
1997
+ client.on("connect", function() {
1998
+ status = "connected";
1999
+ console.info("".concat(LOG, " connected to ").concat(url));
2000
+ });
2001
+ client.on("reconnect", function() {
2002
+ status = "connecting";
2003
+ console.info("".concat(LOG, " reconnecting..."));
2004
+ });
2005
+ client.on("offline", function() {
2006
+ if (status !== "error") {
2007
+ status = "disconnected";
2008
+ }
2009
+ console.warn("".concat(LOG, " offline"));
2010
+ });
2011
+ client.on("error", function(err) {
2012
+ status = "error";
2013
+ console.warn("".concat(LOG, " error:"), err.message);
2014
+ });
2015
+ client.on("close", function() {
2016
+ if (status === "connected" || status === "connecting") {
2017
+ status = "disconnected";
2018
+ }
2019
+ });
2020
+ }
2021
+ function ensureMQTTClient() {
2022
+ if (isMQTTEnabled() && !client) {
2023
+ initMQTTClient();
2024
+ }
2025
+ }
2026
+ function publishMQTT(topic, payload) {
2027
+ if (!isMQTTEnabled()) {
2028
+ return false;
2029
+ }
2030
+ ensureMQTTClient();
2031
+ if (!client) {
2032
+ return false;
2033
+ }
2034
+ try {
2035
+ client.publish(topic, JSON.stringify(payload), {
2036
+ qos: mqttConfig.qos
2037
+ });
2038
+ return true;
2039
+ } catch (err) {
2040
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
2041
+ return false;
2042
+ }
2043
+ }
2044
+ function disconnectMQTT() {
2045
+ if (client) {
2046
+ client.end(true);
2047
+ client = null;
2048
+ status = "disconnected";
2049
+ }
2050
+ }
1877
2051
  // src/utils/tracking.ts
1878
2052
  var cachedBrowserId = null;
1879
2053
  function getClientInfo() {
@@ -2104,139 +2278,164 @@ function getBrowserID(clientInfo) {
2104
2278
  });
2105
2279
  })();
2106
2280
  }
2107
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2108
- function sendTrackRequest(licenseKey, body) {
2281
+ function canPublish(licenseKey) {
2282
+ return Boolean(isMQTTEnabled() && licenseKey);
2283
+ }
2284
+ function buildPlayerMetricEvent() {
2109
2285
  return _async_to_generator(function() {
2110
- var headers, response;
2286
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2287
+ var _arguments = arguments;
2111
2288
  return _ts_generator(this, function(_state) {
2112
2289
  switch(_state.label){
2113
2290
  case 0:
2114
- headers = {
2115
- "Content-Type": "application/json"
2116
- };
2117
- if (licenseKey) {
2118
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2119
- }
2291
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2292
+ clientInfo = getClientInfo();
2120
2293
  return [
2121
2294
  4,
2122
- fetch(TRACK_URL, {
2123
- method: "POST",
2124
- headers: headers,
2125
- body: JSON.stringify(body)
2126
- })
2295
+ getBrowserID(clientInfo)
2127
2296
  ];
2128
2297
  case 1:
2129
- response = _state.sent();
2130
- if (!response.ok) {
2131
- throw new Error("HTTP error! status: ".concat(response.status));
2132
- }
2298
+ playerId = _state.sent();
2299
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2300
+ return [
2301
+ 2,
2302
+ _object_spread({
2303
+ player_id: playerId,
2304
+ device_type: clientInfo.deviceType,
2305
+ os: clientInfo.os.toLowerCase(),
2306
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2307
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2308
+ capture_at: captureAt
2309
+ }, context.inputStreamType ? {
2310
+ input_stream_type: context.inputStreamType
2311
+ } : {})
2312
+ ];
2313
+ }
2314
+ });
2315
+ }).apply(this, arguments);
2316
+ }
2317
+ function publishTracking(licenseKey, channel, body) {
2318
+ ensureMQTTClient();
2319
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2320
+ }
2321
+ function sendInitialTracking(_0) {
2322
+ return _async_to_generator(function(licenseKey) {
2323
+ var context, metricEvent, error;
2324
+ var _arguments = arguments;
2325
+ return _ts_generator(this, function(_state) {
2326
+ switch(_state.label){
2327
+ case 0:
2328
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2329
+ if (!canPublish(licenseKey)) return [
2330
+ 2
2331
+ ];
2332
+ _state.label = 1;
2333
+ case 1:
2334
+ _state.trys.push([
2335
+ 1,
2336
+ 3,
2337
+ ,
2338
+ 4
2339
+ ]);
2133
2340
  return [
2134
2341
  4,
2135
- response.json()
2342
+ buildPlayerMetricEvent(context, {
2343
+ adLoaded: false,
2344
+ adDetect: false
2345
+ })
2136
2346
  ];
2137
2347
  case 2:
2138
- _state.sent();
2348
+ metricEvent = _state.sent();
2349
+ publishTracking(licenseKey, "metrics", {
2350
+ events: [
2351
+ metricEvent
2352
+ ]
2353
+ });
2354
+ return [
2355
+ 3,
2356
+ 4
2357
+ ];
2358
+ case 3:
2359
+ error = _state.sent();
2360
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2361
+ return [
2362
+ 3,
2363
+ 4
2364
+ ];
2365
+ case 4:
2139
2366
  return [
2140
2367
  2
2141
2368
  ];
2142
2369
  }
2143
2370
  });
2144
- })();
2371
+ }).apply(this, arguments);
2145
2372
  }
2146
- function sendInitialTracking(licenseKey) {
2147
- return _async_to_generator(function() {
2148
- var clientInfo, browserId, trackingData, headers, response, error;
2373
+ function sendAdDetectTracking(_0, _1) {
2374
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2375
+ var context, error;
2376
+ var _arguments = arguments;
2149
2377
  return _ts_generator(this, function(_state) {
2150
2378
  switch(_state.label){
2151
2379
  case 0:
2380
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2381
+ _state.label = 1;
2382
+ case 1:
2152
2383
  _state.trys.push([
2153
- 0,
2154
- 4,
2384
+ 1,
2385
+ 3,
2155
2386
  ,
2156
- 5
2387
+ 4
2157
2388
  ]);
2158
- clientInfo = getClientInfo();
2159
- return [
2160
- 4,
2161
- getBrowserID(clientInfo)
2162
- ];
2163
- case 1:
2164
- browserId = _state.sent();
2165
- trackingData = _object_spread({
2166
- browserId: browserId
2167
- }, clientInfo);
2168
- headers = {
2169
- "Content-Type": "application/json"
2170
- };
2171
- if (licenseKey) {
2172
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2173
- }
2174
2389
  return [
2175
2390
  4,
2176
- fetch(TRACK_URL, {
2177
- method: "POST",
2178
- headers: headers,
2179
- body: JSON.stringify(trackingData)
2391
+ sendHeartbeat(licenseKey, context, {
2392
+ adDetect: true,
2393
+ captureAt: adDetectInfo.timestamp
2180
2394
  })
2181
2395
  ];
2182
2396
  case 2:
2183
- response = _state.sent();
2184
- if (!response.ok) {
2185
- throw new Error("HTTP error! status: ".concat(response.status));
2186
- }
2187
- return [
2188
- 4,
2189
- response.json()
2190
- ];
2191
- case 3:
2192
2397
  _state.sent();
2193
2398
  return [
2194
2399
  3,
2195
- 5
2400
+ 4
2196
2401
  ];
2197
- case 4:
2402
+ case 3:
2198
2403
  error = _state.sent();
2199
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2404
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2200
2405
  return [
2201
2406
  3,
2202
- 5
2407
+ 4
2203
2408
  ];
2204
- case 5:
2409
+ case 4:
2205
2410
  return [
2206
2411
  2
2207
2412
  ];
2208
2413
  }
2209
2414
  });
2210
- })();
2415
+ }).apply(this, arguments);
2211
2416
  }
2212
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2213
- return _async_to_generator(function() {
2214
- var clientInfo, browserId, trackingData, error;
2417
+ function sendAdLoadedTracking(_0, _1) {
2418
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2419
+ var context, error;
2420
+ var _arguments = arguments;
2215
2421
  return _ts_generator(this, function(_state) {
2216
2422
  switch(_state.label){
2217
2423
  case 0:
2424
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2425
+ _state.label = 1;
2426
+ case 1:
2218
2427
  _state.trys.push([
2219
- 0,
2428
+ 1,
2220
2429
  3,
2221
2430
  ,
2222
2431
  4
2223
2432
  ]);
2224
- clientInfo = getClientInfo();
2225
- return [
2226
- 4,
2227
- getBrowserID(clientInfo)
2228
- ];
2229
- case 1:
2230
- browserId = _state.sent();
2231
- trackingData = _object_spread({
2232
- browserId: browserId
2233
- }, clientInfo);
2234
2433
  return [
2235
2434
  4,
2236
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2237
- licenseKey: licenseKey,
2238
- adLoadedInfo: adLoadedInfo
2239
- }))
2435
+ sendHeartbeat(licenseKey, context, {
2436
+ adLoaded: true,
2437
+ captureAt: adLoadedInfo.timestamp
2438
+ })
2240
2439
  ];
2241
2440
  case 2:
2242
2441
  _state.sent();
@@ -2257,39 +2456,46 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2257
2456
  ];
2258
2457
  }
2259
2458
  });
2260
- })();
2459
+ }).apply(this, arguments);
2261
2460
  }
2262
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2263
- return _async_to_generator(function() {
2264
- var clientInfo, browserId, trackingData, error;
2461
+ function sendAdImpressionTracking(_0, _1) {
2462
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2463
+ var context, metricEvent, error;
2464
+ var _arguments = arguments;
2265
2465
  return _ts_generator(this, function(_state) {
2266
2466
  switch(_state.label){
2267
2467
  case 0:
2468
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2469
+ if (!canPublish(licenseKey)) return [
2470
+ 2
2471
+ ];
2472
+ _state.label = 1;
2473
+ case 1:
2268
2474
  _state.trys.push([
2269
- 0,
2475
+ 1,
2270
2476
  3,
2271
2477
  ,
2272
2478
  4
2273
2479
  ]);
2274
- clientInfo = getClientInfo();
2275
- return [
2276
- 4,
2277
- getBrowserID(clientInfo)
2278
- ];
2279
- case 1:
2280
- browserId = _state.sent();
2281
- trackingData = _object_spread({
2282
- browserId: browserId
2283
- }, clientInfo);
2284
2480
  return [
2285
2481
  4,
2286
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2287
- licenseKey: licenseKey,
2288
- adImpressionInfo: adImpressionInfo
2289
- }))
2482
+ buildPlayerMetricEvent(context, {
2483
+ captureAt: adImpressionInfo.timestamp
2484
+ })
2290
2485
  ];
2291
2486
  case 2:
2292
- _state.sent();
2487
+ metricEvent = _state.sent();
2488
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2489
+ publishTracking(licenseKey, "impressions", {
2490
+ events: [
2491
+ {
2492
+ player_id: metricEvent.player_id,
2493
+ ad_played_count: 1,
2494
+ ad_url: adImpressionInfo.adUrl,
2495
+ capture_at: adImpressionInfo.timestamp
2496
+ }
2497
+ ]
2498
+ });
2293
2499
  return [
2294
2500
  3,
2295
2501
  4
@@ -2307,74 +2513,52 @@ function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2307
2513
  ];
2308
2514
  }
2309
2515
  });
2310
- })();
2516
+ }).apply(this, arguments);
2311
2517
  }
2312
- function sendHeartbeat(licenseKey) {
2313
- return _async_to_generator(function() {
2314
- var clientInfo, browserId, heartbeatData, headers, response, error;
2518
+ function sendHeartbeat(_0) {
2519
+ return _async_to_generator(function(licenseKey) {
2520
+ var context, flags, heartbeatData, error;
2521
+ var _arguments = arguments;
2315
2522
  return _ts_generator(this, function(_state) {
2316
2523
  switch(_state.label){
2317
2524
  case 0:
2525
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2526
+ if (!canPublish(licenseKey)) return [
2527
+ 2
2528
+ ];
2529
+ _state.label = 1;
2530
+ case 1:
2318
2531
  _state.trys.push([
2319
- 0,
2320
- 4,
2532
+ 1,
2533
+ 3,
2321
2534
  ,
2322
- 5
2535
+ 4
2323
2536
  ]);
2324
- clientInfo = getClientInfo();
2325
- return [
2326
- 4,
2327
- getBrowserID(clientInfo)
2328
- ];
2329
- case 1:
2330
- browserId = _state.sent();
2331
- heartbeatData = {
2332
- browserId: browserId,
2333
- timestamp: /* @__PURE__ */ new Date().toISOString()
2334
- };
2335
- headers = {
2336
- "Content-Type": "application/json"
2337
- };
2338
- if (licenseKey) {
2339
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2340
- }
2341
2537
  return [
2342
2538
  4,
2343
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2344
- method: "POST",
2345
- headers: headers,
2346
- body: JSON.stringify(heartbeatData)
2347
- })
2539
+ buildPlayerMetricEvent(context, flags)
2348
2540
  ];
2349
2541
  case 2:
2350
- response = _state.sent();
2351
- if (!response.ok) {
2352
- throw new Error("HTTP error! status: ".concat(response.status));
2353
- }
2354
- return [
2355
- 4,
2356
- response.json()
2357
- ];
2358
- case 3:
2359
- _state.sent();
2542
+ heartbeatData = _state.sent();
2543
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2360
2544
  return [
2361
2545
  3,
2362
- 5
2546
+ 4
2363
2547
  ];
2364
- case 4:
2548
+ case 3:
2365
2549
  error = _state.sent();
2366
2550
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2367
2551
  return [
2368
2552
  3,
2369
- 5
2553
+ 4
2370
2554
  ];
2371
- case 5:
2555
+ case 4:
2372
2556
  return [
2373
2557
  2
2374
2558
  ];
2375
2559
  }
2376
2560
  });
2377
- })();
2561
+ }).apply(this, arguments);
2378
2562
  }
2379
2563
  // src/utils/polyfills.ts
2380
2564
  function polyfillURLSearchParams() {
@@ -2961,6 +3145,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2961
3145
  this.config = _object_spread({}, browserOverrides, config);
2962
3146
  this.video = config.videoElement;
2963
3147
  this.adTransitionGapMs = (_this_config_adTransitionGapMs = this.config.adTransitionGapMs) !== null && _this_config_adTransitionGapMs !== void 0 ? _this_config_adTransitionGapMs : 100;
3148
+ if (this.config.mqttConfig) {
3149
+ configureMQTT(this.config.mqttConfig);
3150
+ }
2964
3151
  logBrowserInfo(config.debugAdTiming);
2965
3152
  var browserForAdLayer = detectBrowser();
2966
3153
  var isSinglePipeline = browserForAdLayer.isSmartTV || !!this.config.singlePipelineMode;
@@ -3328,7 +3515,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3328
3515
  source: _this.getAdSource(),
3329
3516
  adIndex: _this.currentAdIndex,
3330
3517
  timestamp: /* @__PURE__ */ new Date().toISOString()
3331
- });
3518
+ }, _this.getPlayerAnalyticsContext());
3332
3519
  }
3333
3520
  });
3334
3521
  this.adLayer.on("ad_error", function(errorPayload) {
@@ -3633,7 +3820,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3633
3820
  key: "initializeTracking",
3634
3821
  value: function initializeTracking() {
3635
3822
  var _this = this;
3636
- sendInitialTracking(this.config.licenseKey).then(function() {
3823
+ sendInitialTracking(this.config.licenseKey, this.getPlayerAnalyticsContext()).then(function() {
3637
3824
  _this.heartbeatInterval = window.setInterval(function() {
3638
3825
  _this.sendHeartbeatIfNeeded();
3639
3826
  }, 5e3);
@@ -3654,7 +3841,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3654
3841
  var now = Date.now();
3655
3842
  if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
3656
3843
  this.lastHeartbeatTime = now;
3657
- sendHeartbeat(this.config.licenseKey).catch(function(error) {
3844
+ sendHeartbeat(this.config.licenseKey, this.getPlayerAnalyticsContext()).catch(function(error) {
3658
3845
  if (_this.config.debugAdTiming) {
3659
3846
  console.warn("[StormcloudVideoPlayer] Failed to send heartbeat:", error);
3660
3847
  }
@@ -3748,6 +3935,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3748
3935
  return "other";
3749
3936
  }
3750
3937
  },
3938
+ {
3939
+ key: "getPlayerAnalyticsContext",
3940
+ value: function getPlayerAnalyticsContext() {
3941
+ return {
3942
+ inputStreamType: this.getStreamType()
3943
+ };
3944
+ }
3945
+ },
3751
3946
  {
3752
3947
  key: "shouldShowNativeControls",
3753
3948
  value: function shouldShowNativeControls() {
@@ -4402,7 +4597,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4402
4597
  sendAdLoadedTracking(_this.config.licenseKey, {
4403
4598
  source: _this.getAdSource(),
4404
4599
  timestamp: /* @__PURE__ */ new Date().toISOString()
4405
- });
4600
+ }, _this.getPlayerAnalyticsContext());
4406
4601
  }
4407
4602
  return [
4408
4603
  4,
@@ -4512,7 +4707,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4512
4707
  sendAdLoadedTracking(_this.config.licenseKey, {
4513
4708
  source: _this.getAdSource(),
4514
4709
  timestamp: /* @__PURE__ */ new Date().toISOString()
4515
- });
4710
+ }, _this.getPlayerAnalyticsContext());
4516
4711
  }
4517
4712
  return [
4518
4713
  4,
@@ -4679,7 +4874,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4679
4874
  sendAdLoadedTracking(this.config.licenseKey, {
4680
4875
  source: this.getAdSource(),
4681
4876
  timestamp: /* @__PURE__ */ new Date().toISOString()
4682
- });
4877
+ }, this.getPlayerAnalyticsContext());
4683
4878
  }
4684
4879
  _state.label = 1;
4685
4880
  case 1:
@@ -4878,7 +5073,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4878
5073
  sendAdLoadedTracking(this.config.licenseKey, {
4879
5074
  source: this.getAdSource(),
4880
5075
  timestamp: /* @__PURE__ */ new Date().toISOString()
4881
- });
5076
+ }, this.getPlayerAnalyticsContext());
4882
5077
  }
4883
5078
  return [
4884
5079
  4,
@@ -5823,6 +6018,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5823
6018
  clearInterval(this.heartbeatInterval);
5824
6019
  this.heartbeatInterval = void 0;
5825
6020
  }
6021
+ if (isMQTTEnabled()) {
6022
+ disconnectMQTT();
6023
+ }
5826
6024
  (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.destroy();
5827
6025
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
5828
6026
  this.consecutiveFailures = 0;
@@ -7423,38 +7621,44 @@ function hexToRgb(hex) {
7423
7621
  return "".concat(num >> 16 & 255, ",").concat(num >> 8 & 255, ",").concat(num & 255);
7424
7622
  }
7425
7623
  var FADE_DURATION_MS = 1e3;
7426
- var VALID_ENTER_ANIMATIONS = /* @__PURE__ */ new Set([
7427
- "fade",
7428
- "slide_left",
7429
- "slide_right",
7430
- "slide_up",
7431
- "slide_down"
7432
- ]);
7624
+ var ENTER_ANIMATION_ALIASES = {
7625
+ fade: "fade",
7626
+ slide_from_left: "slide_from_left",
7627
+ slide_from_right: "slide_from_right",
7628
+ slide_from_top: "slide_from_top",
7629
+ slide_from_bottom: "slide_from_bottom",
7630
+ slide_left: "slide_from_left",
7631
+ slide_right: "slide_from_right",
7632
+ slide_up: "slide_from_top",
7633
+ slide_down: "slide_from_bottom"
7634
+ };
7635
+ function normalizeEnterAnimation(v) {
7636
+ var _ENTER_ANIMATION_ALIASES_v;
7637
+ if (typeof v !== "string") return null;
7638
+ return (_ENTER_ANIMATION_ALIASES_v = ENTER_ANIMATION_ALIASES[v]) !== null && _ENTER_ANIMATION_ALIASES_v !== void 0 ? _ENTER_ANIMATION_ALIASES_v : null;
7639
+ }
7433
7640
  function getEnterAnimation(overlay) {
7434
7641
  var flat = overlay.enter_animation;
7435
- if (typeof flat === "string" && VALID_ENTER_ANIMATIONS.has(flat)) {
7436
- return flat;
7437
- }
7642
+ var fromFlat = normalizeEnterAnimation(flat);
7643
+ if (fromFlat) return fromFlat;
7438
7644
  if (overlay.content) {
7439
7645
  try {
7440
7646
  var parsed = JSON.parse(overlay.content);
7441
- var v = parsed === null || parsed === void 0 ? void 0 : parsed.enterAnimation;
7442
- if (typeof v === "string" && VALID_ENTER_ANIMATIONS.has(v)) {
7443
- return v;
7444
- }
7647
+ var fromContent = normalizeEnterAnimation(parsed === null || parsed === void 0 ? void 0 : parsed.enterAnimation);
7648
+ if (fromContent) return fromContent;
7445
7649
  } catch (unused) {}
7446
7650
  }
7447
7651
  return "fade";
7448
7652
  }
7449
7653
  function enterHiddenTransform(anim) {
7450
7654
  switch(anim){
7451
- case "slide_left":
7655
+ case "slide_from_left":
7452
7656
  return "translateX(-120%)";
7453
- case "slide_right":
7657
+ case "slide_from_right":
7454
7658
  return "translateX(120%)";
7455
- case "slide_up":
7659
+ case "slide_from_top":
7456
7660
  return "translateY(-120%)";
7457
- case "slide_down":
7661
+ case "slide_from_bottom":
7458
7662
  return "translateY(120%)";
7459
7663
  default:
7460
7664
  return "";
@@ -8015,7 +8219,18 @@ var CRITICAL_PROPS = [
8015
8219
  "licenseKey",
8016
8220
  "lowLatencyMode",
8017
8221
  "driftToleranceMs",
8018
- "debugAdTiming"
8222
+ "immediateManifestAds",
8223
+ "debugAdTiming",
8224
+ "showCustomControls",
8225
+ "adFailsafeTimeoutMs",
8226
+ "minSegmentsBeforePlay",
8227
+ "disableAds",
8228
+ "disableFiller",
8229
+ "singlePipelineMode",
8230
+ "mqttConfig",
8231
+ "adBreakCheckIntervalMs",
8232
+ "maxAdBreakExtensionMs",
8233
+ "adTransitionGapMs"
8019
8234
  ];
8020
8235
  var CONTROLS_HIDE_DELAY = 3e3;
8021
8236
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
@@ -8026,7 +8241,7 @@ var PANEL_BASE_RIGHT_OFFSET = 10;
8026
8241
  var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props) {
8027
8242
  var _ref;
8028
8243
  var _aiLiveContext_context;
8029
- 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, [
8244
+ 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, [
8030
8245
  "src",
8031
8246
  "autoplay",
8032
8247
  "muted",
@@ -8051,9 +8266,15 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8051
8266
  "poster",
8052
8267
  "children",
8053
8268
  "licenseKey",
8269
+ "adFailsafeTimeoutMs",
8054
8270
  "minSegmentsBeforePlay",
8055
8271
  "disableAds",
8056
8272
  "disableFiller",
8273
+ "singlePipelineMode",
8274
+ "mqttConfig",
8275
+ "adBreakCheckIntervalMs",
8276
+ "maxAdBreakExtensionMs",
8277
+ "adTransitionGapMs",
8057
8278
  "swirlProjectId",
8058
8279
  "swirlShowcaseDemo",
8059
8280
  "swirlOverlayApiBaseUrl",
@@ -8294,7 +8515,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8294
8515
  var debugPanelBottomOffset = shouldShowEnhancedControls ? Math.max(74, 92 * responsiveScale) : Math.max(52, 58 * responsiveScale);
8295
8516
  var criticalPropsKey = (0, import_react2.useMemo)(function() {
8296
8517
  var baseParts = CRITICAL_PROPS.map(function(prop) {
8297
- return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(props[prop]);
8518
+ return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(JSON.stringify(props[prop]));
8298
8519
  }).join("|");
8299
8520
  return "".concat(baseParts, "|adcisionChannelId:").concat(adcisionChannelId !== null && adcisionChannelId !== void 0 ? adcisionChannelId : "");
8300
8521
  }, [
@@ -8303,8 +8524,19 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8303
8524
  licenseKey,
8304
8525
  lowLatencyMode,
8305
8526
  driftToleranceMs,
8527
+ immediateManifestAds,
8306
8528
  adcisionChannelId,
8307
- debugAdTiming
8529
+ debugAdTiming,
8530
+ showCustomControls,
8531
+ adFailsafeTimeoutMs,
8532
+ minSegmentsBeforePlay,
8533
+ disableAds,
8534
+ disableFiller,
8535
+ singlePipelineMode,
8536
+ mqttConfig2,
8537
+ adBreakCheckIntervalMs,
8538
+ maxAdBreakExtensionMs,
8539
+ adTransitionGapMs
8308
8540
  ]);
8309
8541
  (0, import_react2.useEffect)(function() {
8310
8542
  if (typeof window === "undefined") return;
@@ -8338,9 +8570,15 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8338
8570
  if (onFullscreenToggle !== void 0) cfg.onFullscreenToggle = onFullscreenToggle;
8339
8571
  if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
8340
8572
  if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
8573
+ if (adFailsafeTimeoutMs !== void 0) cfg.adFailsafeTimeoutMs = adFailsafeTimeoutMs;
8341
8574
  if (minSegmentsBeforePlay !== void 0) cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
8342
8575
  if (disableAds !== void 0) cfg.disableAds = disableAds;
8343
8576
  cfg.disableFiller = disableFiller !== null && disableFiller !== void 0 ? disableFiller : true;
8577
+ if (singlePipelineMode !== void 0) cfg.singlePipelineMode = singlePipelineMode;
8578
+ if (mqttConfig2 !== void 0) cfg.mqttConfig = mqttConfig2;
8579
+ if (adBreakCheckIntervalMs !== void 0) cfg.adBreakCheckIntervalMs = adBreakCheckIntervalMs;
8580
+ if (maxAdBreakExtensionMs !== void 0) cfg.maxAdBreakExtensionMs = maxAdBreakExtensionMs;
8581
+ if (adTransitionGapMs !== void 0) cfg.adTransitionGapMs = adTransitionGapMs;
8344
8582
  if (adcisionChannelId !== void 0) {
8345
8583
  cfg.projectId = String(adcisionChannelId);
8346
8584
  cfg.channelId = adcisionChannelId;
@@ -11479,36 +11717,54 @@ var StormcloudPlayer = createStormcloudPlayer(players_default, players_default[p
11479
11717
  var StormcloudPlayer_default = StormcloudPlayer;
11480
11718
  // Annotate the CommonJS export names for ESM import in node:
11481
11719
  0 && (module.exports = {
11720
+ DEFAULT_MQTT_CONFIG: DEFAULT_MQTT_CONFIG,
11482
11721
  IS_BROWSER: IS_BROWSER,
11483
11722
  IS_GLOBAL: IS_GLOBAL,
11484
11723
  IS_IOS: IS_IOS,
11485
11724
  IS_SAFARI: IS_SAFARI,
11725
+ MQTT_CA_CERT_FILE: MQTT_CA_CERT_FILE,
11486
11726
  OVERLAY_API_BASE: OVERLAY_API_BASE,
11487
11727
  SUPPORTS_DASH: SUPPORTS_DASH,
11488
11728
  SUPPORTS_HLS: SUPPORTS_HLS,
11489
11729
  StormcloudPlayer: StormcloudPlayer,
11490
11730
  StormcloudVideoPlayer: StormcloudVideoPlayer,
11491
11731
  StormcloudVideoPlayerComponent: StormcloudVideoPlayerComponent,
11732
+ applyMQTTConfig: applyMQTTConfig,
11733
+ buildMQTTBrokerUrl: buildMQTTBrokerUrl,
11734
+ buildPlayerTopic: buildPlayerTopic,
11492
11735
  canPlay: canPlay,
11736
+ configureMQTT: configureMQTT,
11493
11737
  createAdStormPlayer: createAdStormPlayer,
11494
11738
  createStormcloudPlayer: createStormcloudPlayer,
11495
11739
  detectBrowser: detectBrowser,
11740
+ disconnectMQTT: disconnectMQTT,
11741
+ ensureMQTTClient: ensureMQTTClient,
11496
11742
  fetchProjectOverlays: fetchProjectOverlays,
11497
11743
  getBrowserConfigOverrides: getBrowserConfigOverrides,
11498
11744
  getBrowserID: getBrowserID,
11499
11745
  getClientInfo: getClientInfo,
11746
+ getMQTTStatus: getMQTTStatus,
11747
+ initMQTTClient: initMQTTClient,
11500
11748
  initializePolyfills: initializePolyfills,
11749
+ isMQTTConfigured: isMQTTConfigured,
11750
+ isMQTTConnected: isMQTTConnected,
11751
+ isMQTTEnabled: isMQTTEnabled,
11501
11752
  isMediaStream: isMediaStream,
11502
11753
  isOverlayActive: isOverlayActive,
11503
11754
  lazy: lazy,
11504
11755
  logBrowserInfo: logBrowserInfo,
11505
11756
  merge: merge,
11757
+ mqttConfig: mqttConfig,
11506
11758
  normalizeSwirlOverlay: normalizeSwirlOverlay,
11507
11759
  omit: omit,
11508
11760
  parseQuery: parseQuery,
11509
11761
  players: players,
11762
+ publishMQTT: publishMQTT,
11510
11763
  randomString: randomString,
11511
11764
  resolveImageUrl: resolveImageUrl,
11765
+ sendAdDetectTracking: sendAdDetectTracking,
11766
+ sendAdImpressionTracking: sendAdImpressionTracking,
11767
+ sendAdLoadedTracking: sendAdLoadedTracking,
11512
11768
  sendHeartbeat: sendHeartbeat,
11513
11769
  sendInitialTracking: sendInitialTracking,
11514
11770
  supportsFeature: supportsFeature,