stormcloud-video-player 0.3.63 → 0.3.64

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.
@@ -2416,6 +2416,99 @@ function createHlsAdPlayer(contentVideo, options) {
2416
2416
  }
2417
2417
  };
2418
2418
  }
2419
+ // src/utils/mqttConfig.ts
2420
+ var DEFAULT_MQTT_CONFIG = {
2421
+ enabled: true,
2422
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
2423
+ brokerPort: 8883,
2424
+ wsPort: 8084,
2425
+ username: "for-sonifi",
2426
+ password: "sonifi-mqtt",
2427
+ topicPrefix: "adstorm/players",
2428
+ qos: 1
2429
+ };
2430
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
2431
+ function isMQTTEnabled() {
2432
+ return mqttConfig.enabled;
2433
+ }
2434
+ function buildMQTTBrokerUrl() {
2435
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
2436
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
2437
+ }
2438
+ function buildPlayerTopic(licenseKey, channel) {
2439
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
2440
+ }
2441
+ // src/utils/mqttClient.ts
2442
+ var import_mqtt = __toESM(require("mqtt"), 1);
2443
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
2444
+ var client = null;
2445
+ var status = "disconnected";
2446
+ function initMQTTClient() {
2447
+ if (client || !isMQTTEnabled()) return;
2448
+ var url = buildMQTTBrokerUrl();
2449
+ status = "connecting";
2450
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
2451
+ try {
2452
+ client = import_mqtt.default.connect(url, {
2453
+ clientId: clientId,
2454
+ username: mqttConfig.username,
2455
+ password: mqttConfig.password,
2456
+ keepalive: 60,
2457
+ clean: true,
2458
+ reconnectPeriod: 5e3,
2459
+ connectTimeout: 1e4,
2460
+ queueQoSZero: false
2461
+ });
2462
+ } catch (err) {
2463
+ status = "error";
2464
+ console.warn("".concat(LOG, " connect() threw:"), err);
2465
+ return;
2466
+ }
2467
+ client.on("connect", function() {
2468
+ status = "connected";
2469
+ console.info("".concat(LOG, " connected to ").concat(url));
2470
+ });
2471
+ client.on("reconnect", function() {
2472
+ status = "connecting";
2473
+ console.info("".concat(LOG, " reconnecting…"));
2474
+ });
2475
+ client.on("offline", function() {
2476
+ status = "disconnected";
2477
+ console.warn("".concat(LOG, " offline"));
2478
+ });
2479
+ client.on("error", function(err) {
2480
+ status = "error";
2481
+ console.warn("".concat(LOG, " error:"), err.message);
2482
+ });
2483
+ client.on("close", function() {
2484
+ if (status === "connected") {
2485
+ status = "disconnected";
2486
+ }
2487
+ });
2488
+ }
2489
+ function ensureMQTTClient() {
2490
+ if (isMQTTEnabled() && !client) {
2491
+ initMQTTClient();
2492
+ }
2493
+ }
2494
+ function publishMQTT(topic, payload) {
2495
+ if (!isMQTTEnabled()) {
2496
+ return false;
2497
+ }
2498
+ ensureMQTTClient();
2499
+ if (!client) {
2500
+ return false;
2501
+ }
2502
+ try {
2503
+ client.publish(topic, JSON.stringify(payload), {
2504
+ qos: mqttConfig.qos
2505
+ });
2506
+ return true;
2507
+ } catch (err) {
2508
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
2509
+ return false;
2510
+ }
2511
+ }
2419
2512
  // src/utils/tracking.ts
2420
2513
  var cachedBrowserId = null;
