stormcloud-video-player 0.3.64 → 0.3.65

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.
@@ -9,6 +9,7 @@ declare class StormcloudVideoPlayer {
9
9
  private inAdBreak;
10
10
  private currentAdBreakStartWallClockMs;
11
11
  private expectedAdBreakDurationMs;
12
+ private scteAdBreakEndWallClockMs;
12
13
  private adStopTimerId;
13
14
  private adStartTimerId;
14
15
  private adFailsafeTimerId;
@@ -105,6 +106,9 @@ declare class StormcloudVideoPlayer {
105
106
  private activatePendingScte35CuesForFragment;
106
107
  private onScte35Marker;
107
108
  private startScte35AdBreak;
109
+ private resolveScteBreakStartWallClockMs;
110
+ private setAdBreakDurationBoundary;
111
+ private scheduleAdStopAtBreakBoundary;
108
112
  private parseCueOutDuration;
109
113
  private parseCueOutCont;
110
114
  private parseAttributeList;
@@ -188,6 +192,7 @@ declare class StormcloudVideoPlayer {
188
192
  private selectVastTagsForBreak;
189
193
  private logAdState;
190
194
  private getRemainingAdMs;
195
+ private getAdBreakEndWallClockMs;
191
196
  private findBreakForTime;
192
197
  toggleMute(): void;
193
198
  toggleFullscreen(): Promise<void>;
@@ -3879,7 +3879,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3879
3879
  _this.showAds = true;
3880
3880
  _this.resetGamNoFillCounter();
3881
3881
  if (_this.inAdBreak && _this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
3882
- _this.scheduleAdStopCountdown(_this.getRemainingAdMs());
3882
+ _this.scheduleAdStopAtBreakBoundary();
3883
3883
  if (_this.config.debugAdTiming) {
3884
3884
  console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
3885
3885
  }
@@ -4523,12 +4523,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4523
4523
  if (marker.durationSeconds != null) {
4524
4524
  var newDurationMs = marker.durationSeconds * 1e3;
4525
4525
  if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
4526
- this.expectedAdBreakDurationMs = newDurationMs;
4527
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
4528
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
4529
- this.scheduleAdStopCountdown(remainingMs);
4526
+ this.setAdBreakDurationBoundary(newDurationMs);
4527
+ this.scheduleAdStopAtBreakBoundary();
4530
4528
  if (this.config.debugAdTiming) {
4531
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
4529
+ console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(this.getRemainingAdMs(), "ms"));
4532
4530
  }
4533
4531
  }
4534
4532
  }
@@ -4602,13 +4600,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4602
4600
  }
4603
4601
  if (marker.type === "progress" && this.inAdBreak) {
4604
4602
  if (marker.durationSeconds != null) {
4605
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
4606
- }
4607
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
4608
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
4609
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
4610
- this.scheduleAdStopCountdown(remainingMs1);
4603
+ this.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);
4611
4604
  }
4605
+ this.scheduleAdStopAtBreakBoundary();
4612
4606
  if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
4613
4607
  this.tryNextAvailableAdWithRateLimit();
4614
4608
  }
@@ -4633,15 +4627,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4633
4627
  activeAdRequest: this.activeAdRequestToken !== null
4634
4628
  });
4635
4629
  }
4636
- if (adPlaying || remaining > 1e3 && hasQueuedAds) {
4637
- if (this.config.debugAdTiming) {
4638
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active");
4639
- }
4640
- return;
4641
- }
4642
- this.inAdBreak = false;
4643
- this.expectedAdBreakDurationMs = void 0;
4644
- this.currentAdBreakStartWallClockMs = void 0;
4630
+ this.scteAdBreakEndWallClockMs = Date.now();
4645
4631
  this.clearAdStartTimer();
4646
4632
  this.clearAdStopTimer();
4647
4633
  if (adPlaying) {
@@ -4665,12 +4651,46 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4665
4651
  this.inAdBreak = true;
4666
4652
  this.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.pendingScte35CueKey;
4667
4653
  this.scheduledScte35BreakKey = void 0;
4668
- this.expectedAdBreakDurationMs = durationMs;
4669
- this.currentAdBreakStartWallClockMs = Date.now();
4654
+ this.currentAdBreakStartWallClockMs = this.resolveScteBreakStartWallClockMs(marker);
4655
+ this.setAdBreakDurationBoundary(durationMs);
4670
4656
  this.handleAdStart(marker);
4671
- if (this.expectedAdBreakDurationMs != null) {
4672
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4657
+ this.scheduleAdStopAtBreakBoundary();
4658
+ }
4659
+ },
4660
+ {
4661
+ key: "resolveScteBreakStartWallClockMs",
4662
+ value: function resolveScteBreakStartWallClockMs(marker) {
4663
+ var nowWallClockMs = Date.now();
4664
+ if (typeof marker.ptsSeconds !== "number") {
4665
+ return nowWallClockMs;
4673
4666
  }
4667
+ var nowMs = this.video.currentTime * 1e3;
4668
+ var estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
4669
+ var deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;
4670
+ if (!Number.isFinite(deltaMs)) {
4671
+ return nowWallClockMs;
4672
+ }
4673
+ return nowWallClockMs + Math.floor(deltaMs);
4674
+ }
4675
+ },
4676
+ {
4677
+ key: "setAdBreakDurationBoundary",
4678
+ value: function setAdBreakDurationBoundary(durationMs) {
4679
+ this.expectedAdBreakDurationMs = durationMs;
4680
+ if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {
4681
+ this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;
4682
+ } else {
4683
+ this.scteAdBreakEndWallClockMs = void 0;
4684
+ }
4685
+ }
4686
+ },
4687
+ {
4688
+ key: "scheduleAdStopAtBreakBoundary",
4689
+ value: function scheduleAdStopAtBreakBoundary() {
4690
+ if (this.expectedAdBreakDurationMs == null) {
4691
+ return;
4692
+ }
4693
+ this.scheduleAdStopCountdown(this.getRemainingAdMs());
4674
4694
  }
4675
4695
  },
