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.js CHANGED
@@ -6274,6 +6274,7 @@ var HlsEngine = /*#__PURE__*/ function() {
6274
6274
  this.isLiveStream = false;
6275
6275
  this.nativeHlsMode = false;
6276
6276
  this.videoSrcProtection = null;
6277
+ this.reloadingLiveStream = false;
6277
6278
  this.bufferedSegmentsCount = 0;
6278
6279
  this.shouldAutoplayAfterBuffering = false;
6279
6280
  this.hasInitialBufferCompleted = false;
@@ -6407,6 +6408,7 @@ var HlsEngine = /*#__PURE__*/ function() {
6407
6408
  _state.sent();
6408
6409
  _state.label = 3;
6409
6410
  case 3:
6411
+ this.reloadingLiveStream = false;
6410
6412
  return [
6411
6413
  2
6412
6414
  ];
@@ -6751,6 +6753,33 @@ var HlsEngine = /*#__PURE__*/ function() {
6751
6753
  }
6752
6754
  }
6753
6755
  },
6756
+ {
6757
+ key: "reloadLiveStream",
6758
+ value: function reloadLiveStream() {
6759
+ var hls = this.hls;
6760
+ if (!hls) {
6761
+ return;
6762
+ }
6763
+ if (this.debug) {
6764
+ console.log("[StormcloudVideoPlayer] Hard-reloading live stream (detach \u2192 reset video \u2192 re-attach)");
6765
+ }
6766
+ try {
6767
+ this.reloadingLiveStream = true;
6768
+ hls.stopLoad();
6769
+ hls.detachMedia();
6770
+ try {
6771
+ this.video.removeAttribute("src");
6772
+ this.video.load();
6773
+ } catch (unused) {}
6774
+ hls.attachMedia(this.video);
6775
+ } catch (error) {
6776
+ this.reloadingLiveStream = false;
6777
+ if (this.debug) {
6778
+ console.warn("[StormcloudVideoPlayer] Failed to hard-reload live stream:", error);
6779
+ }
6780
+ }
6781
+ }
6782
+ },
6754
6783
  {
6755
6784
  key: "destroy",
6756
6785
  value: function destroy() {
@@ -8091,31 +8120,134 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8091
8120
  return 0;
8092
8121
  }
8093
8122
  },
