stormcloud-video-player 0.3.52 → 0.3.54

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.
@@ -227,9 +227,17 @@ function _ts_generator(thisArg, body) {
227
227
  },
228
228
  trys: [],
229
229
  ops: []
230
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
231
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
232
- return this;
230
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
231
+ return d(g, "next", {
232
+ value: verb(0)
233
+ }), d(g, "throw", {
234
+ value: verb(1)
235
+ }), d(g, "return", {
236
+ value: verb(2)
237
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
238
+ value: function() {
239
+ return this;
240
+ }
233
241
  }), g;
234
242
  function verb(n) {
235
243
  return function(v) {
@@ -329,20 +337,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
329
337
  var __getOwnPropNames = Object.getOwnPropertyNames;
330
338
  var __getProtoOf = Object.getPrototypeOf;
331
339
  var __hasOwnProp = Object.prototype.hasOwnProperty;
332
- var __export = function(target, all) {
340
+ var __export = function __export(target, all) {
333
341
  for(var name in all)__defProp(target, name, {
334
342
  get: all[name],
335
343
  enumerable: true
336
344
  });
337
345
  };
338
- var __copyProps = function(to, from, except, desc) {
346
+ var __copyProps = function __copyProps(to, from, except, desc) {
339
347
  if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
340
348
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
341
349
  try {
342
350
  var _loop = function() {
343
351
  var key = _step.value;
344
352
  if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
345
- get: function() {
353
+ get: function get() {
346
354
  return from[key];
347
355
  },
348
356
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
@@ -366,7 +374,7 @@ var __copyProps = function(to, from, except, desc) {
366
374
  }
367
375
  return to;
368
376
  };
369
- var __toESM = function(mod, isNodeMode, target) {
377
+ var __toESM = function __toESM(mod, isNodeMode, target) {
370
378
  return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
371
379
  // file that has been converted to a CommonJS file using a Babel-
372
380
  // compatible transform (i.e. "__esModule" has not been set), then set
@@ -376,7 +384,7 @@ var __toESM = function(mod, isNodeMode, target) {
376
384
  enumerable: true
377
385
  }) : target, mod);
378
386
  };
379
- var __toCommonJS = function(mod) {
387
+ var __toCommonJS = function __toCommonJS(mod) {
380
388
  return __copyProps(__defProp({}, "__esModule", {
381
389
  value: true
382
390
  }), mod);
@@ -384,7 +392,7 @@ var __toCommonJS = function(mod) {
384
392
  // src/players/HlsPlayer.tsx
385
393
  var HlsPlayer_exports = {};
386
394
  __export(HlsPlayer_exports, {
387
- default: function() {
395
+ default: function _default() {
388
396
  return HlsPlayer;
389
397
  }
390
398
  });
@@ -719,7 +727,7 @@ function createImaController(video, options) {
719
727
  var fn = _step.value;
720
728
  try {
721
729
  fn(payload);
722
- } catch (e) {}
730
+ } catch (unused) {}
723
731
  }
724
732
  } catch (err) {
725
733
  _didIteratorError = true;
@@ -757,7 +765,7 @@ function createImaController(video, options) {
757
765
  console.error("StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.");
758
766
  }
759
767
  }
760
- } catch (e) {}
768
+ } catch (unused) {}
761
769
  if (typeof window !== "undefined" && ((_window_google = window.google) === null || _window_google === void 0 ? void 0 : _window_google.ima)) return Promise.resolve();
762
770
  var existing = document.querySelector('script[data-ima="true"]');
763
771
  if (existing) {
@@ -799,9 +807,6 @@ function createImaController(video, options) {
799
807
  var adDisplayContainer;
800
808
  var adContainerEl;
801
809
  var lastAdTagUrl;
802
- var retryAttempts = 0;
803
- var maxRetries = 2;
804
- var backoffBaseMs = 500;
805
810
  var adsLoadedPromise;
806
811
  var adsLoadedResolve;
807
812
  var adsLoadedReject;
@@ -1005,7 +1010,7 @@ function createImaController(video, options) {
1005
1010
  if (adsManager) {
1006
1011
  try {
1007
1012
  adsManager.destroy();
1008
- } catch (e) {}
1013
+ } catch (unused) {}
1009
1014
  adsManager = void 0;
1010
1015
  }
1011
1016
  if (adVideoElement) {
@@ -1016,7 +1021,7 @@ function createImaController(video, options) {
1016
1021
  if (adsLoader) {
1017
1022
  try {
1018
1023
  adsLoader.destroy();
1019
- } catch (e) {}
1024
+ } catch (unused) {}
1020
1025
  adsLoader = void 0;
1021
1026
  }
1022
1027
  }
@@ -1034,7 +1039,7 @@ function createImaController(video, options) {
1034
1039
  try {
1035
1040
  var _adDisplayContainer_initialize;
1036
1041
  (_adDisplayContainer_initialize = adDisplayContainer.initialize) === null || _adDisplayContainer_initialize === void 0 ? void 0 : _adDisplayContainer_initialize.call(adDisplayContainer);
1037
- } catch (e) {}
1042
+ } catch (unused) {}
1038
1043
  }
1039
1044
  }).catch(function() {});
1040
1045
  },
@@ -1098,7 +1103,6 @@ function createImaController(video, options) {
1098
1103
  _state.sent();
1099
1104
  google = window.google;
1100
1105
  lastAdTagUrl = vastTagUrl;
1101
- retryAttempts = 0;
1102
1106
  if (!adDisplayContainer) {
1103
1107
  container = document.createElement("div");
1104
1108
  container.style.position = "absolute";
@@ -1182,32 +1186,23 @@ function createImaController(video, options) {
1182
1186
  }
1183
1187
  }, 300);
1184
1188
  }
1185
- hideContentVideo();
1189
+ showContentVideo();
1186
1190
  if (adsLoadedReject) {
1187
1191
  adsLoadedReject(new Error("Ad playback error"));
1188
1192
  adsLoadedReject = void 0;
1189
1193
  adsLoadedResolve = void 0;
1190
1194
  }
1191
- if (lastAdTagUrl && retryAttempts < maxRetries && !isNoFill) {
1192
- var delay = backoffBaseMs * Math.pow(2, retryAttempts++);
1193
- window.setTimeout(function() {
1194
- try {
1195
- makeAdsRequest(google, lastAdTagUrl);
1196
- } catch (e) {}
1197
- }, delay);
1198
- } else {
1199
- emit("ad_error", {
1200
- code: errorCode,
1201
- vastErrorCode: vastErrorCode,
1202
- message: errorMessage,
1203
- cause: innerError,
1204
- isNoFill: isNoFill
1205
- });
1206
- if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1207
- if (video.paused) {
1208
- var _video_play;
1209
- (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
1210
- }
1195
+ emit("ad_error", {
1196
+ code: errorCode,
1197
+ vastErrorCode: vastErrorCode,
1198
+ message: errorMessage,
1199
+ cause: innerError,
1200
+ isNoFill: isNoFill
1201
+ });
1202
+ if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1203
+ if (video.paused) {
1204
+ var _video_play;
1205
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
1211
1206
  }
1212
1207
  }
1213
1208
  });
@@ -1225,7 +1220,7 @@ function createImaController(video, options) {
1225
1220
  if (adsManager) {
1226
1221
  try {
1227
1222
  adsManager.setVolume(adVolume);
1228
- } catch (e) {}
1223
+ } catch (unused) {}
1229
1224
  }
1230
1225
  emit("content_pause");
1231
1226
  });
