stormcloud-video-player 0.8.7 → 0.8.9

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.
@@ -76,6 +76,7 @@ declare class StormcloudVideoPlayer {
76
76
  private preloadPoolActive;
77
77
  private preloadPoolLoopRunning;
78
78
  private adDetectSentForCurrentBreak;
79
+ private adBreakEpoch;
79
80
  private palNonce;
80
81
  private palPlaybackStarted;
81
82
  private readonly streamCorrelator;
@@ -202,6 +203,7 @@ declare class StormcloudVideoPlayer {
202
203
  setMuted(muted: boolean): void;
203
204
  setVolume(volume: number): void;
204
205
  getVolume(): number;
206
+ private getAdAudioVolume;
205
207
  isFullscreen(): boolean;
206
208
  isLive(): boolean;
207
209
  get videoElement(): HTMLVideoElement;
@@ -866,7 +866,6 @@ function createHlsAdPlayer(contentVideo, options) {
866
866
  adPlaying = false;
867
867
  setAdPlayingFlag(false);
868
868
  contentVideo.muted = true;
869
- contentVideo.volume = 0;
870
869
  if (adContainerEl) {
871
870
  adContainerEl.style.display = "none";
872
871
  adContainerEl.style.pointerEvents = "none";
@@ -886,7 +885,6 @@ function createHlsAdPlayer(contentVideo, options) {
886
885
  adPlaying = false;
887
886
  setAdPlayingFlag(false);
888
887
  contentVideo.muted = true;
889
- contentVideo.volume = 0;
890
888
  if (adContainerEl) {
891
889
  adContainerEl.style.display = "none";
892
890
  adContainerEl.style.pointerEvents = "none";
@@ -991,7 +989,7 @@ function createHlsAdPlayer(contentVideo, options) {
991
989
  },
992
990
  play: function play() {
993
991
  return _async_to_generator(function() {
994
- var contentVolume, adVolume, mediaFile, isHlsAd;
992
+ var contentVolume, mediaFile, isHlsAd;
995
993
  return _ts_generator(this, function(_state) {
996
994
  if (!currentAd) {
997
995
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -1025,13 +1023,11 @@ function createHlsAdPlayer(contentVideo, options) {
1025
1023
  }
1026
1024
  console.log("[HlsAdPlayer] FORCE MUTING main video");
1027
1025
  contentVideo.muted = true;
1028
- contentVideo.volume = 0;
1029
1026
  adPlaying = true;
1030
1027
  setAdPlayingFlag(true);
1031
1028
  if (adVideoElement) {
1032
- adVolume = originalMutedState ? 0 : originalVolume;
1033
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1034
- adVideoElement.muted = false;
1029
+ adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));
1030
+ adVideoElement.muted = originalMutedState;
1035
1031
  console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
1036
1032
  }
1037
1033
  if (adContainerEl) {
@@ -1139,8 +1135,8 @@ function createHlsAdPlayer(contentVideo, options) {
1139
1135
  setAdPlayingFlag(false);
1140
1136
  previousMutedState = contentVideo.muted;
1141
1137
  contentVideo.muted = originalMutedState;
1142
- contentVideo.volume = originalMutedState ? 0 : originalVolume;
1143
- console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState));
1138
+ contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1139
+ console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1144
1140
  if (adContainerEl) {
1145
1141
  adContainerEl.style.display = "none";
1146
1142
  adContainerEl.style.pointerEvents = "none";
@@ -1195,7 +1191,7 @@ function createHlsAdPlayer(contentVideo, options) {
1195
1191
  adPlaying = false;
1196
1192
  setAdPlayingFlag(false);
1197
1193
  contentVideo.muted = originalMutedState;
1198
- contentVideo.volume = originalMutedState ? 0 : originalVolume;
1194
+ contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1199
1195
  if (adHls) {
1200
1196
  adHls.destroy();
1201
1197
  adHls = void 0;
@@ -1251,7 +1247,9 @@ function createHlsAdPlayer(contentVideo, options) {
1251
1247
  },
1252
1248
  setAdVolume: function setAdVolume(volume) {
1253
1249
  if (adVideoElement && adPlaying) {
1254
- adVideoElement.volume = Math.max(0, Math.min(1, volume));
1250
+ var clamped = Math.max(0, Math.min(1, volume));
1251
+ adVideoElement.volume = clamped;
1252
+ adVideoElement.muted = clamped === 0;
1255
1253
  }
1256
1254
  },
1257
1255
  getAdVolume: function getAdVolume() {
@@ -2704,6 +2702,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2704
2702
  this.preloadPoolActive = false;
2705
2703
  this.preloadPoolLoopRunning = false;
2706
2704
  this.adDetectSentForCurrentBreak = false;
2705
+ this.adBreakEpoch = 0;
2707
2706
  this.palPlaybackStarted = false;
2708
2707
  this.streamCorrelator = generateCorrelator();
2709
2708
  this.consentSignals = {};
@@ -3246,10 +3245,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3246
3245
  console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
3247
3246
  }
3248
3247
  }
3249
- var currentMuted = _this.video.muted;
3250
- var currentVolume = _this.video.volume;
3251
- var adVolume = currentMuted ? 0 : currentVolume;
3252
- _this.adPlayer.setAdVolume(adVolume);
3248
+ _this.adPlayer.setAdVolume(_this.getAdAudioVolume());
3253
3249
  if (_this.isShowingPlaceholder) {
3254
3250
  if (_this.config.debugAdTiming) {
3255
3251
  console.log("[StormcloudVideoPlayer] Hiding placeholder - new ads starting");
@@ -3266,7 +3262,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3266
3262
  }).catch(function() {});
3267
3263
  if (!_this.video.muted) {
3268
3264
  _this.video.muted = true;
3269
- _this.video.volume = 0;
3270
3265
  if (_this.config.debugAdTiming) {
3271
3266
  console.log("[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)");
3272
3267
  }
@@ -3314,7 +3309,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3314
3309
  try {
3315
3310
  this.adPlayer.destroy();
3316
3311
  this.video.muted = true;
3317
- this.video.volume = 0;
3318
3312
  } catch (error) {
3319
3313
  if (this.config.debugAdTiming) {
3320
3314
  console.warn("[StormcloudVideoPlayer] Error destroying old AdController:", error);
@@ -3373,7 +3367,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3373
3367
  }
3374
3368
  if (!this.video.muted) {
3375
3369
  this.video.muted = true;
3376
- this.video.volume = 0;
3377
3370
  if (this.config.debugAdTiming) {
3378
3371
  console.log("[StormcloudVideoPlayer] Muted video when showing placeholder");
3379
3372
  }
@@ -3995,7 +3988,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3995
3988
  if (marker.type === "end") {
3996
3989
  if (!this.video.muted) {
3997
3990
  this.video.muted = true;
3998
- this.video.volume = 0;
3999
3991
  if (this.config.debugAdTiming) {
4000
3992
  console.log("[StormcloudVideoPlayer] Muted video on SCTE end marker");
4001
3993
  }
@@ -4033,13 +4025,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4033
4025
  {
4034
4026
  key: "startScte35AdBreak",
4035
4027
  value: function startScte35AdBreak(marker, cueKey, durationMs) {
4036
- if (!this.video.muted) {
4037
- this.video.muted = true;
4038
- this.video.volume = 0;
4039
- if (this.config.debugAdTiming) {
4040
- console.log("[StormcloudVideoPlayer] Muted video on SCTE start marker");
4041
- }
4042
- }
4043
4028
  this.inAdBreak = true;
4044
4029
  this.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.pendingScte35CueKey;
4045
4030
  this.scheduledScte35BreakKey = void 0;
@@ -5265,7 +5250,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5265
5250
  key: "preloadAdIntoPool",
5266
5251
  value: function preloadAdIntoPool(vastUrl) {
5267
5252
  return _async_to_generator(function() {
5268
- var _this, loadPromise;
5253
+ var _this, epoch, loadPromise;
5269
5254
  return _ts_generator(this, function(_state) {
5270
5255
  _this = this;
5271
5256
  if (this.isGamInCooldown()) {
@@ -5291,6 +5276,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5291
5276
  if (this.config.debugAdTiming) {
5292
5277
  console.log("[PRELOAD-POOL] \uD83D\uDCE5 Preloading ad into pool: ".concat(vastUrl));
5293
5278
  }
5279
+ epoch = this.adBreakEpoch;
5294
5280
  loadPromise = function() {
5295
5281
  return _async_to_generator(function() {
5296
5282
  var _this, hasAdError, adErrorPayload, errorListenerCleanup, continueLiveStreamDuringAds, preloadAd, errorListener, isNoFill, poolEntry, lateErrorListener, error;
@@ -5368,6 +5354,20 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5368
5354
  2
5369
5355
  ];
5370
5356
  }
5357
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch) {
5358
+ if (this.config.debugAdTiming) {
5359
+ console.log("[PRELOAD-POOL] \uD83D\uDEAB Discarding preloaded ad - break ended during fetch");
5360
+ }
5361
+ if (errorListenerCleanup) {
5362
+ errorListenerCleanup();
5363
+ }
5364
+ try {
5365
+ preloadAd.destroy();
5366
+ } catch (unused) {}
5367
+ return [
5368
+ 2
5369
+ ];
5370
+ }
5371
5371
  poolEntry = {
5372
5372
  vastUrl: vastUrl,
5373
5373
  adController: preloadAd,
@@ -5439,7 +5439,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5439
5439
  key: "preloadPoolLoop",
5440
5440
  value: function preloadPoolLoop(baseVastUrl) {
5441
5441
  return _async_to_generator(function() {
5442
- var remaining, newUrls, newUrl;
5442
+ var epoch, remaining, newUrls, newUrl;
5443
5443
  return _ts_generator(this, function(_state) {
5444
5444
  switch(_state.label){
5445
5445
  case 0:
@@ -5449,12 +5449,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5449
5449
  ];
5450
5450
  }
5451
5451
  this.preloadPoolLoopRunning = true;
5452
+ epoch = this.adBreakEpoch;
5452
5453
  if (this.config.debugAdTiming) {
5453
5454
  console.log("[PRELOAD-POOL] \uD83D\uDD04 Starting continuous preload loop");
5454
5455
  }
5455
5456
  _state.label = 1;
5456
5457
  case 1:
5457
- if (!this.preloadPoolActive) return [
5458
+ if (!(this.preloadPoolActive && epoch === this.adBreakEpoch)) return [
5458
5459
  3,
5459
5460
  10
5460
5461
  ];
@@ -5499,7 +5500,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5499
5500
  3,
5500
5501
  8
5501
5502
  ];
5502
- if (!this.preloadPoolActive || this.isGamInCooldown()) {
5503
+ if (!this.preloadPoolActive || epoch !== this.adBreakEpoch || this.isGamInCooldown()) {
5503
5504
  return [
5504
5505
  3,
5505
5506
  8
@@ -5626,7 +5627,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5626
5627
  key: "handleAdStart",
5627
5628
  value: function handleAdStart(_marker) {
5628
5629
  return _async_to_generator(function() {
5629
- var scheduled, tags, baseVastUrl, adBreakDurationMs, mode, currentMuted, currentVolume, firstAdUrl, usePreloadedAd, preloadedController, preloaded, firstAdUrlArray, adVolume, adVolume1, error, fallbackPreloaded, adVolume2, fallbackError;
5630
+ var scheduled, tags, baseVastUrl, adBreakDurationMs, mode, currentMuted, currentVolume, firstAdUrl, usePreloadedAd, preloadedController, preloaded, firstAdUrlArray, preservedMuted, preservedVolume, adVolume, adVolume1, error, fallbackPreloaded, preservedMuted1, preservedVolume1, adVolume2, fallbackError;
5630
5631
  return _ts_generator(this, function(_state) {
5631
5632
  switch(_state.label){
5632
5633
  case 0:
@@ -5666,7 +5667,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5666
5667
  this.adPlayer.updateOriginalMutedState(currentMuted, currentVolume);
5667
5668
  if (!this.video.muted) {
5668
5669
  this.video.muted = true;
5669
- this.video.volume = 0;
5670
5670
  if (this.config.debugAdTiming) {
5671
5671
  console.log("[StormcloudVideoPlayer] Muted video in handleAdStart");
5672
5672
  }
@@ -5736,10 +5736,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5736
5736
  3,
5737
5737
  3
5738
5738
  ];
5739
+ preservedMuted = this.adPlayer.getOriginalMutedState();
5740
+ preservedVolume = this.adPlayer.getOriginalVolume();
5739
5741
  this.adPlayer.destroy();
5740
5742
  this.video.muted = true;
5741
- this.video.volume = 0;
5742
5743
  this.adPlayer = preloadedController;
5744
+ this.adPlayer.updateOriginalMutedState(preservedMuted, preservedVolume);
5743
5745
  this.attachImaEventListeners();
5744
5746
  if (this.config.debugAdTiming) {
5745
5747
  console.log("[CONTINUOUS-FETCH] \u2705 Using preloaded ad, resuming and starting playback immediately (no request delay!)");
@@ -5837,11 +5839,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5837
5839
  ,
5838
5840
  12
5839
5841
  ]);
5842
+ preservedMuted1 = this.adPlayer.getOriginalMutedState();
5843
+ preservedVolume1 = this.adPlayer.getOriginalVolume();
5840
5844
  this.adPlayer.destroy();
5841
5845
  this.video.muted = true;
5842
- this.video.volume = 0;
5843
5846
  this.adPlayer = fallbackPreloaded.adController;
5844
5847
  this.attachImaEventListeners();
5848
+ this.adPlayer.updateOriginalMutedState(preservedMuted1, preservedVolume1);
5845
5849
  this.adPlayer.resume();
5846
5850
  this.consecutiveFailures = 0;
5847
5851
  this.currentAdIndex++;
@@ -5929,7 +5933,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5929
5933
  key: "continuousFetchLoop",
5930
5934
  value: function continuousFetchLoop(baseVastUrl) {
5931
5935
  return _async_to_generator(function() {
5932
- var _this, _loop, _ret;
5936
+ var _this, _loop, epoch, _ret;
5933
5937
  return _ts_generator(this, function(_state) {
5934
5938
  switch(_state.label){
5935
5939
  case 0:
@@ -6039,9 +6043,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6039
6043
  }
6040
6044
  });
6041
6045
  };
6046
+ epoch = this.adBreakEpoch;
6042
6047
  _state.label = 1;
6043
6048
  case 1:
6044
- if (!(this.continuousFetchingActive && this.inAdBreak)) return [
6049
+ if (!(this.continuousFetchingActive && this.inAdBreak && epoch === this.adBreakEpoch)) return [
6045
6050
  3,
6046
6051
  3
6047
6052
  ];
@@ -6090,10 +6095,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6090
6095
  key: "tryNextAvailableAdWithRateLimit",
6091
6096
  value: function tryNextAvailableAdWithRateLimit() {
6092
6097
  return _async_to_generator(function() {
6093
- var backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6098
+ var epoch, backoffMultiplier, backoffDelay, effectiveMinInterval, timeSinceLastRequest, waitTime;
6094
6099
  return _ts_generator(this, function(_state) {
6095
6100
  switch(_state.label){
6096
6101
  case 0:
6102
+ if (!this.inAdBreak) {
6103
+ return [
6104
+ 2
6105
+ ];
6106
+ }
6107
+ epoch = this.adBreakEpoch;
6097
6108
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
6098
6109
  if (this.config.debugAdTiming) {
6099
6110
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break gracefully"));
@@ -6125,6 +6136,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6125
6136
  _state.sent();
6126
6137
  _state.label = 2;
6127
6138
  case 2:
6139
+ if (!this.inAdBreak || epoch !== this.adBreakEpoch) {
6140
+ return [
6141
+ 2
6142
+ ];
6143
+ }
6128
6144
  return [
6129
6145
  2,
6130
6146
  this.tryNextAvailableAd(0)
@@ -6139,10 +6155,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6139
6155
  value: function tryNextAvailableAd() {
6140
6156
  var retryCount = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
6141
6157
  return _async_to_generator(function() {
6142
- var remaining, preloaded, currentMuted, currentVolume, adVolume, error, nextAdUrl, currentMuted1, currentVolume1, error1, errorMessage, maxRetries;
6158
+ var remaining, preloaded, preservedMuted, preservedVolume, error, nextAdUrl, error1, errorMessage, maxRetries;
6143
6159
  return _ts_generator(this, function(_state) {
6144
6160
  switch(_state.label){
6145
6161
  case 0:
6162
+ if (!this.inAdBreak) {
6163
+ return [
6164
+ 2
6165
+ ];
6166
+ }
6146
6167
  remaining = this.getRemainingAdMs();
6147
6168
  if (remaining <= 500) {
6148
6169
  if (this.config.debugAdTiming) {
@@ -6193,11 +6214,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6193
6214
  ,
6194
6215
  4
6195
6216
  ]);
6217
+ preservedMuted = this.adPlayer.getOriginalMutedState();
6218
+ preservedVolume = this.adPlayer.getOriginalVolume();
6196
6219
  this.adPlayer.destroy();
6197
6220
  this.video.muted = true;
6198
- this.video.volume = 0;
6199
6221
  this.adPlayer = preloaded.adController;
6200
6222
  this.attachImaEventListeners();
6223
+ this.adPlayer.updateOriginalMutedState(preservedMuted, preservedVolume);
6201
6224
  this.adPlayer.resume();
6202
6225
  this.currentAdIndex++;
6203
6226
  this.totalAdRequestsInBreak++;
@@ -6211,10 +6234,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6211
6234
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6212
6235
  this.scheduleAdStopCountdown(this.getRemainingAdMs());
6213
6236
  }
6214
- currentMuted = this.video.muted;
6215
- currentVolume = this.video.volume;
6216
- adVolume = currentMuted ? 0 : currentVolume;
6217
- this.adPlayer.setAdVolume(adVolume);
6237
+ this.adPlayer.setAdVolume(this.getAdAudioVolume());
6218
6238
  this.consecutiveFailures = 0;
6219
6239
  return [
6220
6240
  2
@@ -6261,9 +6281,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6261
6281
  if (this.config.debugAdTiming) {
6262
6282
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAC Requesting next ad via HLS ad player (".concat(this.currentAdIndex + 1, "/").concat(this.totalAdsInBreak, ", ").concat(this.adRequestQueue.length, " remaining in queue)"));
6263
6283
  }
6264
- currentMuted1 = this.video.muted;
6265
- currentVolume1 = this.video.volume;
6266
- this.adPlayer.updateOriginalMutedState(currentMuted1, currentVolume1);
6267
6284
  this.currentAdIndex++;
6268
6285
  this.totalAdRequestsInBreak++;
6269
6286
  this.lastAdRequestTime = Date.now();
@@ -6356,7 +6373,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6356
6373
  key: "showPlaceholderAndWaitForAds",
6357
6374
  value: function showPlaceholderAndWaitForAds() {
6358
6375
  return _async_to_generator(function() {
6359
- var remaining, waitTime, checkInterval, maxChecks, i, nextAdUrl, currentMuted, currentVolume, error, errorMessage;
6376
+ var remaining, waitTime, checkInterval, maxChecks, i, nextAdUrl, error, errorMessage;
6360
6377
  return _ts_generator(this, function(_state) {
6361
6378
  switch(_state.label){
6362
6379
  case 0:
@@ -6452,9 +6469,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6452
6469
  }
6453
6470
  this.isShowingPlaceholder = false;
6454
6471
  this.adPlayer.hidePlaceholder();
6455
- currentMuted = this.video.muted;
6456
- currentVolume = this.video.volume;
6457
- this.adPlayer.updateOriginalMutedState(currentMuted, currentVolume);
6458
6472
  this.currentAdIndex++;
6459
6473
  this.totalAdRequestsInBreak++;
6460
6474
  this.lastAdRequestTime = Date.now();
@@ -6904,7 +6918,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6904
6918
  key: "playSingleAd",
6905
6919
  value: function playSingleAd(vastTagUrl) {
6906
6920
  return _async_to_generator(function() {
6907
- var requestToken, currentMuted, currentVolume, adVolume, playError, preloadedFallback, currentMuted1, currentVolume1, adVolume1, fallbackError, error, errorMessage, preloadedFallback1, currentMuted2, currentVolume2, adVolume2, fallbackError1;
6921
+ var requestToken, playError, preloadedFallback, preservedMuted, preservedVolume, fallbackError, error, errorMessage, preloadedFallback1, preservedMuted1, preservedVolume1, fallbackError1;
6908
6922
  return _ts_generator(this, function(_state) {
6909
6923
  switch(_state.label){
6910
6924
  case 0:
@@ -6991,10 +7005,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6991
7005
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6992
7006
  this.scheduleAdStopCountdown(this.getRemainingAdMs());
6993
7007
  }
6994
- currentMuted = this.video.muted;
6995
- currentVolume = this.video.volume;
6996
- adVolume = currentMuted ? 0 : currentVolume;
6997
- this.adPlayer.setAdVolume(adVolume);
7008
+ this.adPlayer.setAdVolume(this.getAdAudioVolume());
6998
7009
  this.consecutiveFailures = 0;
6999
7010
  this.temporaryFailureUrls.delete(vastTagUrl);
7000
7011
  return [
@@ -7023,11 +7034,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7023
7034
  10
7024
7035
  ]);
7025
7036
  this.clearAdFailsafeTimer();
7037
+ preservedMuted = this.adPlayer.getOriginalMutedState();
7038
+ preservedVolume = this.adPlayer.getOriginalVolume();
7026
7039
  this.adPlayer.destroy();
7027
7040
  this.video.muted = true;
7028
- this.video.volume = 0;
7029
7041
  this.adPlayer = preloadedFallback.adController;
7030
7042
  this.attachImaEventListeners();
7043
+ this.adPlayer.updateOriginalMutedState(preservedMuted, preservedVolume);
7031
7044
  this.adPlayer.resume();
7032
7045
  this.consecutiveFailures = 0;
7033
7046
  this.currentAdIndex++;
@@ -7041,10 +7054,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7041
7054
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7042
7055
  this.scheduleAdStopCountdown(this.getRemainingAdMs());
7043
7056
  }
7044
- currentMuted1 = this.video.muted;
7045
- currentVolume1 = this.video.volume;
7046
- adVolume1 = currentMuted1 ? 0 : currentVolume1;
7047
- this.adPlayer.setAdVolume(adVolume1);
7057
+ this.adPlayer.setAdVolume(this.getAdAudioVolume());
7048
7058
  return [
7049
7059
  2
7050
7060
  ];
@@ -7103,11 +7113,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7103
7113
  ]);
7104
7114
  this.clearAdRequestWatchdog();
7105
7115
  this.clearAdFailsafeTimer();
7116
+ preservedMuted1 = this.adPlayer.getOriginalMutedState();
7117
+ preservedVolume1 = this.adPlayer.getOriginalVolume();
7106
7118
  this.adPlayer.destroy();
7107
7119
  this.video.muted = true;
7108
- this.video.volume = 0;
7109
7120
  this.adPlayer = preloadedFallback1.adController;
7110
7121
  this.attachImaEventListeners();
7122
+ this.adPlayer.updateOriginalMutedState(preservedMuted1, preservedVolume1);
7111
7123
  this.adPlayer.resume();
7112
7124
  this.consecutiveFailures = 0;
7113
7125
  this.currentAdIndex++;
@@ -7118,10 +7130,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7118
7130
  ];
7119
7131
  case 14:
7120
7132
  _state.sent();
7121
- currentMuted2 = this.video.muted;
7122
- currentVolume2 = this.video.volume;
7123
- adVolume2 = currentMuted2 ? 0 : currentVolume2;
7124
- this.adPlayer.setAdVolume(adVolume2);
7133
+ this.adPlayer.setAdVolume(this.getAdAudioVolume());
7125
7134
  return [
7126
7135
  2
7127
7136
  ];
@@ -7167,6 +7176,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7167
7176
  if (this.config.debugAdTiming) {
7168
7177
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
7169
7178
  }
7179
+ this.adBreakEpoch++;
7170
7180
  this.clearAdRequestWatchdog();
7171
7181
  this.clearAdFailsafeTimer();
7172
7182
  this.activeAdRequestToken = null;
@@ -7423,10 +7433,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7423
7433
  key: "toggleMute",
7424
7434
  value: function toggleMute() {
7425
7435
  if (this.adPlayer.isAdPlaying()) {
7426
- var currentPerceptualState = this.isMuted();
7427
- var newMutedState = !currentPerceptualState;
7436
+ var newMutedState = !this.adPlayer.getOriginalMutedState();
7437
+ var restoreVolume = this.adPlayer.getOriginalVolume() || 1;
7428
7438
  this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);
7429
- this.adPlayer.setAdVolume(newMutedState ? 0 : 1);
7439
+ this.adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);
7430
7440
  if (this.config.debugAdTiming) {
7431
7441
  console.log("[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:", newMutedState);
7432
7442
  }
@@ -7481,10 +7491,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7481
7491
  key: "isMuted",
7482
7492
  value: function isMuted() {
7483
7493
  if (this.adPlayer.isAdPlaying()) {
7484
- if (this.config.debugAdTiming) {
7485
- console.log("[StormcloudVideoPlayer] isMuted() override during ad playback -> false");
7486
- }
7487
- return false;
7494
+ return this.adPlayer.getOriginalMutedState();
7488
7495
  }
7489
7496
  return this.video.muted;
7490
7497
  }
@@ -7551,6 +7558,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7551
7558
  return this.video.volume;
7552
7559
  }
7553
7560
  },
7561
+ {
7562
+ key: "getAdAudioVolume",
7563
+ value: function getAdAudioVolume() {
7564
+ return this.adPlayer.getOriginalMutedState() ? 0 : this.adPlayer.getOriginalVolume();
7565
+ }
7566
+ },
7554
7567
  {
7555
7568
  key: "isFullscreen",
7556
7569
  value: function isFullscreen() {