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.
@@ -1292,16 +1292,34 @@ function createHlsAdPlayer(contentVideo, options) {
1292
1292
  }
1293
1293
  }, STALL_CHECK_INTERVAL_MS);
1294
1294
  }
1295
+ function releaseAdDecoder() {
1296
+ if (adHls) {
1297
+ adHls.destroy();
1298
+ adHls = void 0;
1299
+ }
1300
+ if (adVideoElement) {
1301
+ adVideoElement.pause();
1302
+ adVideoElement.removeAttribute("src");
1303
+ try {
1304
+ adVideoElement.load();
1305
+ } catch (error) {
1306
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1307
+ }
1308
+ adVideoElement.remove();
1309
+ adVideoElement = void 0;
1310
+ }
1311
+ if (adContainerEl) {
1312
+ adContainerEl.style.display = "none";
1313
+ adContainerEl.style.pointerEvents = "none";
1314
+ }
1315
+ }
1295
1316
  function handleAdComplete() {
1296
1317
  console.log("[HlsAdPlayer] Handling ad completion");
1297
1318
  clearStallWatchdog();
1298
1319
  adPlaying = false;
1299
1320
  setAdPlayingFlag(false);
1300
1321
  contentVideo.muted = true;
1301
- if (adContainerEl) {
1302
- adContainerEl.style.display = "none";
1303
- adContainerEl.style.pointerEvents = "none";
1304
- }
1322
+ releaseAdDecoder();
1305
1323
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1306
1324
  contentVideo.style.visibility = "visible";
1307
1325
  contentVideo.style.opacity = "1";
@@ -1324,10 +1342,7 @@ function createHlsAdPlayer(contentVideo, options) {
1324
1342
  adPlaying = false;
1325
1343
  setAdPlayingFlag(false);
1326
1344
  contentVideo.muted = true;
1327
- if (adContainerEl) {
1328
- adContainerEl.style.display = "none";
1329
- adContainerEl.style.pointerEvents = "none";
1330
- }
1345
+ releaseAdDecoder();
1331
1346
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1332
1347
  contentVideo.style.visibility = "visible";
1333
1348
  contentVideo.style.opacity = "1";
@@ -1536,10 +1551,7 @@ function createHlsAdPlayer(contentVideo, options) {
1536
1551
  contentVideo.muted = originalMutedState;
1537
1552
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1538
1553
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1539
- if (adContainerEl) {
1540
- adContainerEl.style.display = "none";
1541
- adContainerEl.style.pointerEvents = "none";
1542
- }
1554
+ releaseAdDecoder();
1543
1555
  contentVideo.style.visibility = "visible";
1544
1556
  contentVideo.style.opacity = "1";
1545
1557
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
@@ -1550,17 +1562,6 @@ function createHlsAdPlayer(contentVideo, options) {
1550
1562
  });
1551
1563
  }
1552
1564
  }
1553
- if (adHls) {
1554
- adHls.destroy();
1555
- adHls = void 0;
1556
- }
1557
- if (adVideoElement) {
1558
- adVideoElement.pause();
1559
- adVideoElement.removeAttribute("src");
1560
- try {
1561
- adVideoElement.load();
1562
- } catch (unused) {}
1563
- }
1564
1565
  currentAd = void 0;
1565
1566
  podAds = [];
1566
1567
  podIndex = 0;
@@ -1599,19 +1600,7 @@ function createHlsAdPlayer(contentVideo, options) {
1599
1600
  setAdPlayingFlag(false);
1600
1601
  contentVideo.muted = originalMutedState;
1601
1602
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1602
- if (adHls) {
1603
- adHls.destroy();
1604
- adHls = void 0;
1605
- }
1606
- if (adVideoElement) {
1607
- adVideoElement.pause();
1608
- adVideoElement.removeAttribute("src");
1609
- try {
1610
- adVideoElement.load();
1611
- } catch (unused) {}
1612
- adVideoElement.remove();
1613
- adVideoElement = void 0;
1614
- }
1603
+ releaseAdDecoder();
1615
1604
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1616
1605
  adContainerEl.parentElement.removeChild(adContainerEl);
1617
1606
  }
@@ -6771,6 +6760,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6771
6760
  }
6772
6761
  }
6773
6762
  },
