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.
@@ -1205,16 +1205,34 @@ function createHlsAdPlayer(contentVideo, options) {
1205
1205
  }
1206
1206
  }, STALL_CHECK_INTERVAL_MS);
1207
1207
  }
1208
+ function releaseAdDecoder() {
1209
+ if (adHls) {
1210
+ adHls.destroy();
1211
+ adHls = void 0;
1212
+ }
1213
+ if (adVideoElement) {
1214
+ adVideoElement.pause();
1215
+ adVideoElement.removeAttribute("src");
1216
+ try {
1217
+ adVideoElement.load();
1218
+ } catch (error) {
1219
+ console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1220
+ }
1221
+ adVideoElement.remove();
1222
+ adVideoElement = void 0;
1223
+ }
1224
+ if (adContainerEl) {
1225
+ adContainerEl.style.display = "none";
1226
+ adContainerEl.style.pointerEvents = "none";
1227
+ }
1228
+ }
1208
1229
  function handleAdComplete() {
1209
1230
  console.log("[HlsAdPlayer] Handling ad completion");
1210
1231
  clearStallWatchdog();
1211
1232
  adPlaying = false;
1212
1233
  setAdPlayingFlag(false);
1213
1234
  contentVideo.muted = true;
1214
- if (adContainerEl) {
1215
- adContainerEl.style.display = "none";
1216
- adContainerEl.style.pointerEvents = "none";
1217
- }
1235
+ releaseAdDecoder();
1218
1236
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1219
1237
  contentVideo.style.visibility = "visible";
1220
1238
  contentVideo.style.opacity = "1";
@@ -1237,10 +1255,7 @@ function createHlsAdPlayer(contentVideo, options) {
1237
1255
  adPlaying = false;
1238
1256
  setAdPlayingFlag(false);
1239
1257
  contentVideo.muted = true;
1240
- if (adContainerEl) {
1241
- adContainerEl.style.display = "none";
1242
- adContainerEl.style.pointerEvents = "none";
1243
- }
1258
+ releaseAdDecoder();
1244
1259
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1245
1260
  contentVideo.style.visibility = "visible";
1246
1261
  contentVideo.style.opacity = "1";
@@ -1449,10 +1464,7 @@ function createHlsAdPlayer(contentVideo, options) {
1449
1464
  contentVideo.muted = originalMutedState;
1450
1465
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1451
1466
  console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState, ", volume: ").concat(contentVideo.volume));
1452
- if (adContainerEl) {
1453
- adContainerEl.style.display = "none";
1454
- adContainerEl.style.pointerEvents = "none";
1455
- }
1467
+ releaseAdDecoder();
1456
1468
  contentVideo.style.visibility = "visible";
1457
1469
  contentVideo.style.opacity = "1";
1458
1470
  if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
@@ -1463,17 +1475,6 @@ function createHlsAdPlayer(contentVideo, options) {
1463
1475
  });
1464
1476
  }
1465
1477
  }
1466
- if (adHls) {
1467
- adHls.destroy();
1468
- adHls = void 0;
1469
- }
1470
- if (adVideoElement) {
1471
- adVideoElement.pause();
1472
- adVideoElement.removeAttribute("src");
1473
- try {
1474
- adVideoElement.load();
1475
- } catch (unused) {}
1476
- }
1477
1478
  currentAd = void 0;
1478
1479
  podAds = [];
1479
1480
  podIndex = 0;
@@ -1512,19 +1513,7 @@ function createHlsAdPlayer(contentVideo, options) {
1512
1513
  setAdPlayingFlag(false);
1513
1514
  contentVideo.muted = originalMutedState;
1514
1515
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1515
- if (adHls) {
1516
- adHls.destroy();
1517
- adHls = void 0;
1518
- }
1519
- if (adVideoElement) {
1520
- adVideoElement.pause();
1521
- adVideoElement.removeAttribute("src");
1522
- try {
1523
- adVideoElement.load();
1524
- } catch (unused) {}
1525
- adVideoElement.remove();
1526
- adVideoElement = void 0;
1527
- }
1516
+ releaseAdDecoder();
1528
1517
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1529
1518
  adContainerEl.parentElement.removeChild(adContainerEl);
1530
1519
  }
@@ -6684,6 +6673,21 @@ var HlsEngine = /*#__PURE__*/ function() {
6684
6673
  }
6685
6674
  }
6686
6675
  },