@@ -1239,7 +1234,7 @@ function createImaController(video, options) {
1239
1234
  if (adsManager) {
1240
1235
  try {
1241
1236
  adsManager.setVolume(originalMutedState ? 0 : adVolume);
1242
- } catch (e) {}
1237
+ } catch (unused) {}
1243
1238
  }
1244
1239
  }
1245
1240
  if (adContainerEl) {
@@ -1253,7 +1248,7 @@ function createImaController(video, options) {
1253
1248
  adsManager.addEventListener(AdEvent.CONTENT_RESUME_REQUESTED, function() {
1254
1249
  adPlaying = false;
1255
1250
  setAdPlayingFlag(false);
1256
- hideContentVideo();
1251
+ showContentVideo();
1257
1252
  emit("content_resume");
1258
1253
  });
1259
1254
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, function() {
@@ -1269,7 +1264,7 @@ function createImaController(video, options) {
1269
1264
  }
1270
1265
  }, 300);
1271
1266
  }
1272
- hideContentVideo();
1267
+ showContentVideo();
1273
1268
  emit("all_ads_completed");
1274
1269
  });
1275
1270
  if (adsLoadedResolve) {
@@ -1291,7 +1286,7 @@ function createImaController(video, options) {
1291
1286
  }
1292
1287
  }, 300);
1293
1288
  }
1294
- hideContentVideo();
1289
+ showContentVideo();
1295
1290
  if (adsLoadedReject) {
1296
1291
  adsLoadedReject(new Error("Failed to setup ads manager"));
1297
1292
  adsLoadedReject = void 0;
@@ -1334,7 +1329,7 @@ function createImaController(video, options) {
1334
1329
  }
1335
1330
  }, 300);
1336
1331
  }
1337
- hideContentVideo();
1332
+ showContentVideo();
1338
1333
  if (adsLoadedReject) {
1339
1334
  adsLoadedReject(new Error(isNoFill ? "No ads available" : "Ads loader error"));
1340
1335
  adsLoadedReject = void 0;
@@ -1400,7 +1395,7 @@ function createImaController(video, options) {
1400
1395
  }
1401
1396
  try {
1402
1397
  adsManager.setVolume(originalMutedState ? 0 : adVolume);
1403
- } catch (e) {}
1398
+ } catch (unused) {}
1404
1399
  adsManager.start();
1405
1400
  return [
1406
1401
  2,
@@ -1482,7 +1477,7 @@ function createImaController(video, options) {
1482
1477
  try {
1483
1478
  ;
1484
1479
  adsManager === null || adsManager === void 0 ? void 0 : (_adsManager_stop = adsManager.stop) === null || _adsManager_stop === void 0 ? void 0 : _adsManager_stop.call(adsManager);
1485
- } catch (e) {}
1480
+ } catch (unused) {}
1486
1481
  destroyAdsManager();
1487
1482
  return [
1488
1483
  2
@@ -1513,7 +1508,7 @@ function createImaController(video, options) {
1513
1508
  try {
1514
1509
  var _adsLoader_destroy;
1515
1510
  adsLoader === null || adsLoader === void 0 ? void 0 : (_adsLoader_destroy = adsLoader.destroy) === null || _adsLoader_destroy === void 0 ? void 0 : _adsLoader_destroy.call(adsLoader);
1516
- } catch (e) {}
1511
+ } catch (unused) {}
1517
1512
  adDisplayContainer = void 0;
1518
1513
  adsLoader = void 0;
1519
1514
  contentVideoHidden = false;
@@ -1562,7 +1557,7 @@ function createImaController(video, options) {
1562
1557
  if (adsManager && adPlaying) {
1563
1558
  try {
1564
1559
  adsManager.setVolume(clampedVolume);
1565
- } catch (e) {}
1560
+ } catch (unused) {}
1566
1561
  }
1567
1562
  },
1568
1563
  getAdVolume: function getAdVolume() {
@@ -3055,22 +3050,29 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3055
3050
  this.maxPlaceholderDurationMs = 5e3;
3056
3051
  this.isShowingPlaceholder = false;
3057
3052
  this.totalAdRequestsInBreak = 0;
3058
- this.maxTotalAdRequestsPerBreak = 20;
3053
+ this.maxTotalAdRequestsPerBreak = 10;
3059
3054
  this.pendingAdBreak = null;
3060
3055
  this.consecutiveFailures = 0;
3061
3056
  this.maxConsecutiveFailures = 5;
3062
3057
  this.lastAdRequestTime = 0;
3063
- this.minAdRequestIntervalMs = 2500;
3058
+ this.minAdRequestIntervalMs = 3e3;
3064
3059
  this.backoffBaseMs = 1e3;
3065
3060
  this.maxBackoffMs = 15e3;
3061
+ this.globalConsecutiveNoFills = 0;
3062
+ this.globalNoFillThreshold = 3;
3063
+ this.globalNoFillCooldownUntil = 0;
3064
+ this.globalNoFillBackoffBaseMs = 5e3;
3065
+ this.globalNoFillBackoffMaxMs = 6e4;
3066
+ this.globalLastGamRequestTime = 0;
3067
+ this.globalMinGamIntervalMs = 3e3;
3066
3068
  this.preloadPool = [];
3067
- this.maxPreloadPoolSize = 3;
3069
+ this.maxPreloadPoolSize = 2;
3068
3070
  this.preloadPoolActive = false;
3069
3071
  this.preloadPoolLoopRunning = false;
3070
3072
  this.continuousFetchLoopRunning = false;
3071
3073
  initializePolyfills();
3072
3074
  var browserOverrides = getBrowserConfigOverrides();
3073
- this.config = _object_spread({}, config, browserOverrides);
3075
+ this.config = _object_spread({}, browserOverrides, config);
3074
3076
  this.video = config.videoElement;
3075
3077
  logBrowserInfo(config.debugAdTiming);
3076
3078
  this.ima = this.createAdPlayer(false);
@@ -3207,7 +3209,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3207
3209
  });
