stormcloud-video-player 0.6.13 → 0.6.14

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.cjs CHANGED
@@ -3995,7 +3995,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3995
3995
  _this.adLayer.showPlaceholder();
3996
3996
  }
3997
3997
  if (_this.inAdBreak && _this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
3998
- _this.scheduleAdStopCountdown(_this.getRemainingAdMs());
3998
+ _this.scheduleAdStopAtBreakBoundary();
3999
3999
  if (_this.config.debugAdTiming) {
4000
4000
  console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
4001
4001
  }
@@ -4429,12 +4429,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4429
4429
  if (marker.durationSeconds != null) {
4430
4430
  var newDurationMs = marker.durationSeconds * 1e3;
4431
4431
  if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
4432
- this.expectedAdBreakDurationMs = newDurationMs;
4433
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
4434
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
4435
- this.scheduleAdStopCountdown(remainingMs);
4432
+ this.setAdBreakDurationBoundary(newDurationMs);
4433
+ this.scheduleAdStopAtBreakBoundary();
4436
4434
  if (this.config.debugAdTiming) {
4437
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
4435
+ console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(this.getRemainingAdMs(), "ms"));
4438
4436
  }
4439
4437
  }
4440
4438
  }
@@ -4442,8 +4440,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4442
4440
  }
4443
4441
  this.inAdBreak = true;
4444
4442
  var durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : ((_this_pendingAdBreak = this.pendingAdBreak) === null || _this_pendingAdBreak === void 0 ? void 0 : _this_pendingAdBreak.marker.durationSeconds) != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;
4445
- this.expectedAdBreakDurationMs = durationMs;
4446
- this.currentAdBreakStartWallClockMs = Date.now();
4443
+ this.currentAdBreakStartWallClockMs = this.resolveScteBreakStartWallClockMs(marker);
4444
+ this.setAdBreakDurationBoundary(durationMs);
4447
4445
  if (this.config.licenseKey) {
4448
4446
  var _this_pendingAdBreak1;
4449
4447
  var adDetectInfo = _object_spread({
@@ -4507,20 +4505,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4507
4505
  this.clearAdStartTimer();
4508
4506
  this.handleAdStart(marker);
4509
4507
  }
4510
- if (this.expectedAdBreakDurationMs != null) {
4511
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4512
- }
4508
+ this.scheduleAdStopAtBreakBoundary();
4513
4509
  return;
4514
4510
  }
4515
4511
  if (marker.type === "progress" && this.inAdBreak) {
4516
4512
  if (marker.durationSeconds != null) {
4517
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
4518
- }
4519
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
4520
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
4521
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
4522
- this.scheduleAdStopCountdown(remainingMs1);
4513
+ this.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);
4523
4514
  }
4515
+ this.scheduleAdStopAtBreakBoundary();
4524
4516
  if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {
4525
4517
  var bids = this.pendingNextAdBids;
4526
4518
  this.pendingNextAdBids = null;
@@ -4551,15 +4543,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4551
4543
  }
4552
4544
  return;
4553
4545
  }
4554
- if (adPlaying || remaining > 500) {
4555
- if (this.config.debugAdTiming) {
4556
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining");
4557
- }
4558
- return;
4559
- }
4560
- this.inAdBreak = false;
4561
- this.expectedAdBreakDurationMs = void 0;
4562
- this.currentAdBreakStartWallClockMs = void 0;
4546
+ this.scteAdBreakEndWallClockMs = Date.now();
4563
4547
  this.clearAdStartTimer();
4564
4548
  this.clearAdStopTimer();
4565
4549
  if (adPlaying) {
@@ -4570,6 +4554,42 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4570
4554
  }
4571
4555
  }
4572
4556
  },
