hls.js 1.6.0-rc.1.0.canary.11073 → 1.6.0-rc.1.0.canary.11076

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.d.mts CHANGED
@@ -1972,6 +1972,7 @@ export declare type HlsConfig = {
1972
1972
  maxDevicePixelRatio: number;
1973
1973
  preferManagedMediaSource: boolean;
1974
1974
  timelineOffset?: number;
1975
+ ignorePlaylistParsingErrors: boolean;
1975
1976
  loader: {
1976
1977
  new (confg: HlsConfig): Loader<LoaderContext>;
1977
1978
  };
package/dist/hls.d.ts CHANGED
@@ -1972,6 +1972,7 @@ export declare type HlsConfig = {
1972
1972
  maxDevicePixelRatio: number;
1973
1973
  preferManagedMediaSource: boolean;
1974
1974
  timelineOffset?: number;
1975
+ ignorePlaylistParsingErrors: boolean;
1975
1976
  loader: {
1976
1977
  new (confg: HlsConfig): Loader<LoaderContext>;
1977
1978
  };
package/dist/hls.js CHANGED
@@ -1073,7 +1073,7 @@
1073
1073
  // Some browsers don't allow to use bind on console object anyway
1074
1074
  // fallback to default if needed
1075
1075
  try {
1076
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-rc.1.0.canary.11073");
1076
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-rc.1.0.canary.11076");
1077
1077
  } catch (e) {
1078
1078
  /* log fn threw an exception. All logger methods are no-ops. */
1079
1079
  return createLogger();
@@ -7656,7 +7656,7 @@
7656
7656
  // segment URI, group 3 => the URI (note newline is not eaten)
7657
7657
  /#.*/.source // All other non-segment oriented tags will match with all groups empty
7658
7658
  ].join('|'), 'g');
7659
- 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('|'));
7659
+ 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('|'));
7660
7660
  var M3U8Parser = /*#__PURE__*/function () {
7661
7661
  function M3U8Parser() {}
7662
7662
  M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) {
@@ -7856,6 +7856,7 @@
7856
7856
  return results;
7857
7857
  };
7858
7858
  M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId, multivariantVariableList) {
7859
+ var _LEVEL_PLAYLIST_REGEX;
7859
7860
  var base = {
7860
7861
  url: baseurl
7861
7862
  };
@@ -7877,9 +7878,14 @@
7877
7878
  var firstPdtIndex = -1;
7878
7879
  var createNextFrag = false;
7879
7880
  var nextByteRange = null;
7881
+ var serverControlAttrs;
7880
7882
  LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0;
7881
7883
  level.m3u8 = string;
7882
7884
  level.hasVariableRefs = hasVariableReferences(string) ;
7885
+ if (((_LEVEL_PLAYLIST_REGEX = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) == null ? void 0 : _LEVEL_PLAYLIST_REGEX[0]) !== '#EXTM3U') {
7886
+ level.playlistParsingError = new Error('Missing format identifier #EXTM3U');
7887
+ return level;
7888
+ }
7883
7889
  while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) {
7884
7890
  if (createNextFrag) {
7885
7891
  createNextFrag = false;
@@ -7968,15 +7974,23 @@
7968
7974
  }
7969
7975
  break;
7970
7976
  case 'PLAYLIST-TYPE':
7977
+ if (level.type) {
7978
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7979
+ }
7971
7980
  level.type = value1.toUpperCase();
7972
7981
  break;
7973
7982
  case 'MEDIA-SEQUENCE':
7983
+ if (level.startSN !== 0) {
7984
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7985
+ } else if (fragments.length > 0) {
7986
+ assignMustAppearBeforeSegmentsError(level, tag, result);
7987
+ }
7974
7988
  currentSN = level.startSN = parseInt(value1);
7975
7989
  break;
7976
7990
  case 'SKIP':
7977
7991
  {
7978
7992
  if (level.skippedSegments) {
7979
- level.playlistParsingError = new Error("#EXT-X-SKIP MUST NOT appear more than once in a Playlist");
7993
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
7980
7994
  }
7981
7995
  var skipAttrs = new AttrList(value1, level);
7982
7996
  var skippedSegments = skipAttrs.decimalInteger('SKIPPED-SEGMENTS');
@@ -7995,15 +8009,23 @@
7995
8009
  break;
7996
8010
  }
7997
8011
  case 'TARGETDURATION':
8012
+ if (level.targetduration !== 0) {
8013
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8014
+ }
7998
8015
  level.targetduration = Math.max(parseInt(value1), 1);
7999
8016
  break;
8000
8017
  case 'VERSION':
8018
+ if (level.version !== null) {
8019
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8020
+ }
8001
8021
  level.version = parseInt(value1);
8002
8022
  break;
8003
8023
  case 'INDEPENDENT-SEGMENTS':
8004
- case 'EXTM3U':
8005
8024
  break;
8006
8025
  case 'ENDLIST':
8026
+ if (!level.live) {
8027
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8028
+ }
8007
8029
  level.live = false;
8008
8030
  break;
8009
8031
  case '#':
@@ -8055,6 +8077,11 @@
8055
8077
  break;
8056
8078
  }
