stormcloud-video-player 0.8.9 → 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.
package/lib/index.d.cts CHANGED
@@ -27,6 +27,7 @@ interface StormcloudVideoPlayerConfig {
27
27
  adFailsafeTimeoutMs?: number;
28
28
  adBreakCheckIntervalMs?: number;
29
29
  maxAdBreakExtensionMs?: number;
30
+ minRemainingMsToStartAd?: number;
30
31
  showCustomControls?: boolean;
31
32
  hideLoadingIndicator?: boolean;
32
33
  onVolumeToggle?: () => void;
@@ -202,6 +203,7 @@ declare class StormcloudVideoPlayer {
202
203
  private readonly maxConsecutiveFailures;
203
204
  private lastAdRequestTime;
204
205
  private readonly minAdRequestIntervalMs;
206
+ private readonly defaultMinRemainingMsToStartAd;
205
207
  private readonly backoffBaseMs;
206
208
  private readonly maxBackoffMs;
207
209
  private placeholderContainer;
@@ -337,6 +339,8 @@ declare class StormcloudVideoPlayer {
337
339
  private selectVastTagsForBreak;
338
340
  private logAdState;
339
341
  private getRemainingAdMs;
342
+ private getMinRemainingMsToStartAd;
343
+ private hasTimeToStartAnotherAd;
340
344
  private findBreakForTime;
341
345
  toggleMute(): void;
342
346
  toggleFullscreen(): Promise<void>;
package/lib/index.d.ts CHANGED
@@ -27,6 +27,7 @@ interface StormcloudVideoPlayerConfig {
27
27
  adFailsafeTimeoutMs?: number;
28
28
  adBreakCheckIntervalMs?: number;
29
29
  maxAdBreakExtensionMs?: number;
30
+ minRemainingMsToStartAd?: number;
30
31
  showCustomControls?: boolean;
31
32
  hideLoadingIndicator?: boolean;
32
33
  onVolumeToggle?: () => void;
@@ -202,6 +203,7 @@ declare class StormcloudVideoPlayer {
202
203
  private readonly maxConsecutiveFailures;
203
204
  private lastAdRequestTime;
204
205
  private readonly minAdRequestIntervalMs;
206
+ private readonly defaultMinRemainingMsToStartAd;
205
207
  private readonly backoffBaseMs;
206
208
  private readonly maxBackoffMs;
207
209
  private placeholderContainer;
@@ -337,6 +339,8 @@ declare class StormcloudVideoPlayer {
337
339
  private selectVastTagsForBreak;
338
340
  private logAdState;
339
341
  private getRemainingAdMs;
342
+ private getMinRemainingMsToStartAd;
343
+ private hasTimeToStartAnotherAd;
340
344
  private findBreakForTime;
341
345
  toggleMute(): void;
342
346
  toggleFullscreen(): Promise<void>;
package/lib/index.js CHANGED
@@ -2708,6 +2708,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2708
2708
  this.maxConsecutiveFailures = 5;
2709
2709
  this.lastAdRequestTime = 0;
2710
2710
  this.minAdRequestIntervalMs = 3e3;
2711
+ this.defaultMinRemainingMsToStartAd = 4e3;
2711
2712
  this.backoffBaseMs = 1e3;
2712
2713
  this.maxBackoffMs = 15e3;
2713
2714
  this.globalConsecutiveNoFills = 0;
@@ -3227,7 +3228,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3227
3228
  } : {});
3228
3229
  }
3229
3230
  if (_this.inAdBreak) {
3230
- if (remaining > 500) {
3231
+ if (_this.hasTimeToStartAnotherAd()) {
3231
3232
  _this.tryNextAvailableAdWithRateLimit();
3232
3233
  } else {
3233
3234
  _this.handleAdPodComplete();
@@ -3300,7 +3301,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3300
3301
  queuedUrls: _to_consumable_array(_this.adRequestQueue)
3301
3302
  } : {});
3302
3303
  }
3303
- if (remaining > 500) {
3304
+ if (_this.hasTimeToStartAnotherAd()) {
3304
3305
  _this.tryNextAvailableAdWithRateLimit();
3305
3306
  } else {
3306
3307
  _this.handleAdPodComplete();
@@ -4000,7 +4001,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4000
4001
  var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
4001
4002
  this.scheduleAdStopCountdown(remainingMs1);
4002
4003
  }
4003
- if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
4004
+ if (!this.adPlayer.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0 && this.hasTimeToStartAnotherAd()) {
4004
4005
  this.tryNextAvailableAdWithRateLimit();
4005
4006
  }
4006
4007
  return;
@@ -5459,7 +5460,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5459
5460
  key: "preloadPoolLoop",
5460
5461
  value: function preloadPoolLoop(baseVastUrl) {
5461
5462
  return _async_to_generator(function() {
5462
- var epoch, remaining, newUrls, newUrl;
5463
+ var epoch, newUrls, newUrl;
5463
5464
  return _ts_generator(this, function(_state) {
5464
5465
  switch(_state.label){
5465
5466
  case 0:
@@ -5526,14 +5527,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5526
5527
  8
5527
5528
  ];
5528
5529
  }
5529
- if (this.inAdBreak) {
5530
- remaining = this.getRemainingAdMs();
5531
- if (remaining <= 0) {
5532
- return [
5533
- 3,
5534
- 8
5535
- ];
5530
+ if (this.inAdBreak && !this.hasTimeToStartAnotherAd()) {
5531
+ if (this.config.debugAdTiming) {
5532
+ console.log("[PRELOAD-POOL] Not enough ad break time left, stopping preload");
5536
5533
  }
5534
+ return [
5535
+ 3,
5536
+ 8
5537
+ ];
5537
5538
  }
5538
5539
  newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);
5539
5540
  newUrl = newUrls[0];
@@ -5963,9 +5964,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5963
5964
  switch(_state.label){
5964
5965
  case 0:
5965
5966
  remaining = _this.getRemainingAdMs();
5966
- if (remaining <= 0) {
5967
+ if (remaining <= _this.getMinRemainingMsToStartAd()) {
5967
5968
  if (_this.config.debugAdTiming) {
5968
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Ad break time expired, stopping URL generation");
5969
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough ad break time left (".concat(remaining, "ms), stopping URL generation"));
5969
5970
  }
5970
5971
  return [
5971
5972
  2,
@@ -6185,9 +6186,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6185
6186
  ];
6186
6187
  }
6187
6188
  remaining = this.getRemainingAdMs();
6188
- if (remaining <= 500) {
6189
+ if (!this.hasTimeToStartAnotherAd()) {
6189
6190
  if (this.config.debugAdTiming) {
6190
- console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F No time remaining, ending ad break");
6191
+ console.log("[CONTINUOUS-FETCH] ⏹️ Not enough time remaining (".concat(remaining, "ms) to start another ad, ending ad break"));
6191
6192
  }
6192
6193
  this.handleAdPodComplete();
6193
6194
  return [
@@ -6459,12 +6460,27 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6459
6460
  10
6460
6461
  ];
6461
6462
  }
6463
+ if (!this.hasTimeToStartAnotherAd()) {
6464
+ if (this.config.debugAdTiming) {
6465
+ console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F Not enough time remaining during placeholder wait, ending ad break");
6466
+ }
6467
+ return [
6468
+ 3,
6469
+ 10
6470
+ ];
6471
+ }
6462
6472
  _state.label = 3;
6463
6473
  case 3:
6464
6474
  if (!(this.adRequestQueue.length > 0)) return [
6465
6475
  3,
6466
6476
  9
6467
6477
  ];
6478
+ if (!this.hasTimeToStartAnotherAd()) {
6479
+ return [
6480
+ 3,
6481
+ 9
6482
+ ];
6483
+ }
6468
6484
  nextAdUrl = this.adRequestQueue.shift();
6469
6485
  if (!nextAdUrl) {
6470
6486
  return [
@@ -6747,21 +6763,23 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6747
6763
  if (!this.inAdBreak) return;
6748
6764
  this.adStopTimerId = void 0;
6749
6765
  var adPlaying = this.adPlayer.isAdPlaying();
6750
- var pendingAds = this.adPodQueue.length > 0;
6751
6766
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
6752
6767
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
6753
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
6768
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
6754
6769
  var elapsedSinceStartMs = 0;
6755
6770
  if (this.currentAdBreakStartWallClockMs != null) {
6756
6771
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
6757
6772
  }
6758
6773
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
6759
6774
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
6760
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
6775
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
6761
6776
  if (shouldExtendAdBreak) {
6762
6777
  this.scheduleAdStopCountdown(checkIntervalMs);
6763
6778
  return;
6764
6779
  }
6780
+ if (this.config.debugAdTiming) {
6781
+ console.log("[StormcloudVideoPlayer] ⏱️ Ad break boundary reached (overrun=".concat(overrunMs, "ms) - hard-stopping ads and resuming stream"));
6782
+ }
6765
6783
  if (adPlaying) {
6766
6784
  this.adPlayer.stop().catch(function() {});
6767
6785
  }
@@ -7267,11 +7285,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7267
7285
  this.handleAdPodComplete();
7268
7286
  return;
7269
7287
  }
7270
- if (remaining > 500) {
7288
+ if (this.hasTimeToStartAnotherAd()) {
7271
7289
  this.tryNextAvailableAdWithRateLimit();
7272
7290
  } else {
7273
7291
  if (this.config.debugAdTiming) {
7274
- console.log("[AD-ERROR] Ad failed and no time remaining. Failed URLs:", this.failedVastUrls.size);
7292
+ console.log("[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:", this.failedVastUrls.size);
7275
7293
  }
7276
7294
  this.handleAdPodComplete();
7277
7295
  }
@@ -7406,6 +7424,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7406
7424
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
7407
7425
  }
7408
7426
  },
7427
+ {
7428
+ key: "getMinRemainingMsToStartAd",
7429
+ value: function getMinRemainingMsToStartAd() {
7430
+ var configured = this.config.minRemainingMsToStartAd;
7431
+ if (typeof configured === "number" && configured >= 0) {
7432
+ return configured;
7433
+ }
7434
+ return this.defaultMinRemainingMsToStartAd;
7435
+ }
7436
+ },
7437
+ {
7438
+ key: "hasTimeToStartAnotherAd",
7439
+ value: function hasTimeToStartAnotherAd() {
7440
+ return this.getRemainingAdMs() > this.getMinRemainingMsToStartAd();
7441
+ }
7442
+ },
7409
7443
  {
7410
7444
  key: "findBreakForTime",
7411
7445
  value: function findBreakForTime(nowMs) {