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.js CHANGED
@@ -1226,16 +1226,34 @@ function createHlsAdPlayer(contentVideo, options) {
1226
1226
  }
1227
1227
  }, STALL_CHECK_INTERVAL_MS);
1228
1228
  }
1229
+ function releaseAdDecoder() {
1230
+ if (adHls) {
1231
+ adHls.destroy();
1232
+ adHls = void 0;
1233
+ }
1234
+ if (adVideoElement) {
1235
+ adVideoElement.pause();
1236
+ adVideoElement.removeAttribute("src");
1237
+ try {
1238
+ adVideoElement.load();
1239
+ } catch (error) {
1240
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1241
+ }
1242
+ adVideoElement.remove();
1243
+ adVideoElement = void 0;
1244
+ }
1245
+ if (adContainerEl) {
1246
+ adContainerEl.style.display = "none";
1247
+ adContainerEl.style.pointerEvents = "none";
1248
+ }
1249
+ }
1229
1250
  function handleAdComplete() {
1230
1251
  console.log("[HlsAdPlayer] Handling ad completion");
1231
1252
  clearStallWatchdog();
1232
1253
  adPlaying = false;
1233
1254
  setAdPlayingFlag(false);
1234
1255
  contentVideo.muted = true;
1235
- if (adContainerEl) {
1236
- adContainerEl.style.display = "none";
1237
- adContainerEl.style.pointerEvents = "none";
1238
- }
1256
+ releaseAdDecoder();
1239
1257
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1240
1258
  contentVideo.style.visibility = "visible";
1241
1259
  contentVideo.style.opacity = "1";
@@ -1258,10 +1276,7 @@ function createHlsAdPlayer(contentVideo, options) {
1258
1276
  adPlaying = false;
1259
1277
  setAdPlayingFlag(false);
1260
1278
  contentVideo.muted = true;
1261
- if (adContainerEl) {
1262
- adContainerEl.style.display = "none";
1263
- adContainerEl.style.pointerEvents = "none";
1264
- }
1279
+ releaseAdDecoder();
1265
1280
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1266
1281
  contentVideo.style.visibility = "visible";
1267
1282
  contentVideo.style.opacity = "1";
@@ -1470,10 +1485,7 @@ function createHlsAdPlayer(contentVideo, options) {
1470
1485
  contentVideo.muted = originalMutedState;
1471
1486
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1472
1487
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1473
- if (adContainerEl) {
1474
- adContainerEl.style.display = "none";
1475
- adContainerEl.style.pointerEvents = "none";
1476
- }
1488
+ releaseAdDecoder();
1477
1489
  contentVideo.style.visibility = "visible";
1478
1490
  contentVideo.style.opacity = "1";
1479
1491
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
@@ -1484,17 +1496,6 @@ function createHlsAdPlayer(contentVideo, options) {
1484
1496
  });
1485
1497
  }
1486
1498
  }
1487
- if (adHls) {
1488
- adHls.destroy();
1489
- adHls = void 0;
1490
- }
1491
- if (adVideoElement) {
1492
- adVideoElement.pause();
1493
- adVideoElement.removeAttribute("src");
1494
- try {
1495
- adVideoElement.load();
1496
- } catch (unused) {}
1497
- }
1498
1499
  currentAd = void 0;
1499
1500
  podAds = [];
1500
1501
  podIndex = 0;
@@ -1533,19 +1534,7 @@ function createHlsAdPlayer(contentVideo, options) {
1533
1534
  setAdPlayingFlag(false);
1534
1535
  contentVideo.muted = originalMutedState;
1535
1536
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1536
- if (adHls) {
1537
- adHls.destroy();
1538
- adHls = void 0;
1539
- }
1540
- if (adVideoElement) {
1541
- adVideoElement.pause();
1542
- adVideoElement.removeAttribute("src");
1543
- try {
1544
- adVideoElement.load();
1545
- } catch (unused) {}
1546
- adVideoElement.remove();
1547
- adVideoElement = void 0;
1548
- }
1537
+ releaseAdDecoder();
1549
1538
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1550
1539
  adContainerEl.parentElement.removeChild(adContainerEl);
1551
1540
  }
@@ -6757,6 +6746,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6757
6746
  }
6758
6747
  }
