hls.js 1.6.0-beta.1.0.canary.10788 → 1.6.0-beta.1.0.canary.10789

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.
@@ -400,7 +400,7 @@ function enableLogs(debugConfig, context, id) {
400
400
  // Some browsers don't allow to use bind on console object anyway
401
401
  // fallback to default if needed
402
402
  try {
403
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10788"}`);
403
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10789"}`);
404
404
  } catch (e) {
405
405
  /* log fn threw an exception. All logger methods are no-ops. */
406
406
  return createLogger();
@@ -3140,6 +3140,7 @@ class LevelDetails {
3140
3140
  this.dateRanges = void 0;
3141
3141
  this.dateRangeTagCount = 0;
3142
3142
  this.live = true;
3143
+ this.requestScheduled = -1;
3143
3144
  this.ageHeader = 0;
3144
3145
  this.advancedDateTime = void 0;
3145
3146
  this.updated = true;
@@ -5417,6 +5418,9 @@ function mergeDetails(oldDetails, newDetails) {
5417
5418
  newDetails.driftEnd = oldDetails.driftEnd;
5418
5419
  newDetails.advancedDateTime = oldDetails.advancedDateTime;
5419
5420
  }
5421
+ if (newDetails.requestScheduled === -1) {
5422
+ newDetails.requestScheduled = oldDetails.requestScheduled;
5423
+ }
5420
5424
  }
5421
5425
  function mergeDateRanges(oldDateRanges, newDetails) {
5422
5426
  const {
@@ -5585,7 +5589,6 @@ class BasePlaylistController extends Logger {
5585
5589
  super(logPrefix, hls.logger);
5586
5590
  this.hls = void 0;
5587
5591
  this.timer = -1;
5588
- this.requestScheduled = -1;
5589
5592
  this.canLoad = false;
5590
5593
  this.hls = hls;
5591
5594
  }
@@ -5602,7 +5605,6 @@ class BasePlaylistController extends Logger {
5602
5605
  }
5603
5606
  startLoad() {
5604
5607
  this.canLoad = true;
5605
- this.requestScheduled = -1;
5606
5608
  this.loadPlaylist();
5607
5609
  }
5608
5610
  stopLoad() {
@@ -5647,16 +5649,25 @@ class BasePlaylistController extends Logger {
5647
5649
  }
5648
5650
  }
5649
5651
  loadPlaylist(hlsUrlParameters) {
5650
- if (this.requestScheduled === -1) {
5651
- this.requestScheduled = self.performance.now();
5652
- }
5653
5652
  // Loading is handled by the subclasses
5653
+ this.clearTimer();
5654
+ }
5655
+ loadingPlaylist(playlist, hlsUrlParameters) {
5656
+ // Loading is handled by the subclasses
5657
+ this.clearTimer();
5654
5658
  }
5655
5659
  shouldLoadPlaylist(playlist) {
5656
5660
  return this.canLoad && !!playlist && !!playlist.url && (!playlist.details || playlist.details.live);
5657
5661
  }
5658
- shouldReloadPlaylist(playlist) {
5659
- return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
5662
+ getUrlWithDirectives(uri, hlsUrlParameters) {
5663
+ if (hlsUrlParameters) {
5664
+ try {
5665
+ return hlsUrlParameters.addDirectives(uri);
5666
+ } catch (error) {
5667
+ this.warn(`Could not construct new URL with HLS Delivery Directives: ${error}`);
5668
+ }
5669
+ }
5670
+ return uri;
5660
5671
  }
5661
5672
  playlistLoaded(index, data, previousDetails) {
5662
5673
  const {
@@ -5681,10 +5692,9 @@ class BasePlaylistController extends Logger {
5681
5692
 
5682
5693
  // if current playlist is a live playlist, arm a timer to reload it
5683
5694
  if (details.live || previousDetails != null && previousDetails.live) {
5695
+ const levelOrTrack = 'levelInfo' in data ? data.levelInfo : data.track;
5684
5696
  details.reloaded(previousDetails);
5685
- if (previousDetails) {
5686
- this.log(`live playlist ${index} ${details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : details.updated ? 'UPDATED' : 'MISSED'}`);
5687
- }
5697
+ this.log(`live playlist ${index} ${details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : details.updated ? 'UPDATED' : 'MISSED'}`);
5688
5698
  // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
5689
5699
  if (previousDetails && details.fragments.length > 0) {
5690
5700
  mergeDetails(previousDetails, details);
@@ -5740,50 +5750,64 @@ class BasePlaylistController extends Logger {
5740
5750
  }
5741
5751
  deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
5742
5752
  if (lowLatencyMode || !lastPart) {
5743
- this.loadPlaylist(deliveryDirectives);
5753
+ this.loadingPlaylist(levelOrTrack, deliveryDirectives);
5744
5754
  return;
5745
5755
  }
5746
5756
  } else if (details.canBlockReload || details.canSkipUntil) {
5747
5757
  deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
5748
5758
  }
5759
+ if (details.requestScheduled === -1) {
5760
+ details.requestScheduled = stats.loading.start;
5761
+ }
5762
+ if (deliveryDirectives && msn !== undefined && details.canBlockReload) {
5763
+ details.requestScheduled -= details.partTarget * 1000 || 1000;
5764
+ }
5749
5765
  const bufferInfo = this.hls.mainForwardBufferInfo;
5750
5766
  const position = bufferInfo ? bufferInfo.end - bufferInfo.len : 0;
5751
5767
  const distanceToLiveEdgeMs = (details.edge - position) * 1000;
5752
5768
  const reloadInterval = computeReloadInterval(details, distanceToLiveEdgeMs);
5753
- if (details.updated && now > this.requestScheduled + reloadInterval) {
5754
- this.requestScheduled = stats.loading.start;
5755
- }
5756
- if (msn !== undefined && details.canBlockReload) {
5757
- this.requestScheduled = stats.loading.first + reloadInterval - (details.partTarget * 1000 || 1000);
5758
- } else if (this.requestScheduled === -1 || this.requestScheduled + reloadInterval < now) {
5759
- this.requestScheduled = now;
5760
- } else if (this.requestScheduled - now <= 0) {
5761
- this.requestScheduled += reloadInterval;
5762
- }
5763
- let estimatedTimeUntilUpdate = this.requestScheduled - now;
5764
- estimatedTimeUntilUpdate = Math.max(0, estimatedTimeUntilUpdate);
5765
- this.log(`reload live playlist ${index} in ${Math.round(estimatedTimeUntilUpdate)} ms`);
5766
- // this.log(
5767
- // `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
5768
- // reload in ${estimatedTimeUntilUpdate / 1000}
5769
- // round trip ${(stats.loading.end - stats.loading.start) / 1000}
5770
- // diff ${
5771
- // (reloadInterval -
5772
- // (estimatedTimeUntilUpdate +
5773
- // stats.loading.end -
5774
- // stats.loading.start)) /
5775
- // 1000
5776
- // }
5777
- // reload interval ${reloadInterval / 1000}
5778
- // target duration ${details.targetduration}
5779
- // distance to edge ${distanceToLiveEdgeMs / 1000}`
5780
- // );
5781
-
5782
- this.timer = self.setTimeout(() => this.loadPlaylist(deliveryDirectives), estimatedTimeUntilUpdate);
5769
+ if (details.requestScheduled + reloadInterval < now) {
5770
+ details.requestScheduled = now;
5771
+ } else {
5772
+ details.requestScheduled += reloadInterval;
5773
+ }
5774
+ this.scheduleLoading(levelOrTrack, deliveryDirectives);
5783
5775
  } else {
5784
5776
  this.clearTimer();
5785
5777
  }
5786
5778
  }
5779
+ scheduleLoading(levelOrTrack, deliveryDirectives) {
5780
+ const details = levelOrTrack.details;
5781
+ if (!details) {
5782
+ this.loadingPlaylist(levelOrTrack, deliveryDirectives);
5783
+ return;
5784
+ }
5785
+ const now = self.performance.now();
5786
+ const requestScheduled = details.requestScheduled;
5787
+ if (now >= requestScheduled) {
5788
+ this.loadingPlaylist(levelOrTrack, deliveryDirectives);
5789
+ return;
5790
+ }
5791
+ const estimatedTimeUntilUpdate = requestScheduled - now;
5792
+ this.log(`reload live playlist ${levelOrTrack.name || levelOrTrack.bitrate + 'bps'} in ${Math.round(estimatedTimeUntilUpdate)} ms`);
5793
+ // this.log(
5794
+ // `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
5795
+ // reload in ${estimatedTimeUntilUpdate / 1000}
5796
+ // round trip ${(stats.loading.end - stats.loading.start) / 1000}
5797
+ // diff ${
5798
+ // (reloadInterval -
5799
+ // (estimatedTimeUntilUpdate +
5800
+ // stats.loading.end -
5801
+ // stats.loading.start)) /
5802
+ // 1000
5803
+ // }
5804
+ // reload interval ${reloadInterval / 1000}
5805
+ // target duration ${details.targetduration}
5806
+ // distance to edge ${distanceToLiveEdgeMs / 1000}`
5807
+ // );
5808
+
5809
+ this.timer = self.setTimeout(() => this.loadingPlaylist(levelOrTrack, deliveryDirectives), estimatedTimeUntilUpdate);
5810
+ }
5787
5811
  getDeliveryDirectives(details, previousDeliveryDirectives, msn, part) {
5788
5812
  let skip = getSkipValue(details);
5789
5813
  if (previousDeliveryDirectives != null && previousDeliveryDirectives.skip && details.deltaUpdateFailed) {
@@ -5805,7 +5829,6 @@ class BasePlaylistController extends Logger {
5805
5829
  const retry = !!errorAction && !!retryConfig && (action === NetworkErrorAction.RetryRequest || !errorAction.resolved && action === NetworkErrorAction.SendAlternateToPenaltyBox);
5806
5830
  if (retry) {
5807
5831
  var _errorEvent$context;
5808
- this.requestScheduled = -1;
5809
5832
  if (retryCount >= retryConfig.maxNumRetry) {
5810
5833
  return false;
5811
5834
  }
@@ -8608,12 +8631,13 @@ class BaseStreamController extends TaskLoop {
8608
8631
  this.nextLoadPosition = startPosition;
8609
8632
  }
8610
8633
  getLoadPosition() {
8634
+ var _this$hls;
8611
8635
  const {
8612
8636
  media
8613
8637
  } = this;
8614
8638
  // if we have not yet loaded any fragment, start loading from start position
8615
8639
  let pos = 0;
8616
- if (this.hls.hasEnoughToStart && media) {
8640
+ if ((_this$hls = this.hls) != null && _this$hls.hasEnoughToStart && media) {
8617
8641
  pos = media.currentTime;
8618
8642
  } else if (this.nextLoadPosition >= 0) {
8619
8643
  pos = this.nextLoadPosition;
@@ -18518,9 +18542,7 @@ class LevelController extends BasePlaylistController {
18518
18542
  this.currentLevelIndex = newLevel;
18519
18543
  this.currentLevel = level;
18520
18544
  if (lastLevelIndex === newLevel && lastLevel && lastPathwayId === pathwayId) {
18521
- if (level.details || this.requestScheduled !== -1) {
18522
- return;
18523
- }
18545
+ return;
18524
18546
  }
18525
18547
  this.log(`Switching to level ${newLevel} (${level.height ? level.height + 'p ' : ''}${level.videoRange ? level.videoRange + ' ' : ''}${level.codecSet ? level.codecSet + ' ' : ''}@${level.bitrate})${pathwayId ? ' with Pathway ' + pathwayId : ''} from level ${lastLevelIndex}${lastPathwayId ? ' with Pathway ' + lastPathwayId : ''}`);
18526
18548
  const levelSwitchingData = {
@@ -18614,10 +18636,7 @@ class LevelController extends BasePlaylistController {
18614
18636
  return;
18615
18637
  }
18616
18638
  if (data.context.type === PlaylistContextType.LEVEL && data.context.level === this.level) {
18617
- const retry = this.checkRetry(data);
18618
- if (!retry) {
18619
- this.requestScheduled = -1;
18620
- }
18639
+ this.checkRetry(data);
18621
18640
  }
18622
18641
  }
18623
18642
 
@@ -18672,36 +18691,28 @@ class LevelController extends BasePlaylistController {
18672
18691
  }
18673
18692
  loadPlaylist(hlsUrlParameters) {
18674
18693
  super.loadPlaylist();
18675
- const currentLevelIndex = this.currentLevelIndex;
18676
- const currentLevel = this.currentLevel;
18677
- if (currentLevel && this.shouldLoadPlaylist(currentLevel)) {
18678
- let url = currentLevel.uri;
18679
- if (hlsUrlParameters) {
18680
- try {
18681
- url = hlsUrlParameters.addDirectives(url);
18682
- } catch (error) {
18683
- this.warn(`Could not construct new URL with HLS Delivery Directives: ${error}`);
18684
- }
18685
- }
18686
- const pathwayId = currentLevel.attrs['PATHWAY-ID'];
18687
- const details = currentLevel.details;
18688
- const age = details == null ? void 0 : details.age;
18689
- this.log(`Loading level index ${currentLevelIndex}${(hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : ''}${pathwayId ? ' Pathway ' + pathwayId : ''}${age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : ''} ${url}`);
18690
-
18691
- // console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
18692
- // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
18693
- this.clearTimer();
18694
- this.hls.trigger(Events.LEVEL_LOADING, {
18695
- url,
18696
- level: currentLevelIndex,
18697
- levelInfo: currentLevel,
18698
- pathwayId: currentLevel.attrs['PATHWAY-ID'],
18699
- id: 0,
18700
- // Deprecated Level urlId
18701
- deliveryDirectives: hlsUrlParameters || null
18702
- });
18694
+ if (this.shouldLoadPlaylist(this.currentLevel)) {
18695
+ this.scheduleLoading(this.currentLevel, hlsUrlParameters);
18703
18696
  }
18704
18697
  }
18698
+ loadingPlaylist(currentLevel, hlsUrlParameters) {
18699
+ super.loadingPlaylist(currentLevel, hlsUrlParameters);
18700
+ const url = this.getUrlWithDirectives(currentLevel.uri, hlsUrlParameters);
18701
+ const currentLevelIndex = this.currentLevelIndex;
18702
+ const pathwayId = currentLevel.attrs['PATHWAY-ID'];
18703
+ const details = currentLevel.details;
18704
+ const age = details == null ? void 0 : details.age;
18705
+ this.log(`Loading level index ${currentLevelIndex}${(hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : ''}${pathwayId ? ' Pathway ' + pathwayId : ''}${age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : ''} ${url}`);
18706
+ this.hls.trigger(Events.LEVEL_LOADING, {
18707
+ url,
18708
+ level: currentLevelIndex,
18709
+ levelInfo: currentLevel,
18710
+ pathwayId: currentLevel.attrs['PATHWAY-ID'],
18711
+ id: 0,
18712
+ // Deprecated Level urlId
18713
+ deliveryDirectives: hlsUrlParameters || null
18714
+ });
18715
+ }
18705
18716
  get nextLoadLevel() {
18706
18717
  if (this.manualLevelIndex !== -1) {
18707
18718
  return this.manualLevelIndex;
@@ -19119,7 +19130,7 @@ class GapController extends Logger {
19119
19130
  }
19120
19131
  }
19121
19132
 
19122
- const version = "1.6.0-beta.1.0.canary.10788";
19133
+ const version = "1.6.0-beta.1.0.canary.10789";
19123
19134
 
19124
19135
  // ensure the worker ends up in the bundle
19125
19136
  // If the worker should not be included this gets aliased to empty.js