hls.js 1.4.6 → 1.4.8

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.6");
542
+ exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.4.8");
543
543
  } catch (e) {
544
544
  exportedLogger = fakeLogger;
545
545
  }
@@ -9642,10 +9642,8 @@
9642
9642
  retryCount = _ref2$retryCount === void 0 ? 0 : _ref2$retryCount,
9643
9643
  retryConfig = _ref2.retryConfig;
9644
9644
  if (errorAction && action === NetworkErrorAction.RetryRequest && retryConfig) {
9645
- if (!this.loadedmetadata) {
9646
- this.startFragRequested = false;
9647
- this.nextLoadPosition = this.startPosition;
9648
- }
9645
+ var _this$levelLastLoaded;
9646
+ this.resetStartWhenNotLoaded((_this$levelLastLoaded = this.levelLastLoaded) != null ? _this$levelLastLoaded : frag.level);
9649
9647
  var delay = getRetryDelay(retryConfig, retryCount);
9650
9648
  this.warn("Fragment " + frag.sn + " of " + filterType + " " + frag.level + " errored with " + data.details + ", retrying loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " in " + delay + "ms");
9651
9649
  errorAction.resolved = true;
@@ -9661,6 +9659,8 @@
9661
9659
  } else {
9662
9660
  logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
9663
9661
  }
9662
+ } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
9663
+ this.state = State.WAITING_LEVEL;
9664
9664
  } else {
9665
9665
  this.state = State.ERROR;
9666
9666
  }
@@ -9743,9 +9743,10 @@
9743
9743
  }
9744
9744
  };
9745
9745
  _proto.resetWhenMissingContext = function resetWhenMissingContext(chunkMeta) {
9746
+ var _this$levelLastLoaded2;
9746
9747
  this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered.");
9747
9748
  this.removeUnbufferedFrags();
9748
- this.resetStartWhenNotLoaded(chunkMeta.level);
9749
+ this.resetStartWhenNotLoaded((_this$levelLastLoaded2 = this.levelLastLoaded) != null ? _this$levelLastLoaded2 : chunkMeta.level);
9749
9750
  this.resetLoadingState();
9750
9751
  };
9751
9752
  _proto.removeUnbufferedFrags = function removeUnbufferedFrags(start) {
@@ -9821,7 +9822,10 @@
9821
9822
  };
9822
9823
  _proto.recoverWorkerError = function recoverWorkerError(data) {
9823
9824
  if (data.event === 'demuxerWorker') {
9825
+ var _ref3, _this$levelLastLoaded3, _this$fragCurrent3;
9826
+ this.fragmentTracker.removeAllFragments();
9824
9827
  this.resetTransmuxer();
9828
+ this.resetStartWhenNotLoaded((_ref3 = (_this$levelLastLoaded3 = this.levelLastLoaded) != null ? _this$levelLastLoaded3 : (_this$fragCurrent3 = this.fragCurrent) == null ? void 0 : _this$fragCurrent3.level) != null ? _ref3 : 0);
9825
9829
  this.resetLoadingState();
9826
9830
  }
9827
9831
  };
@@ -16157,6 +16161,7 @@
16157
16161
  }
16158
16162
 
16159
16163
  // Avoid buffering if backtracking this fragment
16164
+ var notFirstFragment = frag.sn !== (details == null ? void 0 : details.startSN);
16160
16165
  if (video && remuxResult.independent !== false) {
16161
16166
  if (details) {
16162
16167
  var startPTS = video.startPTS,
@@ -16180,7 +16185,7 @@
16180
16185
  var bufferInfo = this.getMainFwdBufferInfo();
16181
16186
  var targetBufferTime = (bufferInfo ? bufferInfo.end : this.getLoadPosition()) + this.config.maxBufferHole;
16182
16187
  var startTime = video.firstKeyFramePTS ? video.firstKeyFramePTS : startPTS;
16183
- if (targetBufferTime < startTime - this.config.maxBufferHole) {
16188
+ if (notFirstFragment && targetBufferTime < startTime - this.config.maxBufferHole) {
16184
16189
  this.backtrack(frag);
16185
16190
  return;
16186
16191
  }
@@ -16194,7 +16199,7 @@
16194
16199
  }
16195
16200
  this.bufferFragmentData(video, frag, part, chunkMeta);
16196
16201
  }
16197
- } else if (remuxResult.independent === false) {
16202
+ } else if (notFirstFragment && remuxResult.independent === false) {
16198
16203
  this.backtrack(frag);
16199
16204
  return;
16200
16205
  }
@@ -18030,14 +18035,7 @@
18030
18035
  var startOffset = data.startOffset,
18031
18036
  endOffset = data.endOffset;
18032
18037
  if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
