hls.js 1.4.5 → 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.js CHANGED
@@ -539,7 +539,7 @@
539
539
  // Some browsers don't allow to use bind on console object anyway
540
540
  // fallback to default if needed
541
541
  try {
542
- exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.4.5");
542
+ exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.4.7");
543
543
  } catch (e) {
544
544
  exportedLogger = fakeLogger;
545
545
  }
@@ -5773,14 +5773,17 @@
5773
5773
  var _data$frag, _data$context2;
5774
5774
  // Search for next level to retry
5775
5775
  var nextLevel = -1;
5776
- var levels = hls.levels;
5776
+ var levels = hls.levels,
5777
+ loadLevel = hls.loadLevel,
5778
+ minAutoLevel = hls.minAutoLevel,
5779
+ maxAutoLevel = hls.maxAutoLevel;
5777
5780
  var fragErrorType = (_data$frag = data.frag) == null ? void 0 : _data$frag.type;
5778
5781
  var _ref = (_data$context2 = data.context) != null ? _data$context2 : {},
5779
5782
  playlistErrorType = _ref.type,
5780
5783
  playlistErrorGroupId = _ref.groupId;
5781
5784
  for (var i = levels.length; i--;) {
5782
- var candidate = (i + hls.loadLevel) % levels.length;
5783
- if (candidate !== hls.loadLevel && levels[candidate].loadError === 0) {
5785
+ var candidate = (i + loadLevel) % levels.length;
5786
+ if (candidate !== loadLevel && candidate >= minAutoLevel && candidate <= maxAutoLevel && levels[candidate].loadError === 0) {
5784
5787
  var levelCandidate = levels[candidate];
5785
5788
  // Skip level switch if GAP tag is found in next level at same position
5786
5789
  if (data.details === ErrorDetails.FRAG_GAP && data.frag) {
@@ -9658,6 +9661,8 @@
9658
9661
  } else {
9659
9662
  logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
9660
9663
  }
9664
+ } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
9665
+ this.state = State.WAITING_LEVEL;
9661
9666
  } else {
9662
9667
  this.state = State.ERROR;
9663
9668
  }
@@ -18027,14 +18032,7 @@
18027
18032
  var startOffset = data.startOffset,
18028
18033
  endOffset = data.endOffset;
18029
18034
  if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
18030
- var currentTrackId = this.currentTrackId,
18031
- levels = this.levels;
18032
- if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) {
18033
- return;
18034
- }
18035
- var trackDetails = levels[currentTrackId].details;
18036
- var targetDuration = trackDetails.targetduration;
18037
- var endOffsetSubtitles = endOffset - targetDuration;
18035
+ var endOffsetSubtitles = endOffset - 1;
18038
18036
  if (endOffsetSubtitles <= 0) {
18039
18037
  return;
18040
18038
  }
@@ -18228,17 +18226,14 @@
18228
18226
  if (!levels.length || !track || !track.details) {
18229
18227
  return;
18230
18228
  }
18231
-
18232
- // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists
18233
- var trackDetails = track.details;
18234
- var targetDuration = trackDetails.targetduration;
18235
18229
  var config = this.config;
18236
18230
  var currentTime = this.getLoadPosition();
18237
- var bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime - targetDuration, config.maxBufferHole);
18231
+ var bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime, config.maxBufferHole);
18238
18232
  var targetBufferTime = bufferedInfo.end,
18239
18233
  bufferLen = bufferedInfo.len;
18240
18234
  var mainBufferInfo = this.getFwdBufferInfo(this.media, PlaylistLevelType.MAIN);
18241
- var maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + targetDuration;
18235
+ var trackDetails = track.details;
18236
+ var maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + trackDetails.levelTargetDuration;
18242
18237
  if (bufferLen > maxBufLen) {
18243
18238
  return;
18244
18239
  }
@@ -18248,8 +18243,9 @@
18248
18243
  var foundFrag = null;
18249
18244
  var fragPrevious = this.fragPrevious;
18250
18245
  if (targetBufferTime < end) {
18251
- var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
18252
- foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), maxFragLookUpTolerance);
18246
+ var tolerance = config.maxFragLookUpTolerance;
18247
+ var lookupTolerance = targetBufferTime > end - tolerance ? 0 : tolerance;
18248
+ foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), lookupTolerance);
18253
18249
  if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) {
18254
18250
  foundFrag = fragments[0];
18255
18251
  }
@@ -18260,6 +18256,14 @@
18260
18256
  return;
18261
18257
  }
18262
18258
  foundFrag = this.mapToInitFragWhenRequired(foundFrag);
18259
+ if (foundFrag.sn !== 'initSegment') {
18260
+ // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
18261
+ var curSNIdx = foundFrag.sn - trackDetails.startSN;
18262
+ var prevFrag = fragments[curSNIdx - 1];
18263
+ if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
18264
+ foundFrag = prevFrag;
18265
+ }
18266
+ }
18263
18267
  if (this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
18264
18268
  // only load if fragment is not loaded
18265
18269
  this.loadFragment(foundFrag, track, targetBufferTime);
@@ -21639,7 +21643,7 @@
21639
21643
  // Uint8Array.prototype.reduce is not implemented in IE11
21640
21644
  var vttLines = utf8ArrayToStr(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, '\n').split('\n');
21641
21645
  var cues = [];
21642
- var init90kHz = toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale);
21646
+ var init90kHz = initPTS ? toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale) : 0;
21643
21647
  var cueTime = '00:00.000';
21644
21648
  var timestampMapMPEGTS = 0;
21645
21649
  var timestampMapLOCAL = 0;
@@ -21663,6 +21667,10 @@
21663
21667
  }
21664
21668
  }