6763
+ {
6764
+ key: "recoverMediaError",
6765
+ value: function recoverMediaError() {
6766
+ if (!this.hls) {
6767
+ return;
6768
+ }
6769
+ try {
6770
+ this.hls.recoverMediaError();
6771
+ } catch (error) {
6772
+ if (this.debug) {
6773
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6774
+ }
6775
+ }
6776
+ }
6777
+ },
6774
6778
  {
6775
6779
  key: "reloadLiveStream",
6776
6780
  value: function reloadLiveStream() {
@@ -6788,7 +6792,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6788
6792
  try {
6789
6793
  this.video.removeAttribute("src");
6790
6794
  this.video.load();
6791
- } catch (unused) {}
6795
+ } catch (error) {
6796
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6797
+ }
6792
6798
  hls.attachMedia(this.video);
6793
6799
  } catch (error) {
6794
6800
  this.reloadingLiveStream = false;
@@ -8172,8 +8178,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8172
8178
  var pollIntervalMs = 1e3;
8173
8179
  var graceMs = 5e3;
8174
8180
  var recoveryCooldownMs = 5e3;
8175
- var maxRecoveries = 2;
8176
- var maxMonitorMs = 3e4;
8181
+ var maxRecoveries = 3;
8182
+ var maxMonitorMs = 45e3;
8177
8183
  var startTime = Date.now();
8178
8184
  var baseline = resumeBaseline;
8179
8185
  var recoveries = 0;
@@ -8285,8 +8291,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8285
8291
  if (canRecover) {
8286
8292
  recoveries++;
8287
8293
  lastRecoveryAt = Date.now();
8288
- var isFinalAttempt = recoveries >= maxRecoveries;
8289
- if (!isFinalAttempt) {
8294
+ if (recoveries === 1) {
8295
+ if (_this.debug) {
8296
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8297
+ }
8298
+ _this.host.recoverMediaError();
8299
+ } else if (recoveries === 2) {
8290
8300
  var liveSyncPos = _this.host.getLiveSyncPosition();
8291
8301
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8292
8302
  if (_this.debug) {
@@ -8318,17 +8328,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8318
8328
  value: function resumeContentPlayback() {
8319
8329
  var _this = this;
8320
8330
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8321
- var maxAttempts = 3;
8322
- if (!this.host.video.paused) {
8331
+ var maxAttempts = 5;
8332
+ var video = this.host.video;
8333
+ if (!video.paused) {
8323
8334
  if (this.debug && attempt === 0) {
8324
8335
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8325
8336
  }
8326
8337
  return;
8327
8338
  }
8328
8339
  if (this.debug) {
8329
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8340
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8330
8341
  }
8331
- var playResult = this.host.video.play();
8342
+ if (video.readyState < 3) {
8343
+ if (attempt + 1 >= maxAttempts) {
8344
+ var _video_play;
8345
+ if (this.debug) {
8346
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8347
+ }
8348
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8349
+ return;
8350
+ }
8351
+ var onReady = function onReady1() {
8352
+ video.removeEventListener("canplay", onReady);
8353
+ _this.resumeContentPlayback(attempt + 1);
8354
+ };
8355
+ video.addEventListener("canplay", onReady);
8356
+ var backoffMs = 500 * (attempt + 1);
8357
+ window.setTimeout(function() {
8358
+ video.removeEventListener("canplay", onReady);
8359
+ if (video.paused) {
8360
+ _this.resumeContentPlayback(attempt + 1);
8361
+ }
8362
+ }, backoffMs);
8363
+ return;
8364
+ }
8365
+ var playResult = video.play();
8332
8366
  if (playResult && typeof playResult.catch === "function") {
8333
8367
  playResult.catch(function(error) {
8334
8368
  if (attempt + 1 >= maxAttempts) {
@@ -8467,6 +8501,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8467
8501
  reloadLiveStream: function reloadLiveStream() {
8468
8502
  return _this.hlsEngine.reloadLiveStream();
8469
8503
  },
8504
+ recoverMediaError: function recoverMediaError() {
8505
+ return _this.hlsEngine.recoverMediaError();
8506
+ },
8470
8507
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8471
8508
  return _this.generatePodVastUrl(base, breakDurationMs);
8472
8509
  }