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