hls.js 1.6.0-beta.4.0.canary.11033 → 1.6.0-beta.4.0.canary.11034

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-beta.4.0.canary.11033");
1047
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.4.0.canary.11034");
1048
1048
  } catch (e) {
1049
1049
  /* log fn threw an exception. All logger methods are no-ops. */
1050
1050
  return createLogger();
@@ -3426,8 +3426,8 @@
3426
3426
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
3427
3427
  quickly enough to prevent underbuffering
3428
3428
  */
3429
- _this._abandonRulesCheck = function () {
3430
- var _this$hls$latestLevel;
3429
+ _this._abandonRulesCheck = function (levelLoaded) {
3430
+ var _ref;
3431
3431
  var _this2 = _this,
3432
3432
  frag = _this2.fragCurrent,
3433
3433
  part = _this2.partCurrent,
@@ -3442,20 +3442,29 @@
3442
3442
  var duration = part ? part.duration : frag.duration;
3443
3443
  var timeLoading = now - stats.loading.start;
3444
3444
  var minAutoLevel = hls.minAutoLevel;
3445
+ var loadingFragForLevel = frag.level;
3446
+ var currentAutoLevel = _this._nextAutoLevel;
3445
3447
  // If frag loading is aborted, complete, or from lowest level, stop timer and return
3446
- if (stats.aborted || stats.loaded && stats.loaded === stats.total || frag.level <= minAutoLevel) {
3448
+ if (stats.aborted || stats.loaded && stats.loaded === stats.total || loadingFragForLevel <= minAutoLevel) {
3447
3449
  _this.clearTimer();
3448
3450
  // reset forced auto level value so that next level will be selected
3449
3451
  _this._nextAutoLevel = -1;
3450
3452
  return;
3451
3453
  }
3452
3454
 
3453
- // This check only runs if we're in ABR mode and actually playing
3454
- if (!autoLevelEnabled || media.paused || !media.playbackRate || !media.readyState) {
3455
+ // This check only runs if we're in ABR mode
3456
+ if (!autoLevelEnabled) {
3457
+ return;
3458
+ }
3459
+
3460
+ // Must be loading/loaded a new level or be in a playing state
3461
+ var fragBlockingSwitch = currentAutoLevel > -1 && currentAutoLevel !== loadingFragForLevel;
3462
+ var levelChange = !!levelLoaded || fragBlockingSwitch;
3463
+ if (!levelChange && (media.paused || !media.playbackRate || !media.readyState)) {
3455
3464
  return;
3456
3465
  }
3457
3466
  var bufferInfo = hls.mainForwardBufferInfo;
3458
- if (bufferInfo === null) {
3467
+ if (!levelChange && bufferInfo === null) {
3459
3468
  return;
3460
3469
  }
3461
3470
  var ttfbEstimate = _this.bwEstimator.getEstimateTTFB();
@@ -3466,12 +3475,12 @@
3466
3475
  }
3467
3476
 
3468
3477
  // bufferStarvationDelay is an estimate of the amount time (in seconds) it will take to exhaust the buffer
3469
- var bufferStarvationDelay = bufferInfo.len / playbackRate;
3478
+ var bufferStarvationDelay = bufferInfo ? bufferInfo.len / playbackRate : 0;
3470
3479
  var ttfb = stats.loading.first ? stats.loading.first - stats.loading.start : -1;
3471
3480
  var loadedFirstByte = stats.loaded && ttfb > -1;
3472
3481
  var bwEstimate = _this.getBwEstimate();
3473
3482
  var levels = hls.levels;
3474
- var level = levels[frag.level];
3483
+ var level = levels[loadingFragForLevel];
3475
3484
  var expectedLen = Math.max(stats.loaded, Math.round(duration * (frag.bitrate || level.averageBitrate) / 8));
3476
3485
  var timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
3477
3486
  if (timeStreaming < 1 && loadedFirstByte) {
@@ -3486,12 +3495,12 @@
3486
3495
  return;
3487
3496
  }
3488
3497
  var bwe = loadRate ? loadRate * 8 : bwEstimate;
3489
- var live = ((_this$hls$latestLevel = _this.hls.latestLevelDetails) == null ? void 0 : _this$hls$latestLevel.live) === true;
3498
+ var live = ((_ref = (levelLoaded == null ? void 0 : levelLoaded.details) || _this.hls.latestLevelDetails) == null ? void 0 : _ref.live) === true;
3490
3499
  var abrBandWidthUpFactor = _this.hls.config.abrBandWidthUpFactor;
3491
3500
  var fragLevelNextLoadedDelay = Number.POSITIVE_INFINITY;
3492
3501
  var nextLoadLevel;
3493
3502
  // Iterate through lower level and try to find the largest one that avoids rebuffering
3494
- for (nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) {
3503
+ for (nextLoadLevel = loadingFragForLevel - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) {
3495
3504
  // compute time to load next fragment at lower level
3496
3505
  // 8 = bits per byte (bps/Bps)
3497
3506
  var levelNextBitrate = levels[nextLoadLevel].maxBitrate;
@@ -3526,10 +3535,10 @@
3526
3535
  if (bestSwitchLevel > -1) {
3527
3536
  nextLoadLevel = bestSwitchLevel;
3528
3537
  }
3529
- _this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly;\n Fragment duration: " + frag.duration.toFixed(3) + "\n Time to underbuffer: " + bufferStarvationDelay.toFixed(3) + " s\n Estimated load time for current fragment: " + fragLoadedDelay.toFixed(3) + " s\n Estimated load time for down switch fragment: " + fragLevelNextLoadedDelay.toFixed(3) + " s\n TTFB estimate: " + (ttfb | 0) + " ms\n Current BW estimate: " + (isFiniteNumber(bwEstimate) ? bwEstimate | 0 : 'Unknown') + " bps\n New BW estimate: " + (_this.getBwEstimate() | 0) + " bps\n Switching to level " + nextLoadLevel + " @ " + (nextLoadLevelBitrate | 0) + " bps");
3538
+ _this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + loadingFragForLevel + " is loading too slowly;\n Fragment duration: " + frag.duration.toFixed(3) + "\n Time to underbuffer: " + bufferStarvationDelay.toFixed(3) + " s\n Estimated load time for current fragment: " + fragLoadedDelay.toFixed(3) + " s\n Estimated load time for down switch fragment: " + fragLevelNextLoadedDelay.toFixed(3) + " s\n TTFB estimate: " + (ttfb | 0) + " ms\n Current BW estimate: " + (isFiniteNumber(bwEstimate) ? bwEstimate | 0 : 'Unknown') + " bps\n New BW estimate: " + (_this.getBwEstimate() | 0) + " bps\n Switching to level " + nextLoadLevel + " @ " + (nextLoadLevelBitrate | 0) + " bps");
3530
3539
  hls.nextLoadLevel = hls.nextAutoLevel = nextLoadLevel;
3531
3540
  _this.clearTimer();
3532
- _this.timer = self.setInterval(function () {
3541
+ var abortAndSwitch = function abortAndSwitch() {
3533
3542
  // Are nextLoadLevel details available or is stream-controller still in "WAITING_LEVEL" state?
3534
3543
  _this.clearTimer();
3535
3544
  if (_this.fragCurrent === frag && _this.hls.loadLevel === nextLoadLevel && nextLoadLevel > 0) {
@@ -3546,7 +3555,12 @@
3546
3555
  _this.resetEstimator(_this.hls.levels[lowestSwitchLevel].bitrate);
3547
3556
  }
3548
3557
  }
3549
- }, fragLevelNextLoadedDelay * 1000);
3558
+ };
3559
+ if (fragBlockingSwitch || fragLoadedDelay > fragLevelNextLoadedDelay * 2) {
3560
+ abortAndSwitch();
3561
+ } else {
3562
+ _this.timer = self.setInterval(abortAndSwitch, fragLevelNextLoadedDelay * 1000);
3563
+ }
3550
3564
  hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
3551
3565
  frag: frag,
3552
3566
  part: part,
@@ -3678,13 +3692,13 @@
3678
3692
  };
3679
3693
  _proto.getTimeToLoadFrag = function getTimeToLoadFrag(timeToFirstByteSec, bandwidth, fragSizeBits, isSwitch) {
3680
3694
  var fragLoadSec = timeToFirstByteSec + fragSizeBits / bandwidth;
3681
- var playlistLoadSec = isSwitch ? this.lastLevelLoadSec : 0;
3695
+ var playlistLoadSec = isSwitch ? timeToFirstByteSec + this.lastLevelLoadSec : 0;
3682
3696
  return fragLoadSec + playlistLoadSec;
3683
3697
  };
3684
3698
  _proto.onLevelLoaded = function onLevelLoaded(event, data) {
3685
3699
  var config = this.hls.config;
3686
3700
  var loading = data.stats.loading;
3687
- var timeLoadingMs = loading.end - loading.start;
3701
+ var timeLoadingMs = loading.end - loading.first;
3688
3702
  if (isFiniteNumber(timeLoadingMs)) {
3689
3703
  this.lastLevelLoadSec = timeLoadingMs / 1000;
3690
3704
  }
@@ -3693,10 +3707,13 @@
3693
3707
  } else {
3694
3708
  this.bwEstimator.update(config.abrEwmaSlowVoD, config.abrEwmaFastVoD);
3695
3709
  }
3710
+ if (this.timer > -1) {
3711
+ this._abandonRulesCheck(data.levelInfo);
3712
+ }
3696
3713
  };
3697
- _proto.onFragLoaded = function onFragLoaded(event, _ref) {
3698
- var frag = _ref.frag,
3699
- part = _ref.part;
3714
+ _proto.onFragLoaded = function onFragLoaded(event, _ref2) {
3715
+ var frag = _ref2.frag,
3716
+ part = _ref2.part;
3700
3717
  var stats = part ? part.stats : frag.stats;
3701
3718
  if (frag.type === PlaylistLevelType.MAIN) {
3702
3719
  this.bwEstimator.sampleTTFB(stats.loading.first - stats.loading.start);
@@ -3845,7 +3862,7 @@
3845
3862
  return this.bwEstimator.canEstimate() ? this.bwEstimator.getEstimate() : this.hls.config.abrEwmaDefaultEstimate;
3846
3863
  };
3847
3864
  _proto.findBestLevel = function findBestLevel(currentBw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor) {
3848
- var _this$hls$latestLevel2,
3865
+ var _this$hls$latestLevel,
3849
3866
  _this3 = this;
3850
3867
  var maxFetchDuration = bufferStarvationDelay + maxStarvationDelay;
3851
3868
  var lastLoadedFragLevel = this.lastLoadedFragLevel;
@@ -3861,7 +3878,7 @@
3861
3878
  return 0;
3862
3879
  }
3863
3880
  var level = levels[selectionBaseLevel];
3864
- var live = !!((_this$hls$latestLevel2 = this.hls.latestLevelDetails) != null && _this$hls$latestLevel2.live);
3881
+ var live = !!((_this$hls$latestLevel = this.hls.latestLevelDetails) != null && _this$hls$latestLevel.live);
3865
3882
  var firstSelection = loadLevel === -1 || lastLoadedFragLevel === -1;
3866
3883
  var currentCodecSet;
3867
3884
  var currentVideoRange = 'SDR';
@@ -15700,7 +15717,6 @@
15700
15717
  };
15701
15718
  _proto.removeFragment = function removeFragment(fragment) {
15702
15719
  var fragKey = getFragmentKey(fragment);
15703
- fragment.stats.loaded = 0;
15704
15720
  fragment.clearElementaryStreamInfo();
15705
15721
  var activeParts = this.activePartLists[fragment.type];
15706
15722
  if (activeParts) {
@@ -17273,7 +17289,7 @@
17273
17289
  var mainStart = this.hls.startPosition;
17274
17290
  var liveSyncPosition = this.hls.liveSyncPosition;
17275
17291
  var startPosition = frag ? (mainStart !== -1 && mainStart >= start ? mainStart : liveSyncPosition) || frag.start : pos;
17276
- this.log("Setting startPosition to " + startPosition + " to match initial live edge. mainStart: " + mainStart + " liveSyncPosition: " + liveSyncPosition + " frag.start: " + ((_frag = frag) == null ? void 0 : _frag.start));
17292
+ this.log("Setting startPosition to " + startPosition + " to match start frag at live edge. mainStart: " + mainStart + " liveSyncPosition: " + liveSyncPosition + " frag.start: " + ((_frag = frag) == null ? void 0 : _frag.start));
17277
17293
  this.startPosition = this.nextLoadPosition = startPosition;
17278
17294
  }
17279
17295
  } else if (pos <= start) {
@@ -17489,6 +17505,7 @@
17489
17505
  // Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has
17490
17506
  // not been specified via the config or an as an argument to startLoad (#3736).
17491
17507
  startPosition = this.hls.liveSyncPosition || sliding;
17508
+ this.log("Setting startPosition to -1 to start at live edge " + startPosition);
17492
17509
  this.startPosition = -1;
17493
17510
  } else {
17494
17511
  this.log("setting startPosition to 0 by default");
@@ -20069,7 +20086,7 @@
20069
20086
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
20070
20087
  }
20071
20088
 
20072
- var version = "1.6.0-beta.4.0.canary.11033";
20089
+ var version = "1.6.0-beta.4.0.canary.11034";
20073
20090
 
20074
20091
  // ensure the worker ends up in the bundle
20075
20092
  // If the worker should not be included this gets aliased to empty.js
@@ -20987,8 +21004,7 @@
20987
21004
  return;
20988
21005
  }
20989
21006
  var liveSyncPosition = this.hls.liveSyncPosition;
20990
- var mediaCurrentTime = media.currentTime;
20991
- var currentTime = this.hasEnoughToStart || mediaCurrentTime > 0 ? mediaCurrentTime : this.startPosition;
21007
+ var currentTime = this.getLoadPosition();
20992
21008
  var start = levelDetails.fragmentStart;
20993
21009
  var end = levelDetails.edge;
20994
21010
  var withinSlidingWindow = currentTime >= start - config.maxFragLookUpTolerance && currentTime <= end;