stormcloud-video-player 0.8.23 → 0.8.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/stormcloud-vp.min.js +1 -1
  2. package/lib/index.cjs +1187 -1109
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.d.cts +3 -1
  5. package/lib/index.d.ts +3 -1
  6. package/lib/index.js +1028 -954
  7. package/lib/index.js.map +1 -1
  8. package/lib/player/AdBreakOrchestrator.cjs +419 -26
  9. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  10. package/lib/player/AdBreakOrchestrator.d.cts +2 -1
  11. package/lib/player/AdConfigManager.cjs +90 -22
  12. package/lib/player/AdConfigManager.cjs.map +1 -1
  13. package/lib/player/AdConfigManager.d.cts +1 -1
  14. package/lib/player/AdPreloadPool.d.cts +1 -1
  15. package/lib/player/AdTimingService.d.cts +1 -1
  16. package/lib/player/HlsEngine.d.cts +1 -1
  17. package/lib/player/PlayerControls.d.cts +1 -1
  18. package/lib/player/Scte35CueManager.d.cts +1 -1
  19. package/lib/player/Scte35Parser.d.cts +1 -1
  20. package/lib/player/StormcloudVideoPlayer.cjs +1184 -1110
  21. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  22. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  23. package/lib/player/playerTypes.d.cts +1 -1
  24. package/lib/players/HlsPlayer.cjs +1184 -1110
  25. package/lib/players/HlsPlayer.cjs.map +1 -1
  26. package/lib/players/HlsPlayer.d.cts +1 -1
  27. package/lib/players/index.cjs +1184 -1110
  28. package/lib/players/index.cjs.map +1 -1
  29. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  30. package/lib/{types-DNiBmPKK.d.cts → types-Bz4aRmzc.d.cts} +1 -0
  31. package/lib/ui/StormcloudVideoPlayer.cjs +1184 -1110
  32. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  33. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  34. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  35. package/lib/utils/tracking.cjs +411 -20
  36. package/lib/utils/tracking.cjs.map +1 -1
  37. package/lib/utils/tracking.d.cts +3 -2
  38. package/lib/utils/vastEnvironmentSignals.cjs +37 -0
  39. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  40. package/lib/utils/vastEnvironmentSignals.d.cts +4 -1
  41. package/lib/utils/vastMacros.cjs.map +1 -1
  42. package/package.json +1 -1