3208
3210
  this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, function(_, data) {
3209
3211
  return _async_to_generator(function() {
3210
- var _this_hls_levels, _this_hls, _this_hls_levels_some, adBehavior, _this_config_minSegmentsBeforePlay, minSegments, _this_video_play;
3212
+ var _this_config_minSegmentsBeforePlay, _ref, _this_hls_levels, _this_hls, adBehavior, minSegments, _this_video_play;
3211
3213
  return _ts_generator(this, function(_state) {
3212
3214
  switch(_state.label){
3213
3215
  case 0:
@@ -3216,10 +3218,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3216
3218
  } else {
3217
3219
  ;
3218
3220
  ;
3219
- this.isLiveStream = (_this_hls_levels_some = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3221
+ this.isLiveStream = (_ref = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3220
3222
  var _level_details, _level_details1;
3221
3223
  return (level === null || level === void 0 ? void 0 : (_level_details = level.details) === null || _level_details === void 0 ? void 0 : _level_details.live) === true || (level === null || level === void 0 ? void 0 : (_level_details1 = level.details) === null || _level_details1 === void 0 ? void 0 : _level_details1.type) === "LIVE";
3222
- })) !== null && _this_hls_levels_some !== void 0 ? _this_hls_levels_some : false;
3224
+ })) !== null && _ref !== void 0 ? _ref : false;
3223
3225
  }
3224
3226
  if (this.config.debugAdTiming) {
3225
3227
  adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
@@ -3283,9 +3285,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3283
3285
  var tag = "";
3284
3286
  var value = "";
3285
3287
  if (Array.isArray(entry)) {
3286
- var _entry_;
3288
+ var _entry_, _entry_1;
3287
3289
  tag = String((_entry_ = entry[0]) !== null && _entry_ !== void 0 ? _entry_ : "");
3288
- var _entry_1;
3289
3290
  value = String((_entry_1 = entry[1]) !== null && _entry_1 !== void 0 ? _entry_1 : "");
3290
3291
  } else if (typeof entry === "string") {
3291
3292
  var idx = entry.indexOf(":");
@@ -3408,9 +3409,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3408
3409
  var tag = "";
3409
3410
  var value = "";
3410
3411
  if (Array.isArray(entry)) {
3411
- var _entry_;
3412
+ var _entry_, _entry_1;
3412
3413
  tag = String((_entry_ = entry[0]) !== null && _entry_ !== void 0 ? _entry_ : "");
3413
- var _entry_1;
3414
3414
  value = String((_entry_1 = entry[1]) !== null && _entry_1 !== void 0 ? _entry_1 : "");
3415
3415
  } else if (typeof entry === "string") {
3416
3416
  var idx = entry.indexOf(":");
@@ -3460,10 +3460,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3460
3460
  }
3461
3461
  });
3462
3462
  } else if (tag.includes("EXT-X-DATERANGE")) {
3463
+ var _attrs_CLASS;
3463
3464
  var attrs = _this.parseAttributeList(value);
3464
3465
  var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3465
3466
  var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3466
- var _attrs_CLASS;
3467
3467
  var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3468
3468
  var duration = _this.toNumber(attrs["DURATION"]);
3469
3469
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
@@ -3577,6 +3577,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3577
3577
  _this.clearAdRequestWatchdog();
3578
3578
  _this.activeAdRequestToken = null;
3579
3579
  _this.showAds = true;
3580
+ _this.resetGamNoFillCounter();
3580
3581
  if (_this.inAdBreak && _this.expectedAdBreakDurationMs != null) {
3581
3582
  if (_this.adStopTimerId == null) {
3582
3583
  _this.currentAdBreakStartWallClockMs = Date.now();
@@ -3865,11 +3866,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3865
3866
  }
3866
3867
  var daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
3867
3868
  if (daterangeMatch) {
3868
- var _daterangeMatch_;
3869
+ var _daterangeMatch_, _attrs_CLASS;
3869
3870
  var attrs = this.parseAttributeList((_daterangeMatch_ = daterangeMatch[1]) !== null && _daterangeMatch_ !== void 0 ? _daterangeMatch_ : "");
3870
3871
  var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3871
3872
  var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3872
- var _attrs_CLASS;
3873
3873
  var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3874
3874
  var duration = this.toNumber(attrs["DURATION"]);
3875
3875
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
@@ -3945,7 +3945,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3945
3945
  var out = "";
3946
3946
  for(var i = 0; i < value.length; i++)out += String.fromCharCode(value[i]);
3947
3947
  return out;
3948
- } catch (e) {
3948
+ } catch (unused) {
3949
3949
  return void 0;
3950
3950
  }
3951
3951
  }
@@ -3964,6 +3964,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3964
3964
  });
3965
3965
  }
