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.
@@ -1479,7 +1479,6 @@ function createAdStormPlayer(contentVideo, options) {
1479
1479
  contentVideo.muted = originalMutedState;
1480
1480
  contentVideo.volume = originalVolume;
1481
1481
  currentAd = void 0;
1482
- tornDown = false;
1483
1482
  return [
1484
1483
  2,
1485
1484
  Promise.resolve()
@@ -1594,6 +1593,15 @@ function createAdStormPlayer(contentVideo, options) {
1594
1593
  if (!token) return [
1595
1594
  2
1596
1595
  ];
1596
+ if (currentAd) {
1597
+ preloadSlots.set(token, {
1598
+ ad: currentAd
1599
+ });
1600
+ currentAd = void 0;
1601
+ return [
1602
+ 2
1603
+ ];
1604
+ }
1597
1605
  requestContext = typeof arg1 === "string" ? arg2 : arg1;
1598
1606
  return [
1599
1607
  4,
@@ -2087,56 +2095,6 @@ function sendInitialTracking(licenseKey) {
2087
2095
  });
2088
2096
  })();
2089
2097
  }
2090
- function sendAdDetectTracking(licenseKey, adDetectInfo) {
2091
- return _async_to_generator(function() {
2092
- var clientInfo, browserId, trackingData, error;
2093
- return _ts_generator(this, function(_state) {
2094
- switch(_state.label){
2095
- case 0:
2096
- _state.trys.push([
2097
- 0,
2098
- 3,
2099
- ,
2100
- 4
2101
- ]);
2102
- clientInfo = getClientInfo();
2103
- return [
2104
- 4,
2105
- getBrowserID(clientInfo)
2106
- ];
2107
- case 1:
2108
- browserId = _state.sent();
2109
- trackingData = _object_spread({
2110
- browserId: browserId
2111
- }, clientInfo);
2112
- return [
2113
- 4,
2114
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2115
- licenseKey: licenseKey,
2116
- adDetectInfo: adDetectInfo
2117
- }))
2118
- ];
2119
- case 2:
2120
- _state.sent();
2121
- return [
2122
- 3,
2123
- 4
2124
- ];
2125
- case 3:
2126
- error = _state.sent();
2127
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2128
- return [
2129
- 3,
2130
- 4
2131
- ];
2132
- case 4:
2133
- return [
2134
- 2
2135
- ];
2136
- }
2137
- });
2138
- })();
2139
- }
2140
2098
  function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2141
2099
  return _async_to_generator(function() {
2142
2100
  var clientInfo, browserId, trackingData, error;
@@ -2821,7 +2779,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2821
2779
  this.continuousFetchLoopPromise = null;
2822
2780
  this.attached = false;
2823
2781
  this.inAdBreak = false;
2824
- this.ptsDriftEmaMs = 0;
2825
2782
  this.adPodQueue = [];
2826
2783
  this.lastHeartbeatTime = 0;
2827
2784
  this.currentAdIndex = 0;
@@ -2845,7 +2802,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2845
2802
  this.totalAdRequestsInBreak = 0;
2846
2803
  this.maxTotalAdRequestsPerBreak = 20;
2847
2804
  this.pendingAdBreak = null;
2848
- this.savedMutedStateBeforeScte = null;
2805
+ this.savedMutedStateBeforeAd = null;
2849
2806
  this.consecutiveFailures = 0;
2850
2807
  this.maxConsecutiveFailures = 5;
2851
2808
  this.lastAdRequestTime = 0;
@@ -2858,7 +2815,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2858
2815
  this.adRequestRetryBackoffMs = 1500;
2859
2816
  this.preloadedTokens = [];
2860
2817
  this.debugLogEntries = [];
2861
- this.scteMarkerHistory = [];
2862
2818
  this.adInsertionDebugHistory = [];
2863
2819
  initializePolyfills();
2864
2820
  var browserOverrides = getBrowserConfigOverrides();
@@ -3147,18 +3103,44 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3147
3103
  _this.pushAdInsertionDebug("ad_triggered", segmentName, {
3148
3104
  detail: "ad break started (60s)"
3149
3105
  });
3150
- var marker = {
3151
- type: "start",
3152
- durationSeconds: 60,
3153
- raw: {
3154
- apiInsertionPoint: _this.lastAdInsertionPoint
3155
- }
3156
- };
3157
- _this.onScte35Marker(marker);
3106
+ void _this.handleAdStart(60);
3158
3107
  }, offsetMs);
3159
3108
  }
3160
3109
  }
3161
3110
  });
