stormcloud-video-player 0.8.44 → 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";
@@ -1460,7 +1478,9 @@ function createHlsAdPlayer(contentVideo, options) {
1460
1478
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
1461
1479
  if (contentVideo.paused) {
1462
1480
  console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
1463
- contentVideo.play().catch(function() {});
1481
+ contentVideo.play().catch(function(error) {
1482
+ console.error("[HlsAdPlayer] Error resuming content playback in live mode:", error);
1483
+ });
1464
1484
  } else {
1465
1485
  console.log("[HlsAdPlayer] Content video already playing in live mode");
1466
1486
  }
@@ -1473,10 +1493,7 @@ function createHlsAdPlayer(contentVideo, options) {
1473
1493
  adPlaying = false;
1474
1494
  setAdPlayingFlag(false);
1475
1495
  contentVideo.muted = true;
1476
- if (adContainerEl) {
1477
- adContainerEl.style.display = "none";
1478
- adContainerEl.style.pointerEvents = "none";
1479
- }
1496
+ releaseAdDecoder();
1480
1497
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1481
1498
  contentVideo.style.visibility = "visible";
1482
1499
  contentVideo.style.opacity = "1";
@@ -1685,29 +1702,17 @@ function createHlsAdPlayer(contentVideo, options) {
1685
1702
  contentVideo.muted = originalMutedState;
1686
1703
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1687
1704
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1688
- if (adContainerEl) {
1689
- adContainerEl.style.display = "none";
1690
- adContainerEl.style.pointerEvents = "none";
1691
- }
1705
+ releaseAdDecoder();
1692
1706
  contentVideo.style.visibility = "visible";
1693
1707
  contentVideo.style.opacity = "1";
1694
1708
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
1695
1709
  if (contentVideo.paused) {
1696
1710
  console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback on stop");
1697
- contentVideo.play().catch(function() {});
1711
+ contentVideo.play().catch(function(error) {
1712
+ console.error("[HlsAdPlayer] Error resuming content playback in live mode on stop:", error);
1713
+ });
1698
1714
  }
1699
1715
  }
1700
- if (adHls) {
1701
- adHls.destroy();
1702
- adHls = void 0;
1703
- }
1704
- if (adVideoElement) {
1705
- adVideoElement.pause();
1706
- adVideoElement.removeAttribute("src");
1707
- try {
1708
- adVideoElement.load();
1709
- } catch (unused) {}
1710
- }
1711
1716
  currentAd = void 0;
1712
1717
  podAds = [];
1713
1718
  podIndex = 0;
@@ -1746,19 +1751,7 @@ function createHlsAdPlayer(contentVideo, options) {
1746
1751
  setAdPlayingFlag(false);
1747
1752
  contentVideo.muted = originalMutedState;
1748
1753
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1749
- if (adHls) {
1750
- adHls.destroy();
1751
- adHls = void 0;
1752
- }
1753
- if (adVideoElement) {
1754
- adVideoElement.pause();
1755
- adVideoElement.removeAttribute("src");
1756
- try {
1757
- adVideoElement.load();
1758
- } catch (unused) {}
1759
- adVideoElement.remove();
1760
- adVideoElement = void 0;
1761
- }
1754
+ releaseAdDecoder();
1762
1755
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1763
1756
  adContainerEl.parentElement.removeChild(adContainerEl);
1764
1757
  }
@@ -6962,6 +6955,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6962
6955
  }
6963
6956
  }
6964
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
+ },
6965
6973
  {
6966
6974
  key: "reloadLiveStream",
6967
6975
  value: function reloadLiveStream() {
@@ -6979,7 +6987,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6979
6987
  try {
6980
6988
  this.video.removeAttribute("src");
6981
6989
  this.video.load();
6982
- } catch (unused) {}
6990
+ } catch (error) {
6991
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6992
+ }
6983
6993
  hls.attachMedia(this.video);
6984
6994
  } catch (error) {
6985
6995
  this.reloadingLiveStream = false;
@@ -8363,8 +8373,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8363
8373
  var pollIntervalMs = 1e3;
8364
8374
  var graceMs = 5e3;
8365
8375
  var recoveryCooldownMs = 5e3;
8366
- var maxRecoveries = 2;
8367
- var maxMonitorMs = 3e4;
8376
+ var maxRecoveries = 3;
8377
+ var maxMonitorMs = 45e3;
8368
8378
  var startTime = Date.now();
8369
8379
  var baseline = resumeBaseline;
8370
8380
  var recoveries = 0;
@@ -8476,8 +8486,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8476
8486
  if (canRecover) {
8477
8487
  recoveries++;
8478
8488
  lastRecoveryAt = Date.now();
8479
- var isFinalAttempt = recoveries >= maxRecoveries;
8480
- 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) {
8481
8495
  var liveSyncPos = _this.host.getLiveSyncPosition();
8482
8496
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8483
8497
  if (_this.debug) {
@@ -8509,17 +8523,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8509
8523
  value: function resumeContentPlayback() {
8510
8524
  var _this = this;
8511
8525
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8512
- var maxAttempts = 3;
8513
- if (!this.host.video.paused) {
8526
+ var maxAttempts = 5;
8527
+ var video = this.host.video;
8528
+ if (!video.paused) {
8514
8529
  if (this.debug && attempt === 0) {
8515
8530
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8516
8531
  }
8517
8532
  return;
8518
8533
  }
8519
8534
  if (this.debug) {
8520
- 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, ")"));
8521
8536
  }
8522
- 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();
8523
8561
  if (playResult && typeof playResult.catch === "function") {
8524
8562
  playResult.catch(function(error) {
8525
8563
  if (attempt + 1 >= maxAttempts) {
@@ -8658,6 +8696,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8658
8696
  reloadLiveStream: function reloadLiveStream() {
8659
8697
  return _this.hlsEngine.reloadLiveStream();
8660
8698
  },
8699
+ recoverMediaError: function recoverMediaError() {
8700
+ return _this.hlsEngine.recoverMediaError();
8701
+ },
8661
8702
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8662
8703
  return _this.generatePodVastUrl(base, breakDurationMs);
8663
8704
  }