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.
@@ -1242,16 +1242,34 @@ function createHlsAdPlayer(contentVideo, options) {
1242
1242
  }
1243
1243
  }, STALL_CHECK_INTERVAL_MS);
1244
1244
  }
1245
+ function releaseAdDecoder() {
1246
+ if (adHls) {
1247
+ adHls.destroy();
1248
+ adHls = void 0;
1249
+ }
1250
+ if (adVideoElement) {
1251
+ adVideoElement.pause();
1252
+ adVideoElement.removeAttribute("src");
1253
+ try {
1254
+ adVideoElement.load();
1255
+ } catch (error) {
1256
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1257
+ }
1258
+ adVideoElement.remove();
1259
+ adVideoElement = void 0;
1260
+ }
1261
+ if (adContainerEl) {
1262
+ adContainerEl.style.display = "none";
1263
+ adContainerEl.style.pointerEvents = "none";
1264
+ }
1265
+ }
1245
1266
  function handleAdComplete() {
1246
1267
  console.log("[HlsAdPlayer] Handling ad completion");
1247
1268
  clearStallWatchdog();
1248
1269
  adPlaying = false;
1249
1270
  setAdPlayingFlag(false);
1250
1271
  contentVideo.muted = true;
1251
- if (adContainerEl) {
1252
- adContainerEl.style.display = "none";
1253
- adContainerEl.style.pointerEvents = "none";
1254
- }
1272
+ releaseAdDecoder();
1255
1273
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1256
1274
  contentVideo.style.visibility = "visible";
1257
1275
  contentVideo.style.opacity = "1";
@@ -1259,7 +1277,9 @@ function createHlsAdPlayer(contentVideo, options) {
1259
1277
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
1260
1278
  if (contentVideo.paused) {
1261
1279
  console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
1262
- contentVideo.play().catch(function() {});
1280
+ contentVideo.play().catch(function(error) {
1281
+ console.error("[HlsAdPlayer] Error resuming content playback in live mode:", error);
1282
+ });
1263
1283
  } else {
1264
1284
  console.log("[HlsAdPlayer] Content video already playing in live mode");
1265
1285
  }
@@ -1272,10 +1292,7 @@ function createHlsAdPlayer(contentVideo, options) {
1272
1292
  adPlaying = false;
1273
1293
  setAdPlayingFlag(false);
1274
1294
  contentVideo.muted = true;
1275
- if (adContainerEl) {
1276
- adContainerEl.style.display = "none";
1277
- adContainerEl.style.pointerEvents = "none";
1278
- }
1295
+ releaseAdDecoder();
1279
1296
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1280
1297
  contentVideo.style.visibility = "visible";
1281
1298
  contentVideo.style.opacity = "1";
@@ -1484,29 +1501,17 @@ function createHlsAdPlayer(contentVideo, options) {
1484
1501
  contentVideo.muted = originalMutedState;
1485
1502
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1486
1503
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1487
- if (adContainerEl) {
1488
- adContainerEl.style.display = "none";
1489
- adContainerEl.style.pointerEvents = "none";
1490
- }
1504
+ releaseAdDecoder();
1491
1505
  contentVideo.style.visibility = "visible";
1492
1506
  contentVideo.style.opacity = "1";
1493
1507
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
1494
1508
  if (contentVideo.paused) {
1495
1509
  console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback on stop");
1496
- contentVideo.play().catch(function() {});
1510
+ contentVideo.play().catch(function(error) {
1511
+ console.error("[HlsAdPlayer] Error resuming content playback in live mode on stop:", error);
1512
+ });
1497
1513
  }
1498
1514
  }
1499
- if (adHls) {
1500
- adHls.destroy();
1501
- adHls = void 0;
1502
- }
1503
- if (adVideoElement) {
1504
- adVideoElement.pause();
1505
- adVideoElement.removeAttribute("src");
1506
- try {
1507
- adVideoElement.load();
1508
- } catch (unused) {}
1509
- }
1510
1515
  currentAd = void 0;
1511
1516
  podAds = [];
1512
1517
  podIndex = 0;
@@ -1545,19 +1550,7 @@ function createHlsAdPlayer(contentVideo, options) {
1545
1550
  setAdPlayingFlag(false);
1546
1551
  contentVideo.muted = originalMutedState;
1547
1552
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1548
- if (adHls) {
1549
- adHls.destroy();
1550
- adHls = void 0;
1551
- }
1552
- if (adVideoElement) {
1553
- adVideoElement.pause();
1554
- adVideoElement.removeAttribute("src");
1555
- try {
1556
- adVideoElement.load();
1557
- } catch (unused) {}
1558
- adVideoElement.remove();
1559
- adVideoElement = void 0;
1560
- }
1553
+ releaseAdDecoder();
1561
1554
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1562
1555
  adContainerEl.parentElement.removeChild(adContainerEl);
1563
1556
  }
@@ -6717,6 +6710,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6717
6710
  }
6718
6711
  }
6719
6712
  },