18033
- var currentTrackId = this.currentTrackId,
18034
- levels = this.levels;
18035
- if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) {
18036
- return;
18037
- }
18038
- var trackDetails = levels[currentTrackId].details;
18039
- var targetDuration = trackDetails.targetduration;
18040
- var endOffsetSubtitles = endOffset - targetDuration;
18038
+ var endOffsetSubtitles = endOffset - 1;
18041
18039
  if (endOffsetSubtitles <= 0) {
18042
18040
  return;
18043
18041
  }
@@ -18231,17 +18229,14 @@
18231
18229
  if (!levels.length || !track || !track.details) {
18232
18230
  return;
18233
18231
  }
18234
-
18235
- // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists
18236
- var trackDetails = track.details;
18237
- var targetDuration = trackDetails.targetduration;
18238
18232
  var config = this.config;
18239
18233
  var currentTime = this.getLoadPosition();
18240
- var bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime - targetDuration, config.maxBufferHole);
18234
+ var bufferedInfo = BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime, config.maxBufferHole);
18241
18235
  var targetBufferTime = bufferedInfo.end,
18242
18236
  bufferLen = bufferedInfo.len;
18243
18237
  var mainBufferInfo = this.getFwdBufferInfo(this.media, PlaylistLevelType.MAIN);
18244
- var maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + targetDuration;
18238
+ var trackDetails = track.details;
18239
+ var maxBufLen = this.getMaxBufferLength(mainBufferInfo == null ? void 0 : mainBufferInfo.len) + trackDetails.levelTargetDuration;
18245
18240
  if (bufferLen > maxBufLen) {
18246
18241
  return;
18247
18242
  }
@@ -18251,8 +18246,9 @@
18251
18246
  var foundFrag = null;
18252
18247
  var fragPrevious = this.fragPrevious;
18253
18248
  if (targetBufferTime < end) {
18254
- var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
18255
- foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), maxFragLookUpTolerance);
18249
+ var tolerance = config.maxFragLookUpTolerance;
18250
+ var lookupTolerance = targetBufferTime > end - tolerance ? 0 : tolerance;
18251
+ foundFrag = findFragmentByPTS(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), lookupTolerance);
18256
18252
  if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) {
18257
18253
  foundFrag = fragments[0];
18258
18254
  }
@@ -18263,6 +18259,14 @@
18263
18259
  return;
18264
18260
  }
18265
18261
  foundFrag = this.mapToInitFragWhenRequired(foundFrag);
18262
+ if (foundFrag.sn !== 'initSegment') {
18263
+ // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
18264
+ var curSNIdx = foundFrag.sn - trackDetails.startSN;
18265
+ var prevFrag = fragments[curSNIdx - 1];
18266
+ if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
18267
+ foundFrag = prevFrag;
18268
+ }
18269
+ }
18266
18270
  if (this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
18267
18271
  // only load if fragment is not loaded
18268
18272
  this.loadFragment(foundFrag, track, targetBufferTime);
@@ -21642,7 +21646,7 @@
21642
21646
  // Uint8Array.prototype.reduce is not implemented in IE11
21643
21647
  var vttLines = utf8ArrayToStr(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, '\n').split('\n');
21644
21648
  var cues = [];
21645
- var init90kHz = toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale);
21649
+ var init90kHz = initPTS ? toMpegTsClockFromTimescale(initPTS.baseTime, initPTS.timescale) : 0;
21646
21650
  var cueTime = '00:00.000';
21647
21651
  var timestampMapMPEGTS = 0;
21648
21652
  var timestampMapLOCAL = 0;
@@ -21666,6 +21670,10 @@
21666
21670
  }
21667
21671
  }
21668
21672
  if (webVttMpegTsMapOffset) {
21673
+ if (!initPTS) {
21674
+ parsingError = new Error('Missing initPTS for VTT MPEGTS');
21675
+ return;
21676
+ }
21669
21677
  // If we have MPEGTS, offset = presentation time + discontinuity offset
21670
21678
  cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset;
21671
21679
  }
@@ -22156,7 +22164,7 @@
22156
22164
  this.captionsTracks = {};
22157
22165
  this.nonNativeCaptionsTracks = {};
22158
22166
  this.textTracks = [];
22159
- this.unparsedVttFrags = this.unparsedVttFrags || [];
22167
+ this.unparsedVttFrags = [];
22160
22168
  this.initPTS = [];
