hls.js 1.6.0-rc.2 → 1.6.0-rc.2.0.canary.11083

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"}`);
405
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-rc.2.0.canary.11083"}`);
406
406
  } catch (e) {
407
407
  /* log fn threw an exception. All logger methods are no-ops. */
408
408
  return createLogger();
@@ -1308,29 +1308,27 @@ function parseInitSegment(initSegment) {
1308
1308
  soun: ElementaryStreamTypes.AUDIO,
1309
1309
  vide: ElementaryStreamTypes.VIDEO
1310
1310
  }[hdlrType];
1311
+ // Parse codec details
1312
+ const stsdBox = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];
1313
+ const stsd = parseStsd(stsdBox);
1311
1314
  if (type) {
1312
- // Parse codec details
1313
- const stsdBox = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];
1314
- const stsd = parseStsd(stsdBox);
1315
- if (type) {
1316
- // Add 'audio', 'video', and 'audiovideo' track records that will map to SourceBuffers
1317
- result[trackId] = {
1318
- timescale,
1319
- type,
1320
- stsd
1321
- };
1322
- result[type] = _objectSpread2({
1323
- timescale,
1324
- id: trackId
1325
- }, stsd);
1326
- } else {
1327
- // Add 'meta' and other track records required by `offsetStartDTS`
1328
- result[trackId] = {
1329
- timescale,
1330
- type: hdlrType,
1331
- stsd
1332
- };
1333
- }
1315
+ // Add 'audio', 'video', and 'audiovideo' track records that will map to SourceBuffers
1316
+ result[trackId] = {
1317
+ timescale,
1318
+ type,
1319
+ stsd
1320
+ };
1321
+ result[type] = _objectSpread2({
1322
+ timescale,
1323
+ id: trackId
1324
+ }, stsd);
1325
+ } else {
1326
+ // Add 'meta' and other track records required by `offsetStartDTS`
1327
+ result[trackId] = {
1328
+ timescale,
1329
+ type: hdlrType,
1330
+ stsd
1331
+ };
1334
1332
  }
1335
1333
  }
1336
1334
  }