8123
+ {
8124
+ key: "describeVideoState",
8125
+ value: function describeVideoState() {
8126
+ var _networkStates_v_networkState, _readyStates_v_readyState;
8127
+ var v = this.host.video;
8128
+ var networkStates = [
8129
+ "EMPTY",
8130
+ "IDLE",
8131
+ "LOADING",
8132
+ "NO_SOURCE"
8133
+ ];
8134
+ var readyStates = [
8135
+ "HAVE_NOTHING",
8136
+ "HAVE_METADATA",
8137
+ "HAVE_CURRENT_DATA",
8138
+ "HAVE_FUTURE_DATA",
8139
+ "HAVE_ENOUGH_DATA"
8140
+ ];
8141
+ var net = (_networkStates_v_networkState = networkStates[v.networkState]) !== null && _networkStates_v_networkState !== void 0 ? _networkStates_v_networkState : String(v.networkState);
8142
+ var ready = (_readyStates_v_readyState = readyStates[v.readyState]) !== null && _readyStates_v_readyState !== void 0 ? _readyStates_v_readyState : String(v.readyState);
8143
+ var err = v.error ? "code=".concat(v.error.code).concat(v.error.message ? " (".concat(v.error.message, ")") : "") : "none";
8144
+ var ranges = [];
8145
+ for(var i = 0; i < v.buffered.length; i++){
8146
+ ranges.push("[".concat(v.buffered.start(i).toFixed(2), "–").concat(v.buffered.end(i).toFixed(2), "]"));
8147
+ }
8148
+ 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");
8149
+ }
8150
+ },
8094
8151
  {
8095
8152
  key: "monitorLiveResumeStall",
8096
8153
  value: function monitorLiveResumeStall(resumeBaseline) {
8097
8154
  var _this = this;
8098
8155
  var pollIntervalMs = 1e3;
8099
8156
  var graceMs = 5e3;
8100
- var reloadCooldownMs = 5e3;
8101
- var maxHardReloads = 2;
8102
- var maxMonitorMs = 25e3;
8157
+ var recoveryCooldownMs = 5e3;
8158
+ var maxRecoveries = 2;
8159
+ var maxMonitorMs = 3e4;
8103
8160
  var startTime = Date.now();
8104
8161
  var baseline = resumeBaseline;
8105
- var hardReloads = 0;
8106
- var lastReloadAt = 0;
8162
+ var recoveries = 0;
8163
+ var lastRecoveryAt = 0;
8164
+ var video = this.host.video;
8165
+ var listenersAttached = false;
8166
+ var onMediaEvent;
8167
+ var diagEvents = [
8168
+ "loadstart",
8169
+ "loadedmetadata",
8170
+ "loadeddata",
8171
+ "canplay",
8172
+ "canplaythrough",
8173
+ "play",
8174
+ "playing",
8175
+ "pause",
8176
+ "waiting",
8177
+ "stalled",
8178
+ "suspend",
8179
+ "seeking",
8180
+ "seeked",
8181
+ "emptied",
8182
+ "error",
8183
+ "ended"
8184
+ ];
8185
+ if (this.debug) {
8186
+ onMediaEvent = function onMediaEvent(e) {
8187
+ var dt = ((Date.now() - startTime) / 1e3).toFixed(1);
8188
+ console.log("[ResumeDiag] +".concat(dt, "s event=").concat(e.type, " — ").concat(_this.describeVideoState()));
8189
+ };
8190
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8191
+ try {
8192
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8193
+ var name = _step.value;
8194
+ video.addEventListener(name, onMediaEvent);
8195
+ }
8196
+ } catch (err) {
8197
+ _didIteratorError = true;
8198
+ _iteratorError = err;
8199
+ } finally{
8200
+ try {
8201
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8202
+ _iterator.return();
8203
+ }
8204
+ } finally{
8205
+ if (_didIteratorError) {
8206
+ throw _iteratorError;
8207
+ }
8208
+ }
8209
+ }
8210
+ listenersAttached = true;
8211
+ console.log("[ResumeDiag] +0.0s monitor start — ".concat(this.describeVideoState()));
8212
+ }
8213
+ var cleanup = function cleanup() {
8214
+ if (listenersAttached && onMediaEvent) {
8215
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8216
+ try {
8217
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8218
+ var name = _step.value;
8219
+ video.removeEventListener(name, onMediaEvent);
8220
+ }
8221
+ } catch (err) {
8222
+ _didIteratorError = true;
8223
+ _iteratorError = err;
8224
+ } finally{
8225
+ try {
8226
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8227
+ _iterator.return();
8228
+ }
8229
+ } finally{
8230
+ if (_didIteratorError) {
8231
+ throw _iteratorError;
8232
+ }
8233
+ }
8234
+ }
8235
+ listenersAttached = false;
8236
+ }
8237
+ };
8107
8238
  var poll = function poll1() {
8108
8239
  if (_this.inAdBreak) {
8240
+ cleanup();
8109
8241
  return;
8110
8242
  }
8111
- var video = _this.host.video;
8112
8243
  var currentTime = video.currentTime;
8113
8244
  var advanced = currentTime > baseline + 0.5;
8114
8245
  var playing = !video.paused && video.readyState >= 3;
8115
8246
  if (advanced && playing) {
8116
8247
  if (_this.debug) {
8117
- console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break");
8248
+ console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break".concat(_this.describeVideoState()));
8118
8249
  }
8250
+ cleanup();
8119
8251
  return;
8120
8252
  }
8121
8253
  if (video.paused) {
@@ -8127,23 +8259,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8127
8259
  var wedged = bufferedAhead < 0.5 && !advanced;
8128
8260
  if (elapsed >= maxMonitorMs) {
8129
8261
  if (_this.debug && !advanced) {
8130
- 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)"));
8262
+ console.warn("[StormcloudVideoPlayer] Live stream failed to resume after ".concat((maxMonitorMs / 1e3).toFixed(0), "s ").concat(_this.describeVideoState()));
8131
8263
  }
8264
+ cleanup();
8132
8265
  return;
8133
8266
  }
8134
- var canHardReload = wedged && elapsed >= graceMs && Date.now() - lastReloadAt >= reloadCooldownMs && hardReloads < maxHardReloads;
8135
- if (canHardReload) {
8136
- hardReloads++;
8137
- lastReloadAt = Date.now();
8138
- var liveSyncPos = _this.host.getLiveSyncPosition();
8139
- var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8140
- if (_this.debug) {
8141
- 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, ")"));
8142
- }
8143
- if (liveSyncPos != null && liveSyncPos > currentTime) {
8144
- video.currentTime = liveSyncPos;
8267
+ var canRecover = wedged && elapsed >= graceMs && Date.now() - lastRecoveryAt >= recoveryCooldownMs && recoveries < maxRecoveries;
8268
+ if (canRecover) {
8269
+ recoveries++;
8270
+ lastRecoveryAt = Date.now();
8271
+ var isFinalAttempt = recoveries >= maxRecoveries;
8272
+ if (!isFinalAttempt) {
8273
+ var liveSyncPos = _this.host.getLiveSyncPosition();
8274
+ var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8275
+ if (_this.debug) {
8276
+ 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()));
8277
+ }
8278
+ if (liveSyncPos != null && liveSyncPos > currentTime) {
8279
+ video.currentTime = liveSyncPos;
8280
+ }
8281
+ _this.host.restartHlsLoad(reloadPos);
8282
+ } else {
8283
+ if (_this.debug) {
8284
+ console.warn("[StormcloudVideoPlayer] Content still wedged after ad break — hard-reloading live stream (recovery ".concat(recoveries, "/").concat(maxRecoveries, ") — ").concat(_this.describeVideoState()));
8285
+ }
8286
+ _this.host.reloadLiveStream();
8145
8287
  }