@@ -220,6 +220,9 @@ var __toCommonJS = function __toCommonJS(mod) {
220
220
  // src/utils/tracking.ts
221
221
  var tracking_exports = {};
222
222
  __export(tracking_exports, {
223
+ buildAnalyticsContext: function buildAnalyticsContext1() {
224
+ return buildAnalyticsContext;
225
+ },
223
226
  getBrowserID: function getBrowserID1() {
224
227
  return getBrowserID;
225
228
  },
@@ -336,8 +339,362 @@ function publishMQTT(topic, payload) {
336
339
  return false;
337
340
  }
338
341
  }
342
+ // src/utils/vastEnvironmentSignals.ts
343
+ var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
344
+ var DEVICE_ID_STORAGE_KEYS = [
345
+ "rdid",
346
+ "ifa",
347
+ "advertisingId",
348
+ "advertising_id",
349
+ "deviceAdvertisingId",
350
+ "aaid",
351
+ "adid",
352
+ "rida",
353
+ "tifa",
354
+ "lgudid"
355
+ ];
356
+ function inferDeviceIdType() {
357
+ if (typeof navigator === "undefined") {
358
+ return void 0;
359
+ }
360
+ var ua = navigator.userAgent;
361
+ if (/Roku/i.test(ua)) return "rida";
362
+ if (/Tizen|Samsung/i.test(ua)) return "tifa";
363
+ if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
364
+ if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
365
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
366
+ if (/Android|Google TV/i.test(ua)) return "aaid";
367
+ if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
368
+ return void 0;
369
+ }
370
+ function resolveNativeDeviceId() {
371
+ var bridgeSignals = readNativeBridgeSignals();
372
+ var platformDevice = readPlatformNativeDeviceId();
373
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
374
+ if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {
375
+ return void 0;
376
+ }
377
+ return deviceId;
378
+ }
379
+ function getOrCreateStoredUuid(storageKey) {
380
+ if (typeof window === "undefined") {
381
+ return void 0;
382
+ }
383
+ var existing = readStoredString(storageKey);
384
+ if (existing) {
385
+ return existing;
386
+ }
387
+ var id = createUuid();
388
+ try {
389
+ var _window_localStorage;
390
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(storageKey, id);
391
+ } catch (unused) {}
392
+ return id;
393
+ }
394
+ function createUuid() {
395
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
396
+ return crypto.randomUUID();
397
+ }
398
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
399
+ var value = Math.floor(Math.random() * 16);
400
+ var nibble = char === "x" ? value : value & 3 | 8;
401
+ return nibble.toString(16);
402
+ });
403
+ }
404
+ function readPlatformNativeDeviceId() {
405
+ if (typeof window === "undefined") return {};
406
+ try {
407
+ var _window_webapis;
408
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
409
+ if (adinfo) {
410
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
411
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
412
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
413
+ return _object_spread({
414
+ deviceId: tifa,
415
+ deviceIdType: "tifa"
416
+ }, typeof lat === "boolean" ? {
417
+ limitAdTracking: lat
418
+ } : {});
419
+ }
420
+ }
421
+ } catch (unused) {}
422
+ try {
423
+ var webOSDev = window.webOSDev;
424
+ if (webOSDev) {
425
+ var _webOSDev_lgudid;
426
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
427
+ if (typeof lgudid === "string" && lgudid) {
428
+ if (isZeroedAdId(lgudid)) {
429
+ return {
430
+ deviceIdType: "lgudid",
431
+ limitAdTracking: true
432
+ };
433
+ }
434
+ if (!isMacroPlaceholder(lgudid)) {
435
+ return {
436
+ deviceId: lgudid,
437
+ deviceIdType: "lgudid",
438
+ limitAdTracking: false
439
+ };
440
+ }
441
+ }
442
+ }
443
+ } catch (unused) {}
444
+ try {
445
+ var roku = window.Roku;
446
+ if (roku) {
447
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
448
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
449
+ return {
450
+ deviceId: rida,
451
+ deviceIdType: "rida",
452
+ limitAdTracking: false
453
+ };
454
+ }
455
+ }
456
+ } catch (unused) {}
457
+ return {};
458
+ }
459
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
460
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
461
+ "00000000-0000-0000-0000-000000000000"
462
+ ]);
463
+ function isMacroPlaceholder(value) {
464
+ var t = value.trim();
465
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
466
+ }
467
+ function isZeroedAdId(value) {
468
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
469
+ }
470
+ function readNativeBridgeSignals() {
471
+ if (typeof window === "undefined") {
472
+ return {};
473
+ }
474
+ var candidates = [
475
+ window.__STORMCLOUD_CTV_AD_INFO__,
476
+ window.__STORMCLOUD_CTV__,
477
+ window.stormcloudCtv,
478
+ window.AiryTV,
479
+ window.Android,
480
+ window.webOS,
481
+ window.tizen,
482
+ window.amazon
483
+ ].filter(Boolean);
484
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
485
+ try {
486
+ for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
487
+ var source = _step.value;
488
+ var contentUrl = readBridgeValue(source, [
489
+ "contentUrl",
490
+ "url",
491
+ "videoUrl",
492
+ "canonicalUrl"
493
+ ]) || void 0;
494
+ var appId = readBridgeValue(source, [
495
+ "appId",
496
+ "msid",
497
+ "applicationId",
498
+ "packageName"
499
+ ]) || void 0;
500
+ var appName = readBridgeValue(source, [
501
+ "appName",
502
+ "an",
503
+ "applicationName"
504
+ ]) || void 0;
505
+ var deviceId = readBridgeValue(source, [
506
+ "rdid",
507
+ "ifa",
508
+ "advertisingId",
509
+ "adId",
510
+ "deviceId",
511
+ "lgudid",
512
+ "LGUDID",
513
+ "tifa",
514
+ "rida",
515
+ "afai",
516
+ "aaid"
517
+ ]) || void 0;
518
+ if (!contentUrl && !deviceId && !appId && !appName) continue;
519
+ var deviceIdType = readBridgeValue(source, [
520
+ "idtype",
521
+ "deviceIdType",
522
+ "advertisingIdType",
523
+ "idType"
524
+ ]) || inferDeviceIdType();
525
+ var limitAdTracking = readBridgeBoolean(source, [
526
+ "is_lat",
527
+ "limitAdTracking",
528
+ "limitedAdTracking",
529
+ "lat"
530
+ ]);
531
+ return _object_spread({}, contentUrl ? {
532
+ contentUrl: contentUrl
533
+ } : {}, appId ? {
534
+ appId: appId
535
+ } : {}, appName ? {
536
+ appName: appName
537
+ } : {}, deviceId ? {
538
+ deviceId: deviceId
539
+ } : {}, deviceId && deviceIdType ? {
540
+ deviceIdType: deviceIdType
541
+ } : {}, deviceId && limitAdTracking != null ? {
542
+ limitAdTracking: limitAdTracking
543
+ } : {});
544
+ }
545
+ } catch (err) {
546
+ _didIteratorError = true;
547
+ _iteratorError = err;
548
+ } finally{
549
+ try {
550
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
551
+ _iterator.return();
552
+ }
553
+ } finally{
554
+ if (_didIteratorError) {
555
+ throw _iteratorError;
556
+ }
557
+ }
558
+ }
559
+ return {};
560
+ }
561
+ function readBridgeValue(source, keys) {
562
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
563
+ try {
564
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
565
+ var key = _step.value;
566
+ var value = source === null || source === void 0 ? void 0 : source[key];
567
+ if (typeof value === "string" && value) {
568
+ return value;
569
+ }
570
+ if (typeof value === "function") {
571
+ try {
572
+ var result = value.call(source);
573
+ if (typeof result === "string" && result) {
574
+ return result;
575
+ }
576
+ } catch (unused) {}
577
+ }
578
+ }
579
+ } catch (err) {
580
+ _didIteratorError = true;
581
+ _iteratorError = err;
582
+ } finally{
583
+ try {
584
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
585
+ _iterator.return();
586
+ }
587
+ } finally{
588
+ if (_didIteratorError) {
589
+ throw _iteratorError;
590
+ }
591
+ }
592
+ }
593
+ return void 0;
594
+ }
595
+ function readBridgeBoolean(source, keys) {
596
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
597
+ try {
598
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
599
+ var key = _step.value;
600
+ var value = source === null || source === void 0 ? void 0 : source[key];
601
+ var normalized = normalizeBoolean(value);
602
+ if (normalized != null) {
603
+ return normalized;
604
+ }
605
+ if (typeof value === "function") {
606
+ try {
607
+ var result = normalizeBoolean(value.call(source));
608
+ if (result != null) {
609
+ return result;
610
+ }
611
+ } catch (unused) {}
612
+ }
613
+ }
614
+ } catch (err) {
615
+ _didIteratorError = true;
616
+ _iteratorError = err;
617
+ } finally{
618
+ try {
619
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
620
+ _iterator.return();
621
+ }
622
+ } finally{
623
+ if (_didIteratorError) {
624
+ throw _iteratorError;
625
+ }
626
+ }
627
+ }
628
+ return void 0;
629
+ }
630
+ function readStoredDeviceId() {
631
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
632
+ try {
633
+ for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
634
+ var key = _step.value;
635
+ var value = readStoredString(key);
636
+ if (value) {
637
+ return value;
638
+ }
639
+ }
640
+ } catch (err) {
641
+ _didIteratorError = true;
642
+ _iteratorError = err;
643
+ } finally{
644
+ try {
645
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
646
+ _iterator.return();
647
+ }
648
+ } finally{
649
+ if (_didIteratorError) {
650
+ throw _iteratorError;
651
+ }
652
+ }
653
+ }
654
+ return void 0;
655
+ }
656
+ function readStoredString(key) {
657
+ if (typeof window === "undefined") {
658
+ return void 0;
659
+ }
660
+ try {
661
+ var _window_localStorage;
662
+ var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
663
+ return value || void 0;
664
+ } catch (unused) {
665
+ return void 0;
666
+ }
667
+ }
668
+ function normalizeBoolean(value) {
669
+ if (typeof value === "boolean") {
670
+ return value;
671
+ }
672
+ if (typeof value === "number") {
673
+ return value === 1;
674
+ }
675
+ if (typeof value === "string") {
676
+ var normalized = value.toLowerCase();
677
+ if (normalized === "1" || normalized === "true" || normalized === "yes") {
678
+ return true;
679
+ }
680
+ if (normalized === "0" || normalized === "false" || normalized === "no") {
681
+ return false;
682
+ }
683
+ }
684
+ return void 0;
685
+ }
339
686
  // src/utils/tracking.ts
