stormcloud-video-player 0.8.46 → 0.8.48

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.cjs CHANGED
@@ -557,6 +557,9 @@ __export(index_exports, {
557
557
  randomString: function randomString1() {
558
558
  return randomString;
559
559
  },
560
+ requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
561
+ return requiresMediaPipelineResetAfterAds;
562
+ },
560
563
  sendAdDetectTracking: function sendAdDetectTracking1() {
561
564
  return sendAdDetectTracking;
562
565
  },
@@ -589,15 +592,19 @@ var import_react = __toESM(require("react"), 1);
589
592
  var import_hls = __toESM(require("hls.js"), 1);
590
593
  var MAX_VAST_WRAPPER_DEPTH = 5;
591
594
  function createHlsAdPlayer(contentVideo, options) {
595
+ var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP;
592
596
  var adPlaying = false;
593
597
  var originalMutedState = false;
594
598
  var originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
595
599
  var listeners = /* @__PURE__ */ new Map();
596
600
  var licenseKey = options === null || options === void 0 ? void 0 : options.licenseKey;
597
601
  var mainHlsInstance = options === null || options === void 0 ? void 0 : options.mainHlsInstance;
598
- var adVideoElement;
602
+ var AD_CONTAINER_PROP = "__stormcloudAdContainer";
603
+ var AD_VIDEO_PROP = "__stormcloudAdVideo";
604
+ var adVideoElement = (_contentVideo_AD_VIDEO_PROP = contentVideo[AD_VIDEO_PROP]) !== null && _contentVideo_AD_VIDEO_PROP !== void 0 ? _contentVideo_AD_VIDEO_PROP : void 0;
599
605
  var adHls;
600
- var adContainerEl;
606
+ var adContainerEl = (_contentVideo_AD_CONTAINER_PROP = contentVideo[AD_CONTAINER_PROP]) !== null && _contentVideo_AD_CONTAINER_PROP !== void 0 ? _contentVideo_AD_CONTAINER_PROP : void 0;
607
+ var adEventHandlers = [];
601
608
  var currentAd;
602
609
  var podAds = [];
603
610
  var podIndex = 0;
@@ -752,6 +759,56 @@ function createHlsAdPlayer(contentVideo, options) {
752
759
  var url = mediaFile.url.toLowerCase();
753
760
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
754
761
  }
762
+ function isAudioMediaFile(mediaFile) {
763
+ var type = mediaFile.type.toLowerCase();
764
+ var url = (mediaFile.url.toLowerCase().split("?")[0] || "").trim();
765
+ return type.startsWith("audio/") || url.endsWith(".mp3") || url.endsWith(".aac") || url.endsWith(".m4a") || url.endsWith(".ogg") || url.endsWith(".oga") || url.endsWith(".opus") || url.endsWith(".wav") || url.endsWith(".weba");
766
+ }
767
+ function collectVideoMediaFiles(scope, verbose) {
768
+ var mediaFileElements = scope.querySelectorAll("MediaFile");
769
+ var mediaFiles = [];
770
+ if (verbose) {
771
+ console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
772
+ }
773
+ mediaFileElements.forEach(function(mf, index) {
774
+ var _mf_textContent;
775
+ var type = mf.getAttribute("type") || "";
776
+ var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
777
+ var width = mf.getAttribute("width") || "";
778
+ var height = mf.getAttribute("height") || "";
779
+ if (verbose) {
780
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
781
+ }
782
+ if (!url) {
783
+ if (verbose) {
784
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
785
+ }
786
+ return;
787
+ }
788
+ var bitrateAttr = mf.getAttribute("bitrate");
789
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
790
+ var mediaFile = {
791
+ url: url,
792
+ type: type,
793
+ width: parseInt(width || "1920", 10),
794
+ height: parseInt(height || "1080", 10),
795
+ bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
796
+ };
797
+ if (isAudioMediaFile(mediaFile)) {
798
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, ' skipped (audio-only, type="').concat(type, '") — audio ads are not played to avoid a black screen'));
799
+ return;
800
+ }
801
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
802
+ mediaFiles.push(mediaFile);
803
+ if (verbose) {
804
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
805
+ }
806
+ } else if (verbose) {
807
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
808
+ }
809
+ });
810
+ return mediaFiles;
811
+ }
755
812
  function createEmptyTrackingUrls() {
756
813
  return {
757
814
  impression: [],
@@ -839,37 +896,7 @@ function createHlsAdPlayer(contentVideo, options) {
839
896
  var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
840
897
  var durationParts = durationText.split(":");
841
898
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
842
- var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
843
- var mediaFiles = [];
844
- console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
845
- mediaFileElements.forEach(function(mf, index) {
846
- var _mf_textContent;
847
- var type = mf.getAttribute("type") || "";
848
- var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
849
- var width = mf.getAttribute("width") || "";
850
- var height = mf.getAttribute("height") || "";
851
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
852
- var mediaFile = {
853
- url: url,
854
- type: type,
855
- width: parseInt(width || "1920", 10),
856
- height: parseInt(height || "1080", 10),
857
- bitrate: void 0
858
- };
859
- if (!url) {
860
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
861
- return;
862
- }
863
- var bitrateAttr = mf.getAttribute("bitrate");
864
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
865
- mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
866
- if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
867
- mediaFiles.push(mediaFile);
868
- console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
869
- } else {
870
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
871
- }
872
- });
899
+ var mediaFiles = collectVideoMediaFiles(xmlDoc, true);
873
900
  if (mediaFiles.length === 0) {
874
901
  if (isNoAdAvailable) {
875
902
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
@@ -917,28 +944,7 @@ function createHlsAdPlayer(contentVideo, options) {
917
944
  var durationText = ((_adElement_querySelector3 = adElement.querySelector("Duration")) === null || _adElement_querySelector3 === void 0 ? void 0 : _adElement_querySelector3.textContent) || "00:00:30";
918
945
  var durationParts = durationText.split(":");
919
946
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
920
- var mediaFileElements = adElement.querySelectorAll("MediaFile");
921
- var mediaFiles = [];
922
- mediaFileElements.forEach(function(mf) {
923
- var _mf_textContent;
924
- var type = mf.getAttribute("type") || "";
925
- var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
926
- var width = mf.getAttribute("width") || "";
927
- var height = mf.getAttribute("height") || "";
928
- if (!url) return;
929
- var bitrateAttr = mf.getAttribute("bitrate");
930
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
931
- var mediaFile = {
932
- url: url,
933
- type: type,
934
- width: parseInt(width || "1920", 10),
935
- height: parseInt(height || "1080", 10),
936
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
937
- };
938
- if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
939
- mediaFiles.push(mediaFile);
940
- }
941
- });
947
+ var mediaFiles = collectVideoMediaFiles(adElement, false);
942
948
  if (mediaFiles.length === 0) {
943
949
  if (isNoAdAvailable) {
944
950
  console.warn("[HlsAdPlayer] Pod <Ad> indicates no ad available");
@@ -1241,7 +1247,8 @@ function createHlsAdPlayer(contentVideo, options) {
1241
1247
  }
1242
1248
  function setupAdEventListeners() {
1243
1249
  if (!adVideoElement || !currentAd) return;
1244
- adVideoElement.addEventListener("timeupdate", function() {
1250
+ if (adEventHandlers.length > 0) return;
1251
+ var onTimeUpdate = function onTimeUpdate() {
1245
1252
  if (!currentAd || !adVideoElement) return;
1246
1253
  noteAdProgress();
1247
1254
  var progress = adVideoElement.currentTime / currentAd.duration;
@@ -1257,15 +1264,15 @@ function createHlsAdPlayer(contentVideo, options) {
1257
1264
  trackingFired.thirdQuartile = true;
1258
1265
  fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);
1259
1266
  }
1260
- });
1261
- adVideoElement.addEventListener("playing", function() {
1267
+ };
1268
+ var onPlaying = function onPlaying() {
1262
1269
  startStallWatchdog();
1263
1270
  if (!currentAd || trackingFired.start) return;
1264
1271
  trackingFired.start = true;
1265
1272
  fireTrackingPixels(currentAd.trackingUrls.start);
1266
1273
  console.log("[HlsAdPlayer] Ad started playing");
1267
- });
1268
- adVideoElement.addEventListener("ended", function() {
1274
+ };
1275
+ var onEnded = function onEnded() {
1269
1276
  if (!currentAd || trackingFired.complete) return;
1270
1277
  trackingFired.complete = true;
1271
1278
  fireTrackingPixels(currentAd.trackingUrls.complete);
@@ -1274,8 +1281,8 @@ function createHlsAdPlayer(contentVideo, options) {
1274
1281
  return;
1275
1282
  }
1276
1283
  handleAdComplete();
1277
- });
1278
- adVideoElement.addEventListener("error", function(e) {
1284
+ };
1285
+ var onError = function onError(e) {
1279
1286
  if (!adPlaying) return;
1280
1287
  console.error("[HlsAdPlayer] Ad video error:", e);
1281
1288
  if (currentAd) {
@@ -1285,25 +1292,100 @@ function createHlsAdPlayer(contentVideo, options) {
1285
1292
  return;
1286
1293
  }
1287
1294
  handleAdError();
1288
- });
1289
- adVideoElement.addEventListener("volumechange", function() {
1290
- if (!currentAd) return;
1295
+ };
1296
+ var onVolumeChange = function onVolumeChange() {
1297
+ if (!currentAd || !adVideoElement) return;
1291
1298
  if (adVideoElement.muted) {
1292
1299
  fireTrackingPixels(currentAd.trackingUrls.mute);
1293
1300
  } else {
1294
1301
  fireTrackingPixels(currentAd.trackingUrls.unmute);
1295
1302
  }
1296
- });
1297
- adVideoElement.addEventListener("pause", function() {
1298
- if (currentAd && !adVideoElement.ended) {
1303
+ };
1304
+ var onPause = function onPause() {
1305
+ if (currentAd && adVideoElement && !adVideoElement.ended) {
1299
1306
  fireTrackingPixels(currentAd.trackingUrls.pause);
1300
1307
  }
1301
- });
1302
- adVideoElement.addEventListener("play", function() {
1303
- if (currentAd && adVideoElement.currentTime > 0) {
1308
+ };
1309
+ var onPlay = function onPlay() {
1310
+ if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {
1304
1311
  fireTrackingPixels(currentAd.trackingUrls.resume);
1305
1312
  }
1306
- });
1313
+ };
1314
+ adEventHandlers = [
1315
+ {
1316
+ type: "timeupdate",
1317
+ handler: onTimeUpdate
1318
+ },
1319
+ {
1320
+ type: "playing",
1321
+ handler: onPlaying
1322
+ },
1323
+ {
1324
+ type: "ended",
1325
+ handler: onEnded
1326
+ },
1327
+ {
1328
+ type: "error",
1329
+ handler: onError
1330
+ },
1331
+ {
1332
+ type: "volumechange",
1333
+ handler: onVolumeChange
1334
+ },
1335
+ {
1336
+ type: "pause",
1337
+ handler: onPause
1338
+ },
1339
+ {
1340
+ type: "play",
1341
+ handler: onPlay
1342
+ }
1343
+ ];
1344
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1345
+ try {
1346
+ for(var _iterator = adEventHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1347
+ var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
1348
+ adVideoElement.addEventListener(type, handler);
1349
+ }
1350
+ } catch (err) {
1351
+ _didIteratorError = true;
1352
+ _iteratorError = err;
1353
+ } finally{
1354
+ try {
1355
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1356
+ _iterator.return();
1357
+ }
1358
+ } finally{
1359
+ if (_didIteratorError) {
1360
+ throw _iteratorError;
1361
+ }
1362
+ }
1363
+ }
1364
+ }
1365
+ function teardownAdEventListeners() {
1366
+ if (adVideoElement) {
1367
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1368
+ try {
1369
+ for(var _iterator = adEventHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1370
+ var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
1371
+ adVideoElement.removeEventListener(type, handler);
1372
+ }
1373
+ } catch (err) {
1374
+ _didIteratorError = true;
1375
+ _iteratorError = err;
1376
+ } finally{
1377
+ try {
1378
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1379
+ _iterator.return();
1380
+ }
1381
+ } finally{
1382
+ if (_didIteratorError) {
1383
+ throw _iteratorError;
1384
+ }
1385
+ }
1386
+ }
1387
+ }
1388
+ adEventHandlers = [];
1307
1389
  }
1308
1390
  function setAdPlayingFlag(isPlaying) {
1309
1391
  if (isPlaying) {
@@ -1449,15 +1531,13 @@ function createHlsAdPlayer(contentVideo, options) {
1449
1531
  adHls = void 0;
1450
1532
  }
1451
1533
  if (adVideoElement) {
1452
- adVideoElement.pause();
1453
- adVideoElement.removeAttribute("src");
1454
1534
  try {
1535
+ adVideoElement.pause();
1536
+ adVideoElement.removeAttribute("src");
1455
1537
  adVideoElement.load();
1456
1538
  } catch (error) {
1457
- console.warn("[HlsAdPlayer] adVideoElement.load() threw after src removal:", error);
1539
+ console.warn("[HlsAdPlayer] Error releasing ad decoder:", error);
1458
1540
  }
1459
- adVideoElement.remove();
1460
- adVideoElement = void 0;
1461
1541
  }
1462
1542
  if (adContainerEl) {
1463
1543
  adContainerEl.style.display = "none";
@@ -1520,6 +1600,7 @@ function createHlsAdPlayer(contentVideo, options) {
1520
1600
  (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1521
1601
  adContainerEl = container;
1522
1602
  }
1603
+ contentVideo[AD_CONTAINER_PROP] = adContainerEl;
1523
1604
  },
1524
1605
  requestAds: function requestAds(vastTagUrl) {
1525
1606
  return _async_to_generator(function() {
@@ -1622,8 +1703,9 @@ function createHlsAdPlayer(contentVideo, options) {
1622
1703
  if (!adVideoElement) {
1623
1704
  adVideoElement = createAdVideoElement();
1624
1705
  adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.appendChild(adVideoElement);
1625
- setupAdEventListeners();
1706
+ contentVideo[AD_VIDEO_PROP] = adVideoElement;
1626
1707
  }
1708
+ setupAdEventListeners();
1627
1709
  resetQuartileTracking(true);
1628
1710
  contentVolume = contentVideo.volume;
1629
1711
  originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
@@ -1751,11 +1833,8 @@ function createHlsAdPlayer(contentVideo, options) {
1751
1833
  setAdPlayingFlag(false);
1752
1834
  contentVideo.muted = originalMutedState;
1753
1835
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
1836
+ teardownAdEventListeners();
1754
1837
  releaseAdDecoder();
1755
- if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
1756
- adContainerEl.parentElement.removeChild(adContainerEl);
1757
- }
1758
- adContainerEl = void 0;
1759
1838
  currentAd = void 0;
1760
1839
  podAds = [];
1761
1840
  podIndex = 0;
@@ -4189,6 +4268,11 @@ function detectBrowser() {
4189
4268
  chromeVersion: chromeVersionNum
4190
4269
  };
4191
4270
  }
4271
+ function requiresMediaPipelineResetAfterAds() {
4272
+ var _browser_tizenVersion;
4273
+ var browser = detectBrowser();
4274
+ return browser.name === "Samsung Tizen" && ((_browser_tizenVersion = browser.tizenVersion) !== null && _browser_tizenVersion !== void 0 ? _browser_tizenVersion : 0) >= 5;
4275
+ }
4192
4276
  function getBrowserConfigOverrides() {
4193
4277
  var browser = detectBrowser();
4194
4278
  var overrides = {};
@@ -6973,30 +7057,49 @@ var HlsEngine = /*#__PURE__*/ function() {
6973
7057
  {
6974
7058
  key: "reloadLiveStream",
6975
7059
  value: function reloadLiveStream() {
7060
+ var _this = this;
6976
7061
  var hls = this.hls;
6977
7062
  if (!hls) {
6978
7063
  return;
6979
7064
  }
6980
7065
  if (this.debug) {
6981
- console.log("[StormcloudVideoPlayer] Hard-reloading live stream (detach \u2192 reset video \u2192 re-attach)");
7066
+ console.log("[StormcloudVideoPlayer] Hard-reloading live stream (destroy hls \u2192 reset video \u2192 fresh setupHls)");
6982
7067
  }
6983
7068
  try {
6984
7069
  this.reloadingLiveStream = true;
6985
7070
  hls.stopLoad();
6986
7071
  hls.detachMedia();
7072
+ hls.destroy();
7073
+ this.hls = void 0;
6987
7074
  try {
6988
7075
  this.video.removeAttribute("src");
6989
7076
  this.video.load();
6990
7077
  } catch (error) {
6991
7078
  console.warn("[StormcloudVideoPlayer] video.load() threw after src removal:", error);
6992
7079
  }
6993
- hls.attachMedia(this.video);
6994
7080
  } catch (error) {
6995
7081
  this.reloadingLiveStream = false;
7082
+ this.hls = void 0;
6996
7083
  if (this.debug) {
6997
- console.warn("[StormcloudVideoPlayer] Failed to hard-reload live stream:", error);
7084
+ console.warn("[StormcloudVideoPlayer] Failed to tear down during hard-reload:", error);
6998
7085
  }
7086
+ return;
6999
7087
  }
7088
+ var recreateDelayMs = 600;
7089
+ window.setTimeout(function() {
7090
+ if (_this.hls) {
7091
+ _this.reloadingLiveStream = false;
7092
+ return;
7093
+ }
7094
+ try {
7095
+ _this.setupHls();
7096
+ } catch (error) {
7097
+ _this.reloadingLiveStream = false;
7098
+ if (_this.debug) {
7099
+ console.warn("[StormcloudVideoPlayer] Failed to rebuild pipeline during hard-reload:", error);
7100
+ }
7101
+ }
7102
+ }, recreateDelayMs);
7000
7103
  }
7001
7104
  },
7002
7105
  {
@@ -8309,6 +8412,14 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8309
8412
  this.host.video.style.visibility = "visible";
8310
8413
  this.host.video.style.opacity = "1";
8311
8414
  if (this.host.isLiveStream()) {
8415
+ if (this.host.requiresMediaPipelineResetAfterAds()) {
8416
+ if (this.debug) {
8417
+ console.log("[StormcloudVideoPlayer] Live break end \u2014 hard-reloading stream to reacquire decoder (single-decoder platform)");
8418
+ }
8419
+ this.host.reloadLiveStream();
8420
+ this.monitorLiveResumeStall(this.host.video.currentTime);
8421
+ return;
8422
+ }
8312
8423
  var liveSyncPos = this.host.getLiveSyncPosition();
8313
8424
  if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
8314
8425
  if (this.debug) {
@@ -8370,9 +8481,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8370
8481
  key: "monitorLiveResumeStall",
8371
8482
  value: function monitorLiveResumeStall(resumeBaseline) {
8372
8483
  var _this = this;
8484
+ var needsReset = this.host.requiresMediaPipelineResetAfterAds();
8373
8485
  var pollIntervalMs = 1e3;
8374
- var graceMs = 5e3;
8375
- var recoveryCooldownMs = 5e3;
8486
+ var graceMs = needsReset ? 8e3 : 5e3;
8487
+ var recoveryCooldownMs = needsReset ? 7e3 : 5e3;
8376
8488
  var maxRecoveries = 3;
8377
8489
  var maxMonitorMs = 45e3;
8378
8490
  var startTime = Date.now();
@@ -8486,7 +8598,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8486
8598
  if (canRecover) {
8487
8599
  recoveries++;
8488
8600
  lastRecoveryAt = Date.now();
8489
- if (recoveries === 1) {
8601
+ if (needsReset) {
8602
+ if (_this.debug) {
8603
+ console.warn("[StormcloudVideoPlayer] Content still wedged after ad break — hard-reloading live stream (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8604
+ }
8605
+ _this.host.reloadLiveStream();
8606
+ } else if (recoveries === 1) {
8490
8607
  if (_this.debug) {
8491
8608
  console.warn("[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8492
8609
  }
@@ -8699,6 +8816,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8699
8816
  recoverMediaError: function recoverMediaError() {
8700
8817
  return _this.hlsEngine.recoverMediaError();
8701
8818
  },
8819
+ requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
8820
+ return requiresMediaPipelineResetAfterAds();
8821
+ },
8702
8822
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8703
8823
  return _this.generatePodVastUrl(base, breakDurationMs);
8704
8824
  }
@@ -12051,6 +12171,7 @@ var StormcloudPlayer_default = StormcloudPlayer;
12051
12171
  players: players,
12052
12172
  publishMQTT: publishMQTT,
12053
12173
  randomString: randomString,
12174
+ requiresMediaPipelineResetAfterAds: requiresMediaPipelineResetAfterAds,
12054
12175
  sendAdDetectTracking: sendAdDetectTracking,
12055
12176
  sendAdImpressionTracking: sendAdImpressionTracking,
12056
12177
  sendAdLoadedTracking: sendAdLoadedTracking,