8057
8079
  case 'DISCONTINUITY-SEQUENCE':
8080
+ if (level.startCC !== 0) {
8081
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8082
+ } else if (fragments.length > 0) {
8083
+ assignMustAppearBeforeSegmentsError(level, tag, result);
8084
+ }
8058
8085
  level.startCC = discontinuityCounter = parseInt(value1);
8059
8086
  break;
8060
8087
  case 'KEY':
@@ -8113,7 +8140,10 @@
8113
8140
  }
8114
8141
  case 'SERVER-CONTROL':
8115
8142
  {
8116
- var serverControlAttrs = new AttrList(value1);
8143
+ if (serverControlAttrs) {
8144
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8145
+ }
8146
+ serverControlAttrs = new AttrList(value1);
8117
8147
  level.canBlockReload = serverControlAttrs.bool('CAN-BLOCK-RELOAD');
8118
8148
  level.canSkipUntil = serverControlAttrs.optionalFloat('CAN-SKIP-UNTIL', 0);
8119
8149
  level.canSkipDateRanges = level.canSkipUntil > 0 && serverControlAttrs.bool('CAN-SKIP-DATERANGES');
@@ -8123,6 +8153,9 @@
8123
8153
  }
8124
8154
  case 'PART-INF':
8125
8155
  {
8156
+ if (level.partTarget) {
8157
+ assignMultipleMediaPlaylistTagOccuranceError(level, tag, result);
8158
+ }
8126
8159
  var partInfAttrs = new AttrList(value1);
8127
8160
  level.partTarget = partInfAttrs.decimalFloatingPoint('PART-TARGET');
8128
8161
  break;
@@ -8174,6 +8207,9 @@
8174
8207
  setFragLevelKeys(frag, levelkeys, level);
8175
8208
  }
8176
8209
  }
8210
+ if (!level.targetduration) {
8211
+ level.playlistParsingError = new Error("#EXT-X-TARGETDURATION is required");
8212
+ }
8177
8213
  var fragmentLength = fragments.length;
8178
8214
  var firstFragment = fragments[0];
8179
8215
  var lastFragment = fragments[fragmentLength - 1];
@@ -8360,6 +8396,12 @@
8360
8396
  encryptedFragments.push(frag);
8361
8397
  }
8362
8398
  }
8399
+ function assignMultipleMediaPlaylistTagOccuranceError(level, tag, result) {
8400
+ level.playlistParsingError = new Error("#EXT-X-" + tag + " must not appear more than once (" + result[0] + ")");
8401
+ }
8402
+ function assignMustAppearBeforeSegmentsError(level, tag, result) {
8403
+ level.playlistParsingError = new Error("#EXT-X-" + tag + " must appear before the first Media Segment (" + result[0] + ")");
8404
+ }
8363
8405
 
8364
8406
  function updateFromToPTS(fragFrom, fragTo) {
8365
8407
  var fragToPTS = fragTo.startPTS;
@@ -8649,9 +8691,19 @@
8649
8691
  }
8650
8692
  if (_oldFrag && _newFrag) {
8651
8693
  intersectionFn(_oldFrag, _newFrag, i, newFrags);
8694
+ if (_oldFrag.url && _oldFrag.url !== _newFrag.url) {
8695
+ newDetails.playlistParsingError = getSequenceError("media sequence mismatch " + _newFrag.sn + ":", oldDetails, newDetails, _oldFrag, _newFrag);
8696
+ return;
8697
+ } else if (_oldFrag.cc !== _newFrag.cc) {
8698
+ newDetails.playlistParsingError = getSequenceError("discontinuity sequence mismatch (" + _oldFrag.cc + "!=" + _newFrag.cc + ")", oldDetails, newDetails, _oldFrag, _newFrag);
8699
+ return;
8700
+ }
8652
8701
  }
8653
8702
  }
8654
8703
  }
