hls.js 1.5.2-0.canary.9966 → 1.5.2-0.canary.9970

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
@@ -431,7 +431,7 @@ function enableLogs(debugConfig, context, id) {
431
431
  // Some browsers don't allow to use bind on console object anyway
432
432
  // fallback to default if needed
433
433
  try {
434
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.2-0.canary.9966"}`);
434
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.2-0.canary.9970"}`);
435
435
  } catch (e) {
436
436
  /* log fn threw an exception. All logger methods are no-ops. */
437
437
  return createLogger();
@@ -1591,6 +1591,12 @@ function readUint32(buffer, offset) {
1591
1591
  const val = readSint32(buffer, offset);
1592
1592
  return val < 0 ? 4294967296 + val : val;
1593
1593
  }
1594
+ function readUint64(buffer, offset) {
1595
+ let result = readUint32(buffer, offset);
1596
+ result *= Math.pow(2, 32);
1597
+ result += readUint32(buffer, offset + 4);
1598
+ return result;
1599
+ }
1594
1600
  function readSint32(buffer, offset) {
1595
1601
  return buffer[offset] << 24 | buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3];
1596
1602
  }
@@ -1653,15 +1659,14 @@ function parseSegmentIndex(sidx) {
1653
1659
  let index = 8;
1654
1660
  const timescale = readUint32(sidx, index);
1655
1661
  index += 4;
1656
-
1657
- // TODO: parse earliestPresentationTime and firstOffset
1658
- // usually zero in our case
1659
- const earliestPresentationTime = 0;
1660
- const firstOffset = 0;
1662
+ let earliestPresentationTime = 0;
1663
+ let firstOffset = 0;
1661
1664
  if (version === 0) {
1662
- index += 8;
1665
+ earliestPresentationTime = readUint32(sidx, index += 4);
1666
+ firstOffset = readUint32(sidx, index += 4);
1663
1667
  } else {
1664
- index += 16;
1668
+ earliestPresentationTime = readUint64(sidx, index += 8);
1669
+ firstOffset = readUint64(sidx, index += 8);
1665
1670
  }
1666
1671
 
1667
1672
  // skip reserved
@@ -2109,15 +2114,22 @@ function getDuration(data, initData) {
2109
2114
  }
2110
2115
  if (videoDuration === 0 && audioDuration === 0) {
2111
2116
  // If duration samples are not available in the traf use sidx subsegment_duration
2117
+ let sidxMinStart = Infinity;
2118
+ let sidxMaxEnd = 0;
2112
2119
  let sidxDuration = 0;
2113
2120
  const sidxs = findBox(data, ['sidx']);
2114
2121
  for (let i = 0; i < sidxs.length; i++) {
2115
2122
  const sidx = parseSegmentIndex(sidxs[i]);
2116
2123
  if (sidx != null && sidx.references) {
2117
- sidxDuration += sidx.references.reduce((dur, ref) => dur + ref.info.duration || 0, 0);
2124
+ sidxMinStart = Math.min(sidxMinStart, sidx.earliestPresentationTime / sidx.timescale);
2125
+ const subSegmentDuration = sidx.references.reduce((dur, ref) => dur + ref.info.duration || 0, 0);
2126
+ sidxMaxEnd = Math.max(sidxMaxEnd, subSegmentDuration + sidx.earliestPresentationTime / sidx.timescale);
2127
+ sidxDuration = sidxMaxEnd - sidxMinStart;
2118
2128
  }
2119
2129
  }
2120
- return sidxDuration;
2130
+ if (sidxDuration && isFiniteNumber(sidxDuration)) {
2131
+ return sidxDuration;
2132
+ }
2121
2133
  }
2122
2134
  if (videoDuration) {
2123
2135
  return videoDuration;
@@ -7467,8 +7479,12 @@ class AbrController extends Logger {
7467
7479
  return -1;
7468
7480
  }
7469
7481
  set nextAutoLevel(nextLevel) {
7470
- const value = Math.max(this.hls.minAutoLevel, nextLevel);
7471
- if (this._nextAutoLevel != value) {
7482
+ const {
7483
+ maxAutoLevel,
7484
+ minAutoLevel
7485
+ } = this.hls;
7486
+ const value = Math.min(Math.max(nextLevel, minAutoLevel), maxAutoLevel);
7487
+ if (this._nextAutoLevel !== value) {
7472
7488
  this.nextAutoLevelKey = '';
7473
7489
  this._nextAutoLevel = value;
7474
7490
  }
@@ -9164,6 +9180,7 @@ class BaseStreamController extends TaskLoop {
9164
9180
  this.startFragRequested = false;
9165
9181
  this.decrypter = void 0;
9166
9182
  this.initPTS = [];
9183
+ this.buffering = true;
9167
9184
  this.onMediaSeeking = () => {
9168
9185
  const {
9169
9186
  config,
@@ -9269,6 +9286,12 @@ class BaseStreamController extends TaskLoop {
9269
9286
  this.clearNextTick();
9270
9287
  this.state = State.STOPPED;
9271
9288
  }
9289
+ pauseBuffering() {
9290
+ this.buffering = false;
9291
+ }
9292
+ resumeBuffering() {
9293
+ this.buffering = true;
9294
+ }
9272
9295
  _streamEnded(bufferInfo, levelDetails) {
9273
9296
  // If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
9274
9297
  // of nothing loading/loaded return false
@@ -15946,12 +15969,13 @@ class AudioStreamController extends BaseStreamController {
15946
15969
  } = this;
15947
15970
  const config = hls.config;
15948
15971
 
15949
- // 1. if video not attached AND
15972
+ // 1. if buffering is suspended
15973
+ // 2. if video not attached AND
15950
15974
  // start fragment already requested OR start frag prefetch not enabled
15951
- // 2. if tracks or track not loaded and selected
15975
+ // 3. if tracks or track not loaded and selected
15952
15976
  // then exit loop
15953
15977
  // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
15954
- if (!media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
15978
+ if (!this.buffering || !media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
15955
15979
  return;
15956
15980
  }
15957
15981
  const levelInfo = levels[trackId];
@@ -16144,7 +16168,7 @@ class AudioStreamController extends BaseStreamController {
16144
16168
 
16145
16169
  // compute start position if we are aligned with the main playlist
16146
16170
  if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) {
16147
- this.setStartPosition(track.details, sliding);
16171
+ this.setStartPosition(this.mainDetails || newDetails, sliding);
16148
16172
  }
16149
16173
  // only switch back to IDLE state if we were waiting for track to start downloading a new fragment
16150
16174
  if (this.state === State.WAITING_TRACK && !this.waitForCdnTuneIn(newDetails)) {
@@ -17058,7 +17082,7 @@ class SubtitleStreamController extends BaseStreamController {
17058
17082
  track.details = newDetails;
17059
17083
  this.levelLastLoaded = track;
17060
17084
  if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) {
17061
- this.setStartPosition(track.details, sliding);
17085
+ this.setStartPosition(this.mainDetails || newDetails, sliding);
17062
17086
  }
17063
17087
 
17064
17088
  // trigger handler right now
@@ -17990,6 +18014,7 @@ class BufferController extends Logger {
17990
18014
  this.resetBuffer(type);
17991
18015
  });
17992
18016
  this._initSourceBuffer();
18017
+ this.hls.resumeBuffering();
17993
18018
  }
17994
18019
  resetBuffer(type) {
17995
18020
  const sb = this.sourceBuffer[type];
@@ -26734,7 +26759,8 @@ class StreamController extends BaseStreamController {
26734
26759
  }
26735
26760
  // set new level to playlist loader : this will trigger start level load
26736
26761
  // hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
26737
- this.level = hls.nextLoadLevel = startLevel;
26762
+ hls.nextLoadLevel = startLevel;
26763
+ this.level = hls.loadLevel;
26738
26764
  this.loadedmetadata = false;
26739
26765
  }
26740
26766
  // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
@@ -26827,7 +26853,7 @@ class StreamController extends BaseStreamController {
26827
26853
  if (this.altAudio && this.audioOnly) {
26828
26854
  return;
26829
26855
  }
26830
- if (!(levels != null && levels[level])) {
26856
+ if (!this.buffering || !(levels != null && levels[level])) {
26831
26857
  return;
26832
26858
  }
26833
26859
  const levelInfo = levels[level];
@@ -27787,7 +27813,7 @@ class Hls {
27787
27813
  * Get the video-dev/hls.js package version.
27788
27814
  */
27789
27815
  static get version() {
27790
- return "1.5.2-0.canary.9966";
27816
+ return "1.5.2-0.canary.9970";
27791
27817
  }
27792
27818
 
27793
27819
  /**
@@ -27856,7 +27882,6 @@ class Hls {
27856
27882
  this.logger = void 0;
27857
27883
  this.coreComponents = void 0;
27858
27884
  this.networkControllers = void 0;
27859
- this.started = false;
27860
27885
  this._emitter = new EventEmitter();
27861
27886
  this._autoLevelCapping = -1;
27862
27887
  this._maxHdcpLevel = null;
@@ -28071,7 +28096,6 @@ class Hls {
28071
28096
  */
28072
28097
  startLoad(startPosition = -1) {
28073
28098
  this.logger.log(`startLoad(${startPosition})`);
28074
- this.started = true;
28075
28099
  this.networkControllers.forEach(controller => {
28076
28100
  controller.startLoad(startPosition);
28077
28101
  });
@@ -28082,33 +28106,30 @@ class Hls {
28082
28106
  */
28083
28107
  stopLoad() {
28084
28108
  this.logger.log('stopLoad');
28085
- this.started = false;
28086
28109
  this.networkControllers.forEach(controller => {
28087
28110
  controller.stopLoad();
28088
28111
  });
28089
28112
  }
28090
28113
 
28091
28114
  /**
28092
- * Resumes stream controller segment loading if previously started.
28115
+ * Resumes stream controller segment loading after `pauseBuffering` has been called.
28093
28116
  */
28094
28117
  resumeBuffering() {
28095
- if (this.started) {
28096
- this.networkControllers.forEach(controller => {
28097
- if ('fragmentLoader' in controller) {
28098
- controller.startLoad(-1);
28099
- }
28100
- });
28101
- }
28118
+ this.networkControllers.forEach(controller => {
28119
+ if (controller.resumeBuffering) {
28120
+ controller.resumeBuffering();
28121
+ }
28122
+ });
28102
28123
  }
28103
28124
 
28104
28125
  /**
28105
- * Stops stream controller segment loading without changing 'started' state like stopLoad().
28126
+ * Prevents stream controller from loading new segments until `resumeBuffering` is called.
28106
28127
  * This allows for media buffering to be paused without interupting playlist loading.
28107
28128
  */
28108
28129
  pauseBuffering() {
28109
28130
  this.networkControllers.forEach(controller => {
28110
- if ('fragmentLoader' in controller) {
28111
- controller.stopLoad();
28131
+ if (controller.pauseBuffering) {
28132
+ controller.pauseBuffering();
28112
28133
  }
28113
28134
  });
28114
28135
  }