stormcloud-video-player 0.7.11 → 0.7.12

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.
@@ -1443,7 +1443,6 @@ function createAdStormPlayer(contentVideo, options) {
1443
1443
  contentVideo.muted = originalMutedState;
1444
1444
  contentVideo.volume = originalVolume;
1445
1445
  currentAd = void 0;
1446
- tornDown = false;
1447
1446
  return [
1448
1447
  2,
1449
1448
  Promise.resolve()
@@ -1558,6 +1557,15 @@ function createAdStormPlayer(contentVideo, options) {
1558
1557
  if (!token) return [
1559
1558
  2
1560
1559
  ];
1560
+ if (currentAd) {
1561
+ preloadSlots.set(token, {
1562
+ ad: currentAd
1563
+ });
1564
+ currentAd = void 0;
1565
+ return [
1566
+ 2
1567
+ ];
1568
+ }
1561
1569
  requestContext = typeof arg1 === "string" ? arg2 : arg1;
1562
1570
  return [
1563
1571
  4,
@@ -2051,56 +2059,6 @@ function sendInitialTracking(licenseKey) {
2051
2059
  });
2052
2060
  })();
2053
2061
  }
2054
- function sendAdDetectTracking(licenseKey, adDetectInfo) {
2055
- return _async_to_generator(function() {
2056
- var clientInfo, browserId, trackingData, error;
2057
- return _ts_generator(this, function(_state) {
2058
- switch(_state.label){
2059
- case 0:
2060
- _state.trys.push([
2061
- 0,
2062
- 3,
2063
- ,
2064
- 4
2065
- ]);
2066
- clientInfo = getClientInfo();
2067
- return [
2068
- 4,
2069
- getBrowserID(clientInfo)
2070
- ];
2071
- case 1:
2072
- browserId = _state.sent();
2073
- trackingData = _object_spread({
2074
- browserId: browserId
2075
- }, clientInfo);
2076
- return [
2077
- 4,
2078
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2079
- licenseKey: licenseKey,
2080
- adDetectInfo: adDetectInfo
2081
- }))
2082
- ];
2083
- case 2:
2084
- _state.sent();
2085
- return [
2086
- 3,
2087
- 4
2088
- ];
2089
- case 3:
2090
- error = _state.sent();
2091
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2092
- return [
2093
- 3,
2094
- 4
2095
- ];
2096
- case 4:
2097
- return [
2098
- 2
2099
- ];
2100
- }
2101
- });
2102
- })();
2103
- }
2104
2062
  function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2105
2063
  return _async_to_generator(function() {
2106
2064
  var clientInfo, browserId, trackingData, error;
@@ -2785,7 +2743,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2785
2743
  this.continuousFetchLoopPromise = null;
2786
2744
  this.attached = false;
2787
2745
  this.inAdBreak = false;
2788
- this.ptsDriftEmaMs = 0;
2789
2746
  this.adPodQueue = [];
2790
2747
  this.lastHeartbeatTime = 0;
2791
2748
  this.currentAdIndex = 0;
@@ -2809,7 +2766,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2809
2766
  this.totalAdRequestsInBreak = 0;
2810
2767
  this.maxTotalAdRequestsPerBreak = 20;
2811
2768
  this.pendingAdBreak = null;
2812
- this.savedMutedStateBeforeScte = null;
2769
+ this.savedMutedStateBeforeAd = null;
2813
2770
  this.consecutiveFailures = 0;
2814
2771
  this.maxConsecutiveFailures = 5;
2815
2772
  this.lastAdRequestTime = 0;
@@ -2822,7 +2779,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2822
2779
  this.adRequestRetryBackoffMs = 1500;
2823
2780
  this.preloadedTokens = [];
2824
2781
  this.debugLogEntries = [];
2825
- this.scteMarkerHistory = [];
2826
2782
  this.adInsertionDebugHistory = [];
2827
2783
  initializePolyfills();
2828
2784
  var browserOverrides = getBrowserConfigOverrides();
@@ -3111,18 +3067,44 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3111
3067
  _this.pushAdInsertionDebug("ad_triggered", segmentName, {
3112
3068
  detail: "ad break started (60s)"
3113
3069
  });
3114
- var marker = {
3115
- type: "start",
3116
- durationSeconds: 60,
3117
- raw: {
3118
- apiInsertionPoint: _this.lastAdInsertionPoint
3119
- }
3120
- };
3121
- _this.onScte35Marker(marker);
3070
+ void _this.handleAdStart(60);
3122
3071
  }, offsetMs);
3123
3072
  }
3124
3073
  }
3125
3074
  });