340
687
  var cachedBrowserId = null;
688
+ function buildAnalyticsContext(config) {
689
+ var context = {};
690
+ if (config.debugAdTiming) {
691
+ context.debugAdTiming = true;
692
+ }
693
+ if (config.isLiveStream !== void 0) {
694
+ context.inputStreamType = config.isLiveStream ? "live" : "vod";
695
+ }
696
+ return context;
697
+ }
341
698
  function getClientInfo() {
342
699
  var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
343
700
  var ua = navigator.userAgent;
@@ -480,19 +837,12 @@ function getClientInfo() {
480
837
  visibilityState: document.visibilityState
481
838
  };
482
839
  }
483
- function getBrowserID(clientInfo) {
840
+ function sha256Hex(input) {
484
841
  return _async_to_generator(function() {
485
- var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
842
+ var _crypto_subtle, encodedData, utf8, buffer, i, hashBuffer, unused, hash, i1, char, fallbackHash, timestamp, random;
486
843
  return _ts_generator(this, function(_state) {
487
844
  switch(_state.label){
488
845
  case 0:
489
- if (cachedBrowserId) {
490
- return [
491
- 2,
492
- cachedBrowserId
493
- ];
494
- }
495
- fingerprintString = JSON.stringify(clientInfo);
496
846
  if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
497
847
  3,
498
848
  5
@@ -516,9 +866,9 @@ function getBrowserID(clientInfo) {
516
866
  case 2:
517
867
  _state.sent();
518
868
  if (typeof TextEncoder !== "undefined") {
519
- encodedData = new TextEncoder().encode(fingerprintString);
869
+ encodedData = new TextEncoder().encode(input);
520
870
  } else {
521
- utf8 = unescape(encodeURIComponent(fingerprintString));
871
+ utf8 = unescape(encodeURIComponent(input));
522
872
  buffer = new Uint8Array(utf8.length);
523
873
  for(i = 0; i < utf8.length; i++){
524
874
  buffer[i] = utf8.charCodeAt(i);
@@ -531,13 +881,11 @@ function getBrowserID(clientInfo) {
531
881
  ];
532
882
  case 3:
533
883
  hashBuffer = _state.sent();
534
- hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
535
- return b.toString(16).padStart(2, "0");
536
- }).join("");
537
- cachedBrowserId = hashHex;
538
884
  return [
539
885
  2,
540
- hashHex
886
+ Array.from(new Uint8Array(hashBuffer)).map(function(b) {
887
+ return b.toString(16).padStart(2, "0");
888
+ }).join("")
541
889
  ];
542
890
  case 4:
543
891
  unused = _state.sent();
@@ -548,15 +896,50 @@ function getBrowserID(clientInfo) {
548
896
  ];
549
897
  case 5:
550
898
  hash = 0;
551
- for(i1 = 0; i1 < fingerprintString.length; i1++){
552
- char = fingerprintString.charCodeAt(i1);
899
+ for(i1 = 0; i1 < input.length; i1++){
900
+ char = input.charCodeAt(i1);
553
901
  hash = (hash << 5) - hash + char;
554
902
  hash = hash & hash;
555
903
  }
556
904
  fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
557
905
  timestamp = Date.now().toString(16).padStart(12, "0");
558
906
  random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
559
- cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, "0");
907
+ return [
908
+ 2,
909
+ (fallbackHash + timestamp + random).padEnd(64, "0")
910
+ ];
911
+ }
912
+ });
913
+ })();
914
+ }
915
+ function resolvePlayerIdentitySeed(clientInfo) {
916
+ var nativeDeviceId = resolveNativeDeviceId();
917
+ if (nativeDeviceId) {
918
+ return "device:".concat(nativeDeviceId);
919
+ }
920
+ var persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
921
+ if (persistedId) {
922
+ return "persisted:".concat(persistedId);
923
+ }
924
+ return "fingerprint:".concat(JSON.stringify(clientInfo));
925
+ }
926
+ function getBrowserID(clientInfo) {
927
+ return _async_to_generator(function() {
928
+ return _ts_generator(this, function(_state) {
929
+ switch(_state.label){
930
+ case 0:
931
+ if (cachedBrowserId) {
932
+ return [
933
+ 2,
934
+ cachedBrowserId
935
+ ];
936
+ }
937
+ return [
938
+ 4,
939
+ sha256Hex(resolvePlayerIdentitySeed(clientInfo))
940
+ ];
941
+ case 1:
942
+ cachedBrowserId = _state.sent();
560
943
  return [
561
944
  2,
562
945
  cachedBrowserId
@@ -570,19 +953,26 @@ function canPublish(licenseKey) {
570
953
  }
571
954
  function buildPlayerMetricEvent() {
572
955
  return _async_to_generator(function() {
573
- var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
956
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, debugAdTiming, playerId, captureAt;
574
957
  var _arguments = arguments;
575
958
  return _ts_generator(this, function(_state) {
576
959
  switch(_state.label){
577
960
  case 0:
578
961
  context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
579
962
  clientInfo = getClientInfo();
963
+ debugAdTiming = !!context.debugAdTiming;
964
+ if (debugAdTiming) {
965
+ console.log("[StormcloudVideoPlayer] clientInfo: ", JSON.stringify(clientInfo, null, 2));
966
+ }
580
967
  return [
581
968
  4,
582
969
  getBrowserID(clientInfo)
583
970
  ];
584
971
  case 1:
585
972
  playerId = _state.sent();
973
+ if (debugAdTiming) {
974
+ console.log("[StormcloudVideoPlayer] playerId: ", playerId);
975
+ }
586
976
  captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
587
977
  return [
588
978
  2,
@@ -849,6 +1239,7 @@ function sendHeartbeat(_0) {
849
1239
  }
850
1240
  // Annotate the CommonJS export names for ESM import in node:
851
1241
  0 && (module.exports = {
1242
+ buildAnalyticsContext: buildAnalyticsContext,
852
1243
  getBrowserID: getBrowserID,
853
1244
  getClientInfo: getClientInfo,
854
1245
  sendAdDetectTracking: sendAdDetectTracking,