6759
6748
  },
6749
+ {
6750
+ key: "recoverMediaError",
6751
+ value: function recoverMediaError() {
6752
+ if (!this.hls) {
6753
+ return;
6754
+ }
6755
+ try {
6756
+ this.hls.recoverMediaError();
6757
+ } catch (error) {
6758
+ if (this.debug) {
6759
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6760
+ }
6761
+ }
6762
+ }
6763
+ },
6760
6764
  {
6761
6765
  key: "reloadLiveStream",
6762
6766
  value: function reloadLiveStream() {
@@ -6774,7 +6778,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6774
6778
  try {
6775
6779
  this.video.removeAttribute("src");
6776
6780
  this.video.load();
6777
- } catch (unused) {}
6781
+ } catch (error) {
6782
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6783
+ }
6778
6784
  hls.attachMedia(this.video);
6779
6785
  } catch (error) {
6780
6786
  this.reloadingLiveStream = false;
@@ -8159,8 +8165,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8159
8165
  var pollIntervalMs = 1e3;
8160
8166
  var graceMs = 5e3;
8161
8167
  var recoveryCooldownMs = 5e3;
8162
- var maxRecoveries = 2;
8163
- var maxMonitorMs = 3e4;
8168
+ var maxRecoveries = 3;
8169
+ var maxMonitorMs = 45e3;
8164
8170
  var startTime = Date.now();
8165
8171
  var baseline = resumeBaseline;
8166
8172
  var recoveries = 0;
@@ -8272,8 +8278,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8272
8278
  if (canRecover) {
8273
8279
  recoveries++;
8274
8280
  lastRecoveryAt = Date.now();
8275
- var isFinalAttempt = recoveries >= maxRecoveries;
8276
- if (!isFinalAttempt) {
8281
+ if (recoveries === 1) {
8282
+ if (_this.debug) {
8283
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8284
+ }
8285
+ _this.host.recoverMediaError();
8286
+ } else if (recoveries === 2) {
8277
8287
  var liveSyncPos = _this.host.getLiveSyncPosition();
8278
8288
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8279
8289
  if (_this.debug) {
@@ -8305,17 +8315,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8305
8315
  value: function resumeContentPlayback() {
8306
8316
  var _this = this;
8307
8317
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8308
- var maxAttempts = 3;
8309
- if (!this.host.video.paused) {
8318
+ var maxAttempts = 5;
8319
+ var video = this.host.video;
8320
+ if (!video.paused) {
8310
8321
  if (this.debug && attempt === 0) {
8311
8322
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8312
8323
  }
8313
8324
  return;
8314
8325
  }
8315
8326
  if (this.debug) {
8316
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8327
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8317
8328
  }
8318
- var playResult = this.host.video.play();
8329
+ if (video.readyState < 3) {
8330
+ if (attempt + 1 >= maxAttempts) {
8331
+ var _video_play;
8332
+ if (this.debug) {
8333
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8334
+ }
8335
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8336
+ return;
8337
+ }
8338
+ var onReady = function onReady1() {
8339
+ video.removeEventListener("canplay", onReady);
8340
+ _this.resumeContentPlayback(attempt + 1);
8341
+ };
8342
+ video.addEventListener("canplay", onReady);
8343
+ var backoffMs = 500 * (attempt + 1);
8344
+ window.setTimeout(function() {
8345
+ video.removeEventListener("canplay", onReady);
8346
+ if (video.paused) {
8347
+ _this.resumeContentPlayback(attempt + 1);
8348
+ }
8349
+ }, backoffMs);
8350
+ return;
8351
+ }
8352
+ var playResult = video.play();
8319
8353
  if (playResult && typeof playResult.catch === "function") {
8320
8354
  playResult.catch(function(error) {
8321
8355
  if (attempt + 1 >= maxAttempts) {
@@ -8455,6 +8489,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8455
8489
  reloadLiveStream: function reloadLiveStream() {
8456
8490
  return _this.hlsEngine.reloadLiveStream();
8457
8491
  },
8492
+ recoverMediaError: function recoverMediaError() {
8493
+ return _this.hlsEngine.recoverMediaError();
8494
+ },
8458
8495
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8459
8496
  return _this.generatePodVastUrl(base, breakDurationMs);
8460
8497
  }