stormcloud-video-player 0.8.42 → 0.8.44

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
@@ -6483,6 +6483,7 @@ var HlsEngine = /*#__PURE__*/ function() {
6483
6483
  this.isLiveStream = false;
6484
6484
  this.nativeHlsMode = false;
6485
6485
  this.videoSrcProtection = null;
6486
+ this.reloadingLiveStream = false;
6486
6487
  this.bufferedSegmentsCount = 0;
6487
6488
  this.shouldAutoplayAfterBuffering = false;
6488
6489
  this.hasInitialBufferCompleted = false;
@@ -6616,6 +6617,7 @@ var HlsEngine = /*#__PURE__*/ function() {
6616
6617
  _state.sent();
6617
6618
  _state.label = 3;
6618
6619
  case 3:
6620
+ this.reloadingLiveStream = false;
6619
6621
  return [
6620
6622
  2
6621
6623
  ];
@@ -6960,6 +6962,33 @@ var HlsEngine = /*#__PURE__*/ function() {
6960
6962
  }
6961
6963
  }
6962
6964
  },
6965
+ {
6966
+ key: "reloadLiveStream",
6967
+ value: function reloadLiveStream() {
6968
+ var hls = this.hls;
6969
+ if (!hls) {
6970
+ return;
6971
+ }
6972
+ if (this.debug) {
6973
+ console.log("[StormcloudVideoPlayer] Hard-reloading live stream (detach \u2192 reset video \u2192 re-attach)");
6974
+ }
6975
+ try {
6976
+ this.reloadingLiveStream = true;
6977
+ hls.stopLoad();
6978
+ hls.detachMedia();
6979
+ try {
6980
+ this.video.removeAttribute("src");
6981
+ this.video.load();
6982
+ } catch (unused) {}
6983
+ hls.attachMedia(this.video);
6984
+ } catch (error) {
6985
+ this.reloadingLiveStream = false;
6986
+ if (this.debug) {
6987
+ console.warn("[StormcloudVideoPlayer] Failed to hard-reload live stream:", error);
6988
+ }
6989
+ }
6990
+ }
6991
+ },
6963
6992
  {
6964
6993
  key: "destroy",
6965
6994
  value: function destroy() {
@@ -8299,31 +8328,134 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8299
8328
  return 0;
8300
8329
  }
8301
8330
  },