3075
+ this.hls.on(import_hls.default.Events.FRAG_PARSING_USERDATA, function(_evt, data) {
3076
+ var _ref;
3077
+ var samples = (_ref = data === null || data === void 0 ? void 0 : data.samples) !== null && _ref !== void 0 ? _ref : [];
3078
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3079
+ try {
3080
+ for(var _iterator = samples[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
3081
+ var sample = _step.value;
3082
+ var _ref1, _ref2;
3083
+ var _data_frag, _data_frag1;
3084
+ var bytes = sample === null || sample === void 0 ? void 0 : sample.data;
3085
+ if (!bytes || bytes.length < 5) continue;
3086
+ var isSCTE35 = bytes[0] === 252;
3087
+ if (!isSCTE35) continue;
3088
+ var segName = (_ref1 = (_ref2 = data === null || data === void 0 ? void 0 : (_data_frag = data.frag) === null || _data_frag === void 0 ? void 0 : _data_frag.relurl) !== null && _ref2 !== void 0 ? _ref2 : data === null || data === void 0 ? void 0 : (_data_frag1 = data.frag) === null || _data_frag1 === void 0 ? void 0 : _data_frag1.url) !== null && _ref1 !== void 0 ? _ref1 : "";
3089
+ _this.pushAdInsertionDebug("scte35_inserted", segName, {
3090
+ detail: "len=".concat(bytes.length, "B")
3091
+ });
3092
+ }
3093
+ } catch (err) {
3094
+ _didIteratorError = true;
3095
+ _iteratorError = err;
3096
+ } finally{
3097
+ try {
3098
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3099
+ _iterator.return();
3100
+ }
3101
+ } finally{
3102
+ if (_didIteratorError) {
3103
+ throw _iteratorError;
3104
+ }
3105
+ }
3106
+ }
3107
+ });
3126
3108
  this.hls.on(import_hls.default.Events.ERROR, function(_evt, data) {
3127
3109
  if (data === null || data === void 0 ? void 0 : data.fatal) {
3128
3110
  switch(data.type){
@@ -3197,8 +3179,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3197
3179
  _this.activeAdRequestToken = null;
3198
3180
  _this.showAds = true;
3199
3181
  if (_this.config.disableFiller) {
3200
- if (_this.savedMutedStateBeforeScte == null) {
3201
- _this.savedMutedStateBeforeScte = {
3182
+ if (_this.savedMutedStateBeforeAd == null) {
3183
+ _this.savedMutedStateBeforeAd = {
3202
3184
  muted: _this.video.muted,
3203
3185
  volume: _this.video.volume
3204
3186
  };
@@ -3226,10 +3208,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3226
3208
  });
3227
3209
  this.adLayer.on("content_resume", function() {
3228
3210
  var _ref, _ref1;
3229
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
3211
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
3230
3212
  var remaining = _this.getRemainingAdMs();
3231
- var breakMuted = (_ref = (_this_savedMutedStateBeforeScte = _this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte === void 0 ? void 0 : _this_savedMutedStateBeforeScte.muted) !== null && _ref !== void 0 ? _ref : _this.adLayer.getOriginalMutedState();
3232
- var breakVolume = (_ref1 = (_this_savedMutedStateBeforeScte1 = _this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte1 === void 0 ? void 0 : _this_savedMutedStateBeforeScte1.volume) !== null && _ref1 !== void 0 ? _ref1 : _this.adLayer.getOriginalVolume();
3213
+ var breakMuted = (_ref = (_this_savedMutedStateBeforeAd = _this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd === void 0 ? void 0 : _this_savedMutedStateBeforeAd.muted) !== null && _ref !== void 0 ? _ref : _this.adLayer.getOriginalMutedState();
3214
+ var breakVolume = (_ref1 = (_this_savedMutedStateBeforeAd1 = _this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd1 === void 0 ? void 0 : _this_savedMutedStateBeforeAd1.volume) !== null && _ref1 !== void 0 ? _ref1 : _this.adLayer.getOriginalVolume();
3233
3215
  if (_this.config.debugAdTiming) {
3234
3216
  console.log("[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, preloadedTokens=%d, pendingNext=%s", _this.inAdBreak, remaining, _this.preloadedTokens.length, !!_this.pendingNextAdBids);
3235
3217
  }
@@ -3306,7 +3288,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3306
3288
  var remainingFinal = _this.getRemainingAdMs();
3307
3289
  if (_this.inAdBreak && remainingFinal > _this.MIN_AD_REMAINING_MS) {
3308
3290
  if (_this.config.debugAdTiming) {
3309
- console.log("[StormcloudVideoPlayer] content_resume: no more ads, showing filler for", remainingFinal, "ms");
3291
+ console.log("[StormcloudVideoPlayer] content_resume: ad ended/failed with time remaining, showing filler and continuing fetch for", remainingFinal, "ms");
3310
3292
  }
3311
3293
  if (!_this.config.disableFiller) {
3312
3294
  _this.showPlaceholderLayer();
@@ -3324,7 +3306,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3324
3306
  (_this_video_play = _this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
3325
3307
  }
3326
3308
  }
3327
- _this.stopContinuousFetching();
3309
+ _this.continuousFetchingActive = true;
3310
+ _this.startContinuousFetchLoop();
3328
3311
  return;
3329
3312
  }
3330
3313
  if (_this.config.debugAdTiming) {
@@ -3471,547 +3454,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3471
3454
  return !!(this.config.allowNativeHls && canNative);
3472
3455
  }
3473
3456
  },
3474
- {
3475
- key: "onId3Tag",
3476
- value: function onId3Tag(tag) {
3477
- if (typeof tag.ptsSeconds === "number") {
3478
- this.updatePtsDrift(tag.ptsSeconds);
3479
- }
3480
- var marker = this.parseScte35FromId3(tag);
3481
- if (marker) {
3482
- this.onScte35Marker(marker);
3483
- }
3484
- }
3485
- },
3486
- {
3487
- key: "parseScte35FromId3",
3488
- value: function parseScte35FromId3(tag) {
3489
- var text = this.decodeId3ValueToText(tag.value);
3490
- if (!text) return void 0;
3491
- var cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
3492
- if (cueOutMatch) {
3493
- var _cueOutMatch_;
3494
- var arg = ((_cueOutMatch_ = cueOutMatch[1]) !== null && _cueOutMatch_ !== void 0 ? _cueOutMatch_ : "").trim();
3495
- var dur = this.parseCueOutDuration(arg);
3496
- var marker = _object_spread_props(_object_spread({
3497
- type: "start"
3498
- }, tag.ptsSeconds !== void 0 ? {
3499
- ptsSeconds: tag.ptsSeconds
3500
- } : {}, dur !== void 0 ? {
3501
- durationSeconds: dur
3502
- } : {}), {
3503
- raw: {
3504
- id3: text
3505
- }
3506
- });
3507
- return marker;
3508
- }
3509
- var cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
3510
- if (cueOutContMatch) {
3511
- var _cueOutContMatch_;
3512
- var arg1 = ((_cueOutContMatch_ = cueOutContMatch[1]) !== null && _cueOutContMatch_ !== void 0 ? _cueOutContMatch_ : "").trim();
3513
- var cont = this.parseCueOutCont(arg1);
3514
- var marker1 = _object_spread_props(_object_spread({
3515
- type: "progress"
3516
- }, tag.ptsSeconds !== void 0 ? {
3517
- ptsSeconds: tag.ptsSeconds
3518
- } : {}, (cont === null || cont === void 0 ? void 0 : cont.duration) !== void 0 ? {
3519
- durationSeconds: cont.duration
3520
- } : {}), {
3521
- raw: {
3522
- id3: text
3523
- }
3524
- });
3525
- return marker1;
3526
- }
3527
- var cueInMatch = text.match(/EXT-X-CUE-IN\b/i) || text.match(/CUE-IN\b/i);
3528
- if (cueInMatch) {
3529
- var marker2 = _object_spread_props(_object_spread({
3530
- type: "end"
3531
- }, tag.ptsSeconds !== void 0 ? {
3532
- ptsSeconds: tag.ptsSeconds
3533
- } : {}), {
3534
- raw: {
3535
- id3: text
3536
- }
3537
- });
3538
- return marker2;
3539
- }
3540
- var daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
3541
- if (daterangeMatch) {
3542
- var _daterangeMatch_, _attrs_CLASS;
3543
- var attrs = this.parseAttributeList((_daterangeMatch_ = daterangeMatch[1]) !== null && _daterangeMatch_ !== void 0 ? _daterangeMatch_ : "");
3544
- var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3545
- var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3546
- var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3547
- var duration = this.toNumber(attrs["DURATION"]);
3548
- if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
3549
- var marker3 = _object_spread_props(_object_spread({
3550
- type: "start"
3551
- }, tag.ptsSeconds !== void 0 ? {
3552
- ptsSeconds: tag.ptsSeconds
3553
- } : {}, duration !== void 0 ? {
3554
- durationSeconds: duration
3555
- } : {}), {
3556
- raw: {
3557
- id3: text,
3558
- attrs: attrs
3559
- }
3560
- });
3561
- return marker3;
3562
- }
3563
- if (hasScteIn) {
3564
- var marker4 = _object_spread_props(_object_spread({
3565
- type: "end"
3566
- }, tag.ptsSeconds !== void 0 ? {
3567
- ptsSeconds: tag.ptsSeconds
3568
- } : {}), {
3569
- raw: {
3570
- id3: text,
3571
- attrs: attrs
3572
- }
3573
- });
3574
- return marker4;
3575
- }
3576
- }
3577
- if (/SCTE35-OUT/i.test(text)) {
3578
- var marker5 = _object_spread_props(_object_spread({
3579
- type: "start"
3580
- }, tag.ptsSeconds !== void 0 ? {
3581
- ptsSeconds: tag.ptsSeconds
3582
- } : {}), {
3583
- raw: {
3584
- id3: text
3585
- }
3586
- });
3587
- return marker5;
3588
- }
3589
- if (/SCTE35-IN/i.test(text)) {
3590
- var marker6 = _object_spread_props(_object_spread({
3591
- type: "end"
3592
- }, tag.ptsSeconds !== void 0 ? {
3593
- ptsSeconds: tag.ptsSeconds
3594
- } : {}), {
3595
- raw: {
3596
- id3: text
3597
- }
3598
- });
3599
- return marker6;
3600
- }
3601
- if (_instanceof(tag.value, Uint8Array)) {
3602
- var bin = this.parseScte35Binary(tag.value);
3603
- if (bin) return bin;
3604
- }
3605
- return void 0;
3606
- }
3607
- },
3608
- {
3609
- key: "decodeId3ValueToText",
3610
- value: function decodeId3ValueToText(value) {
3611
- try {
3612
- if (typeof value === "string") return value;
3613
- var decoder = new TextDecoder("utf-8", {
3614
- fatal: false
3615
- });
3616
- var text = decoder.decode(value);
3617
- if (text && /[\x20-\x7E]/.test(text)) return text;
3618
- var out = "";
3619
- for(var i = 0; i < value.length; i++)out += String.fromCharCode(value[i]);
3620
- return out;
3621
- } catch (unused) {
3622
- return void 0;
3623
- }
3624
- }
3625
- },
3626
- {
3627
- key: "onScte35Marker",
3628
- value: function onScte35Marker(marker) {
3629
- var _this = this;
3630
- if (this.config.disableAds) return;
3631
- this.pushScteMarker(marker);
3632
- this.pushDebugLog("info", "scte35", "SCTE-35 marker detected", {
3633
- type: marker.type,
3634
- ptsSeconds: marker.ptsSeconds,
3635
- durationSeconds: marker.durationSeconds,
3636
- currentTime: this.video.currentTime
3637
- });
3638
- if (this.config.debugAdTiming) {
3639
- console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
3640
- type: marker.type,
3641
- ptsSeconds: marker.ptsSeconds,
3642
- durationSeconds: marker.durationSeconds,
3643
- currentTime: this.video.currentTime,
3644
- raw: marker.raw,
3645
- hasPendingAdBreak: !!this.pendingAdBreak
3646
- });
3647
- }
3648
- if (marker.type === "start") {
3649
- var _this_config_immediateManifestAds;
3650
- var _this_pendingAdBreak;
3651
- if (this.savedMutedStateBeforeScte == null) {
3652
- this.savedMutedStateBeforeScte = {
3653
- muted: this.video.muted,
3654
- volume: this.video.volume
3655
- };
3656
- this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);
3657
- }
3658
- if (!this.config.disableFiller && !this.video.muted && !this.adLayer.isAdPlaying()) {
3659
- this.video.muted = true;
3660
- this.video.volume = 0;
3661
- if (this.config.debugAdTiming) {
3662
- console.log("[StormcloudVideoPlayer] Muted video on SCTE start marker");
3663
- }
3664
- }
3665
- if (this.inAdBreak) {
3666
- if (marker.durationSeconds != null) {
3667
- var newDurationMs = marker.durationSeconds * 1e3;
3668
- if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
3669
- this.expectedAdBreakDurationMs = newDurationMs;
3670
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
3671
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
3672
- this.scheduleAdStopCountdown(remainingMs);
3673
- if (this.config.debugAdTiming) {
3674
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
3675
- }
3676
- }
3677
- }
3678
- return;
3679
- }
3680
- this.inAdBreak = true;
3681
- 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;
3682
- this.expectedAdBreakDurationMs = durationMs;
3683
- this.currentAdBreakStartWallClockMs = Date.now();
3684
- if (this.config.licenseKey) {
3685
- var _this_pendingAdBreak1;
3686
- var adDetectInfo = _object_spread({
3687
- source: "scte35",
3688
- timestamp: /* @__PURE__ */ new Date().toISOString()
3689
- }, marker.durationSeconds != null && {
3690
- durationSeconds: marker.durationSeconds
3691
- }, marker.ptsSeconds != null && {
3692
- ptsSeconds: marker.ptsSeconds
3693
- }, ((_this_pendingAdBreak1 = this.pendingAdBreak) === null || _this_pendingAdBreak1 === void 0 ? void 0 : _this_pendingAdBreak1.detectedAtFragmentSn) != null && {
3694
- detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn
3695
- });
3696
- sendAdDetectTracking(this.config.licenseKey, adDetectInfo);
3697
- }
3698
- var isManifestMarker = this.isManifestBasedMarker(marker);
3699
- var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
3700
- if (this.config.debugAdTiming) {
3701
- console.log("[StormcloudVideoPlayer] Ad start decision:", {
3702
- isManifestMarker: isManifestMarker,
3703
- forceImmediate: forceImmediate,
3704
- hasPts: typeof marker.ptsSeconds === "number"
3705
- });
3706
- }
3707
- if (isManifestMarker && forceImmediate) {
3708
- if (this.config.debugAdTiming) {
3709
- console.log("[StormcloudVideoPlayer] Starting ad immediately (manifest-based)");
3710
- }
3711
- this.clearAdStartTimer();
3712
- this.handleAdStart(marker);
3713
- } else if (typeof marker.ptsSeconds === "number") {
3714
- var _this_config_driftToleranceMs;
3715
- var tol = (_this_config_driftToleranceMs = this.config.driftToleranceMs) !== null && _this_config_driftToleranceMs !== void 0 ? _this_config_driftToleranceMs : 1e3;
3716
- var nowMs = this.video.currentTime * 1e3;
3717
- var estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
3718
- var deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
3719
- if (this.config.debugAdTiming) {
3720
- console.log("[StormcloudVideoPlayer] PTS-based timing calculation:", {
3721
- nowMs: nowMs,
3722
- estCurrentPtsMs: estCurrentPtsMs,
3723
- markerPtsMs: marker.ptsSeconds * 1e3,
3724
- deltaMs: deltaMs,
3725
- tolerance: tol
3726
- });
3727
- }
3728
- if (deltaMs > tol) {
3729
- if (this.config.debugAdTiming) {
3730
- console.log("[StormcloudVideoPlayer] Scheduling ad start in ".concat(deltaMs, "ms"));
3731
- }
3732
- this.scheduleAdStartIn(deltaMs);
3733
- } else {
3734
- if (this.config.debugAdTiming) {
3735
- console.log("[StormcloudVideoPlayer] Starting ad immediately (within tolerance)");
3736
- }
3737
- this.clearAdStartTimer();
3738
- this.handleAdStart(marker);
3739
- }
3740
- } else {
3741
- if (this.config.debugAdTiming) {
3742
- console.log("[StormcloudVideoPlayer] Starting ad immediately (fallback)");
3743
- }
3744
- this.clearAdStartTimer();
3745
- this.handleAdStart(marker);
3746
- }
3747
- if (this.expectedAdBreakDurationMs != null) {
3748
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
3749
- }
3750
- return;
3751
- }
3752
- if (marker.type === "progress" && this.inAdBreak) {
3753
- if (marker.durationSeconds != null) {
3754
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
3755
- }
3756
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
3757
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
3758
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
3759
- this.scheduleAdStopCountdown(remainingMs1);
3760
- }
3761
- if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {
3762
- var bids = this.pendingNextAdBids;
3763
- this.pendingNextAdBids = null;
3764
- this.currentAdIndex++;
3765
- this.adLayer.playAd(bids).catch(function() {
3766
- return _this.handleAdFailure();
3767
- });
3768
- }
3769
- return;
3770
- }
3771
- if (marker.type === "end") {
3772
- var remaining = this.getRemainingAdMs();
3773
- var adPlaying = this.adLayer.isAdPlaying();
3774
- var hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;
3775
- if (this.config.debugAdTiming) {
3776
- console.log("[StormcloudVideoPlayer] SCTE-35 end marker received:", {
3777
- inAdBreak: this.inAdBreak,
3778
- remaining: remaining,
3779
- adPlaying: adPlaying,
3780
- hasQueuedAds: hasQueuedAds,
3781
- activeAdRequest: this.activeAdRequestToken !== null
3782
- });
3783
- }
3784
- if (!this.inAdBreak) {
3785
- if (this.config.debugAdTiming) {
3786
- console.log("[StormcloudVideoPlayer] Ignoring SCTE-35 end marker - not in ad break");
3787
- }
3788
- return;
3789
- }
3790
- if (adPlaying || remaining > 500) {
3791
- if (this.config.debugAdTiming) {
3792
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining");
3793
- }
3794
- return;
3795
- }
3796
- this.inAdBreak = false;
3797
- this.expectedAdBreakDurationMs = void 0;
3798
- this.currentAdBreakStartWallClockMs = void 0;
3799
- this.clearAdStartTimer();
3800
- this.clearAdStopTimer();
3801
- if (adPlaying) {
3802
- this.adLayer.stop().catch(function() {});
3803
- }
3804
- this.handleAdPodComplete();
3805
- return;
3806
- }
3807
- }
3808
- },
3809
- {
3810
- key: "parseCueOutDuration",
3811
- value: function parseCueOutDuration(value) {
3812
- var num = parseFloat(value.trim());
3813
- if (!Number.isNaN(num)) return num;
3814
- var match = value.match(/(?:^|[,\s])DURATION\s*=\s*([0-9.]+)/i) || value.match(/Duration\s*=\s*([0-9.]+)/i);
3815
- if (match && match[1] != null) {
3816
- var dStr = match[1];
3817
- var d = parseFloat(dStr);
3818
- return Number.isNaN(d) ? void 0 : d;
3819
- }
3820
- return void 0;
3821
- }
3822
- },
3823
- {
3824
- key: "parseCueOutCont",
3825
- value: function parseCueOutCont(value) {
3826
- var res = {};
3827
- var elapsedMatch = value.match(/Elapsed\s*=\s*([0-9.]+)/i);
3828
- var durationMatch = value.match(/Duration\s*=\s*([0-9.]+)/i);
3829
- if (elapsedMatch && elapsedMatch[1] != null) {
3830
- var e = parseFloat(elapsedMatch[1]);
3831
- if (!Number.isNaN(e)) res.elapsed = e;
3832
- }
3833
- if (durationMatch && durationMatch[1] != null) {
3834
- var d = parseFloat(durationMatch[1]);
3835
- if (!Number.isNaN(d)) res.duration = d;
3836
- }
3837
- if (!("elapsed" in res) || !("duration" in res)) {
3838
- var slashMatch = value.match(/([0-9.]+)\s*\/\s*([0-9.]+)/);
3839
- if (slashMatch && slashMatch[1] && slashMatch[2]) {
3840
- var elapsed = parseFloat(slashMatch[1]);
3841
- var duration = parseFloat(slashMatch[2]);
3842
- if (!Number.isNaN(elapsed) && !("elapsed" in res)) res.elapsed = elapsed;
3843
- if (!Number.isNaN(duration) && !("duration" in res)) res.duration = duration;
3844
- }
3845
- }
3846
- if ("elapsed" in res || "duration" in res) return res;
3847
- return void 0;
3848
- }
3849
- },
3850
- {
3851
- key: "parseAttributeList",
3852
- value: function parseAttributeList(value) {
3853
- var attrs = {};
3854
- var regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
3855
- var match;
3856
- while((match = regex.exec(value)) !== null){
3857
- var _match_, _ref, _match_1;
3858
- var key = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : "";
3859
- var rawVal = (_ref = (_match_1 = match[3]) !== null && _match_1 !== void 0 ? _match_1 : match[4]) !== null && _ref !== void 0 ? _ref : "";
3860
- if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
3861
- rawVal = rawVal.slice(1, -1);
3862
- }
3863
- if (key) {
3864
- attrs[key] = rawVal;
3865
- }
3866
- }
3867
- return attrs;
3868
- }
3869
- },
3870
- {
3871
- key: "toNumber",
3872
- value: function toNumber(val) {
3873
- if (val == null) return void 0;
3874
- var n = typeof val === "string" ? parseFloat(val) : Number(val);
3875
- return Number.isNaN(n) ? void 0 : n;
3876
- }
3877
- },
3878
- {
3879
- key: "isManifestBasedMarker",
3880
- value: function isManifestBasedMarker(marker) {
3881
- var raw = marker.raw;
3882
- if (!raw) return false;
3883
- if (raw.tag) {
3884
- var tag = String(raw.tag);
3885
- return tag.includes("EXT-X-CUE-OUT") || tag.includes("EXT-X-CUE-IN") || tag.includes("EXT-X-DATERANGE");
3886
- }
3887
- if (raw.id3) return false;
3888
- if (raw.splice_command_type) return false;
3889
- return false;
3890
- }
3891
- },
3892
- {
3893
- key: "parseScte35Binary",
3894
- value: function parseScte35Binary(data) {
3895
- var BitReader = /*#__PURE__*/ function() {
3896
- function BitReader(buf) {
3897
- _class_call_check(this, BitReader);
3898
- this.buf = buf;
3899
- this.bytePos = 0;
3900
- this.bitPos = 0;
3901
- }
3902
- _create_class(BitReader, [
3903
- {
3904
- key: "readBits",
3905
- value: function readBits(numBits) {
3906
- var result = 0;
3907
- while(numBits > 0){
3908
- if (this.bytePos >= this.buf.length) return result;
3909
- var remainingInByte = 8 - this.bitPos;
3910
- var toRead = Math.min(numBits, remainingInByte);
3911
- var currentByte = this.buf[this.bytePos];
3912
- var shift = remainingInByte - toRead;
3913
- var mask = (1 << toRead) - 1 & 255;
3914
- var bits = currentByte >> shift & mask;
3915
- result = result << toRead | bits;
3916
- this.bitPos += toRead;
3917
- if (this.bitPos >= 8) {
3918
- this.bitPos = 0;
3919
- this.bytePos += 1;
3920
- }
3921
- numBits -= toRead;
3922
- }
3923
- return result >>> 0;
3924
- }
3925
- },
3926
- {
3927
- key: "skipBits",
3928
- value: function skipBits(n) {
3929
- this.readBits(n);
3930
- }
3931
- }
3932
- ]);
3933
- return BitReader;
3934
- }();
3935
- var r = new BitReader(data);
3936
- var tableId = r.readBits(8);
3937
- if (tableId !== 252) return void 0;
3938
- r.readBits(1);
3939
- r.readBits(1);
3940
- r.readBits(2);
3941
- var sectionLength = r.readBits(12);
3942
- r.readBits(8);
3943
- r.readBits(1);
3944
- r.readBits(6);
3945
- var ptsAdjHigh = r.readBits(1);
3946
- var ptsAdjLow = r.readBits(32);
3947
- void ptsAdjHigh;
3948
- void ptsAdjLow;
3949
- r.readBits(8);
3950
- r.readBits(12);
3951
- var spliceCommandLength = r.readBits(12);
3952
- var spliceCommandType = r.readBits(8);
3953
- if (spliceCommandType !== 5) {
3954
- return void 0;
3955
- }
3956
- r.readBits(32);
3957
- var cancel = r.readBits(1) === 1;
3958
- r.readBits(7);
3959
- if (cancel) return void 0;
3960
- var outOfNetwork = r.readBits(1) === 1;
3961
- var programSpliceFlag = r.readBits(1) === 1;
3962
- var durationFlag = r.readBits(1) === 1;
3963
- var spliceImmediateFlag = r.readBits(1) === 1;
3964
- r.readBits(4);
3965
- if (programSpliceFlag && !spliceImmediateFlag) {
3966
- var timeSpecifiedFlag = r.readBits(1) === 1;
3967
- if (timeSpecifiedFlag) {
3968
- r.readBits(6);
3969
- r.readBits(33);
3970
- } else {
3971
- r.readBits(7);
3972
- }
3973
- } else if (!programSpliceFlag) {
3974
- var componentCount = r.readBits(8);
3975
- for(var i = 0; i < componentCount; i++){
3976
- r.readBits(8);
3977
- if (!spliceImmediateFlag) {
3978
- var timeSpecifiedFlag1 = r.readBits(1) === 1;
3979
- if (timeSpecifiedFlag1) {
3980
- r.readBits(6);
3981
- r.readBits(33);
3982
- } else {
3983
- r.readBits(7);
3984
- }
3985
- }
3986
- }
3987
- }
3988
- var durationSeconds = void 0;
3989
- if (durationFlag) {
3990
- r.readBits(6);
3991
- r.readBits(1);
3992
- var high = r.readBits(1);
3993
- var low = r.readBits(32);
3994
- var durationTicks = high * 4294967296 + low;
3995
- durationSeconds = durationTicks / 9e4;
3996
- }
3997
- r.readBits(16);
3998
- r.readBits(8);
3999
- r.readBits(8);
4000
- if (outOfNetwork) {
4001
- var marker = _object_spread_props(_object_spread({
4002
- type: "start"
4003
- }, durationSeconds !== void 0 ? {
4004
- durationSeconds: durationSeconds
4005
- } : {}), {
4006
- raw: {
4007
- splice_command_type: 5
4008
- }
4009
- });
4010
- return marker;
4011
- }
4012
- return void 0;
4013
- }
4014
- },
4015
3457
  {
4016
3458
  key: "initializeTracking",
4017
3459
  value: function initializeTracking() {
@@ -4133,35 +3575,35 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4133
3575
  },
4134
3576
  {
4135
3577
  key: "startAdPrefetch",
4136
- value: function startAdPrefetch(marker, fragmentSn) {
3578
+ value: function startAdPrefetch(durationSeconds, fragmentSn) {
4137
3579
  if (this.config.disableAds) return;
4138
3580
  if (this.pendingAdBreak || this.inAdBreak) {
4139
3581
  return;
4140
3582
  }
4141
- this.pendingAdBreak = _object_spread_props(_object_spread({
4142
- marker: marker
4143
- }, fragmentSn !== void 0 ? {
3583
+ this.pendingAdBreak = _object_spread_props(_object_spread({}, durationSeconds !== void 0 ? {
3584
+ durationSeconds: durationSeconds
3585
+ } : {}, fragmentSn !== void 0 ? {
4144
3586
  detectedAtFragmentSn: fragmentSn
4145
3587
  } : {}), {
4146
3588
  isFetching: false,
4147
3589
  fetchStartTime: Date.now()
4148
3590
  });
4149
- void this.runAdPrefetch(marker);
3591
+ void this.runAdPrefetch(durationSeconds);
4150
3592
  if (this.config.debugAdTiming) {
4151
- console.log("[PREFETCH] Ad break marker registered, multi-ad prefetch started");
3593
+ console.log("[PREFETCH] Ad break registered, multi-ad prefetch started");
4152
3594
  }
4153
3595
  }
4154
3596
  },
4155
3597
  {
4156
3598
  key: "runAdPrefetch",
4157
- value: function runAdPrefetch(marker) {
3599
+ value: function runAdPrefetch(durationSeconds) {
4158
3600
  return _async_to_generator(function() {
4159
- var _this, _marker_durationSeconds, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token;
3601
+ var _this, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, unused1, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token, unused2, err;
4160
3602
  return _ts_generator(this, function(_state) {
4161
3603
  switch(_state.label){
4162
3604
  case 0:
4163
3605
  _this = this;
4164
- durSec = (_marker_durationSeconds = marker.durationSeconds) !== null && _marker_durationSeconds !== void 0 ? _marker_durationSeconds : 60;
3606
+ durSec = durationSeconds !== null && durationSeconds !== void 0 ? durationSeconds : 60;
4165
3607
  context = {
4166
3608
  breakDurationSec: durSec,
4167
3609
  remainingBreakSec: durSec
@@ -4211,14 +3653,43 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4211
3653
  console.log("[PREFETCH] Ad duration=".concat(adDurationSec, "s, break=").concat(durSec, "s → ").concat(estimatedCount, " ad(s) needed"));
4212
3654
  }
4213
3655
  firstToken = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4214
- this.preloadedTokens.push(firstToken);
4215
- void this.adLayer.preloadAd(firstBids, firstToken);
3656
+ _state.label = 5;
3657
+ case 5:
3658
+ _state.trys.push([
3659
+ 5,
3660
+ 7,
3661
+ ,
3662
+ 8
3663
+ ]);
3664
+ return [
3665
+ 4,
3666
+ this.adLayer.preloadAd(firstBids, firstToken)
3667
+ ];
3668
+ case 6:
3669
+ _state.sent();
3670
+ if (!this.inAdBreak) {
3671
+ this.preloadedTokens.push(firstToken);
3672
+ if (this.config.debugAdTiming) {
3673
+ console.log("[PREFETCH] First ad preloaded and queued, token=".concat(firstToken));
3674
+ }
3675
+ }
3676
+ return [
3677
+ 3,
3678
+ 8
3679
+ ];
3680
+ case 7:
3681
+ unused1 = _state.sent();
4216
3682
  if (this.config.debugAdTiming) {
4217
- console.log("[PREFETCH] First ad preloading, token=".concat(firstToken));
3683
+ console.warn("[PREFETCH] First ad preload failed, token=".concat(firstToken));
4218
3684
  }
3685
+ return [
3686
+ 3,
3687
+ 8
3688
+ ];
3689
+ case 8:
4219
3690
  if (!(estimatedCount > 1)) return [
4220
3691
  3,
4221
- 6
3692
+ 19
4222
3693
  ];
4223
3694
  remaining = Array.from({
4224
3695
  length: estimatedCount - 1
@@ -4240,38 +3711,100 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4240
3711
  4,
4241
3712
  Promise.all(remaining)
4242
3713
  ];
4243
- case 5:
3714
+ case 9:
4244
3715
  results = _state.sent();
4245
3716
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3717
+ _state.label = 10;
3718
+ case 10:
3719
+ _state.trys.push([
3720
+ 10,
3721
+ 17,
3722
+ 18,
3723
+ 19
3724
+ ]);
3725
+ _iterator = results[Symbol.iterator]();
3726
+ _state.label = 11;
3727
+ case 11:
3728
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
3729
+ 3,
3730
+ 16
3731
+ ];
3732
+ result = _step.value;
3733
+ if (this.inAdBreak) return [
3734
+ 3,
3735
+ 16
3736
+ ];
3737
+ if (!(result.ok && result.value.length > 0)) return [
3738
+ 3,
3739
+ 15
3740
+ ];
3741
+ token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
3742
+ _state.label = 12;
3743
+ case 12:
3744
+ _state.trys.push([
3745
+ 12,
3746
+ 14,
3747
+ ,
3748
+ 15
3749
+ ]);
3750
+ return [
3751
+ 4,
3752
+ this.adLayer.preloadAd(result.value, token)
3753
+ ];
3754
+ case 13:
3755
+ _state.sent();
3756
+ if (!this.inAdBreak) {
3757
+ this.preloadedTokens.push(token);
3758
+ if (this.config.debugAdTiming) {
3759
+ console.log("[PREFETCH] Additional ad preloaded and queued, token=".concat(token));
3760
+ }
3761
+ }
3762
+ return [
3763
+ 3,
3764
+ 15
3765
+ ];
3766
+ case 14:
3767
+ unused2 = _state.sent();
3768
+ if (this.config.debugAdTiming) {
3769
+ console.warn("[PREFETCH] Additional ad preload failed, token=".concat(token));
3770
+ }
3771
+ return [
3772
+ 3,
3773
+ 15
3774
+ ];
3775
+ case 15:
3776
+ _iteratorNormalCompletion = true;
3777
+ return [
3778
+ 3,
3779
+ 11
3780
+ ];
3781
+ case 16:
3782
+ return [
3783
+ 3,
3784
+ 19
3785
+ ];
3786
+ case 17:
3787
+ err = _state.sent();
3788
+ _didIteratorError = true;
3789
+ _iteratorError = err;
3790
+ return [
3791
+ 3,
3792
+ 19
3793
+ ];
3794
+ case 18:
4246
3795
  try {
4247
- for(_iterator = results[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
4248
- result = _step.value;
4249
- if (this.inAdBreak) break;
4250
- if (result.ok && result.value.length > 0) {
4251
- token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4252
- this.preloadedTokens.push(token);
4253
- void this.adLayer.preloadAd(result.value, token);
4254
- if (this.config.debugAdTiming) {
4255
- console.log("[PREFETCH] Additional ad preloading, token=".concat(token));
4256
- }
4257
- }
3796
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3797
+ _iterator.return();
4258
3798
  }
4259
- } catch (err) {
4260
- _didIteratorError = true;
4261
- _iteratorError = err;
4262
3799
  } finally{
4263
- try {
4264
- if (!_iteratorNormalCompletion && _iterator.return != null) {
4265
- _iterator.return();
4266
- }
4267
- } finally{
4268
- if (_didIteratorError) {
4269
- throw _iteratorError;
4270
- }
3800
+ if (_didIteratorError) {
3801
+ throw _iteratorError;
4271
3802
  }
4272
3803
  }
4273
- _state.label = 6;
4274
- case 6:
3804
+ return [
3805
+ 7
3806
+ ];
3807
+ case 19:
4275
3808
  if (this.config.debugAdTiming) {
4276
3809
  console.log("[PREFETCH] Pre-fetch complete: ".concat(this.preloadedTokens.length, " ad(s) queued"));
4277
3810
  }
@@ -4436,15 +3969,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4436
3969
  if (this.config.debugAdTiming) {
4437
3970
  console.log('[StormcloudVideoPlayer] Ad insertion segment "'.concat(segmentName, '" found in manifest — starting pre-fetch'));
4438
3971
  }
4439
- var marker = {
4440
- type: "start",
4441
- durationSeconds: 60,
4442
- raw: {
4443
- apiInsertionPoint: this.lastAdInsertionPoint,
4444
- earlyDetection: true
4445
- }
4446
- };
4447
- this.startAdPrefetch(marker, frag === null || frag === void 0 ? void 0 : frag.sn);
3972
+ this.startAdPrefetch(60, frag === null || frag === void 0 ? void 0 : frag.sn);
4448
3973
  return;
4449
3974
  }
4450
3975
  }
@@ -4482,8 +4007,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4482
4007
  {
4483
4008
  key: "fragmentMatchesSegment",
4484
4009
  value: function fragmentMatchesSegment(frag, segmentName) {
4485
- var url = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4486
- return url.endsWith(segmentName) || url.includes("/" + segmentName);
4010
+ var _rawUrl_split_;
4011
+ var rawUrl = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4012
+ var url = (_rawUrl_split_ = rawUrl.split("?")[0]) !== null && _rawUrl_split_ !== void 0 ? _rawUrl_split_ : "";
4013
+ var name = segmentName.startsWith("/") ? segmentName : "/" + segmentName;
4014
+ return url.endsWith(name) || url.includes(name);
4487
4015
  }
4488
4016
  },
4489
4017
  {
@@ -4820,13 +4348,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4820
4348
  },
4821
4349
  {
4822
4350
  key: "handleAdStart",
4823
- value: function handleAdStart(_marker) {
4351
+ value: function handleAdStart(durationSeconds) {
4824
4352
  return _async_to_generator(function() {
4825
- var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4353
+ var _this_savedMutedStateBeforeAd, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4826
4354
  return _ts_generator(this, function(_state) {
4827
4355
  switch(_state.label){
4828
4356
  case 0:
4829
- adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : void 0;
4357
+ adBreakDurationMs = durationSeconds != null ? durationSeconds * 1e3 : void 0;
4830
4358
  if (this.config.debugAdTiming) {
4831
4359
  mode = this.isLiveStream ? "LIVE" : "VOD";
4832
4360
  console.log("[CONTINUOUS-FETCH] \uD83D\uDCFA ".concat(mode, " MODE: Target duration=").concat(adBreakDurationMs, "ms"));
@@ -4837,13 +4365,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4837
4365
  this.pendingNextAdBids = null;
4838
4366
  this.isShowingPlaceholder = false;
4839
4367
  this.totalAdRequestsInBreak = 0;
4840
- if (this.savedMutedStateBeforeScte == null && !this.video.muted) {
4841
- this.savedMutedStateBeforeScte = {
4368
+ if (this.savedMutedStateBeforeAd == null && !this.video.muted) {
4369
+ this.savedMutedStateBeforeAd = {
4842
4370
  muted: false,
4843
4371
  volume: this.video.volume
4844
4372
  };
4845
4373
  }
4846
- state = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) !== null && _this_savedMutedStateBeforeScte !== void 0 ? _this_savedMutedStateBeforeScte : {
4374
+ state = (_this_savedMutedStateBeforeAd = this.savedMutedStateBeforeAd) !== null && _this_savedMutedStateBeforeAd !== void 0 ? _this_savedMutedStateBeforeAd : {
4847
4375
  muted: this.video.muted,
4848
4376
  volume: this.video.volume
4849
4377
  };
@@ -4870,6 +4398,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4870
4398
  if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
4871
4399
  this.expectedAdBreakDurationMs = adBreakDurationMs;
4872
4400
  }
4401
+ if (this.expectedAdBreakDurationMs != null) {
4402
+ this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4403
+ }
4873
4404
  this.clearPendingAdBreak();
4874
4405
  adBreakToken = Date.now();
4875
4406
  this.activeAdRequestToken = adBreakToken;
@@ -5368,49 +4899,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5368
4899
  this.handleAdPodComplete();
5369
4900
  }
5370
4901
  },
5371
- {
5372
- key: "scheduleAdStartIn",
5373
- value: function scheduleAdStartIn(delayMs) {
5374
- var _this = this;
5375
- this.clearAdStartTimer();
5376
- var ms = Math.max(0, Math.floor(delayMs));
5377
- if (ms === 0) {
5378
- this.handleAdStart({
5379
- type: "start"
5380
- }).catch(function() {});
5381
- return;
5382
- }
5383
- this.adStartTimerId = window.setTimeout(function() {
5384
- _this.handleAdStart({
5385
- type: "start"
5386
- }).catch(function() {});
5387
- }, ms);
5388
- }
5389
- },
5390
- {
5391
- key: "clearAdStartTimer",
5392
- value: function clearAdStartTimer() {
5393
- if (this.adStartTimerId != null) {
5394
- clearTimeout(this.adStartTimerId);
5395
- this.adStartTimerId = void 0;
5396
- }
5397
- }
5398
- },
5399
- {
5400
- key: "updatePtsDrift",
5401
- value: function updatePtsDrift(ptsSecondsSample) {
5402
- var sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;
5403
- if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;
5404
- var alpha = 0.1;
5405
- this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
5406
- }
5407
- },
5408
4902
  {
5409
4903
  key: "handleAdPodComplete",
5410
4904
  value: function handleAdPodComplete() {
5411
4905
  var _this = this;
5412
4906
  var _ref, _ref1;
5413
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
4907
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
5414
4908
  if (this.config.debugAdTiming) {
5415
4909
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
5416
4910
  }
@@ -5432,7 +4926,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5432
4926
  this.inAdBreak = false;
5433
4927
  this.expectedAdBreakDurationMs = void 0;
5434
4928
  this.currentAdBreakStartWallClockMs = void 0;
5435
- this.clearAdStartTimer();
5436
4929
  this.clearAdStopTimer();
5437
4930
  this.adPodQueue = [];
5438
4931
  this.showAds = false;
@@ -5440,8 +4933,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5440
4933
  this.totalAdsInBreak = 0;
5441
4934
  this.totalAdRequestsInBreak = 0;
5442
4935
  this.consecutiveFailures = 0;
5443
- var restoredMuted = (_ref = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte === void 0 ? void 0 : _this_savedMutedStateBeforeScte.muted) !== null && _ref !== void 0 ? _ref : this.adLayer.getOriginalMutedState();
5444
- var restoredVolume = (_ref1 = (_this_savedMutedStateBeforeScte1 = this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte1 === void 0 ? void 0 : _this_savedMutedStateBeforeScte1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.adLayer.getOriginalVolume();
4936
+ var restoredMuted = (_ref = (_this_savedMutedStateBeforeAd = this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd === void 0 ? void 0 : _this_savedMutedStateBeforeAd.muted) !== null && _ref !== void 0 ? _ref : this.adLayer.getOriginalMutedState();
4937
+ var restoredVolume = (_ref1 = (_this_savedMutedStateBeforeAd1 = this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd1 === void 0 ? void 0 : _this_savedMutedStateBeforeAd1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.adLayer.getOriginalVolume();
5445
4938
  this.adLayer.updateOriginalMutedState(restoredMuted, restoredVolume);
5446
4939
  this.adLayer.stop().catch(function() {});
5447
4940
  if (this.video.muted !== restoredMuted) {
@@ -5550,7 +5043,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5550
5043
  }, delay);
5551
5044
  });
5552
5045
  }
5553
- this.savedMutedStateBeforeScte = null;
5046
+ this.savedMutedStateBeforeAd = null;
5554
5047
  }
5555
5048
  },
5556
5049
  {
@@ -5700,19 +5193,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5700
5193
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
5701
5194
  }
5702
5195
  },
5703
- {
5704
- key: "pushScteMarker",
5705
- value: function pushScteMarker(marker) {
5706
- if (!this.config.debugAdTiming) return;
5707
- this.scteMarkerHistory.push({
5708
- timestampMs: Date.now(),
5709
- marker: marker
5710
- });
5711
- if (this.scteMarkerHistory.length > DEBUG_HISTORY_LIMIT) {
5712
- this.scteMarkerHistory = this.scteMarkerHistory.slice(-DEBUG_HISTORY_LIMIT);
5713
- }
5714
- }
5715
- },
5716
5196
  {
5717
5197
  key: "pushDebugLog",
5718
5198
  value: function pushDebugLog(level, category, message, details) {
@@ -5730,23 +5210,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5730
5210
  }
5731
5211
  }
5732
5212
  },
5733
- {
5734
- key: "getRecentScteMarkers",
5735
- value: function getRecentScteMarkers() {
5736
- return this.scteMarkerHistory.map(function(entry) {
5737
- return _object_spread({
5738
- timestampMs: entry.timestampMs,
5739
- type: entry.marker.type
5740
- }, entry.marker.ptsSeconds !== void 0 ? {
5741
- ptsSeconds: entry.marker.ptsSeconds
5742
- } : {}, entry.marker.durationSeconds !== void 0 ? {
5743
- durationSeconds: entry.marker.durationSeconds
5744
- } : {}, entry.marker.raw !== void 0 ? {
5745
- raw: entry.marker.raw
5746
- } : {});
5747
- });
5748
- }
5749
- },
5750
5213
  {
5751
5214
  key: "pushAdInsertionDebug",
5752
5215
  value: function pushAdInsertionDebug(event, segmentName, opts) {
@@ -6043,7 +5506,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6043
5506
  this.clearAdInsertionOffsetTimer();
6044
5507
  this.stopContinuousFetching();
6045
5508
  this.stopFillerBreakTimer();
6046
- this.clearAdStartTimer();
6047
5509
  this.clearAdStopTimer();
6048
5510
  this.clearAdFailsafeTimer();
6049
5511
  this.clearAdRequestWatchdog();
@@ -6071,7 +5533,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6071
5533
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
6072
5534
  this.consecutiveFailures = 0;
6073
5535
  this.debugLogEntries = [];
6074
- this.scteMarkerHistory = [];
6075
5536
  this.adInsertionDebugHistory = [];
6076
5537
  }
6077
5538
  }