hls.js 1.6.0-beta.1.0.canary.10767 → 1.6.0-beta.1.0.canary.10770

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/dist/hls.d.mts CHANGED
@@ -327,6 +327,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
327
327
  private _loadFragForPlayback;
328
328
  protected clearTrackerIfNeeded(frag: Fragment): void;
329
329
  protected checkLiveUpdate(details: LevelDetails): void;
330
+ protected waitForLive(levelInfo: Level): boolean | undefined;
330
331
  protected flushMainBuffer(startOffset: number, endOffset: number, type?: SourceBufferName | null): void;
331
332
  protected _loadInitSegment(fragment: Fragment, level: Level): void;
332
333
  private completeInitSegmentLoad;
@@ -2584,6 +2585,7 @@ export declare class LevelDetails {
2584
2585
  get age(): number;
2585
2586
  get lastPartIndex(): number;
2586
2587
  get lastPartSn(): number;
2588
+ get expired(): boolean;
2587
2589
  }
2588
2590
 
2589
2591
  export declare class LevelKey implements DecryptData {
package/dist/hls.d.ts CHANGED
@@ -327,6 +327,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
327
327
  private _loadFragForPlayback;
328
328
  protected clearTrackerIfNeeded(frag: Fragment): void;
329
329
  protected checkLiveUpdate(details: LevelDetails): void;
330
+ protected waitForLive(levelInfo: Level): boolean | undefined;
330
331
  protected flushMainBuffer(startOffset: number, endOffset: number, type?: SourceBufferName | null): void;
331
332
  protected _loadInitSegment(fragment: Fragment, level: Level): void;
332
333
  private completeInitSegmentLoad;
@@ -2584,6 +2585,7 @@ export declare class LevelDetails {
2584
2585
  get age(): number;
2585
2586
  get lastPartIndex(): number;
2586
2587
  get lastPartSn(): number;
2588
+ get expired(): boolean;
2587
2589
  }
2588
2590
 
2589
2591
  export declare class LevelKey implements DecryptData {
package/dist/hls.js CHANGED
@@ -1057,7 +1057,7 @@
1057
1057
  // Some browsers don't allow to use bind on console object anyway
1058
1058
  // fallback to default if needed
1059
1059
  try {
1060
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.10767");
1060
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.10770");
1061
1061
  } catch (e) {
1062
1062
  /* log fn threw an exception. All logger methods are no-ops. */
1063
1063
  return createLogger();
@@ -7112,6 +7112,15 @@
7112
7112
  }
7113
7113
  return this.endSN;
7114
7114
  }
7115
+ }, {
7116
+ key: "expired",
7117
+ get: function get() {
7118
+ if (this.live && this.age) {
7119
+ var playlistWindowDuration = this.partEnd - this.fragmentStart;
7120
+ return this.age > Math.max(playlistWindowDuration, this.totalduration) + this.levelTargetDuration;
7121
+ }
7122
+ return false;
7123
+ }
7115
7124
  }]);
7116
7125
  }();
7117
7126
 
@@ -9112,6 +9121,10 @@
9112
9121
  details.deltaUpdateFailed = true;
9113
9122
  }
9114
9123
  };
