stormcloud-video-player 0.8.45 → 0.8.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs CHANGED
@@ -1443,16 +1443,34 @@ function createHlsAdPlayer(contentVideo, options) {
1443
1443
  }
1444
1444
  }, STALL_CHECK_INTERVAL_MS);
1445
1445
  }
1446
+ function releaseAdDecoder() {
1447
+ if (adHls) {
1448
+ adHls.destroy();
1449
+ adHls = void 0;
1450
+ }
1451
+ if (adVideoElement) {
1452
+ adVideoElement.pause();
1453
+ adVideoElement.removeAttribute("src");
1454
+ try {
1455
+ adVideoElement.load();
1456
+ } catch (error) {
1457
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1458
+ }
1459
+ adVideoElement.remove();
1460
+ adVideoElement = void 0;
1461
+ }
1462
+ if (adContainerEl) {
1463
+ adContainerEl.style.display = "none";
1464
+ adContainerEl.style.pointerEvents = "none";
1465
+ }
1466
+ }
1446
1467
  function handleAdComplete() {
1447
1468
  console.log("[HlsAdPlayer] Handling ad completion");
1448
1469
  clearStallWatchdog();
1449
1470
  adPlaying = false;
1450
1471
  setAdPlayingFlag(false);
1451
1472
  contentVideo.muted = true;
1452
- if (adContainerEl) {
1453
- adContainerEl.style.display = "none";
1454
- adContainerEl.style.pointerEvents = "none";
1455
- }
1473
+ releaseAdDecoder();
1456
1474
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1457
1475
  contentVideo.style.visibility = "visible";
1458
1476
  contentVideo.style.opacity = "1";
@@ -1475,10 +1493,7 @@ function createHlsAdPlayer(contentVideo, options) {
1475
1493
  adPlaying = false;
1476
1494
  setAdPlayingFlag(false);
1477
1495
  contentVideo.muted = true;
1478
- if (adContainerEl) {
1479
- adContainerEl.style.display = "none";
1480
- adContainerEl.style.pointerEvents = "none";
1481
- }
1496
+ releaseAdDecoder();
1482
1497
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1483
1498
  contentVideo.style.visibility = "visible";
1484
1499
  contentVideo.style.opacity = "1";
@@ -1687,10 +1702,7 @@ function createHlsAdPlayer(contentVideo, options) {
1687
1702
  contentVideo.muted = originalMutedState;
1688
1703
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1689
1704
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1690
- if (adContainerEl) {
1691
- adContainerEl.style.display = "none";
1692
- adContainerEl.style.pointerEvents = "none";
1693
- }
1705
+ releaseAdDecoder();
1694
1706
  contentVideo.style.visibility = "visible";
1695
1707
  contentVideo.style.opacity = "1";
1696
1708
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
@@ -1701,17 +1713,6 @@ function createHlsAdPlayer(contentVideo, options) {
1701
1713
  });
1702
1714
  }
1703
1715
  }
1704
- if (adHls) {
1705
- adHls.destroy();
1706
- adHls = void 0;
1707
- }
1708
- if (adVideoElement) {
1709
- adVideoElement.pause();
1710
- adVideoElement.removeAttribute("src");
1711
- try {
1712
- adVideoElement.load();
1713
- } catch (unused) {}
1714
- }
1715
1716
  currentAd = void 0;
1716
1717
  podAds = [];
1717
1718
  podIndex = 0;
@@ -1750,19 +1751,7 @@ function createHlsAdPlayer(contentVideo, options) {
1750
1751
  setAdPlayingFlag(false);
1751
1752
  contentVideo.muted = originalMutedState;
1752
1753
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1753
- if (adHls) {
1754
- adHls.destroy();
1755
- adHls = void 0;
1756
- }
1757
- if (adVideoElement) {
1758
- adVideoElement.pause();
1759
- adVideoElement.removeAttribute("src");
1760
- try {
1761
- adVideoElement.load();
1762
- } catch (unused) {}
1763
- adVideoElement.remove();
1764
- adVideoElement = void 0;
1765
- }
1754
+ releaseAdDecoder();
1766
1755
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1767
1756
  adContainerEl.parentElement.removeChild(adContainerEl);
1768
1757
  }
@@ -6966,6 +6955,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6966
6955
  }
