hls.js 1.4.6 → 1.4.7

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
@@ -402,7 +402,7 @@ function enableLogs(debugConfig, id) {
402
402
  // Some browsers don't allow to use bind on console object anyway
403
403
  // fallback to default if needed
404
404
  try {
405
- exportedLogger.log(`Debug logs enabled for "${id}" in hls.js version ${"1.4.6"}`);
405
+ exportedLogger.log(`Debug logs enabled for "${id}" in hls.js version ${"1.4.7"}`);
406
406
  } catch (e) {
407
407
  exportedLogger = fakeLogger;
408
408
  }
@@ -9339,6 +9339,8 @@ class BaseStreamController extends TaskLoop {
9339
9339
  } else {
9340
9340
  logger.warn(`${data.details} reached or exceeded max retry (${retryCount})`);
9341
9341
  }
9342
+ } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
9343
+ this.state = State.WAITING_LEVEL;
9342
9344
  } else {
9343
9345
  this.state = State.ERROR;
9344
9346
  }
@@ -17605,16 +17607,7 @@ class SubtitleStreamController extends BaseStreamController {
17605
17607
  endOffset
17606
17608
  } = data;
17607
17609
  if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
17608
- const {
17609
- currentTrackId,
17610
- levels
17611
- } = this;
17612
- if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) {
17613
- return;
17614
- }
17615
- const trackDetails = levels[currentTrackId].details;
17616
- const targetDuration = trackDetails.targetduration;
17617
- const endOffsetSubtitles = endOffset - targetDuration;
17610
+ const endOffsetSubtitles = endOffset - 1;
17618
17611
  if (endOffsetSubtitles <= 0) {
17619
17612
  return;
17620
17613
  }
@@ -17810,21 +17803,18 @@ class SubtitleStreamController extends BaseStreamController {
17810
17803
  if (!levels.length || !track || !track.details) {
17811
17804
  return;
17812
17805
  }
17813
-
17814
- // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists
17815
- const trackDetails = track.details;
17816
- const targetDuration = trackDetails.targetduration;
17817
17806
  const {
17818
17807
  config
17819
17808
  } = this;
17820
17809
  const currentTime = this.getLoadPosition();
17821
- const bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime - targetDuration, config.maxBufferHole);
17810
+ const bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime, config.maxBufferHole);
17822
17811
  const {
17823
17812
  end: targetBufferTime,
17824
17813
  len: bufferLen
17825
17814
  } = bufferedInfo;
17826
17815
  const mainBufferInfo = this.getFwdBufferInfo(this.media, PlaylistLevelType.MAIN);
17827
- const maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + targetDuration;
17816
+ const trackDetails = track.details;
17817
+ const maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + trackDetails.levelTargetDuration;
17828
17818
  if (bufferLen > maxBufLen) {
17829
17819
  return;
17830
17820
  }
@@ -17834,10 +17824,9 @@ class SubtitleStreamController extends BaseStreamController {
17834
17824
  let foundFrag = null;
17835
17825
  const fragPrevious = this.fragPrevious;
17836
17826
  if (targetBufferTime < end) {
17837
- const {
17838
- maxFragLookUpTolerance
17839
- } = config;
17840
- foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), maxFragLookUpTolerance);
17827
+ const tolerance = config.maxFragLookUpTolerance;
17828
+ const lookupTolerance = targetBufferTime > end - tolerance ? 0 : tolerance;
17829
+ foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), lookupTolerance);
17841
17830
  if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) {
17842
17831
  foundFrag = fragments[0];
17843
17832
  }
@@ -17848,6 +17837,14 @@ class SubtitleStreamController extends BaseStreamController {
17848
17837
  return;
17849
17838
  }
17850
17839
  foundFrag = this.mapToInitFragWhenRequired(foundFrag);
17840
+ if (foundFrag.sn !== 'initSegment') {
17841
+ // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
17842
+ const curSNIdx = foundFrag.sn - trackDetails.startSN;
17843
+ const prevFrag = fragments[curSNIdx - 1];
17844
+ if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
17845
+ foundFrag = prevFrag;
17846
+ }
17847
+ }
17851
17848
  if (this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
17852
17849
  // only load if fragment is not loaded
17853
17850
  this.loadFragment(foundFrag, track, targetBufferTime);
@@ -21191,7 +21188,7 @@ function parseWebVTT(vttByteArray, initPTS, vttCCs, cc, timeOffset, callBack, er
21191
21188
  // Uint8Array.prototype.reduce is not implemented in IE11
21192
21189
  const vttLines = utf8ArrayToStr(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, '\n').split('\n');
21193
21190
  const cues = [];
21194
- const init90kHz = toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale);
21191
+ const init90kHz = initPTS ? toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale) : 0;
21195
21192
  let cueTime = '00:00.000';
21196
21193
  let timestampMapMPEGTS = 0;
21197
21194
  let timestampMapLOCAL = 0;
@@ -21215,6 +21212,10 @@ function parseWebVTT(vttByteArray, initPTS, vttCCs, cc, timeOffset, callBack, er
21215
21212
  }
21216
21213
  }
21217
21214
  if (webVttMpegTsMapOffset) {
21215
+ if (!initPTS) {
21216
+ parsingError = new Error('Missing initPTS for VTT MPEGTS');
21217
+ return;
21218
+ }
21218
21219
  // If we have MPEGTS, offset = presentation time + discontinuity offset
21219
21220
  cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset;
21220
21221
  }