2421
2514
  function getClientInfo() {
@@ -2562,7 +2655,7 @@ function getClientInfo() {
2562
2655
  }
2563
2656
  function getBrowserID(clientInfo) {
2564
2657
  return _async_to_generator(function() {
2565
- var fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashArray, hashHex, error, hash, i1, char, fallbackHash, timestamp, random;
2658
+ var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
2566
2659
  return _ts_generator(this, function(_state) {
2567
2660
  switch(_state.label){
2568
2661
  case 0:
@@ -2573,7 +2666,7 @@ function getBrowserID(clientInfo) {
2573
2666
  ];
2574
2667
  }
2575
2668
  fingerprintString = JSON.stringify(clientInfo);
2576
- if (!(typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest)) return [
2669
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
2577
2670
  3,
2578
2671
  5
2579
2672
  ];
@@ -2611,8 +2704,7 @@ function getBrowserID(clientInfo) {
2611
2704
  ];
2612
2705
  case 3:
2613
2706
  hashBuffer = _state.sent();
2614
- hashArray = Array.from(new Uint8Array(hashBuffer));
2615
- hashHex = hashArray.map(function(b) {
2707
+ hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2616
2708
  return b.toString(16).padStart(2, "0");
2617
2709
  }).join("");
2618
2710
  cachedBrowserId = hashHex;
@@ -2621,8 +2713,8 @@ function getBrowserID(clientInfo) {
2621
2713
  hashHex
2622
2714
  ];
2623
2715
  case 4:
2624
- error = _state.sent();
2625
- console.warn("[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash");
2716
+ unused = _state.sent();
2717
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2626
2718
  return [
2627
2719
  3,
2628
2720
  5
@@ -2646,177 +2738,91 @@ function getBrowserID(clientInfo) {
2646
2738
  });
2647
2739
  })();
2648
2740
  }
2649
- var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2650
- var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2651
- var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2652
- var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2653
- function buildHeaders(licenseKey) {
2654
- var headers = {
2655
- "Content-Type": "application/json"
2656
- };
2657
- if (licenseKey) {
2658
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2659
- }
2660
- return headers;
2661
- }
2662
- function sendTrackRequest(licenseKey, body) {
2663
- return _async_to_generator(function() {
2664
- var response;
2665
- return _ts_generator(this, function(_state) {
2666
- switch(_state.label){
2667
- case 0:
2668
- return [
2669
- 4,
2670
- fetch(TRACK_URL, {
2671
- method: "POST",
2672
- headers: buildHeaders(licenseKey),
2673
- body: JSON.stringify(body)
2674
- })
2675
- ];
2676
- case 1:
2677
- response = _state.sent();
2678
- if (!response.ok) {
2679
- throw new Error("HTTP error! status: ".concat(response.status));
2680
- }
2681
- return [
2682
- 4,
2683
- response.json()
2684
- ];
2685
- case 2:
2686
- _state.sent();
2687
- return [
2688
- 2
2689
- ];
2690
- }
2691
- });
2692
- })();
2741
+ function canPublish(licenseKey) {
2742
+ return Boolean(isMQTTEnabled() && licenseKey);
2693
2743
  }
2694
- function postJson(url, licenseKey, body) {
2744
+ function buildPlayerMetricEvent() {
2695
2745
  return _async_to_generator(function() {
2696
- var response;
2697
- return _ts_generator(this, function(_state) {
2698
- switch(_state.label){
2699
- case 0:
2700
- return [
2701
- 4,
2702
- fetch(url, {
2703
- method: "POST",
2704
- headers: buildHeaders(licenseKey),
2705
- body: JSON.stringify(body)
2706
- })
2707
- ];
2708
- case 1:
2709
- response = _state.sent();
2710
- if (!response.ok) {
2711
- throw new Error("HTTP error! status: ".concat(response.status));
2712
- }
2713
- return [
2714
- 4,
2715
- response.json()
2716
- ];
2717
- case 2:
2718
- _state.sent();
2719
- return [
2720
- 2
2721
- ];
2722
- }
2723
- });
2724
- })();
2725
- }
2726
- function buildPlayerMetricEvent(_0) {
2727
- return _async_to_generator(function(licenseKey) {
2728
- var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2746
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2729
2747
  var _arguments = arguments;
2730
2748
  return _ts_generator(this, function(_state) {
2731
2749
  switch(_state.label){
2732
2750
  case 0:
2733
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2751
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2734
2752
  clientInfo = getClientInfo();
2735
2753
  return [
2736
2754
  4,
2737
2755
  getBrowserID(clientInfo)
2738
2756
  ];
2739
2757
  case 1:
2740
- browserId = _state.sent();
2758
+ playerId = _state.sent();
2741
2759
  captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2742
2760
  return [
2743
2761
  2,
2744
- {
2745
- player_id: browserId,
2746
- browserId: browserId,
2762
+ _object_spread({
2763
+ player_id: playerId,
2747
2764
  device_type: clientInfo.deviceType,
2748
- deviceType: clientInfo.deviceType,
2749
- input_stream_type: context.inputStreamType,
2750
- os: clientInfo.os,
2751
- ad_loaded: flags.adLoaded,
2752
- ad_detect: flags.adDetect,
2753
- license_key: licenseKey,
2754
- capture_at: captureAt,
2755
- timestamp: captureAt
2756
- }
2765
+ os: clientInfo.os.toLowerCase(),
2766
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2767
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2768
+ capture_at: captureAt
2769
+ }, context.inputStreamType ? {
2770
+ input_stream_type: context.inputStreamType
2771
+ } : {})
2757
2772
  ];
2758
2773
  }
2759
2774
  });
2760
2775
  }).apply(this, arguments);
2761
2776
  }
2777
+ function publishTracking(licenseKey, channel, body) {
2778
+ ensureMQTTClient();
2779
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2780
+ }
2762
2781
  function sendInitialTracking(_0) {
2763
2782
  return _async_to_generator(function(licenseKey) {
2764
- var context, clientInfo, browserId, trackingData, error;
2783
+ var context, metricEvent, error;
2765
2784
  var _arguments = arguments;
2766
2785
  return _ts_generator(this, function(_state) {
2767
2786
  switch(_state.label){
2768
2787
  case 0:
2769
2788
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2789
+ if (!canPublish(licenseKey)) return [
2790
+ 2
2791
+ ];
2770
2792
  _state.label = 1;
2771
2793
  case 1:
2772
2794
  _state.trys.push([
2773
2795
  1,
2774
- 4,
2796
+ 3,
2775
2797
  ,
2776
- 5
2798
+ 4
2777
2799
  ]);
2778
- clientInfo = getClientInfo();
2779
2800
  return [
2780
2801
  4,
2781
- getBrowserID(clientInfo)
2782
- ];
2783
- case 2:
2784
- browserId = _state.sent();
2785
- trackingData = _object_spread({
2786
- browserId: browserId
2787
- }, clientInfo);
2788
- return [
2789
- 4,
2790
- sendTrackRequest(licenseKey, {
2791
- events: [
2792
- {
2793
- player_id: browserId,
2794
- device_type: clientInfo.deviceType,
2795
- input_stream_type: context.inputStreamType,
2796
- os: clientInfo.os,
2797
- ad_loaded: false,
2798
- ad_detect: false,
2799
- license_key: licenseKey,
2800
- capture_at: /* @__PURE__ */ new Date().toISOString()
2801
- }
2802
- ],
2803
- trackingData: trackingData
2802
+ buildPlayerMetricEvent(context, {
2803
+ adLoaded: false,
2804
+ adDetect: false
2804
2805
  })
2805
2806
  ];
2806
- case 3:
2807
- _state.sent();
2807
+ case 2:
2808
+ metricEvent = _state.sent();
2809
+ publishTracking(licenseKey, "metrics", {
2810
+ events: [
2811
+ metricEvent
2812
+ ]
2813
+ });
2808
2814
  return [
2809
2815
  3,
2810
- 5
2816
+ 4
2811
2817
  ];
2812
- case 4:
2818
+ case 3:
2813
2819
  error = _state.sent();
2814
2820
  console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2815
2821
  return [
2816
2822
  3,
2817
- 5
2823
+ 4
2818
2824
  ];
2819
- case 5:
2825
+ case 4:
2820
2826
  return [
2821
2827
  2
2822
2828
  ];
@@ -2920,53 +2926,48 @@ function sendAdImpressionTracking(_0, _1) {
2920
2926
  switch(_state.label){
2921
2927
  case 0:
2922
2928
  context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2929
+ if (!canPublish(licenseKey)) return [
2930
+ 2
2931
+ ];
2923
2932
  _state.label = 1;
2924
2933
  case 1:
2925
2934
  _state.trys.push([
2926
2935
  1,
2927
- 4,
2936
+ 3,
2928
2937
  ,
2929
- 5
2938
+ 4
2930
2939
  ]);
2931
2940
  return [
2932
2941
  4,
2933
- buildPlayerMetricEvent(licenseKey, context, {
2942
+ buildPlayerMetricEvent(context, {
2934
2943
  captureAt: adImpressionInfo.timestamp
2935
2944
  })
2936
2945
  ];
2937
2946
  case 2:
2938
2947
  metricEvent = _state.sent();
2939
- return [
2940
- 4,
2941
- Promise.all([
2942
- postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2943
- postJson(IMPRESSIONS_URL, licenseKey, {
2944
- events: [
2945
- {
2946
- player_id: metricEvent.player_id,
2947
- ad_played_count: 1,
2948
- ad_url: adImpressionInfo.adUrl,
2949
- license_key: licenseKey,
2950
- capture_at: adImpressionInfo.timestamp
2951
- }
2952
- ]
2953
- })
2954
- ])
2955
- ];
2956
- case 3:
2957
- _state.sent();
2948
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2949
+ publishTracking(licenseKey, "impressions", {
2950
+ events: [
2951
+ {
2952
+ player_id: metricEvent.player_id,
2953
+ ad_played_count: 1,
2954
+ ad_url: adImpressionInfo.adUrl,
2955
+ capture_at: adImpressionInfo.timestamp
2956
+ }
2957
+ ]
2958
+ });
2958
2959
  return [
2959
2960
  3,
2960
- 5
2961
+ 4
2961
2962
  ];
2962
- case 4:
2963
+ case 3:
2963
2964
  error = _state.sent();
2964
2965
  console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2965
2966
  return [
2966
2967
  3,
2967
- 5
2968
+ 4
2968
2969
  ];
2969
- case 5:
2970
+ case 4:
2970
2971
  return [
2971
2972
  2
2972
2973
  ];
@@ -2982,38 +2983,36 @@ function sendHeartbeat(_0) {
2982
2983
  switch(_state.label){
2983
2984
  case 0:
2984
2985
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2986
+ if (!canPublish(licenseKey)) return [
2987
+ 2
2988
+ ];
2985
2989
  _state.label = 1;
2986
2990
  case 1:
2987
2991
  _state.trys.push([
2988
2992
  1,
2989
- 4,
2993
+ 3,
2990
2994
  ,
2991
- 5
2995
+ 4
2992
2996
  ]);
2993
2997
  return [
2994
2998
  4,
2995
- buildPlayerMetricEvent(licenseKey, context, flags)
2999
+ buildPlayerMetricEvent(context, flags)
2996
3000
  ];
2997
3001
  case 2:
2998
3002
  heartbeatData = _state.sent();
2999
- return [
3000
- 4,
3001
- postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
3002
- ];
3003
- case 3:
3004
- _state.sent();
3003
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
3005
3004
  return [
3006
3005
  3,
3007
- 5
3006
+ 4
3008
3007
  ];
3009
- case 4:
3008
+ case 3:
3010
3009
  error = _state.sent();
3011
3010
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
3012
3011
  return [
3013
3012
  3,
3014
- 5
3013
+ 4
3015
3014
  ];
3016
- case 5:
3015
+ case 4:
3017
3016
  return [
3018
3017
  2
3019
3018
  ];