3966
3966
  if (marker.type === "start") {
3967
+ var _this_config_immediateManifestAds;
3967
3968
  var _this_pendingAdBreak;
3968
3969
  if (!this.video.muted) {
3969
3970
  this.video.muted = true;
@@ -3988,7 +3989,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3988
3989
  this.expectedAdBreakDurationMs = durationMs;
3989
3990
  this.currentAdBreakStartWallClockMs = Date.now();
3990
3991
  var isManifestMarker = this.isManifestBasedMarker(marker);
3991
- var _this_config_immediateManifestAds;
3992
3992
  var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
3993
3993
  if (this.config.debugAdTiming) {
3994
3994
  console.log("[StormcloudVideoPlayer] Ad start decision:", {
@@ -4143,9 +4143,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4143
4143
  var regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
4144
4144
  var match;
4145
4145
  while((match = regex.exec(value)) !== null){
4146
- var _match_;
4146
+ var _match_, _ref, _match_1;
4147
4147
  var key = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : "";
4148
- var _match_1, _ref;
4149
4148
  var rawVal = (_ref = (_match_1 = match[3]) !== null && _match_1 !== void 0 ? _match_1 : match[4]) !== null && _ref !== void 0 ? _ref : "";
4150
4149
  if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
4151
4150
  rawVal = rawVal.slice(1, -1);
@@ -4490,13 +4489,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4490
4489
  {
4491
4490
  key: "shouldShowNativeControls",
4492
4491
  value: function shouldShowNativeControls() {
4492
+ var _this_config_showCustomControls;
4493
4493
  var streamType = this.getStreamType();
4494
4494
  if (streamType === "other") {
4495
- var _this_config_showCustomControls;
4496
- return !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false);
4495
+ var _this_config_showCustomControls1;
4496
+ return !((_this_config_showCustomControls1 = this.config.showCustomControls) !== null && _this_config_showCustomControls1 !== void 0 ? _this_config_showCustomControls1 : false);
4497
4497
  }
4498
- var _this_config_showCustomControls1;
4499
- return !!(this.config.allowNativeHls && !((_this_config_showCustomControls1 = this.config.showCustomControls) !== null && _this_config_showCustomControls1 !== void 0 ? _this_config_showCustomControls1 : false));
4498
+ return !!(this.config.allowNativeHls && !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false));
4500
4499
  }
4501
4500
  },
4502
4501
  {
@@ -4604,6 +4603,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4604
4603
  var _this, loadPromise;
4605
4604
  return _ts_generator(this, function(_state) {
4606
4605
  _this = this;
4606
+ if (this.isGamInCooldown()) {
4607
+ if (this.config.debugAdTiming) {
4608
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, skipping preload");
4609
+ }
4610
+ return [
4611
+ 2
4612
+ ];
4613
+ }
4607
4614
  if (this.preloadPool.some(function(entry) {
4608
4615
  return entry.vastUrl === vastUrl;
4609
4616
  }) || this.failedVastUrls.has(vastUrl) || this.isUrlInCooldown(vastUrl)) {
@@ -4633,26 +4640,32 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4633
4640
  case 1:
4634
4641
  _state.trys.push([
4635
4642
  1,
4636
- 4,
4643
+ 5,
4637
4644
  ,
4638
- 5
4645
+ 6
4639
4646
  ]);
4640
4647
  continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
4641
4648
  preloadIma = this.createAdPlayer(continueLiveStreamDuringAds);
4642
4649
  preloadIma.initialize();
4643
- errorListener = function(payload) {
4650
+ errorListener = function errorListener(payload) {
4644
4651
  hasAdError = true;
4645
4652
  adErrorPayload = payload;
4646
4653
  };
4647
4654
  preloadIma.on("ad_error", errorListener);
4648
- errorListenerCleanup = function() {
4655
+ errorListenerCleanup = function errorListenerCleanup() {
4649
4656
  return preloadIma.off("ad_error", errorListener);
4650
4657
  };
4651
4658
  return [
4652
4659
  4,
4653
- preloadIma.requestAds(vastUrl)
4660
+ this.enforceGlobalRateLimit()
4654
4661
  ];
4655
4662
  case 2:
4663
+ _state.sent();
4664
+ return [
4665
+ 4,
4666
+ preloadIma.requestAds(vastUrl)
4667
+ ];
4668
+ case 3:
4656
4669
  _state.sent();
4657
4670
  preloadIma.pause();
4658
4671
  return [
@@ -4661,7 +4674,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4661
4674
  return setTimeout(resolve, 1500);
4662
4675
  })
4663
4676
  ];
4664
- case 3:
4677
+ case 4:
4665
4678
  _state.sent();
4666
4679
  preloadIma.pause();
4667
4680
  if (hasAdError) {
@@ -4670,6 +4683,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4670
4683
  errorListenerCleanup();
4671
4684
  }
4672
4685
  preloadIma.destroy();
4686
+ this.recordGamNoFill();
4673
4687
  if (isNoFill) {
4674
4688
  if (this.config.debugAdTiming) {
4675
4689
  console.log("[PRELOAD-POOL] ⚠️ Ad preload returned no-fill: ".concat(vastUrl));
@@ -4696,7 +4710,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4696
4710
  isReady: true,
4697
4711
  loadPromise: Promise.resolve()
4698
4712
  };
4699
- lateErrorListener = function(payload) {
4713
+ lateErrorListener = function lateErrorListener(payload) {
4700
4714
  var index = _this.preloadPool.findIndex(function(entry) {
4701
4715
  return entry.vastUrl === vastUrl;
4702
4716
  });
@@ -4707,7 +4721,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4707
4721
  }
4708
4722
  try {
4709
4723
  preloadIma.destroy();
4710
- } catch (e) {}
4724
+ } catch (unused) {}
4711
4725
  }
4712
4726
  };
4713
4727
  preloadIma.on("ad_error", lateErrorListener);
@@ -4720,13 +4734,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4720
4734
  }
4721
4735
  return [
4722
4736
  3,
4723
- 5
4737
+ 6
4724
4738
  ];
4725
- case 4:
4739
+ case 5:
4726
4740
  error = _state.sent();
4727
4741
  if (errorListenerCleanup) {
4728
4742
  errorListenerCleanup();
4729
4743
  }
4744
+ this.recordGamNoFill();
4730
4745
  if (this.config.debugAdTiming) {
4731
4746
  console.warn("[PRELOAD-POOL] ⚠️ Failed to preload ad: ".concat(vastUrl), error);
4732
4747
  }
@@ -4737,9 +4752,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4737
4752
  }
4738
4753
  return [
4739
4754
  3,
4740
- 5
4755
+ 6
4741
4756
  ];
4742
- case 5:
4757
+ case 6:
4743
4758
  return [
4744
4759
  2
4745
4760
  ];
@@ -4778,6 +4793,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4778
4793
  3,
4779
4794
  10
4780
4795
  ];
4796
+ if (this.isGamInCooldown()) {
4797
+ if (this.config.debugAdTiming) {
4798
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop");
4799
+ }
4800
+ return [
4801
+ 3,
4802
+ 10
4803
+ ];
4804
+ }
4781
4805
  if (!(!this.inAdBreak && this.preloadPool.length >= this.maxPreloadPoolSize)) return [
4782
4806
  3,
4783
4807
  3
@@ -4810,7 +4834,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4810
4834
  3,
4811
4835
  8
4812
4836
  ];
4813
- if (!this.preloadPoolActive) {
4837
+ if (!this.preloadPoolActive || this.isGamInCooldown()) {
4814
4838
  return [
4815
4839
  3,
4816
4840
  8
@@ -5026,9 +5050,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5026
5050
  case 1:
5027
5051
  _state.trys.push([
5028
5052
  1,
5029
- 7,
5053
+ 8,
5030
5054
  ,
5031
- 13
5055
+ 14
5032
5056
  ]);
5033
5057
  if (!(usePreloadedAd && preloadedController)) return [
5034
5058
  3,
@@ -5064,15 +5088,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5064
5088
  this.ima.setAdVolume(adVolume);
5065
5089
  return [
5066
5090
  3,
5067
- 6
5091
+ 7
5068
5092
  ];
5069
5093
  case 3:
5094
+ return [
5095
+ 4,
5096
+ this.enforceGlobalRateLimit()
5097
+ ];
5098
+ case 4:
5099
+ _state.sent();
5070
5100
  this.lastAdRequestTime = Date.now();
5071
5101
  return [
5072
5102
  4,
5073
5103
  this.ima.requestAds(firstAdUrl)
5074
5104
  ];
5075
- case 4:
5105
+ case 5:
5076
5106
  _state.sent();
5077
5107
  if (this.config.debugAdTiming) {
5078
5108
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
@@ -5087,7 +5117,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5087
5117
  4,
5088
5118
  this.ima.play()
5089
5119
  ];
5090
- case 5:
5120
+ case 6:
5091
5121
  _state.sent();
5092
5122
  if (this.expectedAdBreakDurationMs != null) {
5093
5123
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -5095,36 +5125,36 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5095
5125
  }
5096
5126
  adVolume1 = currentMuted ? 0 : currentVolume;
5097
5127
  this.ima.setAdVolume(adVolume1);
5098
- _state.label = 6;
5099
- case 6:
5128
+ _state.label = 7;
5129
+ case 7:
5100
5130
  return [
5101
5131
  3,
5102
- 13
5132
+ 14
5103
5133
  ];
5104
- case 7:
5134
+ case 8:
5105
5135
  error = _state.sent();
5106
5136
  if (this.config.debugAdTiming) {
5107
5137
  console.warn("[CONTINUOUS-FETCH] \u26A0\uFE0F First ad request failed:", error);
5108
5138
  }
5109
5139
  if (!!usePreloadedAd) return [
5110
5140
  3,
5111
- 11
5141
+ 12
5112
5142
  ];
5113
5143
  fallbackPreloaded = this.getPreloadedAd();
5114
5144
  if (!fallbackPreloaded) return [
5115
5145
  3,
5116
- 11
5146
+ 12
5117
5147
  ];
5118
5148
  if (this.config.debugAdTiming) {
5119
5149
  console.log("[CONTINUOUS-FETCH] \uD83D\uDD04 First ad failed, using preloaded fallback");
5120
5150
  }
5121
- _state.label = 8;
5122
- case 8:
5151
+ _state.label = 9;
5152
+ case 9:
5123
5153
  _state.trys.push([
5124
- 8,
5125
- 10,
5154
+ 9,
5155
+ 11,
5126
5156
  ,
5127
- 11
5157
+ 12
5128
5158
  ]);
5129
5159
  this.ima.destroy();
5130
5160
  this.video.muted = true;
@@ -5143,7 +5173,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5143
5173
  4,
5144
5174
  this.ima.play()
5145
5175
  ];
5146
- case 9:
5176
+ case 10:
5147
5177
  _state.sent();
5148
5178
  if (this.expectedAdBreakDurationMs != null) {
5149
5179
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -5154,16 +5184,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5154
5184
  return [
5155
5185
  2
5156
5186
  ];
5157
- case 10:
5187
+ case 11:
5158
5188
  fallbackError = _state.sent();
5159
5189
  if (this.config.debugAdTiming) {
5160
5190
  console.warn("[CONTINUOUS-FETCH] \u26A0\uFE0F Preloaded fallback also failed:", fallbackError);
5161
5191
  }
5162
5192
  return [
5163
5193
  3,
5164
- 11
5194
+ 12
5165
5195
  ];
5166
- case 11:
5196
+ case 12:
5167
5197
  if (this.isTemporaryAdError(error)) {
5168
5198
  this.temporaryFailureUrls.set(firstAdUrl, Date.now());
5169
5199
  if (this.config.debugAdTiming) {
@@ -5181,13 +5211,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5181
5211
  4,
5182
5212
  this.tryNextAvailableAdWithRateLimit()
5183
5213
  ];
5184
- case 12:
5214
+ case 13:
5185
5215
  _state.sent();
5186
5216
  return [
5187
5217
  3,
5188
- 13
5218
+ 14
5189
5219
  ];
5190
- case 13:
5220
+ case 14:
5191
5221
  return [
5192
5222
  2
5193
5223
  ];
@@ -5238,6 +5268,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5238
5268
  "break"
5239
5269
  ];
5240
5270
  }
5271
+ if (_this.isGamInCooldown()) {
5272
+ if (_this.config.debugAdTiming) {
5273
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation");
5274
+ }
5275
+ return [
5276
+ 2,
5277
+ "break"
5278
+ ];
5279
+ }
5241
5280
  if (_this.consecutiveFailures >= _this.maxConsecutiveFailures) {
5242
5281
  if (_this.config.debugAdTiming) {
5243
5282
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(_this.consecutiveFailures, "), stopping URL generation"));
@@ -5434,6 +5473,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5434
5473
  2
5435
5474
  ];
5436
5475
  }
5476
+ if (this.isGamInCooldown()) {
5477
+ if (this.config.debugAdTiming) {
5478
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully");
5479
+ }
5480
+ this.handleAdPodComplete();
5481
+ return [
5482
+ 2
5483
+ ];
5484
+ }
5437
5485
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
5438
5486
  if (this.config.debugAdTiming) {
5439
5487
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break"));
@@ -5630,6 +5678,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5630
5678
  case 0:
5631
5679
  remaining = this.getRemainingAdMs();
5632
5680
  waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);
5681
+ if (this.isGamInCooldown()) {
5682
+ if (this.config.debugAdTiming) {
5683
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait");
5684
+ }
5685
+ this.handleAdPodComplete();
5686
+ return [
5687
+ 2
5688
+ ];
5689
+ }
5633
5690
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
5634
5691
  if (this.config.debugAdTiming) {
5635
5692
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Skipping placeholder - too many consecutive failures");
@@ -5893,11 +5950,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5893
5950
  {
5894
5951
  key: "ensureAdStoppedByTimer",
5895
5952
  value: function ensureAdStoppedByTimer() {
5953
+ var _this_config_adBreakCheckIntervalMs, _this_expectedAdBreakDurationMs;
5896
5954
  if (!this.inAdBreak) return;
5897
5955
  this.adStopTimerId = void 0;
5898
5956
  var adPlaying = this.ima.isAdPlaying();
5899
5957
  var pendingAds = this.adPodQueue.length > 0;
5900
- var _this_config_adBreakCheckIntervalMs;
5901
5958
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
5902
5959
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
5903
5960
  var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
@@ -5905,7 +5962,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5905
5962
  if (this.currentAdBreakStartWallClockMs != null) {
5906
5963
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
5907
5964
  }
5908
- var _this_expectedAdBreakDurationMs;
5909
5965
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
5910
5966
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
5911
5967
  var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
@@ -6019,6 +6075,73 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6019
6075
  }
6020
6076
  }
6021
6077
  },
6078
+ {
6079
+ key: "isGamInCooldown",
6080
+ value: function isGamInCooldown() {
6081
+ return Date.now() < this.globalNoFillCooldownUntil;
6082
+ }
6083
+ },
6084
+ {
6085
+ key: "recordGamNoFill",
6086
+ value: function recordGamNoFill() {
6087
+ this.globalConsecutiveNoFills++;
6088
+ if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {
6089
+ var exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;
6090
+ var backoff = Math.min(this.globalNoFillBackoffBaseMs * Math.pow(2, exponent), this.globalNoFillBackoffMaxMs);
6091
+ this.globalNoFillCooldownUntil = Date.now() + backoff;
6092
+ if (this.config.debugAdTiming) {
6093
+ console.log("[CIRCUIT-BREAKER] GAM cooldown activated: ".concat(backoff, "ms (").concat(this.globalConsecutiveNoFills, " consecutive no-fills)"));
6094
+ }
6095
+ }
6096
+ }
6097
+ },
6098
+ {
6099
+ key: "resetGamNoFillCounter",
6100
+ value: function resetGamNoFillCounter() {
6101
+ if (this.globalConsecutiveNoFills > 0 && this.config.debugAdTiming) {
6102
+ console.log("[CIRCUIT-BREAKER] Resetting no-fill counter (was ".concat(this.globalConsecutiveNoFills, ")"));
6103
+ }
6104
+ this.globalConsecutiveNoFills = 0;
6105
+ this.globalNoFillCooldownUntil = 0;
6106
+ }
6107
+ },
6108
+ {
6109
+ key: "enforceGlobalRateLimit",
6110
+ value: function enforceGlobalRateLimit() {
6111
+ return _async_to_generator(function() {
6112
+ var now, elapsed, waitMs;
6113
+ return _ts_generator(this, function(_state) {
6114
+ switch(_state.label){
6115
+ case 0:
6116
+ now = Date.now();
6117
+ elapsed = now - this.globalLastGamRequestTime;
6118
+ if (!(elapsed < this.globalMinGamIntervalMs)) return [
6119
+ 3,
6120
+ 2
6121
+ ];
6122
+ waitMs = this.globalMinGamIntervalMs - elapsed;
6123
+ if (this.config.debugAdTiming) {
6124
+ console.log("[RATE-LIMIT] Waiting ".concat(waitMs, "ms before next GAM request"));
6125
+ }
6126
+ return [
6127
+ 4,
6128
+ new Promise(function(resolve) {
6129
+ return setTimeout(resolve, waitMs);
6130
+ })
6131
+ ];
6132
+ case 1:
6133
+ _state.sent();
6134
+ _state.label = 2;
6135
+ case 2:
6136
+ this.globalLastGamRequestTime = Date.now();
6137
+ return [
6138
+ 2
6139
+ ];
6140
+ }
6141
+ });
6142
+ }).call(this);
6143
+ }
6144
+ },
6022
6145
  {
6023
6146
  key: "playSingleAd",
6024
6147
  value: function playSingleAd(vastTagUrl) {
@@ -6050,6 +6173,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6050
6173
  }
6051
6174
  throw new Error("Too many consecutive failures");
6052
6175
  }
6176
+ if (this.isGamInCooldown()) {
6177
+ if (this.config.debugAdTiming) {
6178
+ console.warn("[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request");
6179
+ }
6180
+ throw new Error("GAM in cooldown");
6181
+ }
6053
6182
  this.recreateImaController();
6054
6183
  requestToken = ++this.adRequestTokenCounter;
6055
6184
  this.activeAdRequestToken = requestToken;
@@ -6058,16 +6187,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6058
6187
  case 1:
6059
6188
  _state.trys.push([
6060
6189
  1,
6061
- 11,
6190
+ 12,
6062
6191
  ,
6063
- 16
6192
+ 17
6064
6193
  ]);
6194
+ return [
6195
+ 4,
6196
+ this.enforceGlobalRateLimit()
6197
+ ];
6198
+ case 2:
6199
+ _state.sent();
6065
6200
  this.lastAdRequestTime = Date.now();
6066
6201
  return [
6067
6202
  4,
6068
6203
  this.ima.requestAds(vastTagUrl)
6069
6204
  ];
6070
- case 2:
6205
+ case 3:
6071
6206
  _state.sent();
6072
6207
  this.clearAdRequestWatchdog();
6073
6208
  if (this.activeAdRequestToken !== requestToken) {
@@ -6075,20 +6210,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6075
6210
  2
6076
6211
  ];
6077
6212
  }
6078
- _state.label = 3;
6079
- case 3:
6213
+ _state.label = 4;
6214
+ case 4:
6080
6215
  _state.trys.push([
6081
- 3,
6082
- 5,
6216
+ 4,
6217
+ 6,
6083
6218
  ,
6084
- 10
6219
+ 11
6085
6220
  ]);
6086
6221
  this.startAdFailsafeTimer(requestToken);
6087
6222
  return [
6088
6223
  4,
6089
6224
  this.ima.play()
6090
6225
  ];
6091
- case 4:
6226
+ case 5:
6092
6227
  _state.sent();
6093
6228
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6094
6229
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -6102,9 +6237,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6102
6237
  this.temporaryFailureUrls.delete(vastTagUrl);
6103
6238
  return [
6104
6239
  3,
6105
- 10
6240
+ 11
6106
6241
  ];
6107
- case 5:
6242
+ case 6:
6108
6243
  playError = _state.sent();
6109
6244
  if (this.config.debugAdTiming) {
6110
6245
  console.error("[AD-ERROR] Failed to play ad:", playError);
@@ -6112,18 +6247,18 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6112
6247
  preloadedFallback = this.getPreloadedAd();
6113
6248
  if (!preloadedFallback) return [
6114
6249
  3,
6115
- 9
6250
+ 10
6116
6251
  ];
6117
6252
  if (this.config.debugAdTiming) {
6118
6253
  console.log("[AD-ERROR] Play failed, trying preloaded fallback ad");
6119
6254
  }
6120
- _state.label = 6;
6121
- case 6:
6255
+ _state.label = 7;
6256
+ case 7:
6122
6257
  _state.trys.push([
6123
- 6,
6124
- 8,
6258
+ 7,
6259
+ 9,
6125
6260
  ,
6126
- 9
6261
+ 10
6127
6262
  ]);
6128
6263
  this.clearAdFailsafeTimer();
6129
6264
  this.ima.destroy();
@@ -6139,7 +6274,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6139
6274
  4,
6140
6275
  this.ima.play()
6141
6276
  ];
6142
- case 7:
6277
+ case 8:
6143
6278
  _state.sent();
6144
6279
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6145
6280
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -6152,16 +6287,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6152
6287
  return [
6153
6288
  2
6154
6289
  ];
6155
- case 8:
6290
+ case 9:
6156
6291
  fallbackError = _state.sent();
6157
6292
  if (this.config.debugAdTiming) {
6158
6293
  console.warn("[AD-ERROR] Preloaded fallback also failed:", fallbackError);
6159
6294
  }
6160
6295
  return [
6161
6296
  3,
6162
- 9
6297
+ 10
6163
6298
  ];
6164
- case 9:
6299
+ case 10:
6165
6300
  if (this.isTemporaryAdError(playError)) {
6166
6301
  this.temporaryFailureUrls.set(vastTagUrl, Date.now());
6167
6302
  if (this.config.debugAdTiming) {
@@ -6178,12 +6313,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6178
6313
  this.activeAdRequestToken = null;
6179
6314
  }
6180
6315
  throw playError;
6181
- case 10:
6316
+ case 11:
6182
6317
  return [
6183
6318
  3,
6184
- 16
6319
+ 17
6185
6320
  ];
6186
- case 11:
6321
+ case 12:
6187
6322
  error = _state.sent();
6188
6323
  errorMessage = (error === null || error === void 0 ? void 0 : error.message) || "";
6189
6324
  if (this.config.debugAdTiming) {
@@ -6192,18 +6327,18 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6192
6327
  preloadedFallback1 = this.getPreloadedAd();
6193
6328
  if (!preloadedFallback1) return [
6194
6329
  3,
6195
- 15
6330
+ 16
6196
6331
  ];
6197
6332
  if (this.config.debugAdTiming) {
6198
6333
  console.log("[AD-ERROR] Request failed, trying preloaded fallback ad");
6199
6334
  }
6200
- _state.label = 12;
6201
- case 12:
6335
+ _state.label = 13;
6336
+ case 13:
6202
6337
  _state.trys.push([
6203
- 12,
6204
- 14,
6338
+ 13,
6339
+ 15,
6205
6340
  ,
6206
- 15
6341
+ 16
6207
6342
  ]);
6208
6343
  this.clearAdRequestWatchdog();
6209
6344
  this.clearAdFailsafeTimer();
@@ -6220,7 +6355,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6220
6355
  4,
6221
6356
  this.ima.play()
6222
6357
  ];
6223
- case 13:
6358
+ case 14:
6224
6359
  _state.sent();
6225
6360
  currentMuted2 = this.video.muted;
6226
6361
  currentVolume2 = this.video.volume;
@@ -6229,16 +6364,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6229
6364
  return [
6230
6365
  2
6231
6366
  ];
6232
- case 14:
6367
+ case 15:
6233
6368
  fallbackError1 = _state.sent();
6234
6369
  if (this.config.debugAdTiming) {
6235
6370
  console.warn("[AD-ERROR] Preloaded fallback also failed:", fallbackError1);
6236
6371
  }
6237
6372
  return [
6238
6373
  3,
6239
- 15
6374
+ 16
6240
6375
  ];
6241
- case 15:
6376
+ case 16:
6242
6377
  if (this.isTemporaryAdError(error)) {
6243
6378
  this.temporaryFailureUrls.set(vastTagUrl, Date.now());
6244
6379
  if (this.config.debugAdTiming) {
@@ -6256,7 +6391,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6256
6391
  this.activeAdRequestToken = null;
6257
6392
  }
6258
6393
  throw error;
6259
- case 16:
6394
+ case 17:
6260
6395
  return [
6261
6396
  2
6262
6397
  ];
@@ -6292,6 +6427,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6292
6427
  this.currentAdIndex = 0;
6293
6428
  this.totalAdsInBreak = 0;
6294
6429
  this.consecutiveFailures = 0;
6430
+ this.globalConsecutiveNoFills = 0;
6295
6431
  this.ima.stop().catch(function() {});
6296
6432
  var restoredMuted = this.ima.getOriginalMutedState();
6297
6433
  var restoredVolume = this.ima.getOriginalVolume();
@@ -6323,6 +6459,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6323
6459
  key: "handleAdFailure",
6324
6460
  value: function handleAdFailure() {
6325
6461
  this.consecutiveFailures++;
6462
+ this.recordGamNoFill();
6326
6463
  var remaining = this.getRemainingAdMs();
6327
6464
  if (this.config.debugAdTiming) {
6328
6465
  console.log("[CONTINUOUS-FETCH] Ad failure: remaining=".concat(remaining, "ms, queued ads=").concat(this.adRequestQueue.length, ", consecutiveFailures=").concat(this.consecutiveFailures), this.adRequestQueue.length > 0 ? {
@@ -6350,8 +6487,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6350
6487
  key: "startAdRequestWatchdog",
6351
6488
  value: function startAdRequestWatchdog(token) {
6352
6489
  var _this = this;
6353
- this.clearAdRequestWatchdog();
6354
6490
  var _this_config_adFailsafeTimeoutMs;
6491
+ this.clearAdRequestWatchdog();
6355
6492
  var timeoutMs = (_this_config_adFailsafeTimeoutMs = this.config.adFailsafeTimeoutMs) !== null && _this_config_adFailsafeTimeoutMs !== void 0 ? _this_config_adFailsafeTimeoutMs : 1e4;
6356
6493
  this.adRequestWatchdogToken = token;
6357
6494
  this.adRequestWatchdogId = window.setTimeout(function() {
@@ -6394,8 +6531,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6394
6531
  key: "startAdFailsafeTimer",
6395
6532
  value: function startAdFailsafeTimer(token) {
6396
6533
  var _this = this;
6397
- this.clearAdFailsafeTimer();
6398
6534
  var _this_config_adFailsafeTimeoutMs;
6535
+ this.clearAdFailsafeTimer();
6399
6536
  var failsafeMs = (_this_config_adFailsafeTimeoutMs = this.config.adFailsafeTimeoutMs) !== null && _this_config_adFailsafeTimeoutMs !== void 0 ? _this_config_adFailsafeTimeoutMs : 1e4;
6400
6537
  this.adFailsafeToken = token;
6401
6538
  this.adFailsafeTimerId = window.setTimeout(function() {
@@ -6716,23 +6853,23 @@ var DASH_EXTENSIONS = /\.(mpd)($|\?)/i;
6716
6853
  var VIDEO_EXTENSIONS = /\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\?)/i;
6717
6854
  var AUDIO_EXTENSIONS = /\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\?)/i;
6718
6855
  var canPlay = {
6719
- hls: function(url) {
6856
+ hls: function hls(url) {
6720
6857
  if (!url || typeof url !== "string") return false;
6721
6858
  return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);
6722
6859
  },
6723
- dash: function(url) {
6860
+ dash: function dash(url) {
6724
6861
  if (!url || typeof url !== "string") return false;
6725
6862
  return DASH_EXTENSIONS.test(url);
6726
6863
  },
6727
- video: function(url) {
6864
+ video: function video(url) {
6728
6865
  if (!url || typeof url !== "string") return false;
6729
6866
  return VIDEO_EXTENSIONS.test(url);
6730
6867
  },
6731
- audio: function(url) {
6868
+ audio: function audio(url) {
6732
6869
  if (!url || typeof url !== "string") return false;
6733
6870
  return AUDIO_EXTENSIONS.test(url);
6734
6871
  },
6735
- file: function(url) {
6872
+ file: function file(url) {
6736
6873
  if (!url || typeof url !== "string") return false;
6737
6874
  return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);
6738
6875
  }
@@ -6743,11 +6880,11 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react_Component) {
6743
6880
  function HlsPlayer() {
6744
6881
  _class_call_check(this, HlsPlayer);
6745
6882
  var _this;
6746
- var _this1, _arguments = arguments;
6747
- _this = _call_super(this, HlsPlayer, _to_consumable_array(_arguments)), _this1 = _this;
6748
- _this1.player = null;
6749
- _this1.mounted = false;
6750
- _this1.load = function() {
6883
+ var _this1;
6884
+ _this = _call_super(this, HlsPlayer, arguments), _this1 = _this;
6885
+ _this.player = null;
6886
+ _this.mounted = false;
6887
+ _this.load = function() {
6751
6888
  return _async_to_generator(function() {
6752
6889
  var _this_props_onMount, _this_props, config, _this_props_onReady, _this_props1, error, _this_props_onError, _this_props2;
6753
6890
  return _ts_generator(this, function(_state) {
@@ -6820,87 +6957,87 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react_Component) {
6820
6957
  });
6821
6958
  })();
6822
6959
  };
6823
- _this1.play = function() {
6824
- if (_this1.props.videoElement) {
6825
- var video = _this1.props.videoElement;
6960
+ _this.play = function() {
6961
+ if (_this.props.videoElement) {
6962
+ var video = _this.props.videoElement;
6826
6963
  var hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
6827
6964
  if (hasValidSource) {
6828
6965
  var _video_play, _this_props_onPlay, _this_props;
6829
6966
  (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function(error) {
6830
6967
  var _this_props_onError, _this_props;
6831
6968
  console.error("[HlsPlayer] Failed to play:", error);
6832
- (_this_props_onError = (_this_props = _this1.props).onError) === null || _this_props_onError === void 0 ? void 0 : _this_props_onError.call(_this_props, error);
6969
+ (_this_props_onError = (_this_props = _this.props).onError) === null || _this_props_onError === void 0 ? void 0 : _this_props_onError.call(_this_props, error);
6833
6970
  });
6834
- (_this_props_onPlay = (_this_props = _this1.props).onPlay) === null || _this_props_onPlay === void 0 ? void 0 : _this_props_onPlay.call(_this_props);
6971
+ (_this_props_onPlay = (_this_props = _this.props).onPlay) === null || _this_props_onPlay === void 0 ? void 0 : _this_props_onPlay.call(_this_props);
6835
6972
  } else {
6836
6973
  console.warn("[HlsPlayer] Cannot play: video has no valid source");
6837
6974
  }
6838
6975
  }
6839
6976
  };
6840
- _this1.pause = function() {
6841
- if (_this1.props.videoElement) {
6977
+ _this.pause = function() {
6978
+ if (_this.props.videoElement) {
6842
6979
  var _this_props_onPause, _this_props;
6843
- _this1.props.videoElement.pause();
6844
- (_this_props_onPause = (_this_props = _this1.props).onPause) === null || _this_props_onPause === void 0 ? void 0 : _this_props_onPause.call(_this_props);
6980
+ _this.props.videoElement.pause();
6981
+ (_this_props_onPause = (_this_props = _this.props).onPause) === null || _this_props_onPause === void 0 ? void 0 : _this_props_onPause.call(_this_props);
6845
6982
  }
6846
6983
  };
6847
- _this1.stop = function() {
6848
- _this1.pause();
6849
- if (_this1.props.videoElement) {
6850
- _this1.props.videoElement.currentTime = 0;
6984
+ _this.stop = function() {
6985
+ _this.pause();
6986
+ if (_this.props.videoElement) {
6987
+ _this.props.videoElement.currentTime = 0;
6851
6988
  }
6852
6989
  };
6853
- _this1.seekTo = function(seconds, keepPlaying) {
6854
- if (_this1.props.videoElement) {
6855
- _this1.props.videoElement.currentTime = seconds;
6990
+ _this.seekTo = function(seconds, keepPlaying) {
6991
+ if (_this.props.videoElement) {
6992
+ _this.props.videoElement.currentTime = seconds;
6856
6993
  if (!keepPlaying) {
6857
- _this1.pause();
6994
+ _this.pause();
6858
6995
  }
6859
6996
  }
6860
6997
  };
6861
- _this1.setVolume = function(volume) {
6862
- if (_this1.props.videoElement) {
6863
- _this1.props.videoElement.volume = Math.max(0, Math.min(1, volume));
6998
+ _this.setVolume = function(volume) {
6999
+ if (_this.props.videoElement) {
7000
+ _this.props.videoElement.volume = Math.max(0, Math.min(1, volume));
6864
7001
  }
6865
7002
  };
6866
- _this1.mute = function() {
6867
- if (_this1.props.videoElement) {
6868
- _this1.props.videoElement.muted = true;
7003
+ _this.mute = function() {
7004
+ if (_this.props.videoElement) {
7005
+ _this.props.videoElement.muted = true;
6869
7006
  }
6870
7007
  };
6871
- _this1.unmute = function() {
6872
- if (_this1.props.videoElement) {
6873
- _this1.props.videoElement.muted = false;
7008
+ _this.unmute = function() {
7009
+ if (_this.props.videoElement) {
7010
+ _this.props.videoElement.muted = false;
6874
7011
  }
6875
7012
  };
6876
- _this1.setPlaybackRate = function(rate) {
6877
- if (_this1.props.videoElement && rate > 0) {
6878
- _this1.props.videoElement.playbackRate = rate;
7013
+ _this.setPlaybackRate = function(rate) {
7014
+ if (_this.props.videoElement && rate > 0) {
7015
+ _this.props.videoElement.playbackRate = rate;
6879
7016
  }
6880
7017
  };
6881
- _this1.getDuration = function() {
6882
- if (_this1.props.videoElement && isFinite(_this1.props.videoElement.duration)) {
6883
- return _this1.props.videoElement.duration;
7018
+ _this.getDuration = function() {
7019
+ if (_this.props.videoElement && isFinite(_this.props.videoElement.duration)) {
7020
+ return _this.props.videoElement.duration;
6884
7021
  }
6885
7022
  return null;
6886
7023
  };
6887
- _this1.getCurrentTime = function() {
6888
- if (_this1.props.videoElement && isFinite(_this1.props.videoElement.currentTime)) {
6889
- return _this1.props.videoElement.currentTime;
7024
+ _this.getCurrentTime = function() {
7025
+ if (_this.props.videoElement && isFinite(_this.props.videoElement.currentTime)) {
7026
+ return _this.props.videoElement.currentTime;
6890
7027
  }
6891
7028
  return null;
6892
7029
  };
6893
- _this1.getSecondsLoaded = function() {
6894
- if (_this1.props.videoElement && _this1.props.videoElement.buffered.length > 0) {
6895
- return _this1.props.videoElement.buffered.end(_this1.props.videoElement.buffered.length - 1);
7030
+ _this.getSecondsLoaded = function() {
7031
+ if (_this.props.videoElement && _this.props.videoElement.buffered.length > 0) {
7032
+ return _this.props.videoElement.buffered.end(_this.props.videoElement.buffered.length - 1);
6896
7033
  }
6897
7034
  return null;
6898
7035
  };
6899
- _this1.getInternalPlayer = function() {
7036
+ _this.getInternalPlayer = function() {
6900
7037
  var key = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "player";
6901
- if (key === "player") return _this1.player;
6902
- if (key === "video") return _this1.props.videoElement;
6903
- if (key === "hls" && _this1.player) return _this1.player.hls;
7038
+ if (key === "player") return _this.player;
7039
+ if (key === "video") return _this.props.videoElement;
7040
+ if (key === "hls" && _this.player) return _this.player.hls;
6904
7041
  return null;
6905
7042
  };
6906
7043
  return _this;