8331
+ {
8332
+ key: "describeVideoState",
8333
+ value: function describeVideoState() {
8334
+ var _networkStates_v_networkState, _readyStates_v_readyState;
8335
+ var v = this.host.video;
8336
+ var networkStates = [
8337
+ "EMPTY",
8338
+ "IDLE",
8339
+ "LOADING",
8340
+ "NO_SOURCE"
8341
+ ];
8342
+ var readyStates = [
8343
+ "HAVE_NOTHING",
8344
+ "HAVE_METADATA",
8345
+ "HAVE_CURRENT_DATA",
8346
+ "HAVE_FUTURE_DATA",
8347
+ "HAVE_ENOUGH_DATA"
8348
+ ];
8349
+ var net = (_networkStates_v_networkState = networkStates[v.networkState]) !== null && _networkStates_v_networkState !== void 0 ? _networkStates_v_networkState : String(v.networkState);
8350
+ var ready = (_readyStates_v_readyState = readyStates[v.readyState]) !== null && _readyStates_v_readyState !== void 0 ? _readyStates_v_readyState : String(v.readyState);
8351
+ var err = v.error ? "code=".concat(v.error.code).concat(v.error.message ? " (".concat(v.error.message, ")") : "") : "none";
8352
+ var ranges = [];
8353
+ for(var i = 0; i < v.buffered.length; i++){
8354
+ ranges.push("[".concat(v.buffered.start(i).toFixed(2), "–").concat(v.buffered.end(i).toFixed(2), "]"));
8355
+ }
8356
+ return "t=".concat(v.currentTime.toFixed(2), "s paused=").concat(v.paused, " ended=").concat(v.ended, " seeking=").concat(v.seeking, " readyState=").concat(ready, " networkState=").concat(net, " error=").concat(err, " buffered=").concat(ranges.length ? ranges.join(",") : "none");
8357
+ }
8358
+ },
8302
8359
  {
8303
8360
  key: "monitorLiveResumeStall",
8304
8361
  value: function monitorLiveResumeStall(resumeBaseline) {
8305
8362
  var _this = this;
8306
8363
  var pollIntervalMs = 1e3;
8307
8364
  var graceMs = 5e3;
8308
- var reloadCooldownMs = 5e3;
8309
- var maxHardReloads = 2;
8310
- var maxMonitorMs = 25e3;
8365
+ var recoveryCooldownMs = 5e3;
8366
+ var maxRecoveries = 2;
8367
+ var maxMonitorMs = 3e4;
8311
8368
  var startTime = Date.now();
8312
8369
  var baseline = resumeBaseline;
8313
- var hardReloads = 0;
8314
- var lastReloadAt = 0;
8370
+ var recoveries = 0;
8371
+ var lastRecoveryAt = 0;
8372
+ var video = this.host.video;
8373
+ var listenersAttached = false;
8374
+ var onMediaEvent;
8375
+ var diagEvents = [
8376
+ "loadstart",
8377
+ "loadedmetadata",
8378
+ "loadeddata",
8379
+ "canplay",
8380
+ "canplaythrough",
8381
+ "play",
8382
+ "playing",
8383
+ "pause",
8384
+ "waiting",
8385
+ "stalled",
8386
+ "suspend",
8387
+ "seeking",
8388
+ "seeked",
8389
+ "emptied",
8390
+ "error",
8391
+ "ended"
8392
+ ];
8393
+ if (this.debug) {
8394
+ onMediaEvent = function onMediaEvent(e) {
8395
+ var dt = ((Date.now() - startTime) / 1e3).toFixed(1);
8396
+ console.log("[ResumeDiag] +".concat(dt, "s event=").concat(e.type, " — ").concat(_this.describeVideoState()));
8397
+ };
8398
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8399
+ try {
8400
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8401
+ var name = _step.value;
8402
+ video.addEventListener(name, onMediaEvent);
8403
+ }
8404
+ } catch (err) {
8405
+ _didIteratorError = true;
8406
+ _iteratorError = err;
8407
+ } finally{
8408
+ try {
8409
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8410
+ _iterator.return();
8411
+ }
8412
+ } finally{
8413
+ if (_didIteratorError) {
8414
+ throw _iteratorError;
8415
+ }
8416
+ }
8417
+ }
8418
+ listenersAttached = true;
8419
+ console.log("[ResumeDiag] +0.0s monitor start — ".concat(this.describeVideoState()));
8420
+ }
8421
+ var cleanup = function cleanup() {
8422
+ if (listenersAttached && onMediaEvent) {
8423
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8424
+ try {
8425
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8426
+ var name = _step.value;
8427
+ video.removeEventListener(name, onMediaEvent);
8428
+ }
8429
+ } catch (err) {
8430
+ _didIteratorError = true;
8431
+ _iteratorError = err;
8432
+ } finally{
8433
+ try {
8434
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8435
+ _iterator.return();
8436
+ }
8437
+ } finally{
8438
+ if (_didIteratorError) {
8439
+ throw _iteratorError;
8440
+ }
8441
+ }
8442
+ }
8443
+ listenersAttached = false;
8444
+ }
8445
+ };
8315
8446
  var poll = function poll1() {
8316
8447
  if (_this.inAdBreak) {
8448
+ cleanup();
8317
8449
  return;
8318
8450
  }
8319
- var video = _this.host.video;
8320
8451
  var currentTime = video.currentTime;
8321
8452
  var advanced = currentTime > baseline + 0.5;
8322
8453
  var playing = !video.paused && video.readyState >= 3;
8323
8454
  if (advanced && playing) {
8324
8455
  if (_this.debug) {
8325
- console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break");
8456
+ console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break".concat(_this.describeVideoState()));
8326
8457
  }
8458
+ cleanup();
8327
8459
  return;
8328
8460
  }
8329
8461
  if (video.paused) {
@@ -8335,23 +8467,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8335
8467
  var wedged = bufferedAhead < 0.5 && !advanced;
8336
8468
  if (elapsed >= maxMonitorMs) {
8337
8469
  if (_this.debug && !advanced) {
8338
- console.warn("[StormcloudVideoPlayer] Live stream failed to resume after ".concat((maxMonitorMs / 1e3).toFixed(0), "s (t=").concat(currentTime.toFixed(2), "s, buffered=").concat(bufferedAhead.toFixed(2), "s)"));
8470
+ console.warn("[StormcloudVideoPlayer] Live stream failed to resume after ".concat((maxMonitorMs / 1e3).toFixed(0), "s ").concat(_this.describeVideoState()));
8339
8471
  }
8472
+ cleanup();
8340
8473
  return;
8341
8474
  }
8342
- var canHardReload = wedged && elapsed >= graceMs && Date.now() - lastReloadAt >= reloadCooldownMs && hardReloads < maxHardReloads;
8343
- if (canHardReload) {
8344
- hardReloads++;
8345
- lastReloadAt = Date.now();
8346
- var liveSyncPos = _this.host.getLiveSyncPosition();
8347
- var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8348
- if (_this.debug) {
8349
- console.warn("[StormcloudVideoPlayer] Content wedged after ad break (t=".concat(currentTime.toFixed(2), "s, buffered=").concat(bufferedAhead.toFixed(2), "s) forcing HLS reload at ").concat(reloadPos.toFixed(2), "s (hard reload ").concat(hardReloads, "/").concat(maxHardReloads, ")"));
8350
- }
8351
- if (liveSyncPos != null && liveSyncPos > currentTime) {
8352
- video.currentTime = liveSyncPos;
8475
+ var canRecover = wedged && elapsed >= graceMs && Date.now() - lastRecoveryAt >= recoveryCooldownMs && recoveries < maxRecoveries;
8476
+ if (canRecover) {
8477
+ recoveries++;
8478
+ lastRecoveryAt = Date.now();
8479
+ var isFinalAttempt = recoveries >= maxRecoveries;
8480
+ if (!isFinalAttempt) {
8481
+ var liveSyncPos = _this.host.getLiveSyncPosition();
8482
+ var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8483
+ if (_this.debug) {
8484
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — restarting HLS load at ".concat(reloadPos.toFixed(2), "s (recovery ").concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8485
+ }
8486
+ if (liveSyncPos != null && liveSyncPos > currentTime) {
8487
+ video.currentTime = liveSyncPos;
8488
+ }
8489
+ _this.host.restartHlsLoad(reloadPos);
8490
+ } else {
8491
+ if (_this.debug) {
8492
+ console.warn("[StormcloudVideoPlayer] Content still wedged after ad break — hard-reloading live stream (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8493
+ }
8494
+ _this.host.reloadLiveStream();
8353
8495
  }
8354
- _this.host.restartHlsLoad(reloadPos);
8355
8496
  baseline = video.currentTime;
8356
8497
  if (video.paused) {
8357
8498
  var _video_play1;
@@ -8514,6 +8655,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8514
8655
  restartHlsLoad: function restartHlsLoad(position) {
8515
8656
  return _this.hlsEngine.restartLoadAt(position);
8516
8657
  },
8658
+ reloadLiveStream: function reloadLiveStream() {
8659
+ return _this.hlsEngine.reloadLiveStream();
8660
+ },
8517
8661
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8518
8662
  return _this.generatePodVastUrl(base, breakDurationMs);
8519
8663
  }
@@ -8645,6 +8789,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8645
8789
  return _async_to_generator(function() {
8646
8790
  var prerollKey, adBehavior;
8647
8791
  return _ts_generator(this, function(_state) {
8792
+ if (this.hlsEngine.reloadingLiveStream) {
8793
+ if (this.debug) {
8794
+ console.log("[StormcloudVideoPlayer] Manifest re-parsed after hard reload \u2014 skipping ad-player setup");
8795
+ }
8796
+ return [
8797
+ 2
8798
+ ];
8799
+ }
8648
8800
  if (!this.adConfig.isVmapEnabled() && !isLive && this.adConfig.vmapBreaks.length === 0 && this.adConfig.apiVastTagUrl) {
8649
8801
  prerollKey = "synthetic-vod-preroll";
8650
8802
  if (!this.adConfig.consumedVmapBreakIds.has(prerollKey)) {