stormcloud-video-player 0.8.8 → 0.8.10

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.
@@ -1,4 +1,4 @@
1
- import { A as AdController } from '../types-CUKMIqHL.cjs';
1
+ import { A as AdController } from '../types-DQM-Tu6a.cjs';
2
2
  import Hls from 'hls.js';
3
3
 
4
4
  declare function createHlsAdPlayer(contentVideo: HTMLVideoElement, options?: {
@@ -12,6 +12,7 @@ interface StormcloudVideoPlayerConfig {
12
12
  adFailsafeTimeoutMs?: number;
13
13
  adBreakCheckIntervalMs?: number;
14
14
  maxAdBreakExtensionMs?: number;
15
+ minRemainingMsToStartAd?: number;
15
16
  showCustomControls?: boolean;
16
17
  hideLoadingIndicator?: boolean;
17
18
  onVolumeToggle?: () => void;
@@ -2674,6 +2674,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2674
2674
  this.maxConsecutiveFailures = 5;
2675
2675
  this.lastAdRequestTime = 0;
2676
2676
  this.minAdRequestIntervalMs = 3e3;
2677
+ this.defaultMinRemainingMsToStartAd = 4e3;
2677
2678
  this.backoffBaseMs = 1e3;
2678
2679
  this.maxBackoffMs = 15e3;
2679
2680
  this.globalConsecutiveNoFills = 0;
@@ -2688,6 +2689,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2688
2689
  this.preloadPoolActive = false;
2689
2690
  this.preloadPoolLoopRunning = false;
2690
2691
  this.adDetectSentForCurrentBreak = false;
2692
+ this.adBreakEpoch = 0;
2691
2693
  this.palPlaybackStarted = false;
2692
2694
  this.streamCorrelator = generateCorrelator();
2693
2695
  this.consentSignals = {};
@@ -3192,7 +3194,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3192
3194
  } : {});
3193
3195
  }
3194
3196
  if (_this.inAdBreak) {
3195
- if (remaining > 500) {
3197
+ if (_this.hasTimeToStartAnotherAd()) {
3196
3198
  _this.tryNextAvailableAdWithRateLimit();
3197
3199
  } else {
3198
3200
  _this.handleAdPodComplete();
@@ -3265,7 +3267,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3265
3267
  queuedUrls: _to_consumable_array(_this.adRequestQueue)
3266
3268
  } : {});
3267
3269
  }
3268
- if (remaining > 500) {
3270
+ if (_this.hasTimeToStartAnotherAd()) {
3269
3271
  _this.tryNextAvailableAdWithRateLimit();
3270
3272
  } else {
3271
3273
  _this.handleAdPodComplete();
@@ -3965,7 +3967,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3965
3967
  var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
3966
3968
  this.scheduleAdStopCountdown(remainingMs1);
3967
3969
  }
3968
- if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
3970
+ if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0 && this.hasTimeToStartAnotherAd()) {
3969
3971
  this.tryNextAvailableAdWithRateLimit();
3970
3972
  }
3971
3973
  return;
@@ -5235,7 +5237,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5235
5237
  key: "preloadAdIntoPool",
5236
5238
  value: function preloadAdIntoPool(vastUrl) {
5237
5239
  return _async_to_generator(function() {
5238
- var _this, loadPromise;
5240
+ var _this, epoch, loadPromise;
5239
5241
  return _ts_generator(this, function(_state) {
5240
5242
  _this = this;
5241
5243
  if (this.isGamInCooldown()) {
@@ -5261,6 +5263,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5261
5263
  if (this.config.debugAdTiming) {
5262
5264
  console.log("[PRELOAD-POOL] \uD83D\uDCE5 Preloading ad into pool: ".concat(vastUrl));
5263
5265
  }
5266
+ epoch = this.adBreakEpoch;
5264
5267
  loadPromise = function() {
5265
5268
  return _async_to_generator(function() {
5266
5269
  var _this, hasAdError, adErrorPayload, errorListenerCleanup, continueLiveStreamDuringAds, preloadAd, errorListener, isNoFill, poolEntry, lateErrorListener, error;
@@ -5338,6 +5341,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5338
5341
  2
5339
5342
  ];
5340
5343
  }
5344
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch) {
5345
+ if (this.config.debugAdTiming) {
5346
+ console.log("[PRELOAD-POOL] \uD83D\uDEAB Discarding preloaded ad - break ended during fetch");
5347
+ }
5348
+ if (errorListenerCleanup) {
5349
+ errorListenerCleanup();
5350
+ }
5351
+ try {
5352
+ preloadAd.destroy();
5353
+ } catch (unused) {}
5354
+ return [
5355
+ 2
5356
+ ];
5357
+ }
5341
5358
  poolEntry = {
5342
5359
  vastUrl: vastUrl,
5343
5360
  adController: preloadAd,
@@ -5409,7 +5426,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5409
5426
  key: "preloadPoolLoop",
5410
5427
  value: function preloadPoolLoop(baseVastUrl) {
5411
5428
  return _async_to_generator(function() {
5412
- var remaining, newUrls, newUrl;
5429
+ var epoch, newUrls, newUrl;
5413
5430
  return _ts_generator(this, function(_state) {
5414
5431
  switch(_state.label){
5415
5432
  case 0:
@@ -5419,12 +5436,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5419
5436
  ];
5420
5437
  }
5421
5438
  this.preloadPoolLoopRunning = true;
5439
+ epoch = this.adBreakEpoch;
5422
5440
  if (this.config.debugAdTiming) {
5423
5441
  console.log("[PRELOAD-POOL] \uD83D\uDD04 Starting continuous preload loop");
5424
5442
  }
5425
5443
  _state.label = 1;
5426
5444
  case 1:
5427
- if (!this.preloadPoolActive) return [
5445
+ if (!(this.preloadPoolActive && epoch === this.adBreakEpoch)) return [
5428
5446
  3,
5429
5447
  10
5430
5448
  ];
@@ -5469,20 +5487,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5469
5487
  3,
5470
5488
  8
5471
5489
  ];
5472
- if (!this.preloadPoolActive || this.isGamInCooldown()) {
5490
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch || this.isGamInCooldown()) {
5473
5491
  return [
5474
5492
  3,
5475
5493
  8
5476
5494
  ];
5477
5495
  }
5478
- if (this.inAdBreak) {
5479
- remaining = this.getRemainingAdMs();
5480
- if (remaining <= 0) {
5481
- return [
5482
- 3,
5483
- 8
5484
- ];
5496
+ if (this.inAdBreak && !this.hasTimeToStartAnotherAd()) {
5497
+ if (this.config.debugAdTiming) {
5498
+ console.log("[PRELOAD-POOL] Not enough ad break time left, stopping preload");
5485
5499
  }
5500
+ return [
5501
+ 3,
5502
+ 8
5503
+ ];
5486
5504
  }
5487
5505
  newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);
5488
5506
  newUrl = newUrls[0];
@@ -5902,7 +5920,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5902
5920
  key: "continuousFetchLoop",
5903
5921
  value: function continuousFetchLoop(baseVastUrl) {
5904
5922
  return _async_to_generator(function() {
5905
- var _this, _loop, _ret;
5923
+ var _this, _loop, epoch, _ret;
5906
5924
  return _ts_generator(this, function(_state) {
5907
5925
  switch(_state.label){
5908
5926
  case 0:
@@ -5912,9 +5930,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5912
5930
  switch(_state.label){
5913
5931
  case 0:
5914
5932
  remaining = _this.getRemainingAdMs();
5915
- if (remaining <= 0) {
5933
+ if (remaining <= _this.getMinRemainingMsToStartAd()) {
5916
5934
  if (_this.config.debugAdTiming) {
5917
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Ad break time expired, stopping URL generation");
5935
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough ad break time left (".concat(remaining, "ms), stopping URL generation"));
5918
5936
  }
5919
5937
  return [
5920
5938
  2,
@@ -6012,9 +6030,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6012
6030
  }
6013
6031
  });
6014
6032
  };
6033
+ epoch = this.adBreakEpoch;
6015
6034
  _state.label = 1;
6016
6035
  case 1:
6017
- if (!(this.continuousFetchingActive && this.inAdBreak)) return [
6036
+ if (!(this.continuousFetchingActive && this.inAdBreak && epoch === this.adBreakEpoch)) return [
6018
6037
  3,
6019
6038
  3
6020
6039
  ];
@@ -6063,10 +6082,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6063
6082
  key: "tryNextAvailableAdWithRateLimit",
6064
6083
  value: function tryNextAvailableAdWithRateLimit() {
6065
6084
  return _async_to_generator(function() {
6066
- var backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6085
+ var epoch, backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6067
6086
  return _ts_generator(this, function(_state) {
6068
6087
  switch(_state.label){
6069
6088
  case 0:
6089
+ if (!this.inAdBreak) {
6090
+ return [
6091
+ 2
6092
+ ];
6093
+ }
6094
+ epoch = this.adBreakEpoch;
6070
6095
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
6071
6096
  if (this.config.debugAdTiming) {
6072
6097
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break gracefully"));
@@ -6098,6 +6123,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6098
6123
  _state.sent();
6099
6124
  _state.label = 2;
6100
6125
  case 2:
6126
+ if (!this.inAdBreak || epoch !== this.adBreakEpoch) {
6127
+ return [
6128
+ 2
6129
+ ];
6130
+ }
6101
6131
  return [
6102
6132
  2,
6103
6133
  this.tryNextAvailableAd(0)
@@ -6116,10 +6146,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6116
6146
  return _ts_generator(this, function(_state) {
6117
6147
  switch(_state.label){
6118
6148
  case 0:
6149
+ if (!this.inAdBreak) {
6150
+ return [
6151
+ 2
6152
+ ];
6153
+ }
6119
6154
  remaining = this.getRemainingAdMs();
6120
- if (remaining <= 500) {
6155
+ if (!this.hasTimeToStartAnotherAd()) {
6121
6156
  if (this.config.debugAdTiming) {
6122
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F No time remaining, ending ad break");
6157
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough time remaining (".concat(remaining, "ms) to start another ad, ending ad break"));
6123
6158
  }
6124
6159
  this.handleAdPodComplete();
6125
6160
  return [
@@ -6391,12 +6426,27 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6391
6426
  10
6392
6427
  ];
6393
6428
  }
6429
+ if (!this.hasTimeToStartAnotherAd()) {
6430
+ if (this.config.debugAdTiming) {
6431
+ console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Not enough time remaining during placeholder wait, ending ad break");
6432
+ }
6433
+ return [
6434
+ 3,
6435
+ 10
6436
+ ];
6437
+ }
6394
6438
  _state.label = 3;
6395
6439
  case 3:
6396
6440
  if (!(this.adRequestQueue.length > 0)) return [
6397
6441
  3,
6398
6442
  9
6399
6443
  ];
6444
+ if (!this.hasTimeToStartAnotherAd()) {
6445
+ return [
6446
+ 3,
6447
+ 9
6448
+ ];
6449
+ }
6400
6450
  nextAdUrl = this.adRequestQueue.shift();
6401
6451
  if (!nextAdUrl) {
6402
6452
  return [
@@ -6679,21 +6729,23 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6679
6729
  if (!this.inAdBreak) return;
6680
6730
  this.adStopTimerId = void 0;
6681
6731
  var adPlaying = this.adPlayer.isAdPlaying();
6682
- var pendingAds = this.adPodQueue.length > 0;
6683
6732
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
6684
6733
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
6685
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
6734
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
6686
6735
  var elapsedSinceStartMs = 0;
6687
6736
  if (this.currentAdBreakStartWallClockMs != null) {
6688
6737
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
6689
6738
  }
6690
6739
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
6691
6740
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
6692
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
6741
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
6693
6742
  if (shouldExtendAdBreak) {
6694
6743
  this.scheduleAdStopCountdown(checkIntervalMs);
6695
6744
  return;
6696
6745
  }
6746
+ if (this.config.debugAdTiming) {
6747
+ console.log("[StormcloudVideoPlayer] ⏱️ Ad break boundary reached (overrun=".concat(overrunMs, "ms) - hard-stopping ads and resuming stream"));
6748
+ }
6697
6749
  if (adPlaying) {
6698
6750
  this.adPlayer.stop().catch(function() {});
6699
6751
  }
@@ -7128,6 +7180,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7128
7180
  if (this.config.debugAdTiming) {
7129
7181
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
7130
7182
  }
7183
+ this.adBreakEpoch++;
7131
7184
  this.clearAdRequestWatchdog();
7132
7185
  this.clearAdFailsafeTimer();
7133
7186
  this.activeAdRequestToken = null;
@@ -7198,11 +7251,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7198
7251
  this.handleAdPodComplete();
7199
7252
  return;
7200
7253
  }
7201
- if (remaining > 500) {
7254
+ if (this.hasTimeToStartAnotherAd()) {
7202
7255
  this.tryNextAvailableAdWithRateLimit();
7203
7256
  } else {
7204
7257
  if (this.config.debugAdTiming) {
7205
- console.log("[AD-ERROR] Ad failed and no time remaining. Failed URLs:", this.failedVastUrls.size);
7258
+ console.log("[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:", this.failedVastUrls.size);
7206
7259
  }
7207
7260
  this.handleAdPodComplete();
7208
7261
  }
@@ -7337,6 +7390,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7337
7390
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
7338
7391
  }
7339
7392
  },
7393
+ {
7394
+ key: "getMinRemainingMsToStartAd",
7395
+ value: function getMinRemainingMsToStartAd() {
7396
+ var configured = this.config.minRemainingMsToStartAd;
7397
+ if (typeof configured === "number" && configured >= 0) {
7398
+ return configured;
7399
+ }
7400
+ return this.defaultMinRemainingMsToStartAd;
7401
+ }
7402
+ },
7403
+ {
7404
+ key: "hasTimeToStartAnotherAd",
7405
+ value: function hasTimeToStartAnotherAd() {
7406
+ return this.getRemainingAdMs() > this.getMinRemainingMsToStartAd();
7407
+ }
7408
+ },
7340
7409
  {
7341
7410
  key: "findBreakForTime",
7342
7411
  value: function findBreakForTime(nowMs) {