stormcloud-video-player 0.3.66 → 0.3.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.cts CHANGED
@@ -232,9 +232,14 @@ declare class StormcloudVideoPlayer {
232
232
  private preloadPoolActive;
233
233
  private preloadPoolLoopRunning;
234
234
  private adDetectSentForCurrentBreak;
235
+ private preAdBreakAudio;
236
+ private detectedLowLatencyStream;
237
+ private latencyProfileApplied;
235
238
  constructor(config: StormcloudVideoPlayerConfig);
236
239
  private createAdPlayer;
237
240
  load(): Promise<void>;
241
+ private applyStreamLatencyProfile;
242
+ private isLowLatencyManifest;
238
243
  private attachImaEventListeners;
239
244
  private recreateImaController;
240
245
  private ensurePlaceholderContainer;
@@ -305,6 +310,7 @@ declare class StormcloudVideoPlayer {
305
310
  isShowingAds(): boolean;
306
311
  getStreamType(): "hls" | "other";
307
312
  shouldShowNativeControls(): boolean;
313
+ isLowLatencyStream(): boolean | undefined;
308
314
  private shouldContinueLiveStreamDuringAds;
309
315
  private startAdPrefetch;
310
316
  private clearPendingAdBreak;
@@ -339,6 +345,8 @@ declare class StormcloudVideoPlayer {
339
345
  private resetGamNoFillCounter;
340
346
  private enforceGlobalRateLimit;
341
347
  private playSingleAd;
348
+ private capturePreAdBreakAudio;
349
+ private getPreAdBreakAdVolume;
342
350
  private handleAdPodComplete;
343
351
  private handleAdFailure;
344
352
  private startAdRequestWatchdog;
package/lib/index.d.ts CHANGED
@@ -232,9 +232,14 @@ declare class StormcloudVideoPlayer {
232
232
  private preloadPoolActive;
233
233
  private preloadPoolLoopRunning;
234
234
  private adDetectSentForCurrentBreak;
235
+ private preAdBreakAudio;
236
+ private detectedLowLatencyStream;
237
+ private latencyProfileApplied;
235
238
  constructor(config: StormcloudVideoPlayerConfig);
236
239
  private createAdPlayer;
237
240
  load(): Promise<void>;
241
+ private applyStreamLatencyProfile;
242
+ private isLowLatencyManifest;
238
243
  private attachImaEventListeners;
239
244
  private recreateImaController;
240
245
  private ensurePlaceholderContainer;
@@ -305,6 +310,7 @@ declare class StormcloudVideoPlayer {
305
310
  isShowingAds(): boolean;
306
311
  getStreamType(): "hls" | "other";
307
312
  shouldShowNativeControls(): boolean;
313
+ isLowLatencyStream(): boolean | undefined;
308
314
  private shouldContinueLiveStreamDuringAds;
309
315
  private startAdPrefetch;
310
316
  private clearPendingAdBreak;
@@ -339,6 +345,8 @@ declare class StormcloudVideoPlayer {
339
345
  private resetGamNoFillCounter;
340
346
  private enforceGlobalRateLimit;
341
347
  private playSingleAd;
348
+ private capturePreAdBreakAudio;
349
+ private getPreAdBreakAdVolume;
342
350
  private handleAdPodComplete;
343
351
  private handleAdFailure;
344
352
  private startAdRequestWatchdog;
package/lib/index.js CHANGED
@@ -1782,7 +1782,7 @@ function createHlsAdPlayer(contentVideo, options) {
1782
1782
  }
1783
1783
  var adElement = xmlDoc.querySelector("Ad");
1784
1784
  if (!adElement) {
1785
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
1785
+ console.warn("[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):", xmlString.substring(0, 2e3));
1786
1786
  return null;
1787
1787
  }
1788
1788
  var adId = adElement.getAttribute("id") || "unknown";
@@ -1878,7 +1878,7 @@ function createHlsAdPlayer(contentVideo, options) {
1878
1878
  }
1879
1879
  function fetchAndParseVastAd(vastTagUrl) {
1880
1880
  return _async_to_generator(function() {
1881
- var response, vastXml;
1881
+ var response, vastXml, trimmedXml;
1882
1882
  return _ts_generator(this, function(_state) {
1883
1883
  switch(_state.label){
1884
1884
  case 0:
@@ -1904,8 +1904,16 @@ function createHlsAdPlayer(contentVideo, options) {
1904
1904
  ];
1905
1905
  case 2:
1906
1906
  vastXml = _state.sent();
1907
- console.log("[HlsAdPlayer] VAST XML received");
1907
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
1908
1908
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1909
+ trimmedXml = vastXml.trim();
1910
+ if (trimmedXml.length === 0) {
1911
+ console.warn("[HlsAdPlayer] VAST response body is empty (no fill)");
1912
+ return [
1913
+ 2,
1914
+ null
1915
+ ];
1916
+ }
1909
1917
  return [
1910
1918
  2,
1911
1919
  parseVastXml(vastXml)
@@ -3369,6 +3377,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3369
3377
  this.preloadPoolActive = false;
3370
3378
  this.preloadPoolLoopRunning = false;
3371
3379
  this.adDetectSentForCurrentBreak = false;
3380
+ this.latencyProfileApplied = false;
3372
3381
  this.continuousFetchLoopRunning = false;
3373
3382
  initializePolyfills();
3374
3383
  var browserOverrides = getBrowserConfigOverrides();
@@ -3485,24 +3494,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3485
3494
  2
3486
3495
  ];
3487
3496
  case 7:
3488
- this.hls = new Hls2(_object_spread_props(_object_spread({
3497
+ this.hls = new Hls2({
3489
3498
  enableWorker: true,
3490
3499
  backBufferLength: 30,
3491
3500
  liveDurationInfinity: true,
3492
3501
  lowLatencyMode: !!this.config.lowLatencyMode,
3493
- maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1
3494
- }, this.config.lowLatencyMode ? {
3495
- liveSyncDuration: 2
3496
- } : {}), {
3502
+ maxLiveSyncPlaybackRate: 1.1,
3497
3503
  maxBufferLength: 30,
3498
3504
  maxMaxBufferLength: 600,
3499
3505
  maxBufferSize: 60 * 1e3 * 1e3,
3500
- maxBufferHole: 0.5,
3506
+ maxBufferHole: 1,
3501
3507
  highBufferWatchdogPeriod: 2,
3502
- nudgeOffset: 0.1,
3503
- nudgeMaxRetry: 3,
3508
+ nudgeOffset: 0.2,
3509
+ nudgeMaxRetry: 5,
3504
3510
  startPosition: -1
3505
- }));
3511
+ });
3506
3512
  this.hls.on(Hls2.Events.MEDIA_ATTACHED, function() {
3507
3513
  var _this_hls;
3508
3514
  (_this_hls = _this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.loadSource(_this.config.src);
@@ -3546,6 +3552,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3546
3552
  this.bufferedSegmentsCount = 0;
3547
3553
  this.hasInitialBufferCompleted = false;
3548
3554
  this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
3555
+ this.latencyProfileApplied = false;
3556
+ this.detectedLowLatencyStream = void 0;
3549
3557
  minSegments = (_this_config_minSegmentsBeforePlay = this.config.minSegmentsBeforePlay) !== null && _this_config_minSegmentsBeforePlay !== void 0 ? _this_config_minSegmentsBeforePlay : 2;
3550
3558
  if (this.config.debugAdTiming) {
3551
3559
  console.log("[StormcloudVideoPlayer] Waiting for", minSegments, "segments to buffer before playback");
@@ -3575,6 +3583,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3575
3583
  }).call(_this);
3576
3584
  });
3577
3585
  this.hls.on(Hls2.Events.LEVEL_LOADED, function(_evt, data) {
3586
+ _this.applyStreamLatencyProfile(data === null || data === void 0 ? void 0 : data.details);
3578
3587
  if (_this.inAdBreak || _this.pendingAdBreak) {
3579
3588
  return;
3580
3589
  }
@@ -3854,6 +3863,64 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3854
3863
  }).call(this);
3855
3864
  }
3856
3865
  },
3866
+ {
3867
+ key: "applyStreamLatencyProfile",
3868
+ value: function applyStreamLatencyProfile(details) {
3869
+ if (this.latencyProfileApplied || !this.hls) {
3870
+ return;
3871
+ }
3872
+ if (!details) {
3873
+ return;
3874
+ }
3875
+ if (details.live !== true) {
3876
+ this.latencyProfileApplied = true;
3877
+ this.detectedLowLatencyStream = false;
3878
+ return;
3879
+ }
3880
+ var isLowLatencyManifest = this.isLowLatencyManifest(details);
3881
+ var useLowLatency = isLowLatencyManifest && !!this.config.lowLatencyMode;
3882
+ this.detectedLowLatencyStream = useLowLatency;
3883
+ this.latencyProfileApplied = true;
3884
+ var cfg = this.hls.config;
3885
+ if (useLowLatency) {
3886
+ cfg.maxLiveSyncPlaybackRate = 1.5;
3887
+ cfg.maxBufferHole = 0.5;
3888
+ delete cfg.liveSyncDuration;
3889
+ } else {
3890
+ cfg.maxLiveSyncPlaybackRate = 1.1;
3891
+ cfg.maxBufferHole = 1;
3892
+ delete cfg.liveSyncDuration;
3893
+ cfg.liveSyncDurationCount = 3;
3894
+ }
3895
+ if (this.config.debugAdTiming) {
3896
+ var _details_targetduration;
3897
+ console.log("[StormcloudVideoPlayer] Live latency profile: ".concat(useLowLatency ? "LL-HLS (low latency)" : "standard live (stability)"), {
3898
+ isLowLatencyManifest: isLowLatencyManifest,
3899
+ lowLatencyModeRequested: !!this.config.lowLatencyMode,
3900
+ canBlockReload: details.canBlockReload,
3901
+ partTarget: details.partTarget,
3902
+ partHoldBack: details.partHoldBack,
3903
+ partListLength: Array.isArray(details.partList) ? details.partList.length : 0,
3904
+ targetDuration: (_details_targetduration = details.targetduration) !== null && _details_targetduration !== void 0 ? _details_targetduration : details.targetDuration,
3905
+ maxLiveSyncPlaybackRate: cfg.maxLiveSyncPlaybackRate,
3906
+ maxBufferHole: cfg.maxBufferHole
3907
+ });
3908
+ }
3909
+ }
3910
+ },
3911
+ {
3912
+ key: "isLowLatencyManifest",
3913
+ value: function isLowLatencyManifest(details) {
3914
+ if (!details) {
3915
+ return false;
3916
+ }
3917
+ var hasParts = Array.isArray(details.partList) && details.partList.length > 0;
3918
+ var hasPartTarget = typeof details.partTarget === "number" && details.partTarget > 0;
3919
+ var hasPartHoldBack = typeof details.partHoldBack === "number" && details.partHoldBack > 0;
3920
+ var canBlockReload = details.canBlockReload === true;
3921
+ return hasParts || hasPartTarget || hasPartHoldBack || canBlockReload;
3922
+ }
3923
+ },
3857
3924
  {
3858
3925
  key: "attachImaEventListeners",
3859
3926
  value: function attachImaEventListeners() {
@@ -3910,10 +3977,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3910
3977
  console.log("[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)");
3911
3978
  }
3912
3979
  }
3913
- var currentMuted = _this.video.muted;
3914
- var currentVolume = _this.video.volume;
3915
- var adVolume = currentMuted ? 0 : currentVolume;
3916
- _this.ima.setAdVolume(adVolume);
3980
+ _this.ima.setAdVolume(_this.getPreAdBreakAdVolume());
3917
3981
  if (_this.isShowingPlaceholder) {
3918
3982
  if (_this.config.debugAdTiming) {
3919
3983
  console.log("[StormcloudVideoPlayer] Hiding placeholder - new ads starting");
@@ -4667,6 +4731,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4667
4731
  {
4668
4732
  key: "startScte35AdBreak",
4669
4733
  value: function startScte35AdBreak(marker, cueKey, durationMs) {
4734
+ this.capturePreAdBreakAudio();
4670
4735
  if (!this.video.muted) {
4671
4736
  this.video.muted = true;
4672
4737
  this.video.volume = 0;
@@ -5844,6 +5909,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5844
5909
  return !!(this.config.allowNativeHls && !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false));
5845
5910
  }
5846
5911
  },
5912
+ {
5913
+ key: "isLowLatencyStream",
5914
+ value: function isLowLatencyStream() {
5915
+ return this.detectedLowLatencyStream;
5916
+ }
5917
+ },
5847
5918
  {
5848
5919
  key: "shouldContinueLiveStreamDuringAds",
5849
5920
  value: function shouldContinueLiveStreamDuringAds() {
@@ -6348,9 +6419,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6348
6419
  this.continuousFetchingActive = true;
6349
6420
  this.isShowingPlaceholder = false;
6350
6421
  this.totalAdRequestsInBreak = 0;
6351
- currentMuted = this.video.muted;
6352
- currentVolume = this.video.volume;
6353
- this.ima.updateOriginalMutedState(currentMuted, currentVolume);
6422
+ this.capturePreAdBreakAudio();
6423
+ currentMuted = this.preAdBreakAudio.muted;
6424
+ currentVolume = this.preAdBreakAudio.volume;
6354
6425
  if (!this.video.muted) {
6355
6426
  this.video.muted = true;
6356
6427
  this.video.volume = 0;
@@ -6825,7 +6896,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6825
6896
  value: function tryNextAvailableAd() {
6826
6897
  var retryCount = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
6827
6898
  return _async_to_generator(function() {
6828
- var remaining, preloaded, currentMuted, currentVolume, adVolume, error, nextAdUrl, currentMuted1, currentVolume1, error1, errorMessage, maxRetries;
6899
+ var remaining, preloaded, error, _ref, _ref1, _this_preAdBreakAudio, _this_preAdBreakAudio1, nextAdUrl, error1, errorMessage, maxRetries;
6829
6900
  return _ts_generator(this, function(_state) {
6830
6901
  switch(_state.label){
6831
6902
  case 0:
@@ -6897,10 +6968,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6897
6968
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6898
6969
  this.scheduleAdStopAtBreakBoundary();
6899
6970
  }
6900
- currentMuted = this.video.muted;
6901
- currentVolume = this.video.volume;
6902
- adVolume = currentMuted ? 0 : currentVolume;
6903
- this.ima.setAdVolume(adVolume);
6971
+ this.ima.setAdVolume(this.getPreAdBreakAdVolume());
6904
6972
  this.consecutiveFailures = 0;
6905
6973
  return [
6906
6974
  2
@@ -6947,9 +7015,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6947
7015
  if (this.config.debugAdTiming) {
6948
7016
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAC Requesting next ad via IMA SDK (".concat(this.currentAdIndex + 1, "/").concat(this.totalAdsInBreak, ", ").concat(this.adRequestQueue.length, " remaining in queue)"));
6949
7017
  }
6950
- currentMuted1 = this.video.muted;
6951
- currentVolume1 = this.video.volume;
6952
- this.ima.updateOriginalMutedState(currentMuted1, currentVolume1);
7018
+ this.ima.updateOriginalMutedState((_ref = (_this_preAdBreakAudio = this.preAdBreakAudio) === null || _this_preAdBreakAudio === void 0 ? void 0 : _this_preAdBreakAudio.muted) !== null && _ref !== void 0 ? _ref : this.video.muted, (_ref1 = (_this_preAdBreakAudio1 = this.preAdBreakAudio) === null || _this_preAdBreakAudio1 === void 0 ? void 0 : _this_preAdBreakAudio1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.video.volume);
6953
7019
  this.currentAdIndex++;
6954
7020
  this.totalAdRequestsInBreak++;
6955
7021
  this.lastAdRequestTime = Date.now();
@@ -7042,7 +7108,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7042
7108
  key: "showPlaceholderAndWaitForAds",
7043
7109
  value: function showPlaceholderAndWaitForAds() {
7044
7110
  return _async_to_generator(function() {
7045
- var remaining, waitTime, checkInterval, maxChecks, i, nextAdUrl, currentMuted, currentVolume, error, errorMessage;
7111
+ var remaining, waitTime, checkInterval, maxChecks, i, _ref, _ref1, _this_preAdBreakAudio, _this_preAdBreakAudio1, nextAdUrl, error, errorMessage;
7046
7112
  return _ts_generator(this, function(_state) {
7047
7113
  switch(_state.label){
7048
7114
  case 0:
@@ -7138,9 +7204,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7138
7204
  }
7139
7205
  this.isShowingPlaceholder = false;
7140
7206
  this.ima.hidePlaceholder();
7141
- currentMuted = this.video.muted;
7142
- currentVolume = this.video.volume;
7143
- this.ima.updateOriginalMutedState(currentMuted, currentVolume);
7207
+ this.ima.updateOriginalMutedState((_ref = (_this_preAdBreakAudio = this.preAdBreakAudio) === null || _this_preAdBreakAudio === void 0 ? void 0 : _this_preAdBreakAudio.muted) !== null && _ref !== void 0 ? _ref : this.video.muted, (_ref1 = (_this_preAdBreakAudio1 = this.preAdBreakAudio) === null || _this_preAdBreakAudio1 === void 0 ? void 0 : _this_preAdBreakAudio1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.video.volume);
7144
7208
  this.currentAdIndex++;
7145
7209
  this.totalAdRequestsInBreak++;
7146
7210
  this.lastAdRequestTime = Date.now();
@@ -7322,7 +7386,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7322
7386
  first = tags[0];
7323
7387
  rest = tags.slice(1);
7324
7388
  this.adPodQueue = rest;
7325
- this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
7389
+ this.capturePreAdBreakAudio();
7326
7390
  this.showAds = true;
7327
7391
  this.inAdBreak = true;
7328
7392
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -7349,12 +7413,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7349
7413
  ];
7350
7414
  case 3:
7351
7415
  error = _state.sent();
7352
- this.adPodQueue = [];
7353
- this.inAdBreak = false;
7354
- this.showAds = false;
7355
7416
  if (this.config.debugAdTiming) {
7356
7417
  console.warn("[StormcloudVideoPlayer] VMAP ad request failed:", error);
7357
7418
  }
7419
+ this.handleAdPodComplete();
7358
7420
  return [
7359
7421
  3,
7360
7422
  4
@@ -7585,7 +7647,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7585
7647
  key: "playSingleAd",
7586
7648
  value: function playSingleAd(vastTagUrl) {
7587
7649
  return _async_to_generator(function() {
7588
- var requestToken, currentMuted, currentVolume, adVolume, playError, preloadedFallback, currentMuted1, currentVolume1, adVolume1, fallbackError, error, errorMessage, preloadedFallback1, currentMuted2, currentVolume2, adVolume2, fallbackError1;
7650
+ var requestToken, playError, preloadedFallback, fallbackError, error, errorMessage, preloadedFallback1, fallbackError1;
7589
7651
  return _ts_generator(this, function(_state) {
7590
7652
  switch(_state.label){
7591
7653
  case 0:
@@ -7672,10 +7734,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7672
7734
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7673
7735
  this.scheduleAdStopAtBreakBoundary();
7674
7736
  }
7675
- currentMuted = this.video.muted;
7676
- currentVolume = this.video.volume;
7677
- adVolume = currentMuted ? 0 : currentVolume;
7678
- this.ima.setAdVolume(adVolume);
7737
+ this.ima.setAdVolume(this.getPreAdBreakAdVolume());
7679
7738
  this.consecutiveFailures = 0;
7680
7739
  this.temporaryFailureUrls.delete(vastTagUrl);
7681
7740
  return [
@@ -7722,10 +7781,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7722
7781
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
7723
7782
  this.scheduleAdStopAtBreakBoundary();
7724
7783
  }
7725
- currentMuted1 = this.video.muted;
7726
- currentVolume1 = this.video.volume;
7727
- adVolume1 = currentMuted1 ? 0 : currentVolume1;
7728
- this.ima.setAdVolume(adVolume1);
7784
+ this.ima.setAdVolume(this.getPreAdBreakAdVolume());
7729
7785
  return [
7730
7786
  2
7731
7787
  ];
@@ -7799,10 +7855,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7799
7855
  ];
7800
7856
  case 14:
7801
7857
  _state.sent();
7802
- currentMuted2 = this.video.muted;
7803
- currentVolume2 = this.video.volume;
7804
- adVolume2 = currentMuted2 ? 0 : currentVolume2;
7805
- this.ima.setAdVolume(adVolume2);
7858
+ this.ima.setAdVolume(this.getPreAdBreakAdVolume());
7806
7859
  return [
7807
7860
  2
7808
7861
  ];
@@ -7842,6 +7895,33 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7842
7895
  }).call(this);
7843
7896
  }
7844
7897
  },
7898
+ {
7899
+ key: "capturePreAdBreakAudio",
7900
+ value: function capturePreAdBreakAudio() {
7901
+ if (this.preAdBreakAudio) {
7902
+ return;
7903
+ }
7904
+ var captured = {
7905
+ muted: this.video.muted,
7906
+ volume: typeof this.video.volume === "number" && !Number.isNaN(this.video.volume) ? Math.max(0, Math.min(1, this.video.volume)) : 1
7907
+ };
7908
+ this.preAdBreakAudio = captured;
7909
+ this.ima.updateOriginalMutedState(captured.muted, captured.volume);
7910
+ if (this.config.debugAdTiming) {
7911
+ console.log("[StormcloudVideoPlayer] Captured pre-ad-break audio state: muted=".concat(captured.muted, ", volume=").concat(captured.volume));
7912
+ }
7913
+ }
7914
+ },
7915
+ {
7916
+ key: "getPreAdBreakAdVolume",
7917
+ value: function getPreAdBreakAdVolume() {
7918
+ var state = this.preAdBreakAudio;
7919
+ if (state) {
7920
+ return state.muted ? 0 : state.volume;
7921
+ }
7922
+ return this.ima.getOriginalMutedState() ? 0 : this.ima.getOriginalVolume();
7923
+ }
7924
+ },
7845
7925
  {
7846
7926
  key: "handleAdPodComplete",
7847
7927
  value: function handleAdPodComplete() {
@@ -7875,14 +7955,19 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7875
7955
  this.consecutiveFailures = 0;
7876
7956
  this.globalConsecutiveNoFills = 0;
7877
7957
  this.ima.stop().catch(function() {});
7878
- var restoredMuted = this.ima.getOriginalMutedState();
7879
- var restoredVolume = this.ima.getOriginalVolume();
7958
+ var restoredMuted = this.preAdBreakAudio ? this.preAdBreakAudio.muted : this.ima.getOriginalMutedState();
7959
+ var restoredVolume = this.preAdBreakAudio ? this.preAdBreakAudio.volume : this.ima.getOriginalVolume();
7960
+ this.ima.updateOriginalMutedState(restoredMuted, restoredVolume);
7880
7961
  if (this.video.muted !== restoredMuted) {
7881
7962
  this.video.muted = restoredMuted;
7882
7963
  }
7883
7964
  if (Math.abs(this.video.volume - restoredVolume) > 0.01) {
7884
7965
  this.video.volume = restoredVolume;
7885
7966
  }
7967
+ this.preAdBreakAudio = void 0;
7968
+ if (this.config.debugAdTiming) {
7969
+ console.log("[StormcloudVideoPlayer] Restored post-ad-break audio state: muted=".concat(restoredMuted, ", volume=").concat(restoredVolume));
7970
+ }
7886
7971
  if (this.shouldContinueLiveStreamDuringAds()) {
7887
7972
  if (this.video.paused) {
7888
7973
  var _this_video_play;
@@ -8292,6 +8377,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8292
8377
  this.clearAdFailsafeTimer();
8293
8378
  this.clearAdRequestWatchdog();
8294
8379
  this.clearPendingAdBreak();
8380
+ this.preAdBreakAudio = void 0;
8295
8381
  if (this.placeholderContainer) {
8296
8382
  if (this.placeholderContainer.parentElement) {
8297
8383
  this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);
@@ -8324,8 +8410,66 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8324
8410
  return StormcloudVideoPlayer;
8325
8411
  }();
8326
8412
  // src/ui/StormcloudVideoPlayer.tsx
8327
- import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress } from "react-icons/fa";
8413
+ import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown } from "react-icons/fa";
8328
8414
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8415
+ var ExpandIcon = function ExpandIcon(param) {
8416
+ var _param_size = param.size, size = _param_size === void 0 ? 18 : _param_size;
8417
+ return /* @__PURE__ */ jsxs("svg", {
8418
+ width: size,
8419
+ height: size,
8420
+ viewBox: "0 0 24 24",
8421
+ fill: "none",
8422
+ stroke: "currentColor",
8423
+ strokeWidth: 2,
8424
+ strokeLinecap: "round",
8425
+ strokeLinejoin: "round",
8426
+ "aria-hidden": "true",
8427
+ focusable: "false",
8428
+ children: [
8429
+ /* @__PURE__ */ jsx("path", {
8430
+ d: "M9 4H4v5"
8431
+ }),
8432
+ /* @__PURE__ */ jsx("path", {
8433
+ d: "M20 9V4h-5"
8434
+ }),
8435
+ /* @__PURE__ */ jsx("path", {
8436
+ d: "M15 20h5v-5"
8437
+ }),
8438
+ /* @__PURE__ */ jsx("path", {
8439
+ d: "M4 15v5h5"
8440
+ })
8441
+ ]
8442
+ });
8443
+ };
8444
+ var CompressIcon = function CompressIcon(param) {
8445
+ var _param_size = param.size, size = _param_size === void 0 ? 18 : _param_size;
8446
+ return /* @__PURE__ */ jsxs("svg", {
8447
+ width: size,
8448
+ height: size,
8449
+ viewBox: "0 0 24 24",
8450
+ fill: "none",
8451
+ stroke: "currentColor",
8452
+ strokeWidth: 2,
8453
+ strokeLinecap: "round",
8454
+ strokeLinejoin: "round",
8455
+ "aria-hidden": "true",
8456
+ focusable: "false",
8457
+ children: [
8458
+ /* @__PURE__ */ jsx("path", {
8459
+ d: "M4 9h5V4"
8460
+ }),
8461
+ /* @__PURE__ */ jsx("path", {
8462
+ d: "M15 4v5h5"
8463
+ }),
8464
+ /* @__PURE__ */ jsx("path", {
8465
+ d: "M20 15h-5v5"
8466
+ }),
8467
+ /* @__PURE__ */ jsx("path", {
8468
+ d: "M9 20v-5H4"
8469
+ })
8470
+ ]
8471
+ });
8472
+ };
8329
8473
  var CRITICAL_PROPS = [
8330
8474
  "src",
8331
8475
  "allowNativeHls",
@@ -9376,9 +9520,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
9376
9520
  minHeight: "".concat(36 * responsiveScale, "px")
9377
9521
  },
9378
9522
  title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
9379
- children: isFullscreen ? /* @__PURE__ */ jsx(FaCompress, {
9523
+ children: isFullscreen ? /* @__PURE__ */ jsx(CompressIcon, {
9380
9524
  size: Math.max(14, 18 * responsiveScale)
9381
- }) : /* @__PURE__ */ jsx(FaExpand, {
9525
+ }) : /* @__PURE__ */ jsx(ExpandIcon, {
9382
9526
  size: Math.max(14, 18 * responsiveScale)
9383
9527
  })
9384
9528
  })
@@ -9576,9 +9720,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
9576
9720
  background: "rgba(0, 0, 0, 0.6)"
9577
9721
  },
9578
9722
  title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
9579
- children: isFullscreen ? /* @__PURE__ */ jsx(FaCompress, {
9723
+ children: isFullscreen ? /* @__PURE__ */ jsx(CompressIcon, {
9580
9724
  size: Math.max(14, 18 * responsiveScale)
9581
- }) : /* @__PURE__ */ jsx(FaExpand, {
9725
+ }) : /* @__PURE__ */ jsx(ExpandIcon, {
9582
9726
  size: Math.max(14, 18 * responsiveScale)
9583
9727
  })
9584
9728
  })