22161
22169
  if (this.cea608Parser1 && this.cea608Parser2) {
22162
22170
  this.cea608Parser1.reset();
@@ -22298,24 +22306,9 @@
22298
22306
  _proto.onFragLoaded = function onFragLoaded(event, data) {
22299
22307
  var frag = data.frag,
22300
22308
  payload = data.payload;
22301
- var initPTS = this.initPTS,
22302
- unparsedVttFrags = this.unparsedVttFrags;
22303
22309
  if (frag.type === PlaylistLevelType.SUBTITLE) {
22304
22310
  // If fragment is subtitle type, parse as WebVTT.
22305
22311
  if (payload.byteLength) {
22306
- // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
22307
- if (!initPTS[frag.cc]) {
22308
- unparsedVttFrags.push(data);
22309
- if (initPTS.length) {
22310
- // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
22311
- this.hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22312
- success: false,
22313
- frag: frag,
22314
- error: new Error('Missing initial subtitle PTS')
22315
- });
22316
- }
22317
- return;
22318
- }
22319
22312
  var decryptData = frag.decryptdata;
22320
22313
  // fragment after decryption has a stats object
22321
22314
  var decrypted = ('stats' in data);
@@ -22334,7 +22327,7 @@
22334
22327
  if (trackPlaylistMedia && trackPlaylistMedia.textCodec === IMSC1_CODEC) {
22335
22328
  this._parseIMSC1(frag, payload);
22336
22329
  } else {
22337
- this._parseVTTs(frag, payload, vttCCs);
22330
+ this._parseVTTs(data);
22338
22331
  }
22339
22332
  }
22340
22333
  } else {
@@ -22365,22 +22358,40 @@
22365
22358
  });
22366
22359
  });
22367
22360
  };
22368
- _proto._parseVTTs = function _parseVTTs(frag, payload, vttCCs) {
22361
+ _proto._parseVTTs = function _parseVTTs(data) {
22369
22362
  var _frag$initSegment,
22370
22363
  _this5 = this;
22364
+ var frag = data.frag,
22365
+ payload = data.payload;
22366
+ // We need an initial synchronisation PTS. Store fragments as long as none has arrived
22367
+ var initPTS = this.initPTS,
22368
+ unparsedVttFrags = this.unparsedVttFrags;
22369
+ var maxAvCC = initPTS.length - 1;
22370
+ if (!initPTS[frag.cc] && maxAvCC === -1) {
22371
+ unparsedVttFrags.push(data);
22372
+ return;
22373
+ }
22371
22374
  var hls = this.hls;
22372
22375
  // Parse the WebVTT file contents.
22373
22376
  var payloadWebVTT = (_frag$initSegment = frag.initSegment) != null && _frag$initSegment.data ? appendUint8Array(frag.initSegment.data, new Uint8Array(payload)) : payload;
22374
- parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], vttCCs, frag.cc, frag.start, function (cues) {
22377
+ parseWebVTT(payloadWebVTT, this.initPTS[frag.cc], this.vttCCs, frag.cc, frag.start, function (cues) {
22375
22378
  _this5._appendCues(cues, frag.level);
22376
22379
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22377
22380
  success: true,
22378
22381
  frag: frag
22379
22382
  });
22380
22383
  }, function (error) {
22381
- _this5._fallbackToIMSC1(frag, payload);
22384
+ var missingInitPTS = error.message === 'Missing initPTS for VTT MPEGTS';
22385
+ if (missingInitPTS) {
22386
+ unparsedVttFrags.push(data);
22387
+ } else {
22388
+ _this5._fallbackToIMSC1(frag, payload);
22389
+ }
22382
22390
  // Something went wrong while parsing. Trigger event with success false.
22383
22391
  logger.log("Failed to parse VTT cue: " + error);
22392
+ if (missingInitPTS && maxAvCC > frag.cc) {
22393
+ return;
22394
+ }
22384
22395
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22385
22396
  success: false,
22386
22397
  frag: frag,
@@ -22431,10 +22442,6 @@
22431
22442
  _proto.onFragDecrypted = function onFragDecrypted(event, data) {
22432
22443
  var frag = data.frag;
22433
22444
  if (frag.type === PlaylistLevelType.SUBTITLE) {
22434
- if (!this.initPTS[frag.cc]) {
22435
- this.unparsedVttFrags.push(data);
22436
- return;
22437
- }
22438
22445
  this.onFragLoaded(Events.FRAG_LOADED, data);
22439
22446
  }
22440
22447
  };
@@ -24625,6 +24632,7 @@
24625
24632
  var stats = this.stats;
24626
24633
  stats.loading.first = 0;
24627
24634
  stats.loaded = 0;
24635
+ stats.aborted = false;
24628
24636
  var xhrSetup = this.xhrSetup;
24629
24637
  if (xhrSetup) {
24630
24638
  Promise.resolve().then(function () {
@@ -26255,7 +26263,7 @@
26255
26263
  * Get the video-dev/hls.js package version.
26256
26264
  */
26257
26265
  function get() {
26258
- return "1.4.6";
26266
+ return "1.4.8";
26259
26267
  }
26260
26268
  }, {
26261
26269
  key: "Events",