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,5 +1,5 @@
1
1
  import { Component } from 'react';
2
- import { S as StormcloudVideoPlayerConfig } from '../types-CUKMIqHL.cjs';
2
+ import { S as StormcloudVideoPlayerConfig } from '../types-DQM-Tu6a.cjs';
3
3
 
4
4
  interface HlsPlayerProps extends StormcloudVideoPlayerConfig {
5
5
  onMount?: (player: any) => void;
@@ -2724,6 +2724,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2724
2724
  this.maxConsecutiveFailures = 5;
2725
2725
  this.lastAdRequestTime = 0;
2726
2726
  this.minAdRequestIntervalMs = 3e3;
2727
+ this.defaultMinRemainingMsToStartAd = 4e3;
2727
2728
  this.backoffBaseMs = 1e3;
2728
2729
  this.maxBackoffMs = 15e3;
2729
2730
  this.globalConsecutiveNoFills = 0;
@@ -2738,6 +2739,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2738
2739
  this.preloadPoolActive = false;
2739
2740
  this.preloadPoolLoopRunning = false;
2740
2741
  this.adDetectSentForCurrentBreak = false;
2742
+ this.adBreakEpoch = 0;
2741
2743
  this.palPlaybackStarted = false;
2742
2744
  this.streamCorrelator = generateCorrelator();
2743
2745
  this.consentSignals = {};
@@ -3242,7 +3244,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3242
3244
  } : {});
3243
3245
  }
3244
3246
  if (_this.inAdBreak) {
3245
- if (remaining > 500) {
3247
+ if (_this.hasTimeToStartAnotherAd()) {
3246
3248
  _this.tryNextAvailableAdWithRateLimit();
3247
3249
  } else {
3248
3250
  _this.handleAdPodComplete();
@@ -3315,7 +3317,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3315
3317
  queuedUrls: _to_consumable_array(_this.adRequestQueue)
3316
3318
  } : {});
3317
3319
  }
3318
- if (remaining > 500) {
3320
+ if (_this.hasTimeToStartAnotherAd()) {
3319
3321
  _this.tryNextAvailableAdWithRateLimit();
3320
3322
  } else {
3321
3323
  _this.handleAdPodComplete();
@@ -4015,7 +4017,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4015
4017
  var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
4016
4018
  this.scheduleAdStopCountdown(remainingMs1);
4017
4019
  }
4018
- if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
4020
+ if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0 && this.hasTimeToStartAnotherAd()) {
4019
4021
  this.tryNextAvailableAdWithRateLimit();
4020
4022
  }
4021
4023
  return;
@@ -5285,7 +5287,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5285
5287
  key: "preloadAdIntoPool",
