hls.js 1.6.0-rc.1.0.canary.11071 → 1.6.0-rc.1.0.canary.11074

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.light.js CHANGED
@@ -1044,7 +1044,7 @@
1044
1044
  // Some browsers don't allow to use bind on console object anyway
1045
1045
  // fallback to default if needed
1046
1046
  try {
1047
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-rc.1.0.canary.11071");
1047
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-rc.1.0.canary.11074");
1048
1048
  } catch (e) {
1049
1049
  /* log fn threw an exception. All logger methods are no-ops. */
1050
1050
  return createLogger();
@@ -7364,7 +7364,7 @@
7364
7364
  // segment URI, group 3 => the URI (note newline is not eaten)
7365
7365
  /#.*/.source // All other non-segment oriented tags will match with all groups empty
7366
7366
  ].join('|'), 'g');
7367
- var LEVEL_PLAYLIST_REGEX_SLOW = new RegExp([/#(EXTM3U)/.source, /#EXT-X-(PROGRAM-DATE-TIME|BYTERANGE|DATERANGE|DEFINE|KEY|MAP|PART|PART-INF|PLAYLIST-TYPE|PRELOAD-HINT|RENDITION-REPORT|SERVER-CONTROL|SKIP|START):(.+)/.source, /#EXT-X-(BITRATE|DISCONTINUITY-SEQUENCE|MEDIA-SEQUENCE|TARGETDURATION|VERSION): *(\d+)/.source, /#EXT-X-(DISCONTINUITY|ENDLIST|GAP|INDEPENDENT-SEGMENTS)/.source, /(#)([^:]*):(.*)/.source, /(#)(.*)(?:.*)\r?\n?/.source].join('|'));
7367
+ var LEVEL_PLAYLIST_REGEX_SLOW = new RegExp([/#EXT-X-(PROGRAM-DATE-TIME|BYTERANGE|DATERANGE|DEFINE|KEY|MAP|PART|PART-INF|PLAYLIST-TYPE|PRELOAD-HINT|RENDITION-REPORT|SERVER-CONTROL|SKIP|START):(.+)/.source, /#EXT-X-(BITRATE|DISCONTINUITY-SEQUENCE|MEDIA-SEQUENCE|TARGETDURATION|VERSION): *(\d+)/.source, /#EXT-X-(DISCONTINUITY|ENDLIST|GAP|INDEPENDENT-SEGMENTS)/.source, /(#)([^:]*):(.*)/.source, /(#)(.*)(?:.*)\r?\n?/.source].join('|'));
7368
7368
  var M3U8Parser = /*#__PURE__*/function () {
7369
7369
  function M3U8Parser() {}
7370
7370
  M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) {
@@ -7559,6 +7559,7 @@
7559
7559
  return results;
7560
7560
  };
7561
7561
  M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId, multivariantVariableList) {
7562
+ var _LEVEL_PLAYLIST_REGEX;
7562
7563
  var base = {
7563
7564
  url: baseurl
7564
7565
  };
@@ -7580,9 +7581,14 @@
7580
7581
  var firstPdtIndex = -1;
7581
7582
  var createNextFrag = false;
7582
7583
  var nextByteRange = null;
7584
+ var serverControlAttrs;
7583
7585
  LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0;
7584
7586
  level.m3u8 = string;
7585
7587
  level.hasVariableRefs = false;
7588
+ if (((_LEVEL_PLAYLIST_REGEX = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) == null ? void 0 : _LEVEL_PLAYLIST_REGEX[0]) !== '#EXTM3U') {
7589
+ level.playlistParsingError = new Error('Missing format identifier #EXTM3U');
7590
+ return level;
7591
+ }
7586
7592
  while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) {
7587
7593
  if (createNextFrag) {
7588
7594
  createNextFrag = false;
@@ -7671,15 +7677,23 @@
7671
7677
  }
7672
7678
  break;
7673
7679
  case 'PLAYLIST-TYPE':
7680
+ if (level.type) {
7681
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7682
+ }
7674
7683
  level.type = value1.toUpperCase();
7675
7684
  break;
7676
7685
  case 'MEDIA-SEQUENCE':
7686
+ if (level.startSN !== 0) {
7687
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7688
+ } else if (fragments.length > 0) {
7689
+ assignMustAppearBeforeSegmentsError(level, tag, result);
7690
+ }
7677
7691
  currentSN = level.startSN = parseInt(value1);
7678
7692
  break;
7679
7693
  case 'SKIP':
7680
7694
  {
7681
7695
  if (level.skippedSegments) {
7682
- level.playlistParsingError = new Error("#EXT-X-SKIP MUST NOT appear more than once in a Playlist");
7696
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7683
7697
  }
7684
7698
  var skipAttrs = new AttrList(value1, level);
7685
7699
  var skippedSegments = skipAttrs.decimalInteger('SKIPPED-SEGMENTS');
@@ -7698,15 +7712,23 @@
7698
7712
  break;
7699
7713
  }
7700
7714
  case 'TARGETDURATION':
7715
+ if (level.targetduration !== 0) {
7716
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7717
+ }
7701
7718
  level.targetduration = Math.max(parseInt(value1), 1);
7702
7719
  break;
7703
7720
  case 'VERSION':
7721
+ if (level.version !== null) {
7722
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7723
+ }
7704
7724
  level.version = parseInt(value1);
7705
7725
  break;
7706
7726
  case 'INDEPENDENT-SEGMENTS':
7707
- case 'EXTM3U':
7708
7727
  break;
7709
7728
  case 'ENDLIST':
7729
+ if (!level.live) {
7730
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7731
+ }
7710
7732
  level.live = false;
7711
7733
  break;
7712
7734
  case '#':
@@ -7750,6 +7772,11 @@
7750
7772
  break;
7751
7773
  }
7752
7774
  case 'DISCONTINUITY-SEQUENCE':
7775
+ if (level.startCC !== 0) {
7776
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7777
+ } else if (fragments.length > 0) {
7778
+ assignMustAppearBeforeSegmentsError(level, tag, result);
7779
+ }
7753
7780
  level.startCC = discontinuityCounter = parseInt(value1);
7754
7781
  break;
7755
7782
  case 'KEY':
@@ -7808,7 +7835,10 @@
7808
7835
  }
7809
7836
  case 'SERVER-CONTROL':
7810
7837
  {
7811
- var serverControlAttrs = new AttrList(value1);
7838
+ if (serverControlAttrs) {
7839
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7840
+ }
7841
+ serverControlAttrs = new AttrList(value1);
7812
7842
  level.canBlockReload = serverControlAttrs.bool('CAN-BLOCK-RELOAD');
7813
7843
  level.canSkipUntil = serverControlAttrs.optionalFloat('CAN-SKIP-UNTIL', 0);
7814
7844
  level.canSkipDateRanges = level.canSkipUntil > 0 && serverControlAttrs.bool('CAN-SKIP-DATERANGES');
@@ -7818,6 +7848,9 @@
7818
7848
  }
7819
7849
  case 'PART-INF':
7820
7850
  {
7851
+ if (level.partTarget) {
7852
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7853
+ }
7821
7854
  var partInfAttrs = new AttrList(value1);
7822
7855
  level.partTarget = partInfAttrs.decimalFloatingPoint('PART-TARGET');
7823
7856
  break;
@@ -7869,6 +7902,9 @@
7869
7902
  setFragLevelKeys(frag, levelkeys, level);
7870
7903
  }
7871
7904
  }
7905
+ if (!level.targetduration) {
7906
+ level.playlistParsingError = new Error("#EXT-X-TARGETDURATION is required");
7907
+ }
7872
7908
  var fragmentLength = fragments.length;
7873
7909
  var firstFragment = fragments[0];
7874
7910
  var lastFragment = fragments[fragmentLength - 1];
@@ -8055,6 +8091,12 @@
8055
8091
  encryptedFragments.push(frag);
8056
8092
  }
