hls.js 1.5.5-0.canary.9985 → 1.5.5-0.canary.9987

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.mjs CHANGED
@@ -512,7 +512,7 @@ function enableLogs(debugConfig, context, id) {
512
512
  // Some browsers don't allow to use bind on console object anyway
513
513
  // fallback to default if needed
514
514
  try {
515
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.5-0.canary.9985"}`);
515
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.5-0.canary.9987"}`);
516
516
  } catch (e) {
517
517
  /* log fn threw an exception. All logger methods are no-ops. */
518
518
  return createLogger();
@@ -9187,6 +9187,7 @@ class BaseStreamController extends TaskLoop {
9187
9187
  this.decrypter = void 0;
9188
9188
  this.initPTS = [];
9189
9189
  this.buffering = true;
9190
+ this.loadingParts = false;
9190
9191
  this.onMediaSeeking = () => {
9191
9192
  const {
9192
9193
  config,
@@ -9223,6 +9224,14 @@ class BaseStreamController extends TaskLoop {
9223
9224
  // Remove gap fragments
9224
9225
  this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
9225
9226
  this.lastCurrentTime = currentTime;
9227
+ if (!this.loadingParts) {
9228
+ const bufferEnd = Math.max(bufferInfo.end, currentTime);
9229
+ const shouldLoadParts = this.shouldLoadParts(this.getLevelDetails(), bufferEnd);
9230
+ if (shouldLoadParts) {
9231
+ this.log(`LL-Part loading ON after seeking to ${currentTime.toFixed(2)} with buffer @${bufferEnd.toFixed(2)}`);
9232
+ this.loadingParts = shouldLoadParts;
9233
+ }
9234
+ }
9226
9235
  }
9227
9236
 
9228
9237
  // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
@@ -9633,8 +9642,16 @@ class BaseStreamController extends TaskLoop {
9633
9642
  } else if (!frag.encrypted && details.encryptedFragments.length) {
9634
9643
  this.keyLoader.loadClear(frag, details.encryptedFragments);
9635
9644
  }
9645
+ const fragPrevious = this.fragPrevious;
9646
+ if (frag.sn !== 'initSegment' && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
9647
+ const shouldLoadParts = this.shouldLoadParts(level.details, frag.end);
9648
+ if (shouldLoadParts !== this.loadingParts) {
9649
+ this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} loading sn ${fragPrevious == null ? void 0 : fragPrevious.sn}->${frag.sn}`);
9650
+ this.loadingParts = shouldLoadParts;
9651
+ }
9652
+ }
9636
9653
  targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
9637
- if (this.config.lowLatencyMode && frag.sn !== 'initSegment') {
9654
+ if (this.loadingParts && frag.sn !== 'initSegment') {
9638
9655
  const partList = details.partList;
9639
9656
  if (partList && progressCallback) {
9640
9657
  if (targetBufferTime > frag.end && details.fragmentHint) {
@@ -9672,6 +9689,13 @@ class BaseStreamController extends TaskLoop {
9672
9689
  }
9673
9690
  }
9674
9691
  }
9692
+ if (frag.sn !== 'initSegment' && this.loadingParts) {
9693
+ this.log(`LL-Part loading OFF after next part miss @${targetBufferTime.toFixed(2)}`);
9694
+ this.loadingParts = false;
9695
+ } else if (!frag.url) {
9696
+ // Selected fragment hint for part but not loading parts
9697
+ return Promise.resolve(null);
9698
+ }
9675
9699
  this.log(`Loading fragment ${frag.sn} cc: ${frag.cc} ${details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : ''}${this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track'}: ${frag.level}, target: ${parseFloat(targetBufferTime.toFixed(3))}`);
9676
9700
  // Don't update nextLoadPosition for fragments which are not buffered
9677
9701
  if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
@@ -9770,8 +9794,36 @@ class BaseStreamController extends TaskLoop {
9770
9794
  if (part) {
9771
9795
  part.stats.parsing.end = now;
9772
9796
  }
9797
+ // See if part loading should be disabled/enabled based on buffer and playback position.
9798
+ if (frag.sn !== 'initSegment') {
9799
+ const levelDetails = this.getLevelDetails();
9800
+ const loadingPartsAtEdge = levelDetails && frag.sn > levelDetails.endSN;
9801
+ const shouldLoadParts = loadingPartsAtEdge || this.shouldLoadParts(levelDetails, frag.end);
9802
+ if (shouldLoadParts !== this.loadingParts) {
9803
+ this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} after parsing segment ending @${frag.end.toFixed(2)}`);
9804
+ this.loadingParts = shouldLoadParts;
9805
+ }
9806
+ }
9773
9807
  this.updateLevelTiming(frag, part, level, chunkMeta.partial);
9774
9808
  }
9809
+ shouldLoadParts(details, bufferEnd) {
9810
+ if (this.config.lowLatencyMode) {
9811
+ if (!details) {
9812
+ return this.loadingParts;
9813
+ }
9814
+ if (details != null && details.partList) {
9815
+ var _details$fragmentHint;
9816
+ // Buffer must be ahead of first part + duration of parts after last segment
9817
+ // and playback must be at or past segment adjacent to part list
9818
+ const firstPart = details.partList[0];
9819
+ const safePartStart = firstPart.end + (((_details$fragmentHint = details.fragmentHint) == null ? void 0 : _details$fragmentHint.duration) || 0);
9820
+ if (bufferEnd >= safePartStart && this.lastCurrentTime > firstPart.start - firstPart.fragment.duration) {
9821
+ return true;
9822
+ }
9823
+ }
9824
+ }
9825
+ return false;
9826
+ }
9775
9827
  getCurrentContext(chunkMeta) {
9776
9828
  const {
9777
9829
  levels,
@@ -9920,7 +9972,8 @@ class BaseStreamController extends TaskLoop {
9920
9972
  config
9921
9973
  } = this;
9922
9974
  const start = fragments[0].start;
9923
- let frag;
9975
+ const canLoadParts = config.lowLatencyMode && !!levelDetails.partList;
9976
+ let frag = null;
9924
9977
  if (levelDetails.live) {
9925
9978
  const initialLiveManifestSize = config.initialLiveManifestSize;
9926
9979
  if (fragLen < initialLiveManifestSize) {
@@ -9932,6 +9985,10 @@ class BaseStreamController extends TaskLoop {
9932
9985
  // Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that
9933
9986
  // we get the fragment matching that start time
9934
9987
  if (!levelDetails.PTSKnown && !this.startFragRequested && this.startPosition === -1 || pos < start) {
9988
+ if (canLoadParts && !this.loadingParts) {
9989
+ this.log(`LL-Part loading ON for initial live fragment`);
9990
+ this.loadingParts = true;
9991
+ }
9935
9992
  frag = this.getInitialLiveFragment(levelDetails, fragments);
9936
9993
  this.startPosition = this.nextLoadPosition = frag ? this.hls.liveSyncPosition || frag.start : pos;
9937
9994
  }
@@ -9942,7 +9999,7 @@ class BaseStreamController extends TaskLoop {
9942
9999
 
9943
10000
  // If we haven't run into any special cases already, just load the fragment most closely matching the requested position
9944
10001
  if (!frag) {
9945
- const end = config.lowLatencyMode ? levelDetails.partEnd : levelDetails.fragmentEnd;
10002
+ const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
9946
10003
  frag = this.getFragmentAtPosition(pos, end, levelDetails);
9947
10004
  }
9948
10005
  return this.mapToInitFragWhenRequired(frag);
@@ -10064,7 +10121,7 @@ class BaseStreamController extends TaskLoop {
10064
10121
  } = levelDetails;
10065
10122
  const tolerance = config.maxFragLookUpTolerance;
10066
10123
  const partList = levelDetails.partList;
10067
- const loadingParts = !!(config.lowLatencyMode && partList != null && partList.length && fragmentHint);
10124
+ const loadingParts = !!(this.loadingParts && partList != null && partList.length && fragmentHint);
10068
10125
  if (loadingParts && fragmentHint && !this.bitrateTest) {
10069
10126
  // Include incomplete fragment with parts at end
10070
10127
  fragments = fragments.concat(fragmentHint);
@@ -17717,7 +17774,7 @@ class SubtitleStreamController extends BaseStreamController {
17717
17774
  onSubtitleTracksUpdated(event, {
17718
17775
  subtitleTracks
17719
17776
  }) {
17720
- if (!this.levels || subtitleOptionsIdentical(this.levels, subtitleTracks)) {
17777
+ if (this.levels && subtitleOptionsIdentical(this.levels, subtitleTracks)) {
17721
17778
  this.levels = subtitleTracks.map(mediaPlaylist => new Level(mediaPlaylist));
17722
17779
  return;
17723
17780
  }
@@ -28537,7 +28594,7 @@ class Hls {
28537
28594
  * Get the video-dev/hls.js package version.
28538
28595
  */
28539
28596
  static get version() {
28540
- return "1.5.5-0.canary.9985";
28597
+ return "1.5.5-0.canary.9987";
28541
28598
  }
28542
28599
 
28543
28600
  /**