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.
package/lib/index.d.cts CHANGED
@@ -145,6 +145,7 @@ declare class StormcloudVideoPlayer {
145
145
  private inAdBreak;
146
146
  private currentAdBreakStartWallClockMs;
147
147
  private expectedAdBreakDurationMs;
148
+ private scteAdBreakEndWallClockMs;
148
149
  private adStopTimerId;
149
150
  private adStartTimerId;
150
151
  private adFailsafeTimerId;
@@ -241,6 +242,9 @@ declare class StormcloudVideoPlayer {
241
242
  private activatePendingScte35CuesForFragment;
242
243
  private onScte35Marker;
243
244
  private startScte35AdBreak;
245
+ private resolveScteBreakStartWallClockMs;
246
+ private setAdBreakDurationBoundary;
247
+ private scheduleAdStopAtBreakBoundary;
244
248
  private parseCueOutDuration;
245
249
  private parseCueOutCont;
246
250
  private parseAttributeList;
@@ -324,6 +328,7 @@ declare class StormcloudVideoPlayer {
324
328
  private selectVastTagsForBreak;
325
329
  private logAdState;
326
330
  private getRemainingAdMs;
331
+ private getAdBreakEndWallClockMs;
327
332
  private findBreakForTime;
328
333
  toggleMute(): void;
329
334
  toggleFullscreen(): Promise<void>;
package/lib/index.d.ts CHANGED
@@ -145,6 +145,7 @@ declare class StormcloudVideoPlayer {
145
145
  private inAdBreak;
146
146
  private currentAdBreakStartWallClockMs;
147
147
  private expectedAdBreakDurationMs;
148
+ private scteAdBreakEndWallClockMs;
148
149
  private adStopTimerId;
149
150
  private adStartTimerId;
150
151
  private adFailsafeTimerId;
@@ -241,6 +242,9 @@ declare class StormcloudVideoPlayer {
241
242
  private activatePendingScte35CuesForFragment;
242
243
  private onScte35Marker;
243
244
  private startScte35AdBreak;
245
+ private resolveScteBreakStartWallClockMs;
246
+ private setAdBreakDurationBoundary;
247
+ private scheduleAdStopAtBreakBoundary;
244
248
  private parseCueOutDuration;
245
249
  private parseCueOutCont;
246
250
  private parseAttributeList;
@@ -324,6 +328,7 @@ declare class StormcloudVideoPlayer {
324
328
  private selectVastTagsForBreak;
325
329
  private logAdState;
326
330
  private getRemainingAdMs;
331
+ private getAdBreakEndWallClockMs;
327
332
  private findBreakForTime;
328
333
  toggleMute(): void;
329
334
  toggleFullscreen(): Promise<void>;
package/lib/index.js CHANGED
@@ -3905,7 +3905,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3905
3905
  _this.showAds = true;
3906
3906
  _this.resetGamNoFillCounter();
3907
3907
  if (_this.inAdBreak && _this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
3908
- _this.scheduleAdStopCountdown(_this.getRemainingAdMs());
3908
+ _this.scheduleAdStopAtBreakBoundary();
3909
3909
  if (_this.config.debugAdTiming) {
3910
3910
  console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
3911
3911
  }
@@ -4549,12 +4549,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4549
4549
  if (marker.durationSeconds != null) {
4550
4550
  var newDurationMs = marker.durationSeconds * 1e3;
4551
4551
  if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
4552
- this.expectedAdBreakDurationMs = newDurationMs;
4553
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
4554
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
4555
- this.scheduleAdStopCountdown(remainingMs);
4552
+ this.setAdBreakDurationBoundary(newDurationMs);
4553
+ this.scheduleAdStopAtBreakBoundary();
4556
4554
  if (this.config.debugAdTiming) {
4557
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
4555
+ console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(this.getRemainingAdMs(), "ms"));
4558
4556
  }
4559
4557
  }
4560
4558
  }
@@ -4628,13 +4626,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4628
4626
  }
4629
4627
  if (marker.type === "progress" && this.inAdBreak) {
4630
4628
  if (marker.durationSeconds != null) {
4631
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
4632
- }
4633
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
4634
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
4635
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
4636
- this.scheduleAdStopCountdown(remainingMs1);
4629
+ this.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);
4637
4630
  }
4631
+ this.scheduleAdStopAtBreakBoundary();
4638
4632
  if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {
4639
4633
  this.tryNextAvailableAdWithRateLimit();
4640
4634
  }
@@ -4659,15 +4653,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4659
4653
  activeAdRequest: this.activeAdRequestToken !== null
4660
4654
  });
4661
4655
  }