8057
8093
  }
8094
+ function assignMultipleMediaPlaylistTagOccuranceError(level, tag, result) {
8095
+ level.playlistParsingError = new Error("#EXT-X-" + tag + " must not appear more than once (" + result[0] + ")");
8096
+ }
8097
+ function assignMustAppearBeforeSegmentsError(level, tag, result) {
8098
+ level.playlistParsingError = new Error("#EXT-X-" + tag + " must appear before the first Media Segment (" + result[0] + ")");
8099
+ }
8058
8100
 
8059
8101
  function updateFromToPTS(fragFrom, fragTo) {
8060
8102
  var fragToPTS = fragTo.startPTS;
@@ -8344,9 +8386,19 @@
8344
8386
  }
8345
8387
  if (_oldFrag && _newFrag) {
8346
8388
  intersectionFn(_oldFrag, _newFrag, i, newFrags);
8389
+ if (_oldFrag.url && _oldFrag.url !== _newFrag.url) {
8390
+ newDetails.playlistParsingError = getSequenceError("media sequence mismatch " + _newFrag.sn + ":", oldDetails, newDetails, _oldFrag, _newFrag);
8391
+ return;
8392
+ } else if (_oldFrag.cc !== _newFrag.cc) {
8393
+ newDetails.playlistParsingError = getSequenceError("discontinuity sequence mismatch (" + _oldFrag.cc + "!=" + _newFrag.cc + ")", oldDetails, newDetails, _oldFrag, _newFrag);
8394
+ return;
8395
+ }
8347
8396
  }
