hls.js 1.6.0-beta.1.0.canary.10751 → 1.6.0-beta.1.0.canary.10754

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
@@ -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.10751"}`);
403
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10754"}`);
404
404
  } catch (e) {
405
405
  /* log fn threw an exception. All logger methods are no-ops. */
406
406
  return createLogger();
@@ -1375,7 +1375,7 @@ class AbrController extends Logger {
1375
1375
  const bwEstimate = this.getBwEstimate();
1376
1376
  const levels = hls.levels;
1377
1377
  const level = levels[frag.level];
1378
- const expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.averageBitrate / 8));
1378
+ const expectedLen = Math.max(stats.loaded, Math.round(duration * (frag.bitrate || level.averageBitrate) / 8));
1379
1379
  let timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
1380
1380
  if (timeStreaming < 1 && loadedFirstByte) {
1381
1381
  timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
@@ -1933,7 +1933,7 @@ class AbrController extends Logger {
1933
1933
  }
1934
1934
 
1935
1935
  // Use average bitrate when starvation delay (buffer length) is gt or eq two segment durations and rebuffering is not expected (maxStarvationDelay > 0)
1936
- const bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ? levels[i].averageBitrate : levels[i].maxBitrate;
1936
+ const bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ? levelInfo.averageBitrate : levelInfo.maxBitrate;
1937
1937
  const fetchDuration = this.getTimeToLoadFrag(ttfbEstimateSec, adjustedbw, bitrate * avgDuration, levelDetails === undefined);
1938
1938
  const canSwitchWithinTolerance =
1939
1939
  // if adjusted bw is greater than level bitrate AND
@@ -3737,6 +3737,8 @@ class Fragment extends BaseSegment {
3737
3737
  this._decryptdata = null;
3738
3738
  this._programDateTime = null;
3739
3739
  this._ref = null;
3740
+ // Approximate bit rate of the fragment expressed in bits per second (bps) as indicated by the last EXT-X-BITRATE (kbps) tag
3741
+ this._bitrate = void 0;
3740
3742
  this.rawProgramDateTime = null;
3741
3743
  this.tagList = [];
3742
3744
  // EXTINF has to be present for a m3u8 to be considered valid
@@ -3791,6 +3793,34 @@ class Fragment extends BaseSegment {
3791
3793
  this.urlId = 0;
3792
3794
  this.type = type;
3793
3795
  }
3796
+ get byteLength() {
3797
+ if (this.hasStats) {
3798
+ const total = this.stats.total;
3799
+ if (total) {
3800
+ return total;
3801
+ }
3802
+ }
3803
+ if (this.byteRange) {
3804
+ const start = this.byteRange[0];
3805
+ const end = this.byteRange[1];
3806
+ if (isFiniteNumber(start) && isFiniteNumber(end)) {
3807
+ return end - start;
3808
+ }
3809
+ }
3810
+ return null;
3811
+ }
3812
+ get bitrate() {
3813
+ if (this.byteLength) {
3814
+ return this.byteLength * 8 / this.duration;
3815
+ }
3816
+ if (this._bitrate) {
3817
+ return this._bitrate;
3818
+ }
3819
+ return null;
3820
+ }
3821
+ set bitrate(value) {
3822
+ this._bitrate = value;
3823
+ }
3794
3824
  get decryptdata() {
3795
3825
  const {
3796
3826
  levelkeys
@@ -6918,6 +6948,7 @@ class M3U8Parser {
6918
6948
  let currentPart = 0;
6919
6949
  let totalduration = 0;
6920
6950
  let discontinuityCounter = 0;
6951
+ let currentBitrate = 0;
6921
6952
  let prevFrag = null;
6922
6953
  let frag = new Fragment(type, base);
6923
6954
  let result;
@@ -6938,6 +6969,9 @@ class M3U8Parser {
6938
6969
  frag.start = totalduration;
6939
6970
  frag.sn = currentSN;
6940
6971
  frag.cc = discontinuityCounter;
6972
+ if (currentBitrate) {
6973
+ frag.bitrate = currentBitrate;
6974
+ }
6941
6975
  frag.level = id;
6942
6976
  if (currentInitSegment) {
6943
6977
  frag.initSegment = currentInitSegment;
@@ -7067,6 +7101,12 @@ class M3U8Parser {
7067
7101
  break;
7068
7102
  case 'BITRATE':
7069
7103
  frag.tagList.push([tag, value1]);
7104
+ currentBitrate = parseInt(value1) * 1000;
7105
+ if (isFiniteNumber(currentBitrate)) {
7106
+ frag.bitrate = currentBitrate;
7107
+ } else {
7108
+ currentBitrate = 0;
7109
+ }
7070
7110
  break;
7071
7111
  case 'DATERANGE':
7072
7112
  {
@@ -9734,7 +9774,7 @@ var eventemitter3 = {exports: {}};
9734
9774
  var eventemitter3Exports = eventemitter3.exports;
9735
9775
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
9736
9776
 
9737
- const version = "1.6.0-beta.1.0.canary.10751";
9777
+ const version = "1.6.0-beta.1.0.canary.10754";
9738
9778
 
9739
9779
  // ensure the worker ends up in the bundle
9740
9780
  // If the worker should not be included this gets aliased to empty.js
@@ -17320,12 +17360,16 @@ class AudioTrackController extends BasePlaylistController {
17320
17360
  return -1;
17321
17361
  }
17322
17362
  loadPlaylist(hlsUrlParameters) {
17363
+ var _this$hls$levels$this;
17323
17364
  const audioTrack = this.currentTrack;
17324
- if (this.shouldLoadPlaylist(audioTrack) && audioTrack) {
17365
+ if (!audioTrack) {
17366
+ return;
17367
+ }
17368
+ let url = audioTrack.url;
17369
+ if (this.shouldLoadPlaylist(audioTrack) && url !== ((_this$hls$levels$this = this.hls.levels[this.hls.loadLevel]) == null ? void 0 : _this$hls$levels$this.uri)) {
17325
17370
  super.loadPlaylist();
17326
17371
  const id = audioTrack.id;
17327
17372
  const groupId = audioTrack.groupId;
17328
- let url = audioTrack.url;
17329
17373
  if (hlsUrlParameters) {
17330
17374
  try {
17331
17375
  url = hlsUrlParameters.addDirectives(url);
@@ -28953,47 +28997,51 @@ class XhrLoader {
28953
28997
  xhr.onprogress = null;
28954
28998
  const status = xhr.status;
28955
28999
  // http status between 200 to 299 are all successful
28956
- const useResponse = xhr.responseType !== 'text';
28957
- if (status >= 200 && status < 300 && (useResponse && xhr.response || xhr.responseText !== null)) {
28958
- stats.loading.end = Math.max(self.performance.now(), stats.loading.first);
28959
- const data = useResponse ? xhr.response : xhr.responseText;
28960
- const len = xhr.responseType === 'arraybuffer' ? data.byteLength : data.length;
28961
- stats.loaded = stats.total = len;
28962
- stats.bwEstimate = stats.total * 8000 / (stats.loading.end - stats.loading.first);
28963
- if (!this.callbacks) {
28964
- return;
28965
- }
28966
- const onProgress = this.callbacks.onProgress;
28967
- if (onProgress) {
28968
- onProgress(stats, context, data, xhr);
28969
- }
28970
- if (!this.callbacks) {
29000
+ const useResponseText = xhr.responseType === 'text' ? xhr.responseText : null;
29001
+ if (status >= 200 && status < 300) {
29002
+ const data = useResponseText != null ? useResponseText : xhr.response;
29003
+ if (data != null) {
29004
+ stats.loading.end = Math.max(self.performance.now(), stats.loading.first);
29005
+ const len = xhr.responseType === 'arraybuffer' ? data.byteLength : data.length;
29006
+ stats.loaded = stats.total = len;
29007
+ stats.bwEstimate = stats.total * 8000 / (stats.loading.end - stats.loading.first);
29008
+ if (!this.callbacks) {
29009
+ return;
29010
+ }
29011
+ const onProgress = this.callbacks.onProgress;
29012
+ if (onProgress) {
29013
+ onProgress(stats, context, data, xhr);
29014
+ }
29015
+ if (!this.callbacks) {
29016
+ return;
29017
+ }
29018
+ const _response = {
29019
+ url: xhr.responseURL,
29020
+ data: data,
29021
+ code: status
29022
+ };
29023
+ this.callbacks.onSuccess(_response, stats, context, xhr);
28971
29024
  return;
28972
29025
  }
28973
- const response = {
28974
- url: xhr.responseURL,
28975
- data: data,
28976
- code: status
28977
- };
28978
- this.callbacks.onSuccess(response, stats, context, xhr);
29026
+ }
29027
+
29028
+ // Handle bad status or nullish response
29029
+ const retryConfig = config.loadPolicy.errorRetry;
29030
+ const retryCount = stats.retry;
29031
+ // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
29032
+ const response = {
29033
+ url: context.url,
29034
+ data: undefined,
29035
+ code: status
29036
+ };
29037
+ if (shouldRetry(retryConfig, retryCount, false, response)) {
29038
+ this.retry(retryConfig);
28979
29039
  } else {
28980
- const retryConfig = config.loadPolicy.errorRetry;
28981
- const retryCount = stats.retry;
28982
- // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
28983
- const response = {
28984
- url: context.url,
28985
- data: undefined,
28986
- code: status
28987
- };
28988
- if (shouldRetry(retryConfig, retryCount, false, response)) {
28989
- this.retry(retryConfig);
28990
- } else {
28991
- logger.error(`${status} while loading ${context.url}`);
28992
- this.callbacks.onError({
28993
- code: status,
28994
- text: xhr.statusText
28995
- }, context, xhr, stats);
28996
- }
29040
+ logger.error(`${status} while loading ${context.url}`);
29041
+ this.callbacks.onError({
29042
+ code: status,
29043
+ text: xhr.statusText
29044
+ }, context, xhr, stats);
28997
29045
  }
28998
29046
  }
28999
29047
  }