21665
21669
  if (webVttMpegTsMapOffset) {
21670
+ if (!initPTS) {
21671
+ parsingError = new Error('Missing initPTS for VTT MPEGTS');
21672
+ return;
21673
+ }
21666
21674
  // If we have MPEGTS, offset = presentation time + discontinuity offset
21667
21675
  cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset;
21668
21676
  }
@@ -22153,7 +22161,7 @@
22153
22161
  this.captionsTracks = {};
22154
22162
  this.nonNativeCaptionsTracks = {};
22155
22163
  this.textTracks = [];
22156
- this.unparsedVttFrags = this.unparsedVttFrags || [];
22164
+ this.unparsedVttFrags = [];
22157
22165
  this.initPTS = [];
22158
22166
  if (this.cea608Parser1 && this.cea608Parser2) {
22159
22167
  this.cea608Parser1.reset();
@@ -22295,24 +22303,9 @@
22295
22303
  _proto.onFragLoaded = function onFragLoaded(event, data) {
22296
22304
  var frag = data.frag,
22297
22305
  payload = data.payload;
22298
- var initPTS = this.initPTS,
22299
- unparsedVttFrags = this.unparsedVttFrags;
22300
22306
  if (frag.type === PlaylistLevelType.SUBTITLE) {
22301
22307
  // If fragment is subtitle type, parse as WebVTT.
22302
22308
  if (payload.byteLength) {
22303
- // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
22304
- if (!initPTS[frag.cc]) {
22305
- unparsedVttFrags.push(data);
22306
- if (initPTS.length) {
22307
- // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
22308
- this.hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22309
- success: false,
22310
- frag: frag,
22311
- error: new Error('Missing initial subtitle PTS')
22312
- });
22313
- }
22314
- return;
22315
- }
22316
22309
  var decryptData = frag.decryptdata;
22317
22310
  // fragment after decryption has a stats object
22318
22311
  var decrypted = ('stats' in data);
@@ -22331,7 +22324,7 @@
22331
22324
  if (trackPlaylistMedia && trackPlaylistMedia.textCodec === IMSC1_CODEC) {
22332
22325
  this._parseIMSC1(frag, payload);
22333
22326
  } else {
22334
- this._parseVTTs(frag, payload, vttCCs);
22327
+ this._parseVTTs(data);
22335
22328
  }
22336
22329
  }
22337
22330
  } else {
@@ -22362,22 +22355,40 @@
22362
22355
  });
22363
22356
  });
22364
22357
  };
22365
- _proto._parseVTTs = function _parseVTTs(frag, payload, vttCCs) {
22358
+ _proto._parseVTTs = function _parseVTTs(data) {
22366
22359
  var _frag$initSegment,
22367
22360
  _this5 = this;
22361
+ var frag = data.frag,
22362
+ payload = data.payload;
22363
+ // We need an initial synchronisation PTS. Store fragments as long as none has arrived
22364
+ var initPTS = this.initPTS,
22365
+ unparsedVttFrags = this.unparsedVttFrags;
22366
+ var maxAvCC = initPTS.length - 1;
22367
+ if (!initPTS[frag.cc] && maxAvCC === -1) {
22368
+ unparsedVttFrags.push(data);
22369
+ return;
22370
+ }
22368
22371
  var hls = this.hls;
22369
22372
  // Parse the WebVTT file contents.
22370
22373
  var payloadWebVTT = (_frag$initSegment = frag.initSegment) != null && _frag$initSegment.data ? appendUint8Array(frag.initSegment.data, new Uint8Array(payload)) : payload;
22371
- parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], vttCCs, frag.cc, frag.start, function (cues) {
22374
+ parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], this.vttCCs, frag.cc, frag.start, function (cues) {
22372
22375
  _this5._appendCues(cues, frag.level);
22373
22376
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22374
22377
  success: true,
22375
22378
  frag: frag
22376
22379
  });
22377
22380
  }, function (error) {
22378
- _this5._fallbackToIMSC1(frag, payload);
22381
+ var missingInitPTS = error.message === 'Missing initPTS for VTT MPEGTS';
22382
+ if (missingInitPTS) {
22383
+ unparsedVttFrags.push(data);
22384
+ } else {
22385
+ _this5._fallbackToIMSC1(frag, payload);
22386
+ }
22379
22387
  // Something went wrong while parsing. Trigger event with success false.
22380
22388
  logger.log("Failed to parse VTT cue: " + error);
22389
+ if (missingInitPTS && maxAvCC > frag.cc) {
22390
+ return;
22391
+ }
22381
22392
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22382
22393
  success: false,
22383
22394
  frag: frag,
@@ -22428,10 +22439,6 @@
22428
22439
  _proto.onFragDecrypted = function onFragDecrypted(event, data) {
22429
22440
  var frag = data.frag;
22430
22441
  if (frag.type === PlaylistLevelType.SUBTITLE) {
22431
- if (!this.initPTS[frag.cc]) {
22432
- this.unparsedVttFrags.push(data);
22433
- return;
22434
- }
22435
22442
  this.onFragLoaded(Events.FRAG_LOADED, data);
22436
22443
  }
22437
22444
  };
@@ -24622,6 +24629,7 @@
24622
24629
  var stats = this.stats;
24623
24630
  stats.loading.first = 0;
24624
24631
  stats.loaded = 0;
24632
+ stats.aborted = false;
24625
24633
  var xhrSetup = this.xhrSetup;
24626
24634
  if (xhrSetup) {
24627
24635
  Promise.resolve().then(function () {
@@ -26252,7 +26260,7 @@
26252
26260
  * Get the video-dev/hls.js package version.
26253
26261
  */
26254
26262
  function get() {
26255
- return "1.4.5";
26263
+ return "1.4.7";
26256
26264
  }
26257
26265
  }, {
26258
26266
  key: "Events",