8704
+ function getSequenceError(message, oldDetails, newDetails, oldFrag, newFrag) {
8705
+ return new Error(message + " " + newFrag.url + "\nPlaylist starting @" + oldDetails.startSN + "\n" + oldDetails.m3u8 + "\n\nPlaylist starting @" + newDetails.startSN + "\n" + newDetails.m3u8);
8706
+ }
8655
8707
  function adjustSliding(oldDetails, newDetails, matchingStableVariantOrRendition) {
8656
8708
  if (matchingStableVariantOrRendition === void 0) {
8657
8709
  matchingStableVariantOrRendition = true;
@@ -16479,7 +16531,7 @@
16479
16531
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
16480
16532
  }
16481
16533
 
16482
- var version = "1.6.0-rc.1.0.canary.11073";
16534
+ var version = "1.6.0-rc.1.0.canary.11076";
16483
16535
 
16484
16536
  // ensure the worker ends up in the bundle
16485
16537
  // If the worker should not be included this gets aliased to empty.js
@@ -17754,6 +17806,29 @@
17754
17806
  // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
17755
17807
  if (previousDetails && details.fragments.length > 0) {
17756
17808
  mergeDetails(previousDetails, details);
17809
+ var error = details.playlistParsingError;
17810
+ if (error) {
17811
+ this.warn(error);
17812
+ var hls = this.hls;
17813
+ if (!hls.config.ignorePlaylistParsingErrors) {
17814
+ var _details$fragments$;
17815
+ var networkDetails = data.networkDetails;
17816
+ hls.trigger(Events.ERROR, {
17817
+ type: ErrorTypes.NETWORK_ERROR,
17818
+ details: ErrorDetails.LEVEL_PARSING_ERROR,
17819
+ fatal: false,
17820
+ url: details.url,
17821
+ error: error,
17822
+ reason: error.message,
17823
+ level: data.level || undefined,
17824
+ parent: (_details$fragments$ = details.fragments[0]) == null ? void 0 : _details$fragments$.type,
17825
+ networkDetails: networkDetails,
17826
+ stats: stats
17827
+ });
17828
+ return;
17829
+ }
17830
+ details.playlistParsingError = null;
17831
+ }
17757
17832
  }
17758
17833
  if (details.requestScheduled === -1) {
17759
17834
  details.requestScheduled = stats.loading.start;
@@ -30619,6 +30694,7 @@
30619
30694
  // used by fps-controller
30620
30695
  appendErrorMaxRetry: 3,
30621
30696
  // used by buffer-controller
30697
+ ignorePlaylistParsingErrors: false,
30622
30698
  loader: XhrLoader,
30623
30699
  // loader: FetchLoader,
30624
30700
  fLoader: undefined,
@@ -34695,21 +34771,25 @@
34695
34771
  }
34696
34772
  var error = levelDetails.playlistParsingError;
34697
34773
  if (error) {
34698
- hls.trigger(Events.ERROR, {
34699
- type: ErrorTypes.NETWORK_ERROR,
34700
- details: ErrorDetails.LEVEL_PARSING_ERROR,
34701
- fatal: false,
34702
- url: url,
34703
- error: error,
34704
- reason: error.message,
34705
- response: response,
34706
- context: context,
34707
- level: levelIndex,
34708
- parent: parent,
34709
- networkDetails: networkDetails,
34710
- stats: stats
34711
- });
34712
- return;
34774
+ this.hls.logger.warn(error);
34775
+ if (!hls.config.ignorePlaylistParsingErrors) {
34776
+ hls.trigger(Events.ERROR, {
34777
+ type: ErrorTypes.NETWORK_ERROR,
34778
+ details: ErrorDetails.LEVEL_PARSING_ERROR,
34779
+ fatal: false,
34780
+ url: url,
34781
+ error: error,
34782
+ reason: error.message,
34783
+ response: response,
34784
+ context: context,
34785
+ level: levelIndex,
34786
+ parent: parent,
34787
+ networkDetails: networkDetails,
34788
+ stats: stats
34789
+ });
34790
+ return;
34791
+ }
34792
+ levelDetails.playlistParsingError = null;
34713
34793
  }
34714
34794
  if (levelDetails.live && loader) {
34715
34795
  if (loader.getCacheAge) {
package/dist/hls.js.d.ts CHANGED
@@ -1972,6 +1972,7 @@ export declare type HlsConfig = {
1972
1972
  maxDevicePixelRatio: number;
1973
1973
  preferManagedMediaSource: boolean;
1974
1974
  timelineOffset?: number;
1975
+ ignorePlaylistParsingErrors: boolean;
1975
1976
  loader: {
1976
1977
  new (confg: HlsConfig): Loader<LoaderContext>;
1977
1978
  };