8146
- _this.host.restartHlsLoad(reloadPos);
8147
8288
  baseline = video.currentTime;
8148
8289
  if (video.paused) {
8149
8290
  var _video_play1;
@@ -8307,6 +8448,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8307
8448
  restartHlsLoad: function restartHlsLoad(position) {
8308
8449
  return _this.hlsEngine.restartLoadAt(position);
8309
8450
  },
8451
+ reloadLiveStream: function reloadLiveStream() {
8452
+ return _this.hlsEngine.reloadLiveStream();
8453
+ },
8310
8454
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8311
8455
  return _this.generatePodVastUrl(base, breakDurationMs);
8312
8456
  }
@@ -8438,6 +8582,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8438
8582
  return _async_to_generator(function() {
8439
8583
  var prerollKey, adBehavior;
8440
8584
  return _ts_generator(this, function(_state) {
8585
+ if (this.hlsEngine.reloadingLiveStream) {
8586
+ if (this.debug) {
8587
+ console.log("[StormcloudVideoPlayer] Manifest re-parsed after hard reload \u2014 skipping ad-player setup");
8588
+ }
8589
+ return [
8590
+ 2
8591
+ ];
8592
+ }
8441
8593
  if (!this.adConfig.isVmapEnabled() && !isLive && this.adConfig.vmapBreaks.length === 0 && this.adConfig.apiVastTagUrl) {
8442
8594
  prerollKey = "synthetic-vod-preroll";
8443
8595
  if (!this.adConfig.consumedVmapBreakIds.has(prerollKey)) {