5286
5288
  value: function preloadAdIntoPool(vastUrl) {
5287
5289
  return _async_to_generator(function() {
5288
- var _this, loadPromise;
5290
+ var _this, epoch, loadPromise;
5289
5291
  return _ts_generator(this, function(_state) {
5290
5292
  _this = this;
5291
5293
  if (this.isGamInCooldown()) {
@@ -5311,6 +5313,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5311
5313
  if (this.config.debugAdTiming) {
5312
5314
  console.log("[PRELOAD-POOL] \uD83D\uDCE5 Preloading ad into pool: ".concat(vastUrl));
5313
5315
  }
5316
+ epoch = this.adBreakEpoch;
5314
5317
  loadPromise = function() {
5315
5318
  return _async_to_generator(function() {
5316
5319
  var _this, hasAdError, adErrorPayload, errorListenerCleanup, continueLiveStreamDuringAds, preloadAd, errorListener, isNoFill, poolEntry, lateErrorListener, error;
@@ -5388,6 +5391,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5388
5391
  2
5389
5392
  ];
5390
5393
  }
5394
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch) {
5395
+ if (this.config.debugAdTiming) {
5396
+ console.log("[PRELOAD-POOL] \uD83D\uDEAB Discarding preloaded ad - break ended during fetch");
5397
+ }
5398
+ if (errorListenerCleanup) {
5399
+ errorListenerCleanup();
5400
+ }
5401
+ try {
5402
+ preloadAd.destroy();
5403
+ } catch (unused) {}
5404
+ return [
5405
+ 2
5406
+ ];
5407
+ }
5391
5408
  poolEntry = {
5392
5409
  vastUrl: vastUrl,
5393
5410
  adController: preloadAd,
@@ -5459,7 +5476,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5459
5476
  key: "preloadPoolLoop",
5460
5477
  value: function preloadPoolLoop(baseVastUrl) {
5461
5478
  return _async_to_generator(function() {
5462
- var remaining, newUrls, newUrl;
5479
+ var epoch, newUrls, newUrl;
5463
5480
  return _ts_generator(this, function(_state) {
5464
5481
  switch(_state.label){
5465
5482
  case 0:
@@ -5469,12 +5486,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5469
5486
  ];
5470
5487
  }
5471
5488
  this.preloadPoolLoopRunning = true;
5489
+ epoch = this.adBreakEpoch;
5472
5490
  if (this.config.debugAdTiming) {
5473
5491
  console.log("[PRELOAD-POOL] \uD83D\uDD04 Starting continuous preload loop");
5474
5492
  }
5475
5493
  _state.label = 1;
5476
5494
  case 1:
5477
- if (!this.preloadPoolActive) return [
5495
+ if (!(this.preloadPoolActive && epoch === this.adBreakEpoch)) return [
5478
5496
  3,
5479
5497
  10
5480
5498
  ];
@@ -5519,20 +5537,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5519
5537
  3,
5520
5538
  8
5521
5539
  ];
5522
- if (!this.preloadPoolActive || this.isGamInCooldown()) {
5540
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch || this.isGamInCooldown()) {
5523
5541
  return [
5524
5542
  3,
5525
5543
  8
5526
5544
  ];
5527
5545
  }
5528
- if (this.inAdBreak) {
5529
- remaining = this.getRemainingAdMs();
5530
- if (remaining <= 0) {
5531
- return [
5532
- 3,
5533
- 8
5534
- ];
5546
+ if (this.inAdBreak && !this.hasTimeToStartAnotherAd()) {
5547
+ if (this.config.debugAdTiming) {
5548
+ console.log("[PRELOAD-POOL] Not enough ad break time left, stopping preload");
5535
5549
  }
5550
+ return [
5551
+ 3,
5552
+ 8
5553
+ ];
5536
5554
  }
5537
5555
  newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);
5538
5556
  newUrl = newUrls[0];
@@ -5952,7 +5970,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5952
5970
  key: "continuousFetchLoop",
5953
5971
  value: function continuousFetchLoop(baseVastUrl) {
5954
5972
  return _async_to_generator(function() {
5955
- var _this, _loop, _ret;
5973
+ var _this, _loop, epoch, _ret;
5956
5974
  return _ts_generator(this, function(_state) {
5957
5975
  switch(_state.label){
5958
5976
  case 0:
@@ -5962,9 +5980,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5962
5980
  switch(_state.label){
5963
5981
  case 0:
5964
5982
  remaining = _this.getRemainingAdMs();
5965
- if (remaining <= 0) {
5983
+ if (remaining <= _this.getMinRemainingMsToStartAd()) {
5966
5984
  if (_this.config.debugAdTiming) {
5967
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Ad break time expired, stopping URL generation");
5985
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough ad break time left (".concat(remaining, "ms), stopping URL generation"));
5968
5986
  }
5969
5987
  return [
5970
5988
  2,
@@ -6062,9 +6080,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6062
6080
  }
6063
6081
  });
6064
6082
  };
6083
+ epoch = this.adBreakEpoch;
6065
6084
  _state.label = 1;
6066
6085
  case 1:
6067
- if (!(this.continuousFetchingActive && this.inAdBreak)) return [
6086
+ if (!(this.continuousFetchingActive && this.inAdBreak && epoch === this.adBreakEpoch)) return [
6068
6087
  3,
6069
6088
  3
6070
6089
  ];
@@ -6113,10 +6132,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6113
6132
  key: "tryNextAvailableAdWithRateLimit",
6114
6133
  value: function tryNextAvailableAdWithRateLimit() {
6115
6134
  return _async_to_generator(function() {
6116
- var backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6135
+ var epoch, backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6117
6136
  return _ts_generator(this, function(_state) {
6118
6137
  switch(_state.label){
6119
6138
  case 0:
6139
+ if (!this.inAdBreak) {
6140
+ return [
6141
+ 2
6142
+ ];
6143
+ }
6144
+ epoch = this.adBreakEpoch;
6120
6145
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
6121
6146
  if (this.config.debugAdTiming) {
6122
6147
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break gracefully"));
@@ -6148,6 +6173,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6148
6173
  _state.sent();
6149
6174
  _state.label = 2;
6150
6175
  case 2:
6176
+ if (!this.inAdBreak || epoch !== this.adBreakEpoch) {
6177
+ return [
6178
+ 2
6179
+ ];
6180
+ }
6151
6181
  return [
6152
6182
  2,
6153
6183
  this.tryNextAvailableAd(0)
@@ -6166,10 +6196,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6166
6196
  return _ts_generator(this, function(_state) {
6167
6197
  switch(_state.label){
6168
6198
  case 0:
6199
+ if (!this.inAdBreak) {
6200
+ return [
6201
+ 2
6202
+ ];
6203
+ }
6169
6204
  remaining = this.getRemainingAdMs();
6170
- if (remaining <= 500) {
6205
+ if (!this.hasTimeToStartAnotherAd()) {
6171
6206
  if (this.config.debugAdTiming) {
6172
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F No time remaining, ending ad break");
6207
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough time remaining (".concat(remaining, "ms) to start another ad, ending ad break"));
6173
6208
  }
6174
6209
  this.handleAdPodComplete();
6175
6210
  return [
@@ -6441,12 +6476,27 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6441
6476
  10
6442
6477
  ];
6443
6478
  }
6479
+ if (!this.hasTimeToStartAnotherAd()) {
6480
+ if (this.config.debugAdTiming) {
6481
+ console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Not enough time remaining during placeholder wait, ending ad break");
6482
+ }
6483
+ return [
6484
+ 3,
6485
+ 10
6486
+ ];
6487
+ }
6444
6488
  _state.label = 3;
6445
6489
  case 3:
6446
6490
  if (!(this.adRequestQueue.length > 0)) return [
6447
6491
  3,
6448
6492
  9
6449
6493
  ];
6494
+ if (!this.hasTimeToStartAnotherAd()) {
6495
+ return [
6496
+ 3,
6497
+ 9
6498
+ ];
6499
+ }
6450
6500
  nextAdUrl = this.adRequestQueue.shift();
6451
6501
  if (!nextAdUrl) {
6452
6502
  return [
@@ -6729,21 +6779,23 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6729
6779
  if (!this.inAdBreak) return;
6730
6780
  this.adStopTimerId = void 0;
6731
6781
  var adPlaying = this.adPlayer.isAdPlaying();
6732
- var pendingAds = this.adPodQueue.length > 0;
6733
6782
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
6734
6783
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
6735
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
6784
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
6736
6785
  var elapsedSinceStartMs = 0;
6737
6786
  if (this.currentAdBreakStartWallClockMs != null) {
6738
6787
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
6739
6788
  }
6740
6789
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
6741
6790
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
6742
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
6791
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
6743
6792
  if (shouldExtendAdBreak) {
6744
6793
  this.scheduleAdStopCountdown(checkIntervalMs);
6745
6794
  return;
6746
6795
  }
6796
+ if (this.config.debugAdTiming) {
6797
+ console.log("[StormcloudVideoPlayer] ⏱️ Ad break boundary reached (overrun=".concat(overrunMs, "ms) - hard-stopping ads and resuming stream"));
6798
+ }
6747
6799
  if (adPlaying) {
6748
6800
  this.adPlayer.stop().catch(function() {});
6749
6801
  }
@@ -7178,6 +7230,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7178
7230
  if (this.config.debugAdTiming) {
7179
7231
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
7180
7232
  }
7233
+ this.adBreakEpoch++;
7181
7234
  this.clearAdRequestWatchdog();
7182
7235
  this.clearAdFailsafeTimer();
7183
7236
  this.activeAdRequestToken = null;
@@ -7248,11 +7301,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7248
7301
  this.handleAdPodComplete();
7249
7302
  return;
7250
7303
  }
7251
- if (remaining > 500) {
7304
+ if (this.hasTimeToStartAnotherAd()) {
7252
7305
  this.tryNextAvailableAdWithRateLimit();
7253
7306
  } else {
7254
7307
  if (this.config.debugAdTiming) {
7255
- console.log("[AD-ERROR] Ad failed and no time remaining. Failed URLs:", this.failedVastUrls.size);
7308
+ console.log("[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:", this.failedVastUrls.size);
7256
7309
  }
7257
7310
  this.handleAdPodComplete();
7258
7311
  }
@@ -7387,6 +7440,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7387
7440
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
7388
7441
  }
7389
7442
  },
7443
+ {
7444
+ key: "getMinRemainingMsToStartAd",
7445
+ value: function getMinRemainingMsToStartAd() {
7446
+ var configured = this.config.minRemainingMsToStartAd;
7447
+ if (typeof configured === "number" && configured >= 0) {
7448
+ return configured;
7449
+ }
7450
+ return this.defaultMinRemainingMsToStartAd;
7451
+ }
7452
+ },
7453
+ {
7454
+ key: "hasTimeToStartAnotherAd",
7455
+ value: function hasTimeToStartAnotherAd() {
7456
+ return this.getRemainingAdMs() > this.getMinRemainingMsToStartAd();
7457
+ }
7458
+ },
7390
7459
  {
7391
7460
  key: "findBreakForTime",
7392
7461
  value: function findBreakForTime(nowMs) {