@@ -21710,7 +21711,7 @@ class TimelineController {
21710
21711
  this.captionsTracks = {};
21711
21712
  this.nonNativeCaptionsTracks = {};
21712
21713
  this.textTracks = [];
21713
- this.unparsedVttFrags = this.unparsedVttFrags || [];
21714
+ this.unparsedVttFrags = [];
21714
21715
  this.initPTS = [];
21715
21716
  if (this.cea608Parser1 && this.cea608Parser2) {
21716
21717
  this.cea608Parser1.reset();
@@ -21854,26 +21855,9 @@ class TimelineController {
21854
21855
  frag,
21855
21856
  payload
21856
21857
  } = data;
21857
- const {
21858
- initPTS,
21859
- unparsedVttFrags
21860
- } = this;
21861
21858
  if (frag.type === PlaylistLevelType.SUBTITLE) {
21862
21859
  // If fragment is subtitle type, parse as WebVTT.
21863
21860
  if (payload.byteLength) {
21864
- // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
21865
- if (!initPTS[frag.cc]) {
21866
- unparsedVttFrags.push(data);
21867
- if (initPTS.length) {
21868
- // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
21869
- this.hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
21870
- success: false,
21871
- frag,
21872
- error: new Error('Missing initial subtitle PTS')
21873
- });
21874
- }
21875
- return;
21876
- }
21877
21861
  const decryptData = frag.decryptdata;
21878
21862
  // fragment after decryption has a stats object
21879
21863
  const decrypted = ('stats' in data);
@@ -21892,7 +21876,7 @@ class TimelineController {
21892
21876
  if (trackPlaylistMedia && trackPlaylistMedia.textCodec === IMSC1_CODEC) {
21893
21877
  this._parseIMSC1(frag, payload);
21894
21878
  } else {
21895
- this._parseVTTs(frag, payload, vttCCs);
21879
+ this._parseVTTs(data);
21896
21880
  }
21897
21881
  }
21898
21882
  } else {
@@ -21922,21 +21906,43 @@ class TimelineController {
21922
21906
  });
21923
21907
  });
21924
21908
  }
21925
- _parseVTTs(frag, payload, vttCCs) {
21909
+ _parseVTTs(data) {
21926
21910
  var _frag$initSegment;
21911
+ const {
21912
+ frag,
21913
+ payload
21914
+ } = data;
21915
+ // We need an initial synchronisation PTS. Store fragments as long as none has arrived
21916
+ const {
21917
+ initPTS,
21918
+ unparsedVttFrags
21919
+ } = this;
21920
+ const maxAvCC = initPTS.length - 1;
21921
+ if (!initPTS[frag.cc] && maxAvCC === -1) {
21922
+ unparsedVttFrags.push(data);
21923
+ return;
21924
+ }
21927
21925
  const hls = this.hls;
21928
21926
  // Parse the WebVTT file contents.
21929
21927
  const payloadWebVTT = (_frag$initSegment = frag.initSegment) != null && _frag$initSegment.data ? appendUint8Array(frag.initSegment.data, new Uint8Array(payload)) : payload;
21930
- parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], vttCCs, frag.cc, frag.start, cues => {
21928
+ parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], this.vttCCs, frag.cc, frag.start, cues => {
21931
21929
  this._appendCues(cues, frag.level);
21932
21930
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
21933
21931
  success: true,
21934
21932
  frag: frag
21935
21933
  });
21936
21934
  }, error => {
21937
- this._fallbackToIMSC1(frag, payload);
21935
+ const missingInitPTS = error.message === 'Missing initPTS for VTT MPEGTS';
21936
+ if (missingInitPTS) {
21937
+ unparsedVttFrags.push(data);
21938
+ } else {
21939
+ this._fallbackToIMSC1(frag, payload);
21940
+ }
21938
21941
  // Something went wrong while parsing. Trigger event with success false.
21939
21942
  logger.log(`Failed to parse VTT cue: ${error}`);
21943
+ if (missingInitPTS && maxAvCC > frag.cc) {
21944
+ return;
21945
+ }
21940
21946
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
21941
21947
  success: false,
21942
21948
  frag: frag,
@@ -21986,10 +21992,6 @@ class TimelineController {
21986
21992
  frag
21987
21993
  } = data;
21988
21994
  if (frag.type === PlaylistLevelType.SUBTITLE) {
21989
- if (!this.initPTS[frag.cc]) {
21990
- this.unparsedVttFrags.push(data);
21991
- return;
21992
- }
21993
21995
  this.onFragLoaded(Events.FRAG_LOADED, data);
21994
21996
  }
21995
21997
  }
@@ -24122,6 +24124,7 @@ class XhrLoader {
24122
24124
  const stats = this.stats;
24123
24125
  stats.loading.first = 0;
24124
24126
  stats.loaded = 0;
24127
+ stats.aborted = false;
24125
24128
  const xhrSetup = this.xhrSetup;
24126
24129
  if (xhrSetup) {
24127
24130
  Promise.resolve().then(() => {
@@ -24993,7 +24996,7 @@ class Hls {
24993
24996
  * Get the video-dev/hls.js package version.
24994
24997
  */
24995
24998
  static get version() {
24996
- return "1.4.6";
24999
+ return "1.4.7";
24997
25000
  }
24998
25001
 
24999
25002
  /**