8348
8397
  }
8349
8398
  }
8399
+ function getSequenceError(message, oldDetails, newDetails, oldFrag, newFrag) {
8400
+ return new Error(message + " " + newFrag.url + "\nPlaylist starting @" + oldDetails.startSN + "\n" + oldDetails.m3u8 + "\n\nPlaylist starting @" + newDetails.startSN + "\n" + newDetails.m3u8);
8401
+ }
8350
8402
  function adjustSliding(oldDetails, newDetails, matchingStableVariantOrRendition) {
8351
8403
  if (matchingStableVariantOrRendition === void 0) {
8352
8404
  matchingStableVariantOrRendition = true;
@@ -15055,6 +15107,7 @@
15055
15107
  // used by fps-controller
15056
15108
  appendErrorMaxRetry: 3,
15057
15109
  // used by buffer-controller
15110
+ ignorePlaylistParsingErrors: false,
15058
15111
  loader: XhrLoader,
15059
15112
  // loader: FetchLoader,
15060
15113
  fLoader: undefined,
@@ -19209,6 +19262,29 @@
19209
19262
  // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
19210
19263
  if (previousDetails && details.fragments.length > 0) {
19211
19264
  mergeDetails(previousDetails, details);
19265
+ var error = details.playlistParsingError;
19266
+ if (error) {
19267
+ this.warn(error);
19268
+ var hls = this.hls;
19269
+ if (!hls.config.ignorePlaylistParsingErrors) {
19270
+ var _details$fragments$;
19271
+ var networkDetails = data.networkDetails;
19272
+ hls.trigger(Events.ERROR, {
19273
+ type: ErrorTypes.NETWORK_ERROR,
19274
+ details: ErrorDetails.LEVEL_PARSING_ERROR,
19275
+ fatal: false,
19276
+ url: details.url,
19277
+ error: error,
19278
+ reason: error.message,
19279
+ level: data.level || undefined,
19280
+ parent: (_details$fragments$ = details.fragments[0]) == null ? void 0 : _details$fragments$.type,
19281
+ networkDetails: networkDetails,
19282
+ stats: stats
19283
+ });
19284
+ return;
19285
+ }
19286
+ details.playlistParsingError = null;
19287
+ }
19212
19288
  }
19213
19289
  if (details.requestScheduled === -1) {
19214
19290
  details.requestScheduled = stats.loading.start;
@@ -20147,7 +20223,7 @@
20147
20223
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
20148
20224
  }
20149
20225
 
20150
- var version = "1.6.0-rc.1.0.canary.11071";
20226
+ var version = "1.6.0-rc.1.0.canary.11074";
20151
20227
 
20152
20228
  // ensure the worker ends up in the bundle
20153
20229
  // If the worker should not be included this gets aliased to empty.js
@@ -22524,21 +22600,25 @@
22524
22600
  }
22525
22601
  var error = levelDetails.playlistParsingError;
22526
22602
  if (error) {
22527
- hls.trigger(Events.ERROR, {
22528
- type: ErrorTypes.NETWORK_ERROR,
22529
- details: ErrorDetails.LEVEL_PARSING_ERROR,
22530
- fatal: false,
22531
- url: url,
22532
- error: error,
22533
- reason: error.message,
22534
- response: response,
22535
- context: context,
22536
- level: levelIndex,
22537
- parent: parent,
22538
- networkDetails: networkDetails,
22539
- stats: stats
22540
- });
22541
- return;
22603
+ this.hls.logger.warn(error);
22604
+ if (!hls.config.ignorePlaylistParsingErrors) {
22605
+ hls.trigger(Events.ERROR, {
22606
+ type: ErrorTypes.NETWORK_ERROR,
22607
+ details: ErrorDetails.LEVEL_PARSING_ERROR,
22608
+ fatal: false,
22609
+ url: url,
22610
+ error: error,
22611
+ reason: error.message,
22612
+ response: response,
22613
+ context: context,
22614
+ level: levelIndex,
22615
+ parent: parent,
22616
+ networkDetails: networkDetails,
22617
+ stats: stats
22618
+ });
22619
+ return;
22620
+ }
22621
+ levelDetails.playlistParsingError = null;
22542
22622
  }
22543
22623
  if (levelDetails.live && loader) {
22544
22624
  if (loader.getCacheAge) {