4676
4696
  {
@@ -6298,7 +6318,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6298
6318
  }
6299
6319
  }
6300
6320
  this.inAdBreak = true;
6301
- this.currentAdBreakStartWallClockMs = Date.now();
6302
6321
  this.currentAdIndex = 0;
6303
6322
  this.totalAdsInBreak = 1;
6304
6323
  this.adPodQueue = [];
@@ -6385,7 +6404,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6385
6404
  case 2:
6386
6405
  _state.sent();
6387
6406
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6388
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6407
+ this.scheduleAdStopAtBreakBoundary();
6389
6408
  }
6390
6409
  adVolume = currentMuted ? 0 : currentVolume;
6391
6410
  this.ima.setAdVolume(adVolume);
@@ -6428,7 +6447,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6428
6447
  case 6:
6429
6448
  _state.sent();
6430
6449
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6431
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6450
+ this.scheduleAdStopAtBreakBoundary();
6432
6451
  }
6433
6452
  adVolume1 = currentMuted ? 0 : currentVolume;
6434
6453
  this.ima.setAdVolume(adVolume1);
@@ -6483,7 +6502,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6483
6502
  case 10:
6484
6503
  _state.sent();
6485
6504
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6486
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6505
+ this.scheduleAdStopAtBreakBoundary();
6487
6506
  }
6488
6507
  adVolume2 = currentMuted ? 0 : currentVolume;
6489
6508
  this.ima.setAdVolume(adVolume2);
@@ -6835,7 +6854,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6835
6854
  case 2:
6836
6855
  _state.sent();
6837
6856
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6838
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6857
+ this.scheduleAdStopAtBreakBoundary();
6839
6858
  }
6840
6859
  currentMuted = this.video.muted;
6841
6860
  currentVolume = this.video.volume;
@@ -7335,21 +7354,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7335
7354
  {
7336
7355
  key: "ensureAdStoppedByTimer",
7337
7356
  value: function ensureAdStoppedByTimer() {
7338
- var _this_config_adBreakCheckIntervalMs, _this_expectedAdBreakDurationMs;
7357
+ var _this_config_adBreakCheckIntervalMs, _this_getAdBreakEndWallClockMs;
7339
7358
  if (!this.inAdBreak) return;
7340
7359
  this.adStopTimerId = void 0;
7341
7360
  var adPlaying = this.ima.isAdPlaying();
7342
- var pendingAds = this.adPodQueue.length > 0;
7343
7361
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
7344
7362
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
7345
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
7346
- var elapsedSinceStartMs = 0;
7347
- if (this.currentAdBreakStartWallClockMs != null) {
7348
- elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
7349
- }
7350
- var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
7351
- var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
7352
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
7363
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
7364
+ var endWallClockMs = (_this_getAdBreakEndWallClockMs = this.getAdBreakEndWallClockMs()) !== null && _this_getAdBreakEndWallClockMs !== void 0 ? _this_getAdBreakEndWallClockMs : Date.now();
7365
+ var overrunMs = Math.max(0, Date.now() - endWallClockMs);
7366
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
7353
7367
  if (shouldExtendAdBreak) {
7354
7368
  this.scheduleAdStopCountdown(checkIntervalMs);
7355
7369
  return;
@@ -7615,7 +7629,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7615
7629
  case 5:
7616
7630
  _state.sent();
7617
7631
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7618
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
7632
+ this.scheduleAdStopAtBreakBoundary();
7619
7633
  }
7620
7634
  currentMuted = this.video.muted;
7621
7635
  currentVolume = this.video.volume;
@@ -7665,7 +7679,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7665
7679
  case 8:
7666
7680
  _state.sent();
7667
7681
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7668
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
7682
+ this.scheduleAdStopAtBreakBoundary();
7669
7683
  }
7670
7684
  currentMuted1 = this.video.muted;
7671
7685
  currentVolume1 = this.video.volume;
@@ -7810,6 +7824,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7810
7824
  this.scheduledScte35BreakKey = void 0;
7811
7825
  this.expectedAdBreakDurationMs = void 0;
7812
7826
  this.currentAdBreakStartWallClockMs = void 0;
7827
+ this.scteAdBreakEndWallClockMs = void 0;
7813
7828
  this.clearAdStartTimer();
7814
7829
  this.clearAdStopTimer();
7815
7830
  this.adPodQueue = [];
@@ -7999,9 +8014,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7999
8014
  {
8000
8015
  key: "getRemainingAdMs",
8001
8016
  value: function getRemainingAdMs() {
8002
- if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) return 0;
8003
- var elapsed = Date.now() - this.currentAdBreakStartWallClockMs;
8004
- return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
8017
+ var endWallClockMs = this.getAdBreakEndWallClockMs();
8018
+ if (endWallClockMs != null) {
8019
+ return Math.max(0, endWallClockMs - Date.now());
8020
+ }
8021
+ return 0;
8022
+ }
8023
+ },
8024
+ {
8025
+ key: "getAdBreakEndWallClockMs",
8026
+ value: function getAdBreakEndWallClockMs() {
8027
+ if (this.scteAdBreakEndWallClockMs != null) {
8028
+ return this.scteAdBreakEndWallClockMs;
8029
+ }
8030
+ if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) return void 0;
8031
+ return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;
8005
8032
  }
8006
8033
  },
8007
8034
  {