6967
6956
  }
6968
6957
  },
6958
+ {
6959
+ key: "recoverMediaError",
6960
+ value: function recoverMediaError() {
6961
+ if (!this.hls) {
6962
+ return;
6963
+ }
6964
+ try {
6965
+ this.hls.recoverMediaError();
6966
+ } catch (error) {
6967
+ if (this.debug) {
6968
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6969
+ }
6970
+ }
6971
+ }
6972
+ },
6969
6973
  {
6970
6974
  key: "reloadLiveStream",
6971
6975
  value: function reloadLiveStream() {
@@ -6983,7 +6987,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6983
6987
  try {
6984
6988
  this.video.removeAttribute("src");
6985
6989
  this.video.load();
6986
- } catch (unused) {}
6990
+ } catch (error) {
6991
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6992
+ }
6987
6993
  hls.attachMedia(this.video);
6988
6994
  } catch (error) {
6989
6995
  this.reloadingLiveStream = false;
@@ -8367,8 +8373,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8367
8373
  var pollIntervalMs = 1e3;
8368
8374
  var graceMs = 5e3;
8369
8375
  var recoveryCooldownMs = 5e3;
8370
- var maxRecoveries = 2;
8371
- var maxMonitorMs = 3e4;
8376
+ var maxRecoveries = 3;
8377
+ var maxMonitorMs = 45e3;
8372
8378
  var startTime = Date.now();
8373
8379
  var baseline = resumeBaseline;
8374
8380
  var recoveries = 0;
@@ -8480,8 +8486,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8480
8486
  if (canRecover) {
8481
8487
  recoveries++;
8482
8488
  lastRecoveryAt = Date.now();
8483
- var isFinalAttempt = recoveries >= maxRecoveries;
8484
- if (!isFinalAttempt) {
8489
+ if (recoveries === 1) {
8490
+ if (_this.debug) {
8491
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8492
+ }
8493
+ _this.host.recoverMediaError();
8494
+ } else if (recoveries === 2) {
8485
8495
  var liveSyncPos = _this.host.getLiveSyncPosition();
8486
8496
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8487
8497
  if (_this.debug) {
@@ -8513,17 +8523,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8513
8523
  value: function resumeContentPlayback() {
8514
8524
  var _this = this;
8515
8525
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8516
- var maxAttempts = 3;
8517
- if (!this.host.video.paused) {
8526
+ var maxAttempts = 5;
8527
+ var video = this.host.video;
8528
+ if (!video.paused) {
8518
8529
  if (this.debug && attempt === 0) {
8519
8530
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8520
8531
  }
8521
8532
  return;
8522
8533
  }
8523
8534
  if (this.debug) {
8524
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8535
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8525
8536
  }
8526
- var playResult = this.host.video.play();
8537
+ if (video.readyState < 3) {
8538
+ if (attempt + 1 >= maxAttempts) {
8539
+ var _video_play;
8540
+ if (this.debug) {
8541
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8542
+ }
8543
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8544
+ return;
8545
+ }
8546
+ var onReady = function onReady1() {
8547
+ video.removeEventListener("canplay", onReady);
8548
+ _this.resumeContentPlayback(attempt + 1);
8549
+ };
8550
+ video.addEventListener("canplay", onReady);
8551
+ var backoffMs = 500 * (attempt + 1);
8552
+ window.setTimeout(function() {
8553
+ video.removeEventListener("canplay", onReady);
8554
+ if (video.paused) {
8555
+ _this.resumeContentPlayback(attempt + 1);
8556
+ }
8557
+ }, backoffMs);
8558
+ return;
8559
+ }
8560
+ var playResult = video.play();
8527
8561
  if (playResult && typeof playResult.catch === "function") {
8528
8562
  playResult.catch(function(error) {
8529
8563
  if (attempt + 1 >= maxAttempts) {
@@ -8662,6 +8696,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8662
8696
  reloadLiveStream: function reloadLiveStream() {
8663
8697
  return _this.hlsEngine.reloadLiveStream();
8664
8698
  },
8699
+ recoverMediaError: function recoverMediaError() {
8700
+ return _this.hlsEngine.recoverMediaError();
8701
+ },
8665
8702
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8666
8703
  return _this.generatePodVastUrl(base, breakDurationMs);
8667
8704
  }