6713
+ {
6714
+ key: "recoverMediaError",
6715
+ value: function recoverMediaError() {
6716
+ if (!this.hls) {
6717
+ return;
6718
+ }
6719
+ try {
6720
+ this.hls.recoverMediaError();
6721
+ } catch (error) {
6722
+ if (this.debug) {
6723
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6724
+ }
6725
+ }
6726
+ }
6727
+ },
6720
6728
  {
6721
6729
  key: "reloadLiveStream",
6722
6730
  value: function reloadLiveStream() {
@@ -6734,7 +6742,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6734
6742
  try {
6735
6743
  this.video.removeAttribute("src");
6736
6744
  this.video.load();
6737
- } catch (unused) {}
6745
+ } catch (error) {
6746
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6747
+ }
6738
6748
  hls.attachMedia(this.video);
6739
6749
  } catch (error) {
6740
6750
  this.reloadingLiveStream = false;
@@ -8118,8 +8128,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8118
8128
  var pollIntervalMs = 1e3;
8119
8129
  var graceMs = 5e3;
8120
8130
  var recoveryCooldownMs = 5e3;
8121
- var maxRecoveries = 2;
8122
- var maxMonitorMs = 3e4;
8131
+ var maxRecoveries = 3;
8132
+ var maxMonitorMs = 45e3;
8123
8133
  var startTime = Date.now();
8124
8134
  var baseline = resumeBaseline;
8125
8135
  var recoveries = 0;
@@ -8231,8 +8241,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8231
8241
  if (canRecover) {
8232
8242
  recoveries++;
8233
8243
  lastRecoveryAt = Date.now();
8234
- var isFinalAttempt = recoveries >= maxRecoveries;
8235
- if (!isFinalAttempt) {
8244
+ if (recoveries === 1) {
8245
+ if (_this.debug) {
8246
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8247
+ }
8248
+ _this.host.recoverMediaError();
8249
+ } else if (recoveries === 2) {
8236
8250
  var liveSyncPos = _this.host.getLiveSyncPosition();
8237
8251
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8238
8252
  if (_this.debug) {
@@ -8264,17 +8278,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8264
8278
  value: function resumeContentPlayback() {
8265
8279
  var _this = this;
8266
8280
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8267
- var maxAttempts = 3;
8268
- if (!this.host.video.paused) {
8281
+ var maxAttempts = 5;
8282
+ var video = this.host.video;
8283
+ if (!video.paused) {
8269
8284
  if (this.debug && attempt === 0) {
8270
8285
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8271
8286
  }
8272
8287
  return;
8273
8288
  }
8274
8289
  if (this.debug) {
8275
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8290
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8276
8291
  }
8277
- var playResult = this.host.video.play();
8292
+ if (video.readyState < 3) {
8293
+ if (attempt + 1 >= maxAttempts) {
8294
+ var _video_play;
8295
+ if (this.debug) {
8296
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8297
+ }
8298
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8299
+ return;
8300
+ }
8301
+ var onReady = function onReady1() {
8302
+ video.removeEventListener("canplay", onReady);
8303
+ _this.resumeContentPlayback(attempt + 1);
8304
+ };
8305
+ video.addEventListener("canplay", onReady);
8306
+ var backoffMs = 500 * (attempt + 1);
8307
+ window.setTimeout(function() {
8308
+ video.removeEventListener("canplay", onReady);
8309
+ if (video.paused) {
8310
+ _this.resumeContentPlayback(attempt + 1);
8311
+ }
8312
+ }, backoffMs);
8313
+ return;
8314
+ }
8315
+ var playResult = video.play();
8278
8316
  if (playResult && typeof playResult.catch === "function") {
8279
8317
  playResult.catch(function(error) {
8280
8318
  if (attempt + 1 >= maxAttempts) {
@@ -8413,6 +8451,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8413
8451
  reloadLiveStream: function reloadLiveStream() {
8414
8452
  return _this.hlsEngine.reloadLiveStream();
8415
8453
  },
8454
+ recoverMediaError: function recoverMediaError() {
8455
+ return _this.hlsEngine.recoverMediaError();
8456
+ },
8416
8457
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8417
8458
  return _this.generatePodVastUrl(base, breakDurationMs);
8418
8459
  }