@@ -3274,6 +3272,7 @@ class AbrController extends Logger {
3274
3272
  this.fragCurrent = null;
3275
3273
  this.partCurrent = null;
3276
3274
  this.bitrateTestDelay = 0;
3275
+ this.rebufferNotice = -1;
3277
3276
  this.bwEstimator = void 0;
3278
3277
  /*
3279
3278
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
@@ -3739,6 +3738,7 @@ class AbrController extends Logger {
3739
3738
  if (bufferStarvationDelay) {
3740
3739
  const _bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, 0, bwFactor, bwUpFactor);
3741
3740
  if (_bestLevel >= 0) {
3741
+ this.rebufferNotice = -1;
3742
3742
  return _bestLevel;
3743
3743
  }
3744
3744
  }
@@ -3761,7 +3761,10 @@ class AbrController extends Logger {
3761
3761
  }
3762
3762
  }
3763
3763
  const bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
3764
- 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
+ }
3765
3768
  if (bestLevel > -1) {
3766
3769
  return bestLevel;
3767
3770
  }
@@ -9158,7 +9161,11 @@ class BaseStreamController extends TaskLoop {
9158
9161
  const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
9159
9162
  frag = this.getFragmentAtPosition(pos, end, levelDetails);
9160
9163
  }
9161
- 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
+ }
9162
9169
  return this.mapToInitFragWhenRequired(programFrag);
9163
9170
  }
9164
9171
  isLoopLoading(frag, targetBufferTime) {
@@ -10110,7 +10117,7 @@ function requireEventemitter3 () {
10110
10117
  var eventemitter3Exports = requireEventemitter3();
10111
10118
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
10112
10119
 
10113
- const version = "1.6.0-rc.2";
10120
+ const version = "1.6.0-rc.2.0.canary.11083";
10114
10121
 
10115
10122
  // ensure the worker ends up in the bundle
10116
10123
  // If the worker should not be included this gets aliased to empty.js
@@ -23890,7 +23897,7 @@ class InterstitialsSchedule extends Logger {
23890
23897
  return !playlists.some(playlistType => {
23891
23898
  const details = mediaSelection[playlistType].details;
23892
23899
  const playlistEnd = details.edge;
23893
- if (resumeTime > playlistEnd) {
23900
+ if (resumeTime >= playlistEnd) {
23894
23901
  // Live playback - resumption segments are not yet available
23895
23902
  this.log(`"${interstitial.identifier}" resumption ${resumeTime} past ${playlistType} playlist end ${playlistEnd}`);
23896
23903
  // Assume alignment is possible (or reset can take place)
@@ -25285,14 +25292,18 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25285
25292
  }
25286
25293
 
25287
25294
  // Schedule buffer control
25288
- checkBuffer() {
25295
+ checkBuffer(starved) {
25289
25296
  const items = this.schedule.items;
25290
25297
  if (!items) {
25291
25298
  return;
25292
25299
  }
25293
25300
  // Find when combined forward buffer change reaches next schedule segment
25294
25301
  const bufferInfo = BufferHelper.bufferInfo(this.primaryMedia, this.timelinePos, 0);
25295
- 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);
25296
25307
  }
25297
25308
  updateBufferedPos(bufferEnd, items, bufferIsEmpty) {
25298
25309
  const schedule = this.schedule;
@@ -25329,8 +25340,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25329
25340
  this.preloadAssets(nextItemToBuffer.event, 0);
25330
25341
  }
25331
25342
  }
25332
- } else if (bufferIsEmpty && playingItem && !this.itemsMatch(playingItem, bufferingItem) && bufferEndIndex === playingIndex) {
25333
- 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
+ }
25334
25349
  }
25335
25350
  }
25336
25351
  assetsBuffered(item, media) {
@@ -25440,7 +25455,11 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25440
25455
  if (neverLoaded) {
25441
25456
  const timelineStart = interstitial.timelineStart;
25442
25457
  if (interstitial.appendInPlace) {
25443
- 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
+ }
25444
25463
  }
25445
25464
  let hlsStartOffset;
25446
25465
  let liveStartPosition = 0;
@@ -25483,6 +25502,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25483
25502
  if (!requiredTracks) {
25484
25503
  return;
25485
25504
  }
25505
+ this.log(`Removing front buffer starting at ${startOffset}`);
25486
25506
  const sourceBufferNames = Object.keys(requiredTracks);
25487
25507
  sourceBufferNames.forEach(type => {
25488
25508
  this.hls.trigger(Events.BUFFER_FLUSHING, {
@@ -25559,11 +25579,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25559
25579
  }
25560
25580
  }
25561
25581
  }
25582
+ const assetId = assetItem.identifier;
25562
25583
  const playerConfig = _objectSpread2(_objectSpread2({}, userConfig), {}, {
25563
25584
  autoStartLoad: true,
25564
25585
  startFragPrefetch: true,
25565
25586
  primarySessionId: primary.sessionId,
25566
- assetPlayerId: assetItem.identifier,
25587
+ assetPlayerId: assetId,
25567
25588
  abrEwmaDefaultEstimate: primary.bandwidthEstimate,
25568
25589
  interstitialsController: undefined,
25569
25590
  startPosition,
@@ -25585,10 +25606,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25585
25606
  contentId: hash(assetItem.uri)
25586
25607
  });
25587
25608
  }
25609
+ if (this.getAssetPlayer(assetId)) {
25610
+ this.warn(`Duplicate date range identifier ${interstitial} and asset ${assetId}`);
25611
+ }
25588
25612
  const player = new HlsAssetPlayer(this.HlsPlayerClass, playerConfig, interstitial, assetItem);
25589
25613
  this.playerQueue.push(player);
25590
25614
  interstitial.assetList[assetListIndex] = assetItem;
25591
- const assetId = assetItem.identifier;
25592
25615
  // Listen for LevelDetails and PTS change to update duration
25593
25616
  const updateAssetPlayerDetails = details => {
25594
25617
  if (details.live) {
@@ -25630,15 +25653,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25630
25653
  }
25631
25654
  };
25632
25655
  player.on(Events.BUFFER_CODECS, onBufferCodecs);
25633
- const bufferedToEnd = name => {
25656
+ const bufferedToEnd = () => {
25634
25657
  var _this$schedule$items2;
25635
25658
  const inQueuPlayer = this.getAssetPlayer(assetId);
25636
25659
  this.log(`buffered to end of asset ${inQueuPlayer}`);
25637
25660
  if (!inQueuPlayer) {
25638
25661
  return;
25639
25662
  }
25640
- inQueuPlayer.off(Events.BUFFERED_TO_END, bufferedToEnd);
25641
-
25642
25663
  // Preload at end of asset
25643
25664
  const scheduleIndex = this.schedule.findEventIndex(interstitial.identifier);
25644
25665
  const assetListIndex = interstitial.findAssetIndex(assetItem);
@@ -25646,7 +25667,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25646
25667
  const item = (_this$schedule$items2 = this.schedule.items) == null ? void 0 : _this$schedule$items2[scheduleIndex];
25647
25668
  if (this.isInterstitial(item)) {
25648
25669
  if (assetListIndex !== -1 && !interstitial.isAssetPastPlayoutLimit(nextAssetIndex) && !interstitial.assetList[nextAssetIndex].error) {
25649
- this.bufferedToItem(item, assetListIndex + 1);
25670
+ this.bufferedToItem(item, nextAssetIndex);
25650
25671
  } else {
25651
25672
  var _this$schedule$items3;
25652
25673
  const nextItem = (_this$schedule$items3 = this.schedule.items) == null ? void 0 : _this$schedule$items3[scheduleIndex + 1];
@@ -25671,6 +25692,22 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25671
25692
  player.once(Events.MEDIA_ENDED, endedWithAssetIndex(assetListIndex));
25672
25693
  player.once(Events.PLAYOUT_LIMIT_REACHED, endedWithAssetIndex(Infinity));
25673
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
+ }
25674
25711
  this.handleAssetItemError(data, interstitial, this.schedule.findEventIndex(interstitial.identifier), assetListIndex, `Asset player error ${data.error} ${interstitial}`);
25675
25712
  });
25676
25713
  player.on(Events.DESTROYING, () => {
@@ -25745,10 +25782,9 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25745
25782
  player
25746
25783
  });
25747
25784
  }
25748
- if (!player.bufferedInPlaceToEnd(media)) {
25749
- // detach media and attach to interstitial player if it does not have another element attached
25750
- this.bufferAssetPlayer(player, media);
25751
- }
25785
+
25786
+ // detach media and attach to interstitial player if it does not have another element attached
25787
+ this.bufferAssetPlayer(player, media);
25752
25788
  }
25753
25789
  bufferAssetPlayer(player, media) {
25754
25790
  var _this$schedule$items4, _this$detachedData5;
@@ -25931,6 +25967,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
25931
25967
  if (interstitial) {
25932
25968
  this.primaryFallback(interstitial);
25933
25969
  }
25970
+ break;
25971
+ }
25972
+ case ErrorDetails.BUFFER_STALLED_ERROR:
25973
+ {
25974
+ this.onTimeupdate();
25975
+ this.checkBuffer(true);
25976
+ break;
25934
25977
  }
25935
25978
  }
25936
25979
  }
@@ -35100,5 +35143,5 @@ class Hls {
35100
35143
  }
35101
35144
  Hls.defaultConfig = void 0;
35102
35145
 
35103
- 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 };
35104
35147
  //# sourceMappingURL=hls.mjs.map