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.
@@ -1256,16 +1256,34 @@ function createHlsAdPlayer(contentVideo, options) {
1256
1256
  }
1257
1257
  }, STALL_CHECK_INTERVAL_MS);
1258
1258
  }
1259
+ function releaseAdDecoder() {
1260
+ if (adHls) {
1261
+ adHls.destroy();
1262
+ adHls = void 0;
1263
+ }
1264
+ if (adVideoElement) {
1265
+ adVideoElement.pause();
1266
+ adVideoElement.removeAttribute("src");
1267
+ try {
1268
+ adVideoElement.load();
1269
+ } catch (error) {
1270
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1271
+ }
1272
+ adVideoElement.remove();
1273
+ adVideoElement = void 0;
1274
+ }
1275
+ if (adContainerEl) {
1276
+ adContainerEl.style.display = "none";
1277
+ adContainerEl.style.pointerEvents = "none";
1278
+ }
1279
+ }
1259
1280
  function handleAdComplete() {
1260
1281
  console.log("[HlsAdPlayer] Handling ad completion");
1261
1282
  clearStallWatchdog();
1262
1283
  adPlaying = false;
1263
1284
  setAdPlayingFlag(false);
1264
1285
  contentVideo.muted = true;
1265
- if (adContainerEl) {
1266
- adContainerEl.style.display = "none";
1267
- adContainerEl.style.pointerEvents = "none";
1268
- }
1286
+ releaseAdDecoder();
1269
1287
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1270
1288
  contentVideo.style.visibility = "visible";
1271
1289
  contentVideo.style.opacity = "1";
@@ -1288,10 +1306,7 @@ function createHlsAdPlayer(contentVideo, options) {
1288
1306
  adPlaying = false;
1289
1307
  setAdPlayingFlag(false);
1290
1308
  contentVideo.muted = true;
1291
- if (adContainerEl) {
1292
- adContainerEl.style.display = "none";
1293
- adContainerEl.style.pointerEvents = "none";
1294
- }
1309
+ releaseAdDecoder();
1295
1310
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1296
1311
  contentVideo.style.visibility = "visible";
1297
1312
  contentVideo.style.opacity = "1";
@@ -1500,10 +1515,7 @@ function createHlsAdPlayer(contentVideo, options) {
1500
1515
  contentVideo.muted = originalMutedState;
1501
1516
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1502
1517
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1503
- if (adContainerEl) {
1504
- adContainerEl.style.display = "none";
1505
- adContainerEl.style.pointerEvents = "none";
1506
- }
1518
+ releaseAdDecoder();
1507
1519
  contentVideo.style.visibility = "visible";
1508
1520
  contentVideo.style.opacity = "1";
1509
1521
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
@@ -1514,17 +1526,6 @@ function createHlsAdPlayer(contentVideo, options) {
1514
1526
  });
1515
1527
  }
1516
1528
  }
1517
- if (adHls) {
1518
- adHls.destroy();
1519
- adHls = void 0;
1520
- }
1521
- if (adVideoElement) {
1522
- adVideoElement.pause();
1523
- adVideoElement.removeAttribute("src");
1524
- try {
1525
- adVideoElement.load();
1526
- } catch (unused) {}
1527
- }
1528
1529
  currentAd = void 0;
1529
1530
  podAds = [];
1530
1531
  podIndex = 0;
@@ -1563,19 +1564,7 @@ function createHlsAdPlayer(contentVideo, options) {
1563
1564
  setAdPlayingFlag(false);
1564
1565
  contentVideo.muted = originalMutedState;
1565
1566
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1566
- if (adHls) {
1567
- adHls.destroy();
1568
- adHls = void 0;
1569
- }
1570
- if (adVideoElement) {
1571
- adVideoElement.pause();
1572
- adVideoElement.removeAttribute("src");
1573
- try {
1574
- adVideoElement.load();
1575
- } catch (unused) {}
1576
- adVideoElement.remove();
1577
- adVideoElement = void 0;
1578
- }
1567
+ releaseAdDecoder();
1579
1568
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1580
1569
  adContainerEl.parentElement.removeChild(adContainerEl);
1581
1570
  }
@@ -6735,6 +6724,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6735
6724
  }
6736
6725
  }
6737
6726
  },