9124
+ _proto.waitForLive = function waitForLive(levelInfo) {
9125
+ var details = levelInfo.details;
9126
+ return (details == null ? void 0 : details.live) && details.type !== 'EVENT' && (this.levelLastLoaded !== levelInfo || details.expired);
9127
+ };
9115
9128
  _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset, type) {
9116
9129
  if (type === void 0) {
9117
9130
  type = null;
@@ -9473,7 +9486,7 @@
9473
9486
  sn = chunkMeta.sn,
9474
9487
  partIndex = chunkMeta.part;
9475
9488
  if (!(levels != null && levels[levelIndex])) {
9476
- this.warn("Levels object was unset while buffering fragment " + sn + " of level " + levelIndex + ". The current chunk will not be buffered.");
9489
+ this.warn("Levels object was unset while buffering fragment " + sn + " of " + this.playlistLabel() + " " + levelIndex + ". The current chunk will not be buffered.");
9477
9490
  return null;
9478
9491
  }
9479
9492
  var level = levels[levelIndex];
@@ -9847,6 +9860,7 @@
9847
9860
  // Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has
9848
9861
  // not been specified via the config or an as an argument to startLoad (#3736).
9849
9862
  startPosition = this.hls.liveSyncPosition || sliding;
9863
+ this.startPosition = -1;
9850
9864
  } else {
9851
9865
  this.log("setting startPosition to 0 by default");
9852
9866
  this.startPosition = startPosition = 0;
@@ -9867,8 +9881,8 @@
9867
9881
  return pos;
9868
9882
  };
9869
9883
  _proto.handleFragLoadAborted = function handleFragLoadAborted(frag, part) {
9870
- if (this.transmuxer && isMediaFragment(frag) && frag.stats.aborted) {
9871
- this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " was aborted");
9884
+ if (this.transmuxer && frag.type === this.playlistType && isMediaFragment(frag) && frag.stats.aborted) {
9885
+ this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of " + this.playlistLabel() + " " + frag.level + " was aborted");
9872
9886
  this.resetFragmentLoading(frag);
9873
9887
  }
9874
9888
  };
@@ -10019,7 +10033,7 @@
10019
10033
  }
10020
10034
  };
10021
10035
  _proto.resetWhenMissingContext = function resetWhenMissingContext(chunkMeta) {
10022
- this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered.");
10036
+ this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of " + this.playlistLabel() + " " + chunkMeta.level + ". This chunk will not be buffered.");
10023
10037
  this.removeUnbufferedFrags();
10024
10038
  this.resetStartWhenNotLoaded(this.levelLastLoaded);
10025
10039
  this.resetLoadingState();
@@ -10064,7 +10078,7 @@
10064
10078
  return result;
10065
10079
  }, false);
10066
10080
  if (!parsed && ((_this$transmuxer = this.transmuxer) == null ? void 0 : _this$transmuxer.error) === null) {
10067
- var error = new Error("Found no media in fragment " + frag.sn + " of level " + frag.level + " resetting transmuxer to fallback to playlist timing");
10081
+ var error = new Error("Found no media in fragment " + frag.sn + " of " + this.playlistLabel() + " " + frag.level + " resetting transmuxer to fallback to playlist timing");
10068
10082
  if (level.fragmentError === 0) {
10069
10083
  // Mark and track the odd empty segment as a gap to avoid reloading
10070
10084
  this.treatAsGap(frag, level);
@@ -10076,7 +10090,7 @@
10076
10090
  fatal: false,
10077
10091
  error: error,
10078
10092
  frag: frag,
10079
- reason: "Found no media in msn " + frag.sn + " of level \"" + level.url + "\""
10093
+ reason: "Found no media in msn " + frag.sn + " of " + this.playlistLabel() + " \"" + level.url + "\""
10080
10094
  });
10081
10095
  if (!this.hls) {
10082
10096
  return;
@@ -16239,7 +16253,7 @@
16239
16253
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
16240
16254
  }
16241
16255
 
16242
- var version = "1.6.0-beta.1.0.canary.10767";
16256
+ var version = "1.6.0-beta.1.0.canary.10770";
16243
16257
 
16244
16258
  // ensure the worker ends up in the bundle
16245
16259
  // If the worker should not be included this gets aliased to empty.js
@@ -16763,11 +16777,11 @@
16763
16777
  break;
16764
16778
  case State.WAITING_TRACK:
16765
16779
  {
16766
- var _levels$trackId;
16767
16780
  var levels = this.levels,
16768
16781
  trackId = this.trackId;
16769
- var details = levels == null ? void 0 : (_levels$trackId = levels[trackId]) == null ? void 0 : _levels$trackId.details;
16770
- if (details) {
16782
+ var currenTrack = levels == null ? void 0 : levels[trackId];
16783
+ var details = currenTrack == null ? void 0 : currenTrack.details;
16784
+ if (details && !this.waitForLive(currenTrack)) {
16771
16785
  if (this.waitForCdnTuneIn(details)) {
16772
16786
  break;
16773
16787
  }
@@ -16872,8 +16886,9 @@
16872
16886
  }
16873
16887
  var levelInfo = levels[trackId];
16874
16888
  var trackDetails = levelInfo.details;
16875
- if (!trackDetails || trackDetails.live && this.levelLastLoaded !== levelInfo || this.waitForCdnTuneIn(trackDetails)) {
16889
+ if (!trackDetails || this.waitForLive(levelInfo) || this.waitForCdnTuneIn(trackDetails)) {
16876
16890
  this.state = State.WAITING_TRACK;
16891
+ this.startFragRequested = false;
16877
16892
  return;
16878
16893
  }
16879
16894
  var bufferable = this.mediaBuffer ? this.mediaBuffer : this.media;
@@ -17941,7 +17956,9 @@
17941
17956
  }
17942
17957
  }
17943
17958
  // track not retrieved yet, or live playlist we need to (re)load it
17944
- this.log("loading audio-track playlist " + id + " \"" + audioTrack.name + "\" lang:" + audioTrack.lang + " group:" + groupId);
17959
+ var details = audioTrack.details;
17960
+ var age = details == null ? void 0 : details.age;
17961
+ this.log("Loading audio-track " + id + " \"" + audioTrack.name + "\" lang:" + audioTrack.lang + " group:" + groupId + ((hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : '') + (age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : '') + " " + url);
17945
17962
  this.clearTimer();
17946
17963
  this.hls.trigger(Events.AUDIO_TRACK_LOADING, {
17947
17964
  url: url,
@@ -25767,6 +25784,9 @@
25767
25784
  if (!track || !levels.length || !track.details) {
25768
25785
  return;
25769
25786
  }
25787
+ if (this.waitForLive(track)) {
25788
+ return;
25789
+ }
25770
25790
  var config = this.config;
25771
25791
  var currentTime = this.getLoadPosition();
25772
25792
  var bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime, config.maxBufferHole);
@@ -26308,7 +26328,9 @@
26308
26328
  this.warn("Could not construct new URL with HLS Delivery Directives: " + error);
26309
26329
  }
26310
26330
  }
26311
- this.log("Loading subtitle playlist for id " + id);
26331
+ var details = currentTrack.details;
26332
+ var age = details == null ? void 0 : details.age;
26333
+ this.log("Loading subtitle " + id + " \"" + currentTrack.name + "\" lang:" + currentTrack.lang + " group:" + groupId + ((hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : '') + (age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : '') + " " + url);
26312
26334
  this.hls.trigger(Events.SUBTITLE_TRACK_LOADING, {
26313
26335
  url: url,
26314
26336
  id: id,
@@ -31329,7 +31351,9 @@
31329
31351
  }
31330
31352
  }
31331
31353
  var pathwayId = currentLevel.attrs['PATHWAY-ID'];
31332
- this.log("Loading level index " + currentLevelIndex + ((hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : '') + " with" + (pathwayId ? ' Pathway ' + pathwayId : '') + " " + url);
31354
+ var details = currentLevel.details;
31355
+ var age = details == null ? void 0 : details.age;
31356
+ this.log("Loading level index " + currentLevelIndex + ((hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : '') + (pathwayId ? ' Pathway ' + pathwayId : '') + (age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : '') + " " + url);
31333
31357
 
31334
31358
  // console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
31335
31359
  // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
@@ -32038,7 +32062,7 @@
32038
32062
  this._hasEnoughToStart = false;
32039
32063
  }
32040
32064
  // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
32041
- if (lastCurrentTime > 0 && startPosition === -1) {
32065
+ if (lastCurrentTime > 0 && startPosition === -1 && !skipSeekToStartPosition) {
32042
32066
  this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3));
32043
32067
  startPosition = lastCurrentTime;
32044
32068
  }
@@ -32063,7 +32087,7 @@
32063
32087
  level = this.level;
32064
32088
  var currentLevel = levels == null ? void 0 : levels[level];
32065
32089
  var details = currentLevel == null ? void 0 : currentLevel.details;
32066
- if (details && (!details.live || this.levelLastLoaded === currentLevel)) {
32090
+ if (details && (!details.live || this.levelLastLoaded === currentLevel && !this.waitForLive(currentLevel))) {
32067
32091
  if (this.waitForCdnTuneIn(details)) {
32068
32092
  break;
32069
32093
  }
@@ -32153,9 +32177,10 @@
32153
32177
  // if level info not retrieved yet, switch state and wait for level retrieval
32154
32178
  // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
32155
32179
  // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
32156
- if (!levelDetails || this.state === State.WAITING_LEVEL || levelDetails.live && this.levelLastLoaded !== levelInfo) {
32180
+ if (!levelDetails || this.state === State.WAITING_LEVEL || this.waitForLive(levelInfo)) {
32157
32181
  this.level = level;
32158
32182
  this.state = State.WAITING_LEVEL;
32183
+ this.startFragRequested = false;
32159
32184
  return;
32160
32185
  }
32161
32186
  var bufferLen = bufferInfo.len;
@@ -32399,7 +32424,7 @@
32399
32424
  return;
32400
32425
  }
32401
32426
  var level = data.levelInfo;
32402
- if (!level.details || level.details.live && this.levelLastLoaded !== level || this.waitForCdnTuneIn(level.details)) {
32427
+ if (!level.details || level.details.live && (this.levelLastLoaded !== level || level.details.expired) || this.waitForCdnTuneIn(level.details)) {
32403
32428
  this.state = State.WAITING_LEVEL;
32404
32429
  }
32405
32430
  };
@@ -33614,13 +33639,18 @@
33614
33639
  // Check if a loader for this context already exists
33615
33640
  var loader = this.getInternalLoader(context);
33616
33641
  if (loader) {
33642
+ var logger = this.hls.logger;
33617
33643
  var loaderContext = loader.context;
33618
- if (loaderContext && loaderContext.url === context.url && loaderContext.levelOrTrack === context.levelOrTrack) {
33619
- // same URL can't overlap
33620
- this.hls.logger.trace('[playlist-loader]: playlist request ongoing');
33644
+ if (loaderContext && loaderContext.levelOrTrack === context.levelOrTrack && (loaderContext.url === context.url || loaderContext.deliveryDirectives && !context.deliveryDirectives)) {
33645
+ // same URL can't overlap, or wait for blocking request
33646
+ if (loaderContext.url === context.url) {
33647
+ logger.log("[playlist-loader]: playlist request ongoing");
33648
+ } else {
33649
+ logger.log("[playlist-loader]: ignore " + context.url + " in favor of " + loaderContext.url);
33650
+ }
33621
33651
  return;
33622
33652
  }
33623
- this.hls.logger.log("[playlist-loader]: aborting previous loader for type: " + context.type);
33653
+ logger.log("[playlist-loader]: aborting previous loader for type: " + context.type);
33624
33654
  loader.abort();
33625
33655
  }
33626
33656
 
package/dist/hls.js.d.ts CHANGED
@@ -327,6 +327,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
327
327
  private _loadFragForPlayback;
328
328
  protected clearTrackerIfNeeded(frag: Fragment): void;
329
329
  protected checkLiveUpdate(details: LevelDetails): void;
330
+ protected waitForLive(levelInfo: Level): boolean | undefined;
330
331
  protected flushMainBuffer(startOffset: number, endOffset: number, type?: SourceBufferName | null): void;
331
332
  protected _loadInitSegment(fragment: Fragment, level: Level): void;
332
333
  private completeInitSegmentLoad;
@@ -2584,6 +2585,7 @@ export declare class LevelDetails {
2584
2585
  get age(): number;
2585
2586
  get lastPartIndex(): number;
2586
2587
  get lastPartSn(): number;
2588
+ get expired(): boolean;
2587
2589
  }
2588
2590
 
2589
2591
  export declare class LevelKey implements DecryptData {