3111
+ this.hls.on(import_hls.default.Events.FRAG_PARSING_USERDATA, function(_evt, data) {
3112
+ var _ref;
3113
+ var samples = (_ref = data === null || data === void 0 ? void 0 : data.samples) !== null && _ref !== void 0 ? _ref : [];
3114
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3115
+ try {
3116
+ for(var _iterator = samples[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
3117
+ var sample = _step.value;
3118
+ var _ref1, _ref2;
3119
+ var _data_frag, _data_frag1;
3120
+ var bytes = sample === null || sample === void 0 ? void 0 : sample.data;
3121
+ if (!bytes || bytes.length < 5) continue;
3122
+ var isSCTE35 = bytes[0] === 252;
3123
+ if (!isSCTE35) continue;
3124
+ 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 : "";
3125
+ _this.pushAdInsertionDebug("scte35_inserted", segName, {
3126
+ detail: "len=".concat(bytes.length, "B")
3127
+ });
3128
+ }
3129
+ } catch (err) {
3130
+ _didIteratorError = true;
3131
+ _iteratorError = err;
3132
+ } finally{
3133
+ try {
3134
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3135
+ _iterator.return();
3136
+ }
3137
+ } finally{
3138
+ if (_didIteratorError) {
3139
+ throw _iteratorError;
3140
+ }
3141
+ }
3142
+ }
3143
+ });
3162
3144
  this.hls.on(import_hls.default.Events.ERROR, function(_evt, data) {
3163
3145
  if (data === null || data === void 0 ? void 0 : data.fatal) {
3164
3146
  switch(data.type){
@@ -3233,8 +3215,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3233
3215
  _this.activeAdRequestToken = null;
3234
3216
  _this.showAds = true;
3235
3217
  if (_this.config.disableFiller) {
3236
- if (_this.savedMutedStateBeforeScte == null) {
3237
- _this.savedMutedStateBeforeScte = {
3218
+ if (_this.savedMutedStateBeforeAd == null) {
3219
+ _this.savedMutedStateBeforeAd = {
3238
3220
  muted: _this.video.muted,
3239
3221
  volume: _this.video.volume
3240
3222
  };
@@ -3262,10 +3244,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3262
3244
  });
3263
3245
  this.adLayer.on("content_resume", function() {
3264
3246
  var _ref, _ref1;
3265
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
3247
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
3266
3248
  var remaining = _this.getRemainingAdMs();
3267
- 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();
3268
- 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();
3249
+ 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();
3250
+ 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();
3269
3251
  if (_this.config.debugAdTiming) {
3270
3252
  console.log("[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, preloadedTokens=%d, pendingNext=%s", _this.inAdBreak, remaining, _this.preloadedTokens.length, !!_this.pendingNextAdBids);
3271
3253
  }
@@ -3342,7 +3324,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3342
3324
  var remainingFinal = _this.getRemainingAdMs();
3343
3325
  if (_this.inAdBreak && remainingFinal > _this.MIN_AD_REMAINING_MS) {
3344
3326
  if (_this.config.debugAdTiming) {
3345
- console.log("[StormcloudVideoPlayer] content_resume: no more ads, showing filler for", remainingFinal, "ms");
3327
+ console.log("[StormcloudVideoPlayer] content_resume: ad ended/failed with time remaining, showing filler and continuing fetch for", remainingFinal, "ms");
3346
3328
  }
3347
3329
  if (!_this.config.disableFiller) {
3348
3330
  _this.showPlaceholderLayer();
@@ -3360,7 +3342,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3360
3342
  (_this_video_play = _this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
3361
3343
  }
3362
3344
  }
3363
- _this.stopContinuousFetching();
3345
+ _this.continuousFetchingActive = true;
3346
+ _this.startContinuousFetchLoop();
3364
3347
  return;
3365
3348
  }
3366
3349
  if (_this.config.debugAdTiming) {
@@ -3507,547 +3490,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3507
3490
  return !!(this.config.allowNativeHls && canNative);
3508
3491
  }
3509
3492
  },
3510
- {
3511
- key: "onId3Tag",
3512
- value: function onId3Tag(tag) {
3513
- if (typeof tag.ptsSeconds === "number") {
3514
- this.updatePtsDrift(tag.ptsSeconds);
3515
- }
3516
- var marker = this.parseScte35FromId3(tag);
3517
- if (marker) {
3518
- this.onScte35Marker(marker);
3519
- }
3520
- }
3521
- },
3522
- {
3523
- key: "parseScte35FromId3",
3524
- value: function parseScte35FromId3(tag) {
3525
- var text = this.decodeId3ValueToText(tag.value);
3526
- if (!text) return void 0;
3527
- var cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
3528
- if (cueOutMatch) {
3529
- var _cueOutMatch_;
3530
- var arg = ((_cueOutMatch_ = cueOutMatch[1]) !== null && _cueOutMatch_ !== void 0 ? _cueOutMatch_ : "").trim();
3531
- var dur = this.parseCueOutDuration(arg);
3532
- var marker = _object_spread_props(_object_spread({
3533
- type: "start"
3534
- }, tag.ptsSeconds !== void 0 ? {
3535
- ptsSeconds: tag.ptsSeconds
3536
- } : {}, dur !== void 0 ? {
3537
- durationSeconds: dur
3538
- } : {}), {
3539
- raw: {
3540
- id3: text
3541
- }
3542
- });
3543
- return marker;
3544
- }
3545
- var cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
3546
- if (cueOutContMatch) {
3547
- var _cueOutContMatch_;
3548
- var arg1 = ((_cueOutContMatch_ = cueOutContMatch[1]) !== null && _cueOutContMatch_ !== void 0 ? _cueOutContMatch_ : "").trim();
3549
- var cont = this.parseCueOutCont(arg1);
3550
- var marker1 = _object_spread_props(_object_spread({
3551
- type: "progress"
3552
- }, tag.ptsSeconds !== void 0 ? {
3553
- ptsSeconds: tag.ptsSeconds
3554
- } : {}, (cont === null || cont === void 0 ? void 0 : cont.duration) !== void 0 ? {
3555
- durationSeconds: cont.duration
3556
- } : {}), {
3557
- raw: {
3558
- id3: text
3559
- }
3560
- });
3561
- return marker1;
3562
- }
3563
- var cueInMatch = text.match(/EXT-X-CUE-IN\b/i) || text.match(/CUE-IN\b/i);
3564
- if (cueInMatch) {
3565
- var marker2 = _object_spread_props(_object_spread({
3566
- type: "end"
3567
- }, tag.ptsSeconds !== void 0 ? {
3568
- ptsSeconds: tag.ptsSeconds
3569
- } : {}), {
3570
- raw: {
3571
- id3: text
3572
- }
3573
- });
3574
- return marker2;
3575
- }
3576
- var daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
3577
- if (daterangeMatch) {
3578
- var _daterangeMatch_, _attrs_CLASS;
3579
- var attrs = this.parseAttributeList((_daterangeMatch_ = daterangeMatch[1]) !== null && _daterangeMatch_ !== void 0 ? _daterangeMatch_ : "");
3580
- var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3581
- var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3582
- var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3583
- var duration = this.toNumber(attrs["DURATION"]);
3584
- if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
3585
- var marker3 = _object_spread_props(_object_spread({
3586
- type: "start"
3587
- }, tag.ptsSeconds !== void 0 ? {
3588
- ptsSeconds: tag.ptsSeconds
3589
- } : {}, duration !== void 0 ? {
3590
- durationSeconds: duration
3591
- } : {}), {
3592
- raw: {
3593
- id3: text,
3594
- attrs: attrs
3595
- }
3596
- });
3597
- return marker3;
3598
- }
3599
- if (hasScteIn) {
3600
- var marker4 = _object_spread_props(_object_spread({
3601
- type: "end"
3602
- }, tag.ptsSeconds !== void 0 ? {
3603
- ptsSeconds: tag.ptsSeconds
3604
- } : {}), {
3605
- raw: {
3606
- id3: text,
3607
- attrs: attrs
3608
- }
3609
- });
3610
- return marker4;
3611
- }
3612
- }
3613
- if (/SCTE35-OUT/i.test(text)) {
3614
- var marker5 = _object_spread_props(_object_spread({
3615
- type: "start"
3616
- }, tag.ptsSeconds !== void 0 ? {
3617
- ptsSeconds: tag.ptsSeconds
3618
- } : {}), {
3619
- raw: {
3620
- id3: text
3621
- }
3622
- });
3623
- return marker5;
3624
- }
3625
- if (/SCTE35-IN/i.test(text)) {
3626
- var marker6 = _object_spread_props(_object_spread({
3627
- type: "end"
3628
- }, tag.ptsSeconds !== void 0 ? {
3629
- ptsSeconds: tag.ptsSeconds
3630
- } : {}), {
3631
- raw: {
3632
- id3: text
3633
- }
3634
- });
3635
- return marker6;
3636
- }
3637
- if (_instanceof(tag.value, Uint8Array)) {
3638
- var bin = this.parseScte35Binary(tag.value);
3639
- if (bin) return bin;
3640
- }
3641
- return void 0;
3642
- }
3643
- },
3644
- {
3645
- key: "decodeId3ValueToText",
3646
- value: function decodeId3ValueToText(value) {
3647
- try {
3648
- if (typeof value === "string") return value;
3649
- var decoder = new TextDecoder("utf-8", {
3650
- fatal: false
3651
- });
3652
- var text = decoder.decode(value);
3653
- if (text && /[\x20-\x7E]/.test(text)) return text;
3654
- var out = "";
3655
- for(var i = 0; i < value.length; i++)out += String.fromCharCode(value[i]);
3656
- return out;
3657
- } catch (unused) {
3658
- return void 0;
3659
- }
3660
- }
3661
- },
3662
- {
3663
- key: "onScte35Marker",
3664
- value: function onScte35Marker(marker) {
3665
- var _this = this;
3666
- if (this.config.disableAds) return;
3667
- this.pushScteMarker(marker);
3668
- this.pushDebugLog("info", "scte35", "SCTE-35 marker detected", {
3669
- type: marker.type,
3670
- ptsSeconds: marker.ptsSeconds,
3671
- durationSeconds: marker.durationSeconds,
3672
- currentTime: this.video.currentTime
3673
- });
3674
- if (this.config.debugAdTiming) {
3675
- console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
3676
- type: marker.type,
3677
- ptsSeconds: marker.ptsSeconds,
3678
- durationSeconds: marker.durationSeconds,
3679
- currentTime: this.video.currentTime,
3680
- raw: marker.raw,
3681
- hasPendingAdBreak: !!this.pendingAdBreak
3682
- });
3683
- }
3684
- if (marker.type === "start") {
3685
- var _this_config_immediateManifestAds;
3686
- var _this_pendingAdBreak;
3687
- if (this.savedMutedStateBeforeScte == null) {
3688
- this.savedMutedStateBeforeScte = {
3689
- muted: this.video.muted,
3690
- volume: this.video.volume
3691
- };
3692
- this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);
3693
- }
3694
- if (!this.config.disableFiller && !this.video.muted && !this.adLayer.isAdPlaying()) {
3695
- this.video.muted = true;
3696
- this.video.volume = 0;
3697
- if (this.config.debugAdTiming) {
3698
- console.log("[StormcloudVideoPlayer] Muted video on SCTE start marker");
3699
- }
3700
- }
3701
- if (this.inAdBreak) {
3702
- if (marker.durationSeconds != null) {
3703
- var newDurationMs = marker.durationSeconds * 1e3;
3704
- if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
3705
- this.expectedAdBreakDurationMs = newDurationMs;
3706
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
3707
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
3708
- this.scheduleAdStopCountdown(remainingMs);
3709
- if (this.config.debugAdTiming) {
3710
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
3711
- }
3712
- }
3713
- }
3714
- return;
3715
- }
3716
- this.inAdBreak = true;
3717
- 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;
3718
- this.expectedAdBreakDurationMs = durationMs;
3719
- this.currentAdBreakStartWallClockMs = Date.now();
3720
- if (this.config.licenseKey) {
3721
- var _this_pendingAdBreak1;
3722
- var adDetectInfo = _object_spread({
3723
- source: "scte35",
3724
- timestamp: /* @__PURE__ */ new Date().toISOString()
3725
- }, marker.durationSeconds != null && {
3726
- durationSeconds: marker.durationSeconds
3727
- }, marker.ptsSeconds != null && {
3728
- ptsSeconds: marker.ptsSeconds
3729
- }, ((_this_pendingAdBreak1 = this.pendingAdBreak) === null || _this_pendingAdBreak1 === void 0 ? void 0 : _this_pendingAdBreak1.detectedAtFragmentSn) != null && {
3730
- detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn
3731
- });
3732
- sendAdDetectTracking(this.config.licenseKey, adDetectInfo);
3733
- }
3734
- var isManifestMarker = this.isManifestBasedMarker(marker);
3735
- var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
3736
- if (this.config.debugAdTiming) {
3737
- console.log("[StormcloudVideoPlayer] Ad start decision:", {
3738
- isManifestMarker: isManifestMarker,
3739
- forceImmediate: forceImmediate,
3740
- hasPts: typeof marker.ptsSeconds === "number"
3741
- });
3742
- }
3743
- if (isManifestMarker && forceImmediate) {
3744
- if (this.config.debugAdTiming) {
3745
- console.log("[StormcloudVideoPlayer] Starting ad immediately (manifest-based)");
3746
- }
3747
- this.clearAdStartTimer();
3748
- this.handleAdStart(marker);
3749
- } else if (typeof marker.ptsSeconds === "number") {
3750
- var _this_config_driftToleranceMs;
3751
- var tol = (_this_config_driftToleranceMs = this.config.driftToleranceMs) !== null && _this_config_driftToleranceMs !== void 0 ? _this_config_driftToleranceMs : 1e3;
3752
- var nowMs = this.video.currentTime * 1e3;
3753
- var estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
3754
- var deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
3755
- if (this.config.debugAdTiming) {
3756
- console.log("[StormcloudVideoPlayer] PTS-based timing calculation:", {
3757
- nowMs: nowMs,
3758
- estCurrentPtsMs: estCurrentPtsMs,
3759
- markerPtsMs: marker.ptsSeconds * 1e3,
3760
- deltaMs: deltaMs,
3761
- tolerance: tol
3762
- });
3763
- }
3764
- if (deltaMs > tol) {
3765
- if (this.config.debugAdTiming) {
3766
- console.log("[StormcloudVideoPlayer] Scheduling ad start in ".concat(deltaMs, "ms"));
3767
- }
3768
- this.scheduleAdStartIn(deltaMs);
3769
- } else {
3770
- if (this.config.debugAdTiming) {
3771
- console.log("[StormcloudVideoPlayer] Starting ad immediately (within tolerance)");
3772
- }
3773
- this.clearAdStartTimer();
3774
- this.handleAdStart(marker);
3775
- }
3776
- } else {
3777
- if (this.config.debugAdTiming) {
3778
- console.log("[StormcloudVideoPlayer] Starting ad immediately (fallback)");
3779
- }
3780
- this.clearAdStartTimer();
3781
- this.handleAdStart(marker);
3782
- }
3783
- if (this.expectedAdBreakDurationMs != null) {
3784
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
3785
- }
3786
- return;
3787
- }
3788
- if (marker.type === "progress" && this.inAdBreak) {
3789
- if (marker.durationSeconds != null) {
3790
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
3791
- }
3792
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
3793
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
3794
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
3795
- this.scheduleAdStopCountdown(remainingMs1);
3796
- }
3797
- if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {
3798
- var bids = this.pendingNextAdBids;
3799
- this.pendingNextAdBids = null;
3800
- this.currentAdIndex++;
3801
- this.adLayer.playAd(bids).catch(function() {
3802
- return _this.handleAdFailure();
3803
- });
3804
- }
3805
- return;
3806
- }
3807
- if (marker.type === "end") {
3808
- var remaining = this.getRemainingAdMs();
3809
- var adPlaying = this.adLayer.isAdPlaying();
3810
- var hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;
3811
- if (this.config.debugAdTiming) {
3812
- console.log("[StormcloudVideoPlayer] SCTE-35 end marker received:", {
3813
- inAdBreak: this.inAdBreak,
3814
- remaining: remaining,
3815
- adPlaying: adPlaying,
3816
- hasQueuedAds: hasQueuedAds,
3817
- activeAdRequest: this.activeAdRequestToken !== null
3818
- });
3819
- }
3820
- if (!this.inAdBreak) {
3821
- if (this.config.debugAdTiming) {
3822
- console.log("[StormcloudVideoPlayer] Ignoring SCTE-35 end marker - not in ad break");
3823
- }
3824
- return;
3825
- }
3826
- if (adPlaying || remaining > 500) {
3827
- if (this.config.debugAdTiming) {
3828
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining");
3829
- }
3830
- return;
3831
- }
3832
- this.inAdBreak = false;
3833
- this.expectedAdBreakDurationMs = void 0;
3834
- this.currentAdBreakStartWallClockMs = void 0;
3835
- this.clearAdStartTimer();
3836
- this.clearAdStopTimer();
3837
- if (adPlaying) {
3838
- this.adLayer.stop().catch(function() {});
3839
- }
3840
- this.handleAdPodComplete();
3841
- return;
3842
- }
3843
- }
3844
- },
3845
- {
3846
- key: "parseCueOutDuration",
3847
- value: function parseCueOutDuration(value) {
3848
- var num = parseFloat(value.trim());
3849
- if (!Number.isNaN(num)) return num;
3850
- var match = value.match(/(?:^|[,\s])DURATION\s*=\s*([0-9.]+)/i) || value.match(/Duration\s*=\s*([0-9.]+)/i);
3851
- if (match && match[1] != null) {
3852
- var dStr = match[1];
3853
- var d = parseFloat(dStr);
3854
- return Number.isNaN(d) ? void 0 : d;
3855
- }
3856
- return void 0;
3857
- }
3858
- },
3859
- {
3860
- key: "parseCueOutCont",
3861
- value: function parseCueOutCont(value) {
3862
- var res = {};
3863
- var elapsedMatch = value.match(/Elapsed\s*=\s*([0-9.]+)/i);
3864
- var durationMatch = value.match(/Duration\s*=\s*([0-9.]+)/i);
3865
- if (elapsedMatch && elapsedMatch[1] != null) {
3866
- var e = parseFloat(elapsedMatch[1]);
3867
- if (!Number.isNaN(e)) res.elapsed = e;
3868
- }
3869
- if (durationMatch && durationMatch[1] != null) {
3870
- var d = parseFloat(durationMatch[1]);
3871
- if (!Number.isNaN(d)) res.duration = d;
3872
- }
3873
- if (!("elapsed" in res) || !("duration" in res)) {
3874
- var slashMatch = value.match(/([0-9.]+)\s*\/\s*([0-9.]+)/);
3875
- if (slashMatch && slashMatch[1] && slashMatch[2]) {
3876
- var elapsed = parseFloat(slashMatch[1]);
3877
- var duration = parseFloat(slashMatch[2]);
3878
- if (!Number.isNaN(elapsed) && !("elapsed" in res)) res.elapsed = elapsed;
3879
- if (!Number.isNaN(duration) && !("duration" in res)) res.duration = duration;
3880
- }
3881
- }
3882
- if ("elapsed" in res || "duration" in res) return res;
3883
- return void 0;
3884
- }
3885
- },
3886
- {
3887
- key: "parseAttributeList",
3888
- value: function parseAttributeList(value) {
3889
- var attrs = {};
3890
- var regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
3891
- var match;
3892
- while((match = regex.exec(value)) !== null){
3893
- var _match_, _ref, _match_1;
3894
- var key = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : "";
3895
- var rawVal = (_ref = (_match_1 = match[3]) !== null && _match_1 !== void 0 ? _match_1 : match[4]) !== null && _ref !== void 0 ? _ref : "";
3896
- if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
3897
- rawVal = rawVal.slice(1, -1);
3898
- }
3899
- if (key) {
3900
- attrs[key] = rawVal;
3901
- }
3902
- }
3903
- return attrs;
3904
- }
3905
- },
3906
- {
3907
- key: "toNumber",
3908
- value: function toNumber(val) {
3909
- if (val == null) return void 0;
3910
- var n = typeof val === "string" ? parseFloat(val) : Number(val);
3911
- return Number.isNaN(n) ? void 0 : n;
3912
- }
3913
- },
3914
- {
3915
- key: "isManifestBasedMarker",
3916
- value: function isManifestBasedMarker(marker) {
3917
- var raw = marker.raw;
3918
- if (!raw) return false;
3919
- if (raw.tag) {
3920
- var tag = String(raw.tag);
3921
- return tag.includes("EXT-X-CUE-OUT") || tag.includes("EXT-X-CUE-IN") || tag.includes("EXT-X-DATERANGE");
3922
- }
3923
- if (raw.id3) return false;
3924
- if (raw.splice_command_type) return false;
3925
- return false;
3926
- }
3927
- },
3928
- {
3929
- key: "parseScte35Binary",
3930
- value: function parseScte35Binary(data) {
3931
- var BitReader = /*#__PURE__*/ function() {
3932
- function BitReader(buf) {
3933
- _class_call_check(this, BitReader);
3934
- this.buf = buf;
3935
- this.bytePos = 0;
3936
- this.bitPos = 0;
3937
- }
3938
- _create_class(BitReader, [
3939
- {
3940
- key: "readBits",
3941
- value: function readBits(numBits) {
3942
- var result = 0;
3943
- while(numBits > 0){
3944
- if (this.bytePos >= this.buf.length) return result;
3945
- var remainingInByte = 8 - this.bitPos;
3946
- var toRead = Math.min(numBits, remainingInByte);
3947
- var currentByte = this.buf[this.bytePos];
3948
- var shift = remainingInByte - toRead;
3949
- var mask = (1 << toRead) - 1 & 255;
3950
- var bits = currentByte >> shift & mask;
3951
- result = result << toRead | bits;
3952
- this.bitPos += toRead;
3953
- if (this.bitPos >= 8) {
3954
- this.bitPos = 0;
3955
- this.bytePos += 1;
3956
- }
3957
- numBits -= toRead;
3958
- }
3959
- return result >>> 0;
3960
- }
3961
- },
3962
- {
3963
- key: "skipBits",
3964
- value: function skipBits(n) {
3965
- this.readBits(n);
3966
- }
3967
- }
3968
- ]);
3969
- return BitReader;
3970
- }();
3971
- var r = new BitReader(data);
3972
- var tableId = r.readBits(8);
3973
- if (tableId !== 252) return void 0;
3974
- r.readBits(1);
3975
- r.readBits(1);
3976
- r.readBits(2);
3977
- var sectionLength = r.readBits(12);
3978
- r.readBits(8);
3979
- r.readBits(1);
3980
- r.readBits(6);
3981
- var ptsAdjHigh = r.readBits(1);
3982
- var ptsAdjLow = r.readBits(32);
3983
- void ptsAdjHigh;
3984
- void ptsAdjLow;
3985
- r.readBits(8);
3986
- r.readBits(12);
3987
- var spliceCommandLength = r.readBits(12);
3988
- var spliceCommandType = r.readBits(8);
3989
- if (spliceCommandType !== 5) {
3990
- return void 0;
3991
- }
3992
- r.readBits(32);
3993
- var cancel = r.readBits(1) === 1;
3994
- r.readBits(7);
3995
- if (cancel) return void 0;
3996
- var outOfNetwork = r.readBits(1) === 1;
3997
- var programSpliceFlag = r.readBits(1) === 1;
3998
- var durationFlag = r.readBits(1) === 1;
3999
- var spliceImmediateFlag = r.readBits(1) === 1;
4000
- r.readBits(4);
4001
- if (programSpliceFlag && !spliceImmediateFlag) {
4002
- var timeSpecifiedFlag = r.readBits(1) === 1;
4003
- if (timeSpecifiedFlag) {
4004
- r.readBits(6);
4005
- r.readBits(33);
4006
- } else {
4007
- r.readBits(7);
4008
- }
4009
- } else if (!programSpliceFlag) {
4010
- var componentCount = r.readBits(8);
4011
- for(var i = 0; i < componentCount; i++){
4012
- r.readBits(8);
4013
- if (!spliceImmediateFlag) {
4014
- var timeSpecifiedFlag1 = r.readBits(1) === 1;
4015
- if (timeSpecifiedFlag1) {
4016
- r.readBits(6);
4017
- r.readBits(33);
4018
- } else {
4019
- r.readBits(7);
4020
- }
4021
- }
4022
- }
4023
- }
4024
- var durationSeconds = void 0;
4025
- if (durationFlag) {
4026
- r.readBits(6);
4027
- r.readBits(1);
4028
- var high = r.readBits(1);
4029
- var low = r.readBits(32);
4030
- var durationTicks = high * 4294967296 + low;
4031
- durationSeconds = durationTicks / 9e4;
4032
- }
4033
- r.readBits(16);
4034
- r.readBits(8);
4035
- r.readBits(8);
4036
- if (outOfNetwork) {
4037
- var marker = _object_spread_props(_object_spread({
4038
- type: "start"
4039
- }, durationSeconds !== void 0 ? {
4040
- durationSeconds: durationSeconds
4041
- } : {}), {
4042
- raw: {
4043
- splice_command_type: 5
4044
- }
4045
- });
4046
- return marker;
4047
- }
4048
- return void 0;
4049
- }
4050
- },
4051
3493
  {
4052
3494
  key: "initializeTracking",
4053
3495
  value: function initializeTracking() {
@@ -4169,35 +3611,35 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4169
3611
  },
4170
3612
  {
4171
3613
  key: "startAdPrefetch",
4172
- value: function startAdPrefetch(marker, fragmentSn) {
3614
+ value: function startAdPrefetch(durationSeconds, fragmentSn) {
4173
3615
  if (this.config.disableAds) return;
4174
3616
  if (this.pendingAdBreak || this.inAdBreak) {
4175
3617
  return;
4176
3618
  }
4177
- this.pendingAdBreak = _object_spread_props(_object_spread({
4178
- marker: marker
4179
- }, fragmentSn !== void 0 ? {
3619
+ this.pendingAdBreak = _object_spread_props(_object_spread({}, durationSeconds !== void 0 ? {
3620
+ durationSeconds: durationSeconds
3621
+ } : {}, fragmentSn !== void 0 ? {
4180
3622
  detectedAtFragmentSn: fragmentSn
4181
3623
  } : {}), {
4182
3624
  isFetching: false,
4183
3625
  fetchStartTime: Date.now()
4184
3626
  });
4185
- void this.runAdPrefetch(marker);
3627
+ void this.runAdPrefetch(durationSeconds);
4186
3628
  if (this.config.debugAdTiming) {
4187
- console.log("[PREFETCH] Ad break marker registered, multi-ad prefetch started");
3629
+ console.log("[PREFETCH] Ad break registered, multi-ad prefetch started");
4188
3630
  }
4189
3631
  }
4190
3632
  },
4191
3633
  {
4192
3634
  key: "runAdPrefetch",
4193
- value: function runAdPrefetch(marker) {
3635
+ value: function runAdPrefetch(durationSeconds) {
4194
3636
  return _async_to_generator(function() {
4195
- var _this, _marker_durationSeconds, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token;
3637
+ var _this, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, unused1, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token, unused2, err;
4196
3638
  return _ts_generator(this, function(_state) {
4197
3639
  switch(_state.label){
4198
3640
  case 0:
4199
3641
  _this = this;
4200
- durSec = (_marker_durationSeconds = marker.durationSeconds) !== null && _marker_durationSeconds !== void 0 ? _marker_durationSeconds : 60;
3642
+ durSec = durationSeconds !== null && durationSeconds !== void 0 ? durationSeconds : 60;
4201
3643
  context = {
4202
3644
  breakDurationSec: durSec,
4203
3645
  remainingBreakSec: durSec
@@ -4247,14 +3689,43 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4247
3689
  console.log("[PREFETCH] Ad duration=".concat(adDurationSec, "s, break=").concat(durSec, "s → ").concat(estimatedCount, " ad(s) needed"));
4248
3690
  }
4249
3691
  firstToken = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4250
- this.preloadedTokens.push(firstToken);
4251
- void this.adLayer.preloadAd(firstBids, firstToken);
3692
+ _state.label = 5;
3693
+ case 5:
3694
+ _state.trys.push([
3695
+ 5,
3696
+ 7,
3697
+ ,
3698
+ 8
3699
+ ]);
3700
+ return [
3701
+ 4,
3702
+ this.adLayer.preloadAd(firstBids, firstToken)
3703
+ ];
3704
+ case 6:
3705
+ _state.sent();
3706
+ if (!this.inAdBreak) {
3707
+ this.preloadedTokens.push(firstToken);
3708
+ if (this.config.debugAdTiming) {
3709
+ console.log("[PREFETCH] First ad preloaded and queued, token=".concat(firstToken));
3710
+ }
3711
+ }
3712
+ return [
3713
+ 3,
3714
+ 8
3715
+ ];
3716
+ case 7:
3717
+ unused1 = _state.sent();
4252
3718
  if (this.config.debugAdTiming) {
4253
- console.log("[PREFETCH] First ad preloading, token=".concat(firstToken));
3719
+ console.warn("[PREFETCH] First ad preload failed, token=".concat(firstToken));
4254
3720
  }
3721
+ return [
3722
+ 3,
3723
+ 8
3724
+ ];
3725
+ case 8:
4255
3726
  if (!(estimatedCount > 1)) return [
4256
3727
  3,
4257
- 6
3728
+ 19
4258
3729
  ];
4259
3730
  remaining = Array.from({
4260
3731
  length: estimatedCount - 1
@@ -4276,38 +3747,100 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4276
3747
  4,
4277
3748
  Promise.all(remaining)
4278
3749
  ];
4279
- case 5:
3750
+ case 9:
4280
3751
  results = _state.sent();
4281
3752
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3753
+ _state.label = 10;
3754
+ case 10:
3755
+ _state.trys.push([
3756
+ 10,
3757
+ 17,
3758
+ 18,
3759
+ 19
3760
+ ]);
3761
+ _iterator = results[Symbol.iterator]();
3762
+ _state.label = 11;
3763
+ case 11:
3764
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
3765
+ 3,
3766
+ 16
3767
+ ];
3768
+ result = _step.value;
3769
+ if (this.inAdBreak) return [
3770
+ 3,
3771
+ 16
3772
+ ];
3773
+ if (!(result.ok && result.value.length > 0)) return [
3774
+ 3,
3775
+ 15
3776
+ ];
3777
+ token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
3778
+ _state.label = 12;
3779
+ case 12:
3780
+ _state.trys.push([
3781
+ 12,
3782
+ 14,
3783
+ ,
3784
+ 15
3785
+ ]);
3786
+ return [
3787
+ 4,
3788
+ this.adLayer.preloadAd(result.value, token)
3789
+ ];
3790
+ case 13:
3791
+ _state.sent();
3792
+ if (!this.inAdBreak) {
3793
+ this.preloadedTokens.push(token);
3794
+ if (this.config.debugAdTiming) {
3795
+ console.log("[PREFETCH] Additional ad preloaded and queued, token=".concat(token));
3796
+ }
3797
+ }
3798
+ return [
3799
+ 3,
3800
+ 15
3801
+ ];
3802
+ case 14:
3803
+ unused2 = _state.sent();
3804
+ if (this.config.debugAdTiming) {
3805
+ console.warn("[PREFETCH] Additional ad preload failed, token=".concat(token));
3806
+ }
3807
+ return [
3808
+ 3,
3809
+ 15
3810
+ ];
3811
+ case 15:
3812
+ _iteratorNormalCompletion = true;
3813
+ return [
3814
+ 3,
3815
+ 11
3816
+ ];
3817
+ case 16:
3818
+ return [
3819
+ 3,
3820
+ 19
3821
+ ];
3822
+ case 17:
3823
+ err = _state.sent();
3824
+ _didIteratorError = true;
3825
+ _iteratorError = err;
3826
+ return [
3827
+ 3,
3828
+ 19
3829
+ ];
3830
+ case 18:
4282
3831
  try {
4283
- for(_iterator = results[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
4284
- result = _step.value;
4285
- if (this.inAdBreak) break;
4286
- if (result.ok && result.value.length > 0) {
4287
- token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4288
- this.preloadedTokens.push(token);
4289
- void this.adLayer.preloadAd(result.value, token);
4290
- if (this.config.debugAdTiming) {
4291
- console.log("[PREFETCH] Additional ad preloading, token=".concat(token));
4292
- }
4293
- }
3832
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3833
+ _iterator.return();
4294
3834
  }
4295
- } catch (err) {
4296
- _didIteratorError = true;
4297
- _iteratorError = err;
4298
3835
  } finally{
4299
- try {
4300
- if (!_iteratorNormalCompletion && _iterator.return != null) {
4301
- _iterator.return();
4302
- }
4303
- } finally{
4304
- if (_didIteratorError) {
4305
- throw _iteratorError;
4306
- }
3836
+ if (_didIteratorError) {
3837
+ throw _iteratorError;
4307
3838
  }
4308
3839
  }
4309
- _state.label = 6;
4310
- case 6:
3840
+ return [
3841
+ 7
3842
+ ];
3843
+ case 19:
4311
3844
  if (this.config.debugAdTiming) {
4312
3845
  console.log("[PREFETCH] Pre-fetch complete: ".concat(this.preloadedTokens.length, " ad(s) queued"));
4313
3846
  }
@@ -4472,15 +4005,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4472
4005
  if (this.config.debugAdTiming) {
4473
4006
  console.log('[StormcloudVideoPlayer] Ad insertion segment "'.concat(segmentName, '" found in manifest — starting pre-fetch'));
4474
4007
  }
4475
- var marker = {
4476
- type: "start",
4477
- durationSeconds: 60,
4478
- raw: {
4479
- apiInsertionPoint: this.lastAdInsertionPoint,
4480
- earlyDetection: true
4481
- }
4482
- };
4483
- this.startAdPrefetch(marker, frag === null || frag === void 0 ? void 0 : frag.sn);
4008
+ this.startAdPrefetch(60, frag === null || frag === void 0 ? void 0 : frag.sn);
4484
4009
  return;
4485
4010
  }
4486
4011
  }
@@ -4518,8 +4043,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4518
4043
  {
4519
4044
  key: "fragmentMatchesSegment",
4520
4045
  value: function fragmentMatchesSegment(frag, segmentName) {
4521
- var url = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4522
- return url.endsWith(segmentName) || url.includes("/" + segmentName);
4046
+ var _rawUrl_split_;
4047
+ var rawUrl = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4048
+ var url = (_rawUrl_split_ = rawUrl.split("?")[0]) !== null && _rawUrl_split_ !== void 0 ? _rawUrl_split_ : "";
4049
+ var name = segmentName.startsWith("/") ? segmentName : "/" + segmentName;
4050
+ return url.endsWith(name) || url.includes(name);
4523
4051
  }
4524
4052
  },
4525
4053
  {
@@ -4856,13 +4384,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4856
4384
  },
4857
4385
  {
4858
4386
  key: "handleAdStart",
4859
- value: function handleAdStart(_marker) {
4387
+ value: function handleAdStart(durationSeconds) {
4860
4388
  return _async_to_generator(function() {
4861
- var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4389
+ var _this_savedMutedStateBeforeAd, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4862
4390
  return _ts_generator(this, function(_state) {
4863
4391
  switch(_state.label){
4864
4392
  case 0:
4865
- adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : void 0;
4393
+ adBreakDurationMs = durationSeconds != null ? durationSeconds * 1e3 : void 0;
4866
4394
  if (this.config.debugAdTiming) {
4867
4395
  mode = this.isLiveStream ? "LIVE" : "VOD";
4868
4396
  console.log("[CONTINUOUS-FETCH] \uD83D\uDCFA ".concat(mode, " MODE: Target duration=").concat(adBreakDurationMs, "ms"));
@@ -4873,13 +4401,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4873
4401
  this.pendingNextAdBids = null;
4874
4402
  this.isShowingPlaceholder = false;
4875
4403
  this.totalAdRequestsInBreak = 0;
4876
- if (this.savedMutedStateBeforeScte == null && !this.video.muted) {
4877
- this.savedMutedStateBeforeScte = {
4404
+ if (this.savedMutedStateBeforeAd == null && !this.video.muted) {
4405
+ this.savedMutedStateBeforeAd = {
4878
4406
  muted: false,
4879
4407
  volume: this.video.volume
4880
4408
  };
4881
4409
  }
4882
- state = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) !== null && _this_savedMutedStateBeforeScte !== void 0 ? _this_savedMutedStateBeforeScte : {
4410
+ state = (_this_savedMutedStateBeforeAd = this.savedMutedStateBeforeAd) !== null && _this_savedMutedStateBeforeAd !== void 0 ? _this_savedMutedStateBeforeAd : {
4883
4411
  muted: this.video.muted,
4884
4412
  volume: this.video.volume
4885
4413
  };
@@ -4906,6 +4434,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4906
4434
  if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
4907
4435
  this.expectedAdBreakDurationMs = adBreakDurationMs;
4908
4436
  }
4437
+ if (this.expectedAdBreakDurationMs != null) {
4438
+ this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4439
+ }
4909
4440
  this.clearPendingAdBreak();
4910
4441
  adBreakToken = Date.now();
4911
4442
  this.activeAdRequestToken = adBreakToken;
@@ -5404,49 +4935,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5404
4935
  this.handleAdPodComplete();
5405
4936
  }
5406
4937
  },
5407
- {
5408
- key: "scheduleAdStartIn",
5409
- value: function scheduleAdStartIn(delayMs) {
5410
- var _this = this;
5411
- this.clearAdStartTimer();
5412
- var ms = Math.max(0, Math.floor(delayMs));
5413
- if (ms === 0) {
5414
- this.handleAdStart({
5415
- type: "start"
5416
- }).catch(function() {});
5417
- return;
5418
- }
5419
- this.adStartTimerId = window.setTimeout(function() {
5420
- _this.handleAdStart({
5421
- type: "start"
5422
- }).catch(function() {});
5423
- }, ms);
5424
- }
5425
- },
5426
- {
5427
- key: "clearAdStartTimer",
5428
- value: function clearAdStartTimer() {
5429
- if (this.adStartTimerId != null) {
5430
- clearTimeout(this.adStartTimerId);
5431
- this.adStartTimerId = void 0;
5432
- }
5433
- }
5434
- },
5435
- {
5436
- key: "updatePtsDrift",
5437
- value: function updatePtsDrift(ptsSecondsSample) {
5438
- var sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;
5439
- if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;
5440
- var alpha = 0.1;
5441
- this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
5442
- }
5443
- },
5444
4938
  {
5445
4939
  key: "handleAdPodComplete",
5446
4940
  value: function handleAdPodComplete() {
5447
4941
  var _this = this;
5448
4942
  var _ref, _ref1;
5449
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
4943
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
5450
4944
  if (this.config.debugAdTiming) {
5451
4945
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
5452
4946
  }
@@ -5468,7 +4962,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5468
4962
  this.inAdBreak = false;
5469
4963
  this.expectedAdBreakDurationMs = void 0;
5470
4964
  this.currentAdBreakStartWallClockMs = void 0;
5471
- this.clearAdStartTimer();
5472
4965
  this.clearAdStopTimer();
5473
4966
  this.adPodQueue = [];
5474
4967
  this.showAds = false;
@@ -5476,8 +4969,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5476
4969
  this.totalAdsInBreak = 0;
5477
4970
  this.totalAdRequestsInBreak = 0;
5478
4971
  this.consecutiveFailures = 0;
5479
- 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();
5480
- 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();
4972
+ 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();
4973
+ 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();
5481
4974
  this.adLayer.updateOriginalMutedState(restoredMuted, restoredVolume);
5482
4975
  this.adLayer.stop().catch(function() {});
5483
4976
  if (this.video.muted !== restoredMuted) {
@@ -5586,7 +5079,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5586
5079
  }, delay);
5587
5080
  });
5588
5081
  }
5589
- this.savedMutedStateBeforeScte = null;
5082
+ this.savedMutedStateBeforeAd = null;
5590
5083
  }
5591
5084
  },
5592
5085
  {
@@ -5736,19 +5229,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5736
5229
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
5737
5230
  }
5738
5231
  },
5739
- {
5740
- key: "pushScteMarker",
5741
- value: function pushScteMarker(marker) {
5742
- if (!this.config.debugAdTiming) return;
5743
- this.scteMarkerHistory.push({
5744
- timestampMs: Date.now(),
5745
- marker: marker
5746
- });
5747
- if (this.scteMarkerHistory.length > DEBUG_HISTORY_LIMIT) {
5748
- this.scteMarkerHistory = this.scteMarkerHistory.slice(-DEBUG_HISTORY_LIMIT);
5749
- }
5750
- }
5751
- },
5752
5232
  {
5753
5233
  key: "pushDebugLog",
5754
5234
  value: function pushDebugLog(level, category, message, details) {
@@ -5766,23 +5246,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5766
5246
  }
5767
5247
  }
5768
5248
  },
5769
- {
5770
- key: "getRecentScteMarkers",
5771
- value: function getRecentScteMarkers() {
5772
- return this.scteMarkerHistory.map(function(entry) {
5773
- return _object_spread({
5774
- timestampMs: entry.timestampMs,
5775
- type: entry.marker.type
5776
- }, entry.marker.ptsSeconds !== void 0 ? {
5777
- ptsSeconds: entry.marker.ptsSeconds
5778
- } : {}, entry.marker.durationSeconds !== void 0 ? {
5779
- durationSeconds: entry.marker.durationSeconds
5780
- } : {}, entry.marker.raw !== void 0 ? {
5781
- raw: entry.marker.raw
5782
- } : {});
5783
- });
5784
- }
5785
- },
5786
5249
  {
5787
5250
  key: "pushAdInsertionDebug",
5788
5251
  value: function pushAdInsertionDebug(event, segmentName, opts) {
@@ -6079,7 +5542,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6079
5542
  this.clearAdInsertionOffsetTimer();
6080
5543
  this.stopContinuousFetching();
6081
5544
  this.stopFillerBreakTimer();
6082
- this.clearAdStartTimer();
6083
5545
  this.clearAdStopTimer();
6084
5546
  this.clearAdFailsafeTimer();
6085
5547
  this.clearAdRequestWatchdog();
@@ -6107,7 +5569,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6107
5569
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
6108
5570
  this.consecutiveFailures = 0;
6109
5571
  this.debugLogEntries = [];
6110
- this.scteMarkerHistory = [];
6111
5572
  this.adInsertionDebugHistory = [];
6112
5573
  }
6113
5574
  }