4557
+ {
4558
+ key: "resolveScteBreakStartWallClockMs",
4559
+ value: function resolveScteBreakStartWallClockMs(marker) {
4560
+ var nowWallClockMs = Date.now();
4561
+ if (typeof marker.ptsSeconds !== "number") {
4562
+ return nowWallClockMs;
4563
+ }
4564
+ var nowMs = this.video.currentTime * 1e3;
4565
+ var estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
4566
+ var deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;
4567
+ if (!Number.isFinite(deltaMs)) {
4568
+ return nowWallClockMs;
4569
+ }
4570
+ return nowWallClockMs + Math.floor(deltaMs);
4571
+ }
4572
+ },
4573
+ {
4574
+ key: "setAdBreakDurationBoundary",
4575
+ value: function setAdBreakDurationBoundary(durationMs) {
4576
+ this.expectedAdBreakDurationMs = durationMs;
4577
+ if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {
4578
+ this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;
4579
+ } else {
4580
+ this.scteAdBreakEndWallClockMs = void 0;
4581
+ }
4582
+ }
4583
+ },
4584
+ {
4585
+ key: "scheduleAdStopAtBreakBoundary",
4586
+ value: function scheduleAdStopAtBreakBoundary() {
4587
+ if (this.expectedAdBreakDurationMs == null) {
4588
+ return;
4589
+ }
4590
+ this.scheduleAdStopCountdown(this.getRemainingAdMs());
4591
+ }
4592
+ },
4573
4593
  {
4574
4594
  key: "parseCueOutDuration",
4575
4595
  value: function parseCueOutDuration(value) {
@@ -5205,7 +5225,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5205
5225
  case 9:
5206
5226
  _state.sent();
5207
5227
  if (_this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
5208
- _this.scheduleAdStopCountdown(_this.getRemainingAdMs());
5228
+ _this.scheduleAdStopAtBreakBoundary();
5209
5229
  }
5210
5230
  _this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ? 1 : _this.adLayer.getOriginalVolume());
5211
5231
  return [
@@ -5310,7 +5330,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5310
5330
  case 19:
5311
5331
  _state.sent();
5312
5332
  if (_this.expectedAdBreakDurationMs != null && _this.adStopTimerId == null) {
5313
- _this.scheduleAdStopCountdown(_this.getRemainingAdMs());
5333
+ _this.scheduleAdStopAtBreakBoundary();
5314
5334
  }
5315
5335
  _this.adLayer.setAdVolume(_this.adLayer.getOriginalMutedState() ? 1 : _this.adLayer.getOriginalVolume());
5316
5336
  _state.label = 20;
@@ -5393,7 +5413,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5393
5413
  key: "handleAdStart",
5394
5414
  value: function handleAdStart(_marker) {
5395
5415
  return _async_to_generator(function() {
5396
- var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
5416
+ var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, fillerRemainingMs, adBreakToken, adVolume, token, remaining, err;
5397
5417
  return _ts_generator(this, function(_state) {
5398
5418
  switch(_state.label){
5399
5419
  case 0:
@@ -5427,20 +5447,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5427
5447
  }
5428
5448
  }
5429
5449
  this.inAdBreak = true;
5430
- this.currentAdBreakStartWallClockMs = Date.now();
5431
5450
  this.currentAdIndex = 0;
5432
5451
  this.totalAdsInBreak = Math.max(1, this.preloadedTokens.length);
5433
5452
  this.adPodQueue = [];
5434
5453
  if (!this.config.disableFiller) this.showAds = true;
5435
- if (adBreakDurationMs != null) {
5436
- this.startFillerBreakTimer(adBreakDurationMs);
5454
+ if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
5455
+ this.currentAdBreakStartWallClockMs = Date.now();
5456
+ this.setAdBreakDurationBoundary(adBreakDurationMs);
5457
+ }
5458
+ fillerRemainingMs = this.getRemainingAdMs();
5459
+ if (this.expectedAdBreakDurationMs != null && fillerRemainingMs > 0) {
5460
+ this.startFillerBreakTimer(fillerRemainingMs);
5437
5461
  } else if (!this.config.disableFiller && this.preloadedTokens.length === 0) {
5438
5462
  this.showPlaceholderLayer();
5439
5463
  }
5440
5464
  if (!this.config.disableFiller) this.adLayer.showPlaceholder();
5441
- if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
5442
- this.expectedAdBreakDurationMs = adBreakDurationMs;
5443
- }
5444
5465
  this.clearPendingAdBreak();
5445
5466
  adBreakToken = Date.now();
5446
5467
  this.activeAdRequestToken = adBreakToken;
@@ -5477,7 +5498,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5477
5498
  case 2:
5478
5499
  _state.sent();
5479
5500
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
5480
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
5501
+ this.scheduleAdStopAtBreakBoundary();
5481
5502
  }
5482
5503
  this.adLayer.setAdVolume(adVolume);
5483
5504
  return [
@@ -5663,7 +5684,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5663
5684
  case 4:
5664
5685
  _state.sent();
5665
5686
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
5666
- this.scheduleAdStopCountdown(this.getRemainingAdMs());
5687
+ this.scheduleAdStopAtBreakBoundary();
5667
5688
  }
5668
5689
  this.adLayer.setAdVolume(this.adLayer.getOriginalMutedState() ? 1 : this.adLayer.getOriginalVolume());
5669
5690
  _state.label = 5;
@@ -5905,21 +5926,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5905
5926
  {
5906
5927
  key: "ensureAdStoppedByTimer",
5907
5928
  value: function ensureAdStoppedByTimer() {
5908
- var _this_config_adBreakCheckIntervalMs, _this_expectedAdBreakDurationMs;
5929
+ var _this_config_adBreakCheckIntervalMs, _this_getAdBreakEndWallClockMs;
5909
5930
  if (!this.inAdBreak) return;
5910
5931
  this.adStopTimerId = void 0;
5911
5932
  var adPlaying = this.adLayer.isAdPlaying();
5912
- var pendingAds = this.adPodQueue.length > 0;
5913
5933
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
5914
5934
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
5915
- var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
5916
- var elapsedSinceStartMs = 0;
5917
- if (this.currentAdBreakStartWallClockMs != null) {
5918
- elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
5919
- }
5920
- var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
5921
- var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
5922
- var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
5935
+ var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;
5936
+ var endWallClockMs = (_this_getAdBreakEndWallClockMs = this.getAdBreakEndWallClockMs()) !== null && _this_getAdBreakEndWallClockMs !== void 0 ? _this_getAdBreakEndWallClockMs : Date.now();
5937
+ var overrunMs = Math.max(0, Date.now() - endWallClockMs);
5938
+ var shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;
5923
5939
  if (shouldExtendAdBreak) {
5924
5940
  this.scheduleAdStopCountdown(checkIntervalMs);
5925
5941
  return;
@@ -5993,6 +6009,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5993
6009
  this.inAdBreak = false;
5994
6010
  this.expectedAdBreakDurationMs = void 0;
5995
6011
  this.currentAdBreakStartWallClockMs = void 0;
6012
+ this.scteAdBreakEndWallClockMs = void 0;
5996
6013
  this.clearAdStartTimer();
5997
6014
  this.clearAdStopTimer();
5998
6015
  this.adPodQueue = [];
@@ -6254,10 +6271,25 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6254
6271
  {
6255
6272
  key: "getRemainingAdMs",
6256
6273
  value: function getRemainingAdMs() {
6274
+ var endWallClockMs = this.getAdBreakEndWallClockMs();
6275
+ if (endWallClockMs != null) {
6276
+ return Math.max(0, endWallClockMs - Date.now());
6277
+ }
6257
6278
  if (this.currentAdBreakStartWallClockMs == null) return 0;
6258
6279
  if (this.expectedAdBreakDurationMs == null) return Number.MAX_SAFE_INTEGER;
6259
- var elapsed = Date.now() - this.currentAdBreakStartWallClockMs;
6260
- return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
6280
+ return 0;
6281
+ }
6282
+ },
6283
+ {
6284
+ key: "getAdBreakEndWallClockMs",
6285
+ value: function getAdBreakEndWallClockMs() {
6286
+ if (this.scteAdBreakEndWallClockMs != null) {
6287
+ return this.scteAdBreakEndWallClockMs;
6288
+ }
6289
+ if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) {
6290
+ return void 0;
6291
+ }
6292
+ return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;
6261
6293
  }
6262
6294
  },
6263
6295
  {