hls.js 1.6.0-rc.2.0.canary.11081 → 1.6.0

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, context, 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
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-rc.2.0.canary.11081"}`);
405
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0"}`);
406
406
  } catch (e) {
407
407
  /* log fn threw an exception. All logger methods are no-ops. */
408
408
  return createLogger();
@@ -3272,6 +3272,7 @@ class AbrController extends Logger {
3272
3272
  this.fragCurrent = null;
3273
3273
  this.partCurrent = null;
3274
3274
  this.bitrateTestDelay = 0;
3275
+ this.rebufferNotice = -1;
3275
3276
  this.bwEstimator = void 0;
3276
3277
  /*
3277
3278
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
@@ -3737,6 +3738,7 @@ class AbrController extends Logger {
3737
3738
  if (bufferStarvationDelay) {
3738
3739
  const _bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, 0, bwFactor, bwUpFactor);
3739
3740
  if (_bestLevel >= 0) {
3741
+ this.rebufferNotice = -1;
3740
3742
  return _bestLevel;
3741
3743
  }
3742
3744
  }
@@ -3759,7 +3761,10 @@ class AbrController extends Logger {
3759
3761
  }
3760
3762
  }
3761
3763
  const bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
3762
- this.info(`${bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'}, optimal quality level ${bestLevel}`);
3764
+ if (this.rebufferNotice !== bestLevel) {
3765
+ this.rebufferNotice = bestLevel;
3766
+ this.info(`${bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'}, optimal quality level ${bestLevel}`);
3767
+ }
3763
3768
  if (bestLevel > -1) {
3764
3769
  return bestLevel;
3765
3770
  }
@@ -9156,7 +9161,11 @@ class BaseStreamController extends TaskLoop {
9156
9161
  const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
9157
9162
  frag = this.getFragmentAtPosition(pos, end, levelDetails);
9158
9163
  }
9159
- const programFrag = this.filterReplacedPrimary(frag, levelDetails);
9164
+ let programFrag = this.filterReplacedPrimary(frag, levelDetails);
9165
+ if (!programFrag && frag) {
9166
+ const curSNIdx = frag.sn - levelDetails.startSN;
9167
+ programFrag = this.filterReplacedPrimary(fragments[curSNIdx + 1] || null, levelDetails);
9168
+ }
9160
9169
  return this.mapToInitFragWhenRequired(programFrag);
9161
9170
  }
9162
9171
  isLoopLoading(frag, targetBufferTime) {
@@ -10108,7 +10117,7 @@ function requireEventemitter3 () {
10108
10117
  var eventemitter3Exports = requireEventemitter3();
10109
10118
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
10110
10119
 
10111
- const version = "1.6.0-rc.2.0.canary.11081";
10120
+ const version = "1.6.0";
10112
10121
 
10113
10122
  // ensure the worker ends up in the bundle
10114
10123
  // If the worker should not be included this gets aliased to empty.js
@@ -23888,7 +23897,7 @@ class InterstitialsSchedule extends Logger {
23888
23897
  return !playlists.some(playlistType => {
23889
23898
  const details = mediaSelection[playlistType].details;
23890
23899
  const playlistEnd = details.edge;
23891
- if (resumeTime > playlistEnd) {
23900
+ if (resumeTime >= playlistEnd) {
23892
23901
  // Live playback - resumption segments are not yet available
23893
23902
  this.log(`"${interstitial.identifier}" resumption ${resumeTime} past ${playlistType} playlist end ${playlistEnd}`);
23894
23903
  // Assume alignment is possible (or reset can take place)
@@ -25283,14 +25292,18 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25283
25292
  }
25284
25293
 
25285
25294
  // Schedule buffer control
25286
- checkBuffer() {
25295
+ checkBuffer(starved) {
25287
25296
  const items = this.schedule.items;
25288
25297
  if (!items) {
25289
25298
  return;
25290
25299
  }
25291
25300
  // Find when combined forward buffer change reaches next schedule segment
25292
25301
  const bufferInfo = BufferHelper.bufferInfo(this.primaryMedia, this.timelinePos, 0);
25293
- this.updateBufferedPos(bufferInfo.end, items, bufferInfo.len === 0);
25302
+ if (starved) {
25303
+ this.bufferedPos = this.timelinePos;
25304
+ }
25305
+ starved || (starved = bufferInfo.len < 1);
25306
+ this.updateBufferedPos(bufferInfo.end, items, starved);
25294
25307
  }
25295
25308
  updateBufferedPos(bufferEnd, items, bufferIsEmpty) {
25296
25309
  const schedule = this.schedule;
@@ -25327,8 +25340,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25327
25340
  this.preloadAssets(nextItemToBuffer.event, 0);
25328
25341
  }
25329
25342
  }
25330
- } else if (bufferIsEmpty && playingItem && !this.itemsMatch(playingItem, bufferingItem) && bufferEndIndex === playingIndex) {
25331
- this.bufferedToItem(playingItem);
25343
+ } else if (bufferIsEmpty && playingItem && !this.itemsMatch(playingItem, bufferingItem)) {
25344
+ if (bufferEndIndex === playingIndex) {
25345
+ this.bufferedToItem(playingItem);
25346
+ } else if (bufferEndIndex === playingIndex + 1) {
25347
+ this.bufferedToItem(items[bufferEndIndex]);
25348
+ }
25332
25349
  }
25333
25350
  }
25334
25351
  assetsBuffered(item, media) {
@@ -25438,7 +25455,11 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25438
25455
  if (neverLoaded) {
25439
25456
  const timelineStart = interstitial.timelineStart;
25440
25457
  if (interstitial.appendInPlace) {
25441
- this.flushFrontBuffer(timelineStart + 0.25);
25458
+ var _playingItem$nextEven;
25459
+ const playingItem = this.playingItem;
25460
+ if (!this.isInterstitial(playingItem) && (playingItem == null ? void 0 : (_playingItem$nextEven = playingItem.nextEvent) == null ? void 0 : _playingItem$nextEven.identifier) === interstitial.identifier) {
25461
+ this.flushFrontBuffer(timelineStart + 0.25);
25462
+ }
25442
25463
  }
25443
25464
  let hlsStartOffset;
25444
25465
  let liveStartPosition = 0;
@@ -25481,6 +25502,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25481
25502
  if (!requiredTracks) {
25482
25503
  return;
25483
25504
  }
25505
+ this.log(`Removing front buffer starting at ${startOffset}`);
25484
25506
  const sourceBufferNames = Object.keys(requiredTracks);
25485
25507
  sourceBufferNames.forEach(type => {
25486
25508
  this.hls.trigger(Events.BUFFER_FLUSHING, {
@@ -25557,11 +25579,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25557
25579
  }
25558
25580
  }
25559
25581
  }
25582
+ const assetId = assetItem.identifier;
25560
25583
  const playerConfig = _objectSpread2(_objectSpread2({}, userConfig), {}, {
25561
25584
  autoStartLoad: true,
25562
25585
  startFragPrefetch: true,
25563
25586
  primarySessionId: primary.sessionId,
25564
- assetPlayerId: assetItem.identifier,
25587
+ assetPlayerId: assetId,
25565
25588
  abrEwmaDefaultEstimate: primary.bandwidthEstimate,
25566
25589
  interstitialsController: undefined,
25567
25590
  startPosition,
@@ -25583,10 +25606,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25583
25606
  contentId: hash(assetItem.uri)
25584
25607
  });
25585
25608
  }
25609
+ if (this.getAssetPlayer(assetId)) {
25610
+ this.warn(`Duplicate date range identifier ${interstitial} and asset ${assetId}`);
25611
+ }
25586
25612
  const player = new HlsAssetPlayer(this.HlsPlayerClass, playerConfig, interstitial, assetItem);
25587
25613
  this.playerQueue.push(player);
25588
25614
  interstitial.assetList[assetListIndex] = assetItem;
25589
- const assetId = assetItem.identifier;
25590
25615
  // Listen for LevelDetails and PTS change to update duration
25591
25616
  const updateAssetPlayerDetails = details => {
25592
25617
  if (details.live) {
@@ -25628,15 +25653,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25628
25653
  }
25629
25654
  };
25630
25655
  player.on(Events.BUFFER_CODECS, onBufferCodecs);
25631
- const bufferedToEnd = name => {
25656
+ const bufferedToEnd = () => {
25632
25657
  var _this$schedule$items2;
25633
25658
  const inQueuPlayer = this.getAssetPlayer(assetId);
25634
25659
  this.log(`buffered to end of asset ${inQueuPlayer}`);
25635
25660
  if (!inQueuPlayer) {
25636
25661
  return;
25637
25662
  }
25638
- inQueuPlayer.off(Events.BUFFERED_TO_END, bufferedToEnd);
25639
-
25640
25663
  // Preload at end of asset
25641
25664
  const scheduleIndex = this.schedule.findEventIndex(interstitial.identifier);
25642
25665
  const assetListIndex = interstitial.findAssetIndex(assetItem);
@@ -25644,7 +25667,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25644
25667
  const item = (_this$schedule$items2 = this.schedule.items) == null ? void 0 : _this$schedule$items2[scheduleIndex];
25645
25668
  if (this.isInterstitial(item)) {
25646
25669
  if (assetListIndex !== -1 && !interstitial.isAssetPastPlayoutLimit(nextAssetIndex) && !interstitial.assetList[nextAssetIndex].error) {
25647
- this.bufferedToItem(item, assetListIndex + 1);
25670
+ this.bufferedToItem(item, nextAssetIndex);
25648
25671
  } else {
25649
25672
  var _this$schedule$items3;
25650
25673
  const nextItem = (_this$schedule$items3 = this.schedule.items) == null ? void 0 : _this$schedule$items3[scheduleIndex + 1];
@@ -25669,6 +25692,22 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25669
25692
  player.once(Events.MEDIA_ENDED, endedWithAssetIndex(assetListIndex));
25670
25693
  player.once(Events.PLAYOUT_LIMIT_REACHED, endedWithAssetIndex(Infinity));
25671
25694
  player.on(Events.ERROR, (event, data) => {
25695
+ const inQueuPlayer = this.getAssetPlayer(assetId);
25696
+ if (data.details === ErrorDetails.BUFFER_STALLED_ERROR) {
25697
+ if (inQueuPlayer != null && inQueuPlayer.media) {
25698
+ const assetCurrentTime = inQueuPlayer.currentTime;
25699
+ const distanceFromEnd = inQueuPlayer.duration - assetCurrentTime;
25700
+ if (assetCurrentTime && interstitial.appendInPlace && distanceFromEnd / inQueuPlayer.media.playbackRate < 0.5) {
25701
+ this.log(`Advancing buffer past end of asset ${assetId} ${interstitial} at ${inQueuPlayer.media.currentTime}`);
25702
+ bufferedToEnd();
25703
+ } else {
25704
+ this.warn(`Stalled at ${assetCurrentTime} of ${assetCurrentTime + distanceFromEnd} in asset ${assetId} ${interstitial}`);
25705
+ this.onTimeupdate();
25706
+ this.checkBuffer(true);
25707
+ }
25708
+ }
25709
+ return;
25710
+ }
25672
25711
  this.handleAssetItemError(data, interstitial, this.schedule.findEventIndex(interstitial.identifier), assetListIndex, `Asset player error ${data.error} ${interstitial}`);
25673
25712
  });
25674
25713
  player.on(Events.DESTROYING, () => {
@@ -25743,10 +25782,9 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25743
25782
  player
25744
25783
  });
25745
25784
  }
25746
- if (!player.bufferedInPlaceToEnd(media)) {
25747
- // detach media and attach to interstitial player if it does not have another element attached
25748
- this.bufferAssetPlayer(player, media);
25749
- }
25785
+
25786
+ // detach media and attach to interstitial player if it does not have another element attached
25787
+ this.bufferAssetPlayer(player, media);
25750
25788
  }
25751
25789
  bufferAssetPlayer(player, media) {
25752
25790
  var _this$schedule$items4, _this$detachedData5;
@@ -25929,6 +25967,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25929
25967
  if (interstitial) {
25930
25968
  this.primaryFallback(interstitial);
25931
25969
  }
25970
+ break;
25971
+ }
25972
+ case ErrorDetails.BUFFER_STALLED_ERROR:
25973
+ {
25974
+ this.onTimeupdate();
25975
+ this.checkBuffer(true);
25976
+ break;
25932
25977
  }
25933
25978
  }
25934
25979
  }
@@ -35098,5 +35143,5 @@ class Hls {
35098
35143
  }
35099
35144
  Hls.defaultConfig = void 0;
35100
35145
 
35101
- export { AbrController, AttrList, AudioStreamController, AudioTrackController, BasePlaylistController, BaseSegment, BaseStreamController, BufferController, CMCDController, CapLevelController, ChunkMetadata, ContentSteeringController, Cues, DateRange, EMEController, ErrorActionFlags, ErrorController, ErrorDetails, ErrorTypes, Events, FPSController, FetchLoader, Fragment, Hls, HlsSkip, HlsUrlParameters, KeySystemFormats, KeySystems, Level, LevelDetails, LevelKey, LoadStats, MetadataSchema, NetworkErrorAction, Part, PlaylistLevelType, SubtitleStreamController, SubtitleTrackController, TimelineController, XhrLoader, Hls as default, fetchSupported, getMediaSource, isMSESupported, isSupported, requestMediaKeySystemAccess };
35146
+ export { AbrController, AttrList, AudioStreamController, AudioTrackController, BasePlaylistController, BaseSegment, BaseStreamController, BufferController, CMCDController, CapLevelController, ChunkMetadata, ContentSteeringController, Cues, DateRange, EMEController, ErrorActionFlags, ErrorController, ErrorDetails, ErrorTypes, Events, FPSController, FetchLoader, Fragment, Hls, HlsSkip, HlsUrlParameters, KeySystemFormats, KeySystems, Level, LevelDetails, LevelKey, LoadStats, M3U8Parser, MetadataSchema, NetworkErrorAction, Part, PlaylistLevelType, SubtitleStreamController, SubtitleTrackController, TimelineController, XhrLoader, Hls as default, fetchSupported, getMediaSource, isMSESupported, isSupported, requestMediaKeySystemAccess };
35102
35147
  //# sourceMappingURL=hls.mjs.map