6676
+ {
6677
+ key: "recoverMediaError",
6678
+ value: function recoverMediaError() {
6679
+ if (!this.hls) {
6680
+ return;
6681
+ }
6682
+ try {
6683
+ this.hls.recoverMediaError();
6684
+ } catch (error) {
6685
+ if (this.debug) {
6686
+ console.warn("[StormcloudVideoPlayer] recoverMediaError() failed:", error);
6687
+ }
6688
+ }
6689
+ }
6690
+ },
6687
6691
  {
6688
6692
  key: "reloadLiveStream",
6689
6693
  value: function reloadLiveStream() {
@@ -6701,7 +6705,9 @@ var HlsEngine = /*#__PURE__*/ function() {
6701
6705
  try {
6702
6706
  this.video.removeAttribute("src");
6703
6707
  this.video.load();
6704
- } catch (unused) {}
6708
+ } catch (error) {
6709
+ console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6710
+ }
6705
6711
  hls.attachMedia(this.video);
6706
6712
  } catch (error) {
6707
6713
  this.reloadingLiveStream = false;
@@ -8085,8 +8091,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8085
8091
  var pollIntervalMs = 1e3;
8086
8092
  var graceMs = 5e3;
8087
8093
  var recoveryCooldownMs = 5e3;
8088
- var maxRecoveries = 2;
8089
- var maxMonitorMs = 3e4;
8094
+ var maxRecoveries = 3;
8095
+ var maxMonitorMs = 45e3;
8090
8096
  var startTime = Date.now();
8091
8097
  var baseline = resumeBaseline;
8092
8098
  var recoveries = 0;
@@ -8198,8 +8204,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8198
8204
  if (canRecover) {
8199
8205
  recoveries++;
8200
8206
  lastRecoveryAt = Date.now();
8201
- var isFinalAttempt = recoveries >= maxRecoveries;
8202
- if (!isFinalAttempt) {
8207
+ if (recoveries === 1) {
8208
+ if (_this.debug) {
8209
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8210
+ }
8211
+ _this.host.recoverMediaError();
8212
+ } else if (recoveries === 2) {
8203
8213
  var liveSyncPos = _this.host.getLiveSyncPosition();
8204
8214
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8205
8215
  if (_this.debug) {
@@ -8231,17 +8241,41 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8231
8241
  value: function resumeContentPlayback() {
8232
8242
  var _this = this;
8233
8243
  var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
8234
- var maxAttempts = 3;
8235
- if (!this.host.video.paused) {
8244
+ var maxAttempts = 5;
8245
+ var video = this.host.video;
8246
+ if (!video.paused) {
8236
8247
  if (this.debug && attempt === 0) {
8237
8248
  console.log("[StormcloudVideoPlayer] Content video already playing after ads");
8238
8249
  }
8239
8250
  return;
8240
8251
  }
8241
8252
  if (this.debug) {
8242
- console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
8253
+ console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ", readyState=").concat(video.readyState, ")"));
8243
8254
  }
8244
- var playResult = this.host.video.play();
8255
+ if (video.readyState < 3) {
8256
+ if (attempt + 1 >= maxAttempts) {
8257
+ var _video_play;
8258
+ if (this.debug) {
8259
+ console.warn("[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()");
8260
+ }
8261
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
8262
+ return;
8263
+ }
8264
+ var onReady = function onReady1() {
8265
+ video.removeEventListener("canplay", onReady);
8266
+ _this.resumeContentPlayback(attempt + 1);
8267
+ };
8268
+ video.addEventListener("canplay", onReady);
8269
+ var backoffMs = 500 * (attempt + 1);
8270
+ window.setTimeout(function() {
8271
+ video.removeEventListener("canplay", onReady);
8272
+ if (video.paused) {
8273
+ _this.resumeContentPlayback(attempt + 1);
8274
+ }
8275
+ }, backoffMs);
8276
+ return;
8277
+ }
8278
+ var playResult = video.play();
8245
8279
  if (playResult && typeof playResult.catch === "function") {
8246
8280
  playResult.catch(function(error) {
8247
8281
  if (attempt + 1 >= maxAttempts) {
@@ -8380,6 +8414,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8380
8414
  reloadLiveStream: function reloadLiveStream() {
8381
8415
  return _this.hlsEngine.reloadLiveStream();
8382
8416
  },
8417
+ recoverMediaError: function recoverMediaError() {
8418
+ return _this.hlsEngine.recoverMediaError();
8419
+ },
8383
8420
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8384
8421
  return _this.generatePodVastUrl(base, breakDurationMs);
8385
8422
  }