6727
+ {
6728
+ key: "recoverMediaError",
6729
+ value: function recoverMediaError() {
6730
+ if (!this.hls) {
6731
+ return;
6732
+ }
6733
+ try {
6734
+ this.hls.recoverMediaError();
6735
+ } catch (error) {
6736
+ if (this.debug) {
6737
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6738
+ }
6739
+ }
6740
+ }
6741
+ },
6738
6742
  {
6739
6743
  key: "reloadLiveStream",
6740
6744
  value: function reloadLiveStream() {
@@ -6752,7 +6756,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6752
6756
  try {
6753
6757
  this.video.removeAttribute("src");
6754
6758
  this.video.load();
6755
- } catch (unused) {}
6759
+ } catch (error) {
6760
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6761
+ }
6756
6762
  hls.attachMedia(this.video);
6757
6763
  } catch (error) {
6758
6764
  this.reloadingLiveStream = false;
@@ -8136,8 +8142,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8136
8142
  var pollIntervalMs = 1e3;
8137
8143
  var graceMs = 5e3;
8138
8144
  var recoveryCooldownMs = 5e3;
8139
- var maxRecoveries = 2;
8140
- var maxMonitorMs = 3e4;
8145
+ var maxRecoveries = 3;
8146
+ var maxMonitorMs = 45e3;
8141
8147
  var startTime = Date.now();
8142
8148
  var baseline = resumeBaseline;
8143
8149
  var recoveries = 0;
@@ -8249,8 +8255,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8249
8255
  if (canRecover) {
8250
8256
  recoveries++;
8251
8257
  lastRecoveryAt = Date.now();
8252
- var isFinalAttempt = recoveries >= maxRecoveries;
8253
- if (!isFinalAttempt) {
8258
+ if (recoveries === 1) {
8259
+ if (_this.debug) {
8260
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8261
+ }
8262
+ _this.host.recoverMediaError();
8263
+ } else if (recoveries === 2) {
8254
8264
  var liveSyncPos = _this.host.getLiveSyncPosition();
8255
8265
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8256
8266
  if (_this.debug) {
@@ -8282,17 +8292,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8282
8292
  value: function resumeContentPlayback() {
8283
8293
  var _this = this;
8284
8294
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8285
- var maxAttempts = 3;
8286
- if (!this.host.video.paused) {
8295
+ var maxAttempts = 5;
8296
+ var video = this.host.video;
8297
+ if (!video.paused) {
8287
8298
  if (this.debug && attempt === 0) {
8288
8299
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8289
8300
  }
8290
8301
  return;
8291
8302
  }
8292
8303
  if (this.debug) {
8293
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8304
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8294
8305
  }
8295
- var playResult = this.host.video.play();
8306
+ if (video.readyState < 3) {
8307
+ if (attempt + 1 >= maxAttempts) {
8308
+ var _video_play;
8309
+ if (this.debug) {
8310
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8311
+ }
8312
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8313
+ return;
8314
+ }
8315
+ var onReady = function onReady1() {
8316
+ video.removeEventListener("canplay", onReady);
8317
+ _this.resumeContentPlayback(attempt + 1);
8318
+ };
8319
+ video.addEventListener("canplay", onReady);
8320
+ var backoffMs = 500 * (attempt + 1);
8321
+ window.setTimeout(function() {
8322
+ video.removeEventListener("canplay", onReady);
8323
+ if (video.paused) {
8324
+ _this.resumeContentPlayback(attempt + 1);
8325
+ }
8326
+ }, backoffMs);
8327
+ return;
8328
+ }
8329
+ var playResult = video.play();
8296
8330
  if (playResult && typeof playResult.catch === "function") {
8297
8331
  playResult.catch(function(error) {
8298
8332
  if (attempt + 1 >= maxAttempts) {
@@ -8431,6 +8465,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8431
8465
  reloadLiveStream: function reloadLiveStream() {
8432
8466
  return _this.hlsEngine.reloadLiveStream();
8433
8467
  },
8468
+ recoverMediaError: function recoverMediaError() {
8469
+ return _this.hlsEngine.recoverMediaError();
8470
+ },
8434
8471
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8435
8472
  return _this.generatePodVastUrl(base, breakDurationMs);
8436
8473
  }