4662
- if (adPlaying || remaining > 1e3 && hasQueuedAds) {
4663
- if (this.config.debugAdTiming) {
4664
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active");
4665
- }
4666
- return;
4667
- }
4668
- this.inAdBreak = false;
4669
- this.expectedAdBreakDurationMs = void 0;
4670
- this.currentAdBreakStartWallClockMs = void 0;
4656
+ this.scteAdBreakEndWallClockMs = Date.now();
4671
4657
  this.clearAdStartTimer();
4672
4658
  this.clearAdStopTimer();
4673
4659
  if (adPlaying) {
@@ -4691,12 +4677,46 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4691
4677
  this.inAdBreak = true;
4692
4678
  this.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.pendingScte35CueKey;
4693
4679
  this.scheduledScte35BreakKey = void 0;
4694
- this.expectedAdBreakDurationMs = durationMs;
4695
- this.currentAdBreakStartWallClockMs = Date.now();
4680
+ this.currentAdBreakStartWallClockMs = this.resolveScteBreakStartWallClockMs(marker);
4681
+ this.setAdBreakDurationBoundary(durationMs);
4696
4682
  this.handleAdStart(marker);
4697
- if (this.expectedAdBreakDurationMs != null) {
4698
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4683
+ this.scheduleAdStopAtBreakBoundary();
4684
+ }
4685
+ },
4686
+ {
4687
+ key: "resolveScteBreakStartWallClockMs",
4688
+ value: function resolveScteBreakStartWallClockMs(marker) {
4689
+ var nowWallClockMs = Date.now();
4690
+ if (typeof marker.ptsSeconds !== "number") {
4691
+ return nowWallClockMs;
4699
4692
  }
4693
+ var nowMs = this.video.currentTime * 1e3;
4694
+ var estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
4695
+ var deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;
4696
+ if (!Number.isFinite(deltaMs)) {
4697
+ return nowWallClockMs;
4698
+ }
4699
+ return nowWallClockMs + Math.floor(deltaMs);
4700
+ }
4701
+ },
4702
+ {
4703
+ key: "setAdBreakDurationBoundary",
4704
+ value: function setAdBreakDurationBoundary(durationMs) {
4705
+ this.expectedAdBreakDurationMs = durationMs;
4706
+ if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {
4707
+ this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;
4708
+ } else {
4709
+ this.scteAdBreakEndWallClockMs = void 0;
4710
+ }
4711
+ }
4712
+ },
4713
+ {
4714
+ key: "scheduleAdStopAtBreakBoundary",
4715
+ value: function scheduleAdStopAtBreakBoundary() {
4716
+ if (this.expectedAdBreakDurationMs == null) {
4717
+ return;
4718
+ }
4719
+ this.scheduleAdStopCountdown(this.getRemainingAdMs());
4700
4720
  }
4701
4721
  },
4702
4722
  {
@@ -6324,7 +6344,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6324
6344
  }
6325
6345
  }
6326
6346
  this.inAdBreak = true;
6327
- this.currentAdBreakStartWallClockMs = Date.now();
6328
6347
  this.currentAdIndex = 0;
6329
6348
  this.totalAdsInBreak = 1;
6330
6349
  this.adPodQueue = [];
@@ -6411,7 +6430,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6411
6430
  case 2:
6412
6431
  _state.sent();
6413
6432
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6414
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6433
+ this.scheduleAdStopAtBreakBoundary();
6415
6434
  }
6416
6435
  adVolume = currentMuted ? 0 : currentVolume;
6417
6436
  this.ima.setAdVolume(adVolume);
@@ -6454,7 +6473,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6454
6473
  case 6:
6455
6474
  _state.sent();
6456
6475
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6457
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6476
+ this.scheduleAdStopAtBreakBoundary();
6458
6477
  }
6459
6478
  adVolume1 = currentMuted ? 0 : currentVolume;
6460
6479
  this.ima.setAdVolume(adVolume1);
@@ -6509,7 +6528,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6509
6528
  case 10:
6510
6529
  _state.sent();
6511
6530
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6512
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6531
+ this.scheduleAdStopAtBreakBoundary();
6513
6532
  }
6514
6533
  adVolume2 = currentMuted ? 0 : currentVolume;
6515
6534
  this.ima.setAdVolume(adVolume2);
@@ -6861,7 +6880,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6861
6880
  case 2:
6862
6881
  _state.sent();
6863
6882
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6864
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
6883
+ this.scheduleAdStopAtBreakBoundary();
6865
6884
  }
6866
6885
  currentMuted = this.video.muted;
6867
6886
  currentVolume = this.video.volume;
@@ -7361,21 +7380,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7361
7380
  {
7362
7381
  key: "ensureAdStoppedByTimer",
7363
7382
  value: function ensureAdStoppedByTimer() {
7364
- var _this_config_adBreakCheckIntervalMs, _this_expectedAdBreakDurationMs;
7383
+ var _this_config_adBreakCheckIntervalMs, _this_getAdBreakEndWallClockMs;
7365
7384
  if (!this.inAdBreak) return;
7366
7385
  this.adStopTimerId = void 0;
7367
7386
  var adPlaying = this.ima.isAdPlaying();
7368
- var pendingAds = this.adPodQueue.length > 0;
7369
7387
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
7370
7388
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
7371
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
7372
- var elapsedSinceStartMs = 0;
7373
- if (this.currentAdBreakStartWallClockMs != null) {
7374
- elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
7375
- }
7376
- var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
7377
- var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
7378
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
7389
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
7390
+ var endWallClockMs = (_this_getAdBreakEndWallClockMs = this.getAdBreakEndWallClockMs()) !== null && _this_getAdBreakEndWallClockMs !== void 0 ? _this_getAdBreakEndWallClockMs : Date.now();
7391
+ var overrunMs = Math.max(0, Date.now() - endWallClockMs);
7392
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
7379
7393
  if (shouldExtendAdBreak) {
7380
7394
  this.scheduleAdStopCountdown(checkIntervalMs);
7381
7395
  return;
@@ -7641,7 +7655,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7641
7655
  case 5:
7642
7656
  _state.sent();
7643
7657
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7644
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
7658
+ this.scheduleAdStopAtBreakBoundary();
7645
7659
  }
7646
7660
  currentMuted = this.video.muted;
7647
7661
  currentVolume = this.video.volume;
@@ -7691,7 +7705,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7691
7705
  case 8:
7692
7706
  _state.sent();
7693
7707
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7694
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
7708
+ this.scheduleAdStopAtBreakBoundary();
7695
7709
  }
7696
7710
  currentMuted1 = this.video.muted;
7697
7711
  currentVolume1 = this.video.volume;
@@ -7836,6 +7850,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7836
7850
  this.scheduledScte35BreakKey = void 0;
7837
7851
  this.expectedAdBreakDurationMs = void 0;
7838
7852
  this.currentAdBreakStartWallClockMs = void 0;
7853
+ this.scteAdBreakEndWallClockMs = void 0;
7839
7854
  this.clearAdStartTimer();
7840
7855
  this.clearAdStopTimer();
7841
7856
  this.adPodQueue = [];
@@ -8025,9 +8040,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8025
8040
  {
8026
8041
  key: "getRemainingAdMs",
8027
8042
  value: function getRemainingAdMs() {
8028
- if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) return 0;
8029
- var elapsed = Date.now() - this.currentAdBreakStartWallClockMs;
8030
- return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
8043
+ var endWallClockMs = this.getAdBreakEndWallClockMs();
8044
+ if (endWallClockMs != null) {
8045
+ return Math.max(0, endWallClockMs - Date.now());
8046
+ }
8047
+ return 0;
8048
+ }
8049
+ },
8050
+ {
8051
+ key: "getAdBreakEndWallClockMs",
8052
+ value: function getAdBreakEndWallClockMs() {
8053
+ if (this.scteAdBreakEndWallClockMs != null) {
8054
+ return this.scteAdBreakEndWallClockMs;
8055
+ }
8056
+ if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) return void 0;
8057
+ return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;
8031
8058
  }
8032
8059
  },
8033
8060
  {