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 { S as StormcloudVideoPlayerConfig } from '../types-CUKMIqHL.cjs';
1
+ import { S as StormcloudVideoPlayerConfig } from '../types-DQM-Tu6a.cjs';
2
2
 
3
3
  declare class StormcloudVideoPlayer {
4
4
  private readonly video;
@@ -61,6 +61,7 @@ declare class StormcloudVideoPlayer {
61
61
  private readonly maxConsecutiveFailures;
62
62
  private lastAdRequestTime;
63
63
  private readonly minAdRequestIntervalMs;
64
+ private readonly defaultMinRemainingMsToStartAd;
64
65
  private readonly backoffBaseMs;
65
66
  private readonly maxBackoffMs;
66
67
  private placeholderContainer;
@@ -76,6 +77,7 @@ declare class StormcloudVideoPlayer {
76
77
  private preloadPoolActive;
77
78
  private preloadPoolLoopRunning;
78
79
  private adDetectSentForCurrentBreak;
80
+ private adBreakEpoch;
79
81
  private palNonce;
80
82
  private palPlaybackStarted;
81
83
  private readonly streamCorrelator;
@@ -195,6 +197,8 @@ declare class StormcloudVideoPlayer {
195
197
  private selectVastTagsForBreak;
196
198
  private logAdState;
197
199
  private getRemainingAdMs;
200
+ private getMinRemainingMsToStartAd;
201
+ private hasTimeToStartAnotherAd;
198
202
  private findBreakForTime;
199
203
  toggleMute(): void;
200
204
  toggleFullscreen(): Promise<void>;
@@ -2688,6 +2688,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2688
2688
  this.maxConsecutiveFailures = 5;
2689
2689
  this.lastAdRequestTime = 0;
2690
2690
  this.minAdRequestIntervalMs = 3e3;
2691
+ this.defaultMinRemainingMsToStartAd = 4e3;
2691
2692
  this.backoffBaseMs = 1e3;
2692
2693
  this.maxBackoffMs = 15e3;
2693
2694
  this.globalConsecutiveNoFills = 0;
@@ -2702,6 +2703,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2702
2703
  this.preloadPoolActive = false;
2703
2704
  this.preloadPoolLoopRunning = false;
2704
2705
  this.adDetectSentForCurrentBreak = false;
2706
+ this.adBreakEpoch = 0;
2705
2707
  this.palPlaybackStarted = false;
2706
2708
  this.streamCorrelator = generateCorrelator();
2707
2709
  this.consentSignals = {};
@@ -3206,7 +3208,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3206
3208
  } : {});
3207
3209
  }
3208
3210
  if (_this.inAdBreak) {
3209
- if (remaining > 500) {
3211
+ if (_this.hasTimeToStartAnotherAd()) {
3210
3212
  _this.tryNextAvailableAdWithRateLimit();
3211
3213
  } else {
3212
3214
  _this.handleAdPodComplete();
@@ -3279,7 +3281,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3279
3281
  queuedUrls: _to_consumable_array(_this.adRequestQueue)
3280
3282
  } : {});
3281
3283
  }
3282
- if (remaining > 500) {
3284
+ if (_this.hasTimeToStartAnotherAd()) {
3283
3285
  _this.tryNextAvailableAdWithRateLimit();
3284
3286
  } else {
3285
3287
  _this.handleAdPodComplete();
@@ -3979,7 +3981,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3979
3981
  var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
3980
3982
  this.scheduleAdStopCountdown(remainingMs1);
3981
3983
  }
3982
- if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
3984
+ if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0 && this.hasTimeToStartAnotherAd()) {
3983
3985
  this.tryNextAvailableAdWithRateLimit();
3984
3986
  }
3985
3987
  return;
@@ -5249,7 +5251,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5249
5251
  key: "preloadAdIntoPool",
5250
5252
  value: function preloadAdIntoPool(vastUrl) {
5251
5253
  return _async_to_generator(function() {
5252
- var _this, loadPromise;
5254
+ var _this, epoch, loadPromise;
5253
5255
  return _ts_generator(this, function(_state) {
5254
5256
  _this = this;
5255
5257
  if (this.isGamInCooldown()) {
@@ -5275,6 +5277,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5275
5277
  if (this.config.debugAdTiming) {
5276
5278
  console.log("[PRELOAD-POOL] \uD83D\uDCE5 Preloading ad into pool: ".concat(vastUrl));
5277
5279
  }
5280
+ epoch = this.adBreakEpoch;
5278
5281
  loadPromise = function() {
5279
5282
  return _async_to_generator(function() {
5280
5283
  var _this, hasAdError, adErrorPayload, errorListenerCleanup, continueLiveStreamDuringAds, preloadAd, errorListener, isNoFill, poolEntry, lateErrorListener, error;
@@ -5352,6 +5355,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5352
5355
  2
5353
5356
  ];
5354
5357
  }
5358
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch) {
5359
+ if (this.config.debugAdTiming) {
5360
+ console.log("[PRELOAD-POOL] \uD83D\uDEAB Discarding preloaded ad - break ended during fetch");
5361
+ }
5362
+ if (errorListenerCleanup) {
5363
+ errorListenerCleanup();
5364
+ }
5365
+ try {
5366
+ preloadAd.destroy();
5367
+ } catch (unused) {}
5368
+ return [
5369
+ 2
5370
+ ];
5371
+ }
5355
5372
  poolEntry = {
5356
5373
  vastUrl: vastUrl,
5357
5374
  adController: preloadAd,
@@ -5423,7 +5440,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5423
5440
  key: "preloadPoolLoop",
5424
5441
  value: function preloadPoolLoop(baseVastUrl) {
5425
5442
  return _async_to_generator(function() {
5426
- var remaining, newUrls, newUrl;
5443
+ var epoch, newUrls, newUrl;
5427
5444
  return _ts_generator(this, function(_state) {
5428
5445
  switch(_state.label){
5429
5446
  case 0:
@@ -5433,12 +5450,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5433
5450
  ];
5434
5451
  }
5435
5452
  this.preloadPoolLoopRunning = true;
5453
+ epoch = this.adBreakEpoch;
5436
5454
  if (this.config.debugAdTiming) {
5437
5455
  console.log("[PRELOAD-POOL] \uD83D\uDD04 Starting continuous preload loop");
5438
5456
  }
5439
5457
  _state.label = 1;
5440
5458
  case 1:
5441
- if (!this.preloadPoolActive) return [
5459
+ if (!(this.preloadPoolActive && epoch === this.adBreakEpoch)) return [
5442
5460
  3,
5443
5461
  10
5444
5462
  ];
@@ -5483,20 +5501,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5483
5501
  3,
5484
5502
  8
5485
5503
  ];
5486
- if (!this.preloadPoolActive || this.isGamInCooldown()) {
5504
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch || this.isGamInCooldown()) {
5487
5505
  return [
5488
5506
  3,
5489
5507
  8
5490
5508
  ];
5491
5509
  }
5492
- if (this.inAdBreak) {
5493
- remaining = this.getRemainingAdMs();
5494
- if (remaining <= 0) {
5495
- return [
5496
- 3,
5497
- 8
5498
- ];
5510
+ if (this.inAdBreak && !this.hasTimeToStartAnotherAd()) {
5511
+ if (this.config.debugAdTiming) {
5512
+ console.log("[PRELOAD-POOL] Not enough ad break time left, stopping preload");
5499
5513
  }
5514
+ return [
5515
+ 3,
5516
+ 8
5517
+ ];
5500
5518
  }
5501
5519
  newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);
5502
5520
  newUrl = newUrls[0];
@@ -5916,7 +5934,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5916
5934
  key: "continuousFetchLoop",
5917
5935
  value: function continuousFetchLoop(baseVastUrl) {
5918
5936
  return _async_to_generator(function() {
5919
- var _this, _loop, _ret;
5937
+ var _this, _loop, epoch, _ret;
5920
5938
  return _ts_generator(this, function(_state) {
5921
5939
  switch(_state.label){
5922
5940
  case 0:
@@ -5926,9 +5944,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5926
5944
  switch(_state.label){
5927
5945
  case 0:
5928
5946
  remaining = _this.getRemainingAdMs();
5929
- if (remaining <= 0) {
5947
+ if (remaining <= _this.getMinRemainingMsToStartAd()) {
5930
5948
  if (_this.config.debugAdTiming) {
5931
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Ad break time expired, stopping URL generation");
5949
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough ad break time left (".concat(remaining, "ms), stopping URL generation"));
5932
5950
  }
5933
5951
  return [
5934
5952
  2,
@@ -6026,9 +6044,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6026
6044
  }
6027
6045
  });
6028
6046
  };
6047
+ epoch = this.adBreakEpoch;
6029
6048
  _state.label = 1;
6030
6049
  case 1:
6031
- if (!(this.continuousFetchingActive && this.inAdBreak)) return [
6050
+ if (!(this.continuousFetchingActive && this.inAdBreak && epoch === this.adBreakEpoch)) return [
6032
6051
  3,
6033
6052
  3
6034
6053
  ];
@@ -6077,10 +6096,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6077
6096
  key: "tryNextAvailableAdWithRateLimit",
6078
6097
  value: function tryNextAvailableAdWithRateLimit() {
6079
6098
  return _async_to_generator(function() {
6080
- var backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6099
+ var epoch, backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6081
6100
  return _ts_generator(this, function(_state) {
6082
6101
  switch(_state.label){
6083
6102
  case 0:
6103
+ if (!this.inAdBreak) {
6104
+ return [
6105
+ 2
6106
+ ];
6107
+ }
6108
+ epoch = this.adBreakEpoch;
6084
6109
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
6085
6110
  if (this.config.debugAdTiming) {
6086
6111
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break gracefully"));
@@ -6112,6 +6137,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6112
6137
  _state.sent();
6113
6138
  _state.label = 2;
6114
6139
  case 2:
6140
+ if (!this.inAdBreak || epoch !== this.adBreakEpoch) {
6141
+ return [
6142
+ 2
6143
+ ];
6144
+ }
6115
6145
  return [
6116
6146
  2,
6117
6147
  this.tryNextAvailableAd(0)
@@ -6130,10 +6160,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6130
6160
  return _ts_generator(this, function(_state) {
6131
6161
  switch(_state.label){
6132
6162
  case 0:
6163
+ if (!this.inAdBreak) {
6164
+ return [
6165
+ 2
6166
+ ];
6167
+ }
6133
6168
  remaining = this.getRemainingAdMs();
6134
- if (remaining <= 500) {
6169
+ if (!this.hasTimeToStartAnotherAd()) {
6135
6170
  if (this.config.debugAdTiming) {
6136
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F No time remaining, ending ad break");
6171
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough time remaining (".concat(remaining, "ms) to start another ad, ending ad break"));
6137
6172
  }
6138
6173
  this.handleAdPodComplete();
6139
6174
  return [
@@ -6405,12 +6440,27 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6405
6440
  10
6406
6441
  ];
6407
6442
  }
6443
+ if (!this.hasTimeToStartAnotherAd()) {
6444
+ if (this.config.debugAdTiming) {
6445
+ console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Not enough time remaining during placeholder wait, ending ad break");
6446
+ }
6447
+ return [
6448
+ 3,
6449
+ 10
6450
+ ];
6451
+ }
6408
6452
  _state.label = 3;
6409
6453
  case 3:
6410
6454
  if (!(this.adRequestQueue.length > 0)) return [
6411
6455
  3,
6412
6456
  9
6413
6457
  ];
6458
+ if (!this.hasTimeToStartAnotherAd()) {
6459
+ return [
6460
+ 3,
6461
+ 9
6462
+ ];
6463
+ }
6414
6464
  nextAdUrl = this.adRequestQueue.shift();
6415
6465
  if (!nextAdUrl) {
6416
6466
  return [
@@ -6693,21 +6743,23 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6693
6743
  if (!this.inAdBreak) return;
6694
6744
  this.adStopTimerId = void 0;
6695
6745
  var adPlaying = this.adPlayer.isAdPlaying();
6696
- var pendingAds = this.adPodQueue.length > 0;
6697
6746
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
6698
6747
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
6699
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
6748
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
6700
6749
  var elapsedSinceStartMs = 0;
6701
6750
  if (this.currentAdBreakStartWallClockMs != null) {
6702
6751
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
6703
6752
  }
6704
6753
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
6705
6754
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
6706
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
6755
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
6707
6756
  if (shouldExtendAdBreak) {
6708
6757
  this.scheduleAdStopCountdown(checkIntervalMs);
6709
6758
  return;
6710
6759
  }
6760
+ if (this.config.debugAdTiming) {
6761
+ console.log("[StormcloudVideoPlayer] ⏱️ Ad break boundary reached (overrun=".concat(overrunMs, "ms) - hard-stopping ads and resuming stream"));
6762
+ }
6711
6763
  if (adPlaying) {
6712
6764
  this.adPlayer.stop().catch(function() {});
6713
6765
  }
@@ -7142,6 +7194,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7142
7194
  if (this.config.debugAdTiming) {
7143
7195
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
7144
7196
  }
7197
+ this.adBreakEpoch++;
7145
7198
  this.clearAdRequestWatchdog();
7146
7199
  this.clearAdFailsafeTimer();
7147
7200
  this.activeAdRequestToken = null;
@@ -7212,11 +7265,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7212
7265
  this.handleAdPodComplete();
7213
7266
  return;
7214
7267
  }
7215
- if (remaining > 500) {
7268
+ if (this.hasTimeToStartAnotherAd()) {
7216
7269
  this.tryNextAvailableAdWithRateLimit();
7217
7270
  } else {
7218
7271
  if (this.config.debugAdTiming) {
7219
- console.log("[AD-ERROR] Ad failed and no time remaining. Failed URLs:", this.failedVastUrls.size);
7272
+ console.log("[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:", this.failedVastUrls.size);
7220
7273
  }
7221
7274
  this.handleAdPodComplete();
7222
7275
  }
@@ -7351,6 +7404,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7351
7404
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
7352
7405
  }
7353
7406
  },
7407
+ {
7408
+ key: "getMinRemainingMsToStartAd",
7409
+ value: function getMinRemainingMsToStartAd() {
7410
+ var configured = this.config.minRemainingMsToStartAd;
7411
+ if (typeof configured === "number" && configured >= 0) {
7412
+ return configured;
7413
+ }
7414
+ return this.defaultMinRemainingMsToStartAd;
7415
+ }
7416
+ },
7417
+ {
7418
+ key: "hasTimeToStartAnotherAd",
7419
+ value: function hasTimeToStartAnotherAd() {
7420
+ return this.getRemainingAdMs() > this.getMinRemainingMsToStartAd();
7421
+ }
7422
+ },
7354
7423
  {
7355
7424
  key: "findBreakForTime",
7356
7425
  value: function findBreakForTime(nowMs) {