hls.js 1.5.2-0.canary.9924 → 1.5.2

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.
Files changed (57) hide show
  1. package/dist/hls-demo.js +0 -5
  2. package/dist/hls-demo.js.map +1 -1
  3. package/dist/hls.js +686 -762
  4. package/dist/hls.js.d.ts +47 -49
  5. package/dist/hls.js.map +1 -1
  6. package/dist/hls.light.js +471 -563
  7. package/dist/hls.light.js.map +1 -1
  8. package/dist/hls.light.min.js +1 -1
  9. package/dist/hls.light.min.js.map +1 -1
  10. package/dist/hls.light.mjs +329 -409
  11. package/dist/hls.light.mjs.map +1 -1
  12. package/dist/hls.min.js +1 -1
  13. package/dist/hls.min.js.map +1 -1
  14. package/dist/hls.mjs +500 -559
  15. package/dist/hls.mjs.map +1 -1
  16. package/dist/hls.worker.js +1 -1
  17. package/dist/hls.worker.js.map +1 -1
  18. package/package.json +9 -9
  19. package/src/config.ts +2 -3
  20. package/src/controller/abr-controller.ts +22 -23
  21. package/src/controller/audio-stream-controller.ts +14 -11
  22. package/src/controller/audio-track-controller.ts +1 -1
  23. package/src/controller/base-playlist-controller.ts +7 -7
  24. package/src/controller/base-stream-controller.ts +29 -42
  25. package/src/controller/buffer-controller.ts +11 -10
  26. package/src/controller/cap-level-controller.ts +2 -1
  27. package/src/controller/content-steering-controller.ts +6 -8
  28. package/src/controller/eme-controller.ts +22 -9
  29. package/src/controller/error-controller.ts +8 -6
  30. package/src/controller/fps-controller.ts +3 -2
  31. package/src/controller/gap-controller.ts +10 -16
  32. package/src/controller/latency-controller.ts +11 -9
  33. package/src/controller/level-controller.ts +19 -8
  34. package/src/controller/stream-controller.ts +29 -20
  35. package/src/controller/subtitle-stream-controller.ts +14 -13
  36. package/src/controller/subtitle-track-controller.ts +3 -5
  37. package/src/controller/timeline-controller.ts +30 -23
  38. package/src/crypt/aes-crypto.ts +2 -21
  39. package/src/crypt/decrypter.ts +18 -32
  40. package/src/crypt/fast-aes-key.ts +5 -24
  41. package/src/demux/audio/adts.ts +4 -9
  42. package/src/demux/sample-aes.ts +0 -2
  43. package/src/demux/transmuxer-interface.ts +12 -4
  44. package/src/demux/transmuxer-worker.ts +4 -4
  45. package/src/demux/transmuxer.ts +3 -16
  46. package/src/demux/tsdemuxer.ts +17 -12
  47. package/src/hls.ts +20 -32
  48. package/src/loader/fragment-loader.ts +2 -9
  49. package/src/loader/key-loader.ts +0 -2
  50. package/src/loader/level-key.ts +9 -10
  51. package/src/remux/mp4-remuxer.ts +3 -4
  52. package/src/task-loop.ts +2 -5
  53. package/src/types/demuxer.ts +0 -1
  54. package/src/utils/codecs.ts +4 -33
  55. package/src/utils/logger.ts +24 -53
  56. package/src/crypt/decrypter-aes-mode.ts +0 -4
  57. package/src/utils/encryption-methods-util.ts +0 -21
package/dist/hls.light.js CHANGED
@@ -476,21 +476,6 @@
476
476
  return ErrorDetails;
477
477
  }({});
478
478
 
479
- var Logger = function Logger(label, logger) {
480
- this.trace = void 0;
481
- this.debug = void 0;
482
- this.log = void 0;
483
- this.warn = void 0;
484
- this.info = void 0;
485
- this.error = void 0;
486
- var lb = "[" + label + "]:";
487
- this.trace = noop;
488
- this.debug = logger.debug.bind(null, lb);
489
- this.log = logger.log.bind(null, lb);
490
- this.warn = logger.warn.bind(null, lb);
491
- this.info = logger.info.bind(null, lb);
492
- this.error = logger.error.bind(null, lb);
493
- };
494
479
  var noop = function noop() {};
495
480
  var fakeLogger = {
496
481
  trace: noop,
@@ -500,9 +485,7 @@
500
485
  info: noop,
501
486
  error: noop
502
487
  };
503
- function createLogger() {
504
- return _extends({}, fakeLogger);
505
- }
488
+ var exportedLogger = fakeLogger;
506
489
 
507
490
  // let lastCallTime;
508
491
  // function formatMsgWithTimeInfo(type, msg) {
@@ -513,36 +496,38 @@
513
496
  // return msg;
514
497
  // }
515
498
 
516
- function consolePrintFn(type, id) {
499
+ function consolePrintFn(type) {
517
500
  var func = self.console[type];
518
- return func ? func.bind(self.console, (id ? '[' + id + '] ' : '') + "[" + type + "] >") : noop;
501
+ if (func) {
502
+ return func.bind(self.console, "[" + type + "] >");
503
+ }
504
+ return noop;
519
505
  }
520
- function getLoggerFn(key, debugConfig, id) {
521
- return debugConfig[key] ? debugConfig[key].bind(debugConfig) : consolePrintFn(key, id);
506
+ function exportLoggerFunctions(debugConfig) {
507
+ for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
508
+ functions[_key - 1] = arguments[_key];
509
+ }
510
+ functions.forEach(function (type) {
511
+ exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
512
+ });
522
513
  }
523
- var exportedLogger = createLogger();
524
- function enableLogs(debugConfig, context, id) {
514
+ function enableLogs(debugConfig, id) {
525
515
  // check that console is available
526
- var newLogger = createLogger();
527
516
  if (typeof console === 'object' && debugConfig === true || typeof debugConfig === 'object') {
528
- var keys = [
517
+ exportLoggerFunctions(debugConfig,
529
518
  // Remove out from list here to hard-disable a log-level
530
519
  // 'trace',
531
- 'debug', 'log', 'info', 'warn', 'error'];
532
- keys.forEach(function (key) {
533
- newLogger[key] = getLoggerFn(key, debugConfig, id);
534
- });
520
+ 'debug', 'log', 'info', 'warn', 'error');
535
521
  // Some browsers don't allow to use bind on console object anyway
536
522
  // fallback to default if needed
537
523
  try {
538
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9924");
524
+ exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.2");
539
525
  } catch (e) {
540
- /* log fn threw an exception. All logger methods are no-ops. */
541
- return createLogger();
526
+ exportedLogger = fakeLogger;
542
527
  }
528
+ } else {
529
+ exportedLogger = fakeLogger;
543
530
  }
544
- exportedLogger = newLogger;
545
- return newLogger;
546
531
  }
547
532
  var logger = exportedLogger;
548
533
 
@@ -1188,26 +1173,6 @@
1188
1173
  return LevelDetails;
1189
1174
  }();
1190
1175
 
1191
- var DecrypterAesMode = {
1192
- cbc: 0,
1193
- ctr: 1
1194
- };
1195
-
1196
- function isFullSegmentEncryption(method) {
1197
- return method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR';
1198
- }
1199
- function getAesModeFromFullSegmentMethod(method) {
1200
- switch (method) {
1201
- case 'AES-128':
1202
- case 'AES-256':
1203
- return DecrypterAesMode.cbc;
1204
- case 'AES-256-CTR':
1205
- return DecrypterAesMode.ctr;
1206
- default:
1207
- throw new Error("invalid full segment method " + method);
1208
- }
1209
- }
1210
-
1211
1176
  // This file is inserted as a shim for modules which we do not want to include into the distro.
1212
1177
  // This replacement is done in the "alias" plugin of the rollup config.
1213
1178
  var empty = undefined;
@@ -2649,13 +2614,13 @@
2649
2614
  this.keyFormatVersions = formatversions;
2650
2615
  this.iv = iv;
2651
2616
  this.encrypted = method ? method !== 'NONE' : false;
2652
- this.isCommonEncryption = this.encrypted && !isFullSegmentEncryption(method);
2617
+ this.isCommonEncryption = this.encrypted && method !== 'AES-128';
2653
2618
  }
2654
2619
  var _proto = LevelKey.prototype;
2655
2620
  _proto.isSupported = function isSupported() {
2656
2621
  // If it's Segment encryption or No encryption, just select that key system
2657
2622
  if (this.method) {
2658
- if (isFullSegmentEncryption(this.method) || this.method === 'NONE') {
2623
+ if (this.method === 'AES-128' || this.method === 'NONE') {
2659
2624
  return true;
2660
2625
  }
2661
2626
  if (this.keyFormat === 'identity') {
@@ -2669,13 +2634,14 @@
2669
2634
  if (!this.encrypted || !this.uri) {
2670
2635
  return null;
2671
2636
  }
2672
- if (isFullSegmentEncryption(this.method) && this.uri && !this.iv) {
2637
+ if (this.method === 'AES-128' && this.uri && !this.iv) {
2673
2638
  if (typeof sn !== 'number') {
2674
2639
  // We are fetching decryption data for a initialization segment
2675
- // If the segment was encrypted with AES-128/256
2640
+ // If the segment was encrypted with AES-128
2676
2641
  // It must have an IV defined. We cannot substitute the Segment Number in.
2677
- logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
2678
-
2642
+ if (this.method === 'AES-128' && !this.iv) {
2643
+ logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
2644
+ }
2679
2645
  // Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
2680
2646
  sn = 0;
2681
2647
  }
@@ -2837,28 +2803,23 @@
2837
2803
  if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
2838
2804
  return CODEC_COMPATIBLE_NAMES[lowerCaseCodec];
2839
2805
  }
2806
+
2807
+ // Idealy fLaC and Opus would be first (spec-compliant) but
2808
+ // some browsers will report that fLaC is supported then fail.
2809
+ // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
2840
2810
  var codecsToCheck = {
2841
- // Idealy fLaC and Opus would be first (spec-compliant) but
2842
- // some browsers will report that fLaC is supported then fail.
2843
- // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
2844
2811
  flac: ['flac', 'fLaC', 'FLAC'],
2845
- opus: ['opus', 'Opus'],
2846
- // Replace audio codec info if browser does not support mp4a.40.34,
2847
- // and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs="mp3"'
2848
- 'mp4a.40.34': ['mp3']
2812
+ opus: ['opus', 'Opus']
2849
2813
  }[lowerCaseCodec];
2850
2814
  for (var i = 0; i < codecsToCheck.length; i++) {
2851
- var _getMediaSource;
2852
2815
  if (isCodecMediaSourceSupported(codecsToCheck[i], 'audio', preferManagedMediaSource)) {
2853
2816
  CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];
2854
2817
  return codecsToCheck[i];
2855
- } else if (codecsToCheck[i] === 'mp3' && (_getMediaSource = getMediaSource(preferManagedMediaSource)) != null && _getMediaSource.isTypeSupported('audio/mpeg')) {
2856
- return '';
2857
2818
  }
2858
2819
  }
2859
2820
  return lowerCaseCodec;
2860
2821
  }
2861
- var AUDIO_CODEC_REGEXP = /flac|opus|mp4a\.40\.34/i;
2822
+ var AUDIO_CODEC_REGEXP = /flac|opus/i;
2862
2823
  function getCodecCompatibleName(codec, preferManagedMediaSource) {
2863
2824
  if (preferManagedMediaSource === void 0) {
2864
2825
  preferManagedMediaSource = true;
@@ -2886,18 +2847,6 @@
2886
2847
  }
2887
2848
  return codec;
2888
2849
  }
2889
- function getM2TSSupportedAudioTypes(preferManagedMediaSource) {
2890
- var MediaSource = getMediaSource(preferManagedMediaSource) || {
2891
- isTypeSupported: function isTypeSupported() {
2892
- return false;
2893
- }
2894
- };
2895
- return {
2896
- mpeg: MediaSource.isTypeSupported('audio/mpeg'),
2897
- mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
2898
- ac3: false
2899
- };
2900
- }
2901
2850
 
2902
2851
  var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-(SESSION-DATA|SESSION-KEY|DEFINE|CONTENT-STEERING|START):([^\r\n]*)[\r\n]+/g;
2903
2852
  var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
@@ -4472,43 +4421,8 @@
4472
4421
  this.currentTime = 0;
4473
4422
  this.stallCount = 0;
4474
4423
  this._latency = null;
4475
- this.onTimeupdate = function () {
4476
- var media = _this.media,
4477
- levelDetails = _this.levelDetails;
4478
- if (!media || !levelDetails) {
4479
- return;
4480
- }
4481
- _this.currentTime = media.currentTime;
4482
- var latency = _this.computeLatency();
4483
- if (latency === null) {
4484
- return;
4485
- }
4486
- _this._latency = latency;
4487
-
4488
- // Adapt playbackRate to meet target latency in low-latency mode
4489
- var _this$config = _this.config,
4490
- lowLatencyMode = _this$config.lowLatencyMode,
4491
- maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
4492
- if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
4493
- return;
4494
- }
4495
- var targetLatency = _this.targetLatency;
4496
- if (targetLatency === null) {
4497
- return;
4498
- }
4499
- var distanceFromTarget = latency - targetLatency;
4500
- // Only adjust playbackRate when within one target duration of targetLatency
4501
- // and more than one second from under-buffering.
4502
- // Playback further than one target duration from target can be considered DVR playback.
4503
- var liveMinLatencyDuration = Math.min(_this.maxLatency, targetLatency + levelDetails.targetduration);
4504
- var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
4505
- if (inLiveRange && distanceFromTarget > 0.05 && _this.forwardBufferLength > 1) {
4506
- var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
4507
- var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - _this.edgeStalled)) * 20) / 20;
4508
- media.playbackRate = Math.min(max, Math.max(1, rate));
4509
- } else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
4510
- media.playbackRate = 1;
4511
- }
4424
+ this.timeupdateHandler = function () {
4425
+ return _this.timeupdate();
4512
4426
  };
4513
4427
  this.hls = hls;
4514
4428
  this.config = hls.config;
@@ -4520,7 +4434,7 @@
4520
4434
  this.onMediaDetaching();
4521
4435
  this.levelDetails = null;
4522
4436
  // @ts-ignore
4523
- this.hls = null;
4437
+ this.hls = this.timeupdateHandler = null;
4524
4438
  };
4525
4439
  _proto.registerListeners = function registerListeners() {
4526
4440
  this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
@@ -4538,11 +4452,11 @@
4538
4452
  };
4539
4453
  _proto.onMediaAttached = function onMediaAttached(event, data) {
4540
4454
  this.media = data.media;
4541
- this.media.addEventListener('timeupdate', this.onTimeupdate);
4455
+ this.media.addEventListener('timeupdate', this.timeupdateHandler);
4542
4456
  };
4543
4457
  _proto.onMediaDetaching = function onMediaDetaching() {
4544
4458
  if (this.media) {
4545
- this.media.removeEventListener('timeupdate', this.onTimeupdate);
4459
+ this.media.removeEventListener('timeupdate', this.timeupdateHandler);
4546
4460
  this.media = null;
4547
4461
  }
4548
4462
  };
@@ -4555,10 +4469,10 @@
4555
4469
  var details = _ref.details;
4556
4470
  this.levelDetails = details;
4557
4471
  if (details.advanced) {
4558
- this.onTimeupdate();
4472
+ this.timeupdate();
4559
4473
  }
4560
4474
  if (!details.live && this.media) {
4561
- this.media.removeEventListener('timeupdate', this.onTimeupdate);
4475
+ this.media.removeEventListener('timeupdate', this.timeupdateHandler);
4562
4476
  }
4563
4477
  };
4564
4478
  _proto.onError = function onError(event, data) {
@@ -4568,7 +4482,45 @@
4568
4482
  }
4569
4483
  this.stallCount++;
4570
4484
  if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
4571
- this.hls.logger.warn('[latency-controller]: Stall detected, adjusting target latency');
4485
+ logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
4486
+ }
4487
+ };
4488
+ _proto.timeupdate = function timeupdate() {
4489
+ var media = this.media,
4490
+ levelDetails = this.levelDetails;
4491
+ if (!media || !levelDetails) {
4492
+ return;
4493
+ }
4494
+ this.currentTime = media.currentTime;
4495
+ var latency = this.computeLatency();
4496
+ if (latency === null) {
4497
+ return;
4498
+ }
4499
+ this._latency = latency;
4500
+
4501
+ // Adapt playbackRate to meet target latency in low-latency mode
4502
+ var _this$config = this.config,
4503
+ lowLatencyMode = _this$config.lowLatencyMode,
4504
+ maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
4505
+ if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
4506
+ return;
4507
+ }
4508
+ var targetLatency = this.targetLatency;
4509
+ if (targetLatency === null) {
4510
+ return;
4511
+ }
4512
+ var distanceFromTarget = latency - targetLatency;
4513
+ // Only adjust playbackRate when within one target duration of targetLatency
4514
+ // and more than one second from under-buffering.
4515
+ // Playback further than one target duration from target can be considered DVR playback.
4516
+ var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration);
4517
+ var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
4518
+ if (inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) {
4519
+ var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
4520
+ var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20;
4521
+ media.playbackRate = Math.min(max, Math.max(1, rate));
4522
+ } else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
4523
+ media.playbackRate = 1;
4572
4524
  }
4573
4525
  };
4574
4526
  _proto.estimateLiveEdge = function estimateLiveEdge() {
@@ -5476,17 +5428,19 @@
5476
5428
  MoveAllAlternatesMatchingHDCP: 2,
5477
5429
  SwitchToSDR: 4
5478
5430
  }; // Reserved for future use
5479
- var ErrorController = /*#__PURE__*/function (_Logger) {
5480
- _inheritsLoose(ErrorController, _Logger);
5431
+ var ErrorController = /*#__PURE__*/function () {
5481
5432
  function ErrorController(hls) {
5482
- var _this;
5483
- _this = _Logger.call(this, 'error-controller', hls.logger) || this;
5484
- _this.hls = void 0;
5485
- _this.playlistError = 0;
5486
- _this.penalizedRenditions = {};
5487
- _this.hls = hls;
5488
- _this.registerListeners();
5489
- return _this;
5433
+ this.hls = void 0;
5434
+ this.playlistError = 0;
5435
+ this.penalizedRenditions = {};
5436
+ this.log = void 0;
5437
+ this.warn = void 0;
5438
+ this.error = void 0;
5439
+ this.hls = hls;
5440
+ this.log = logger.log.bind(logger, "[info]:");
5441
+ this.warn = logger.warn.bind(logger, "[warning]:");
5442
+ this.error = logger.error.bind(logger, "[error]:");
5443
+ this.registerListeners();
5490
5444
  }
5491
5445
  var _proto = ErrorController.prototype;
5492
5446
  _proto.registerListeners = function registerListeners() {
@@ -5842,19 +5796,19 @@
5842
5796
  }
5843
5797
  };
5844
5798
  return ErrorController;
5845
- }(Logger);
5799
+ }();
5846
5800
 
5847
- var BasePlaylistController = /*#__PURE__*/function (_Logger) {
5848
- _inheritsLoose(BasePlaylistController, _Logger);
5801
+ var BasePlaylistController = /*#__PURE__*/function () {
5849
5802
  function BasePlaylistController(hls, logPrefix) {
5850
- var _this;
5851
- _this = _Logger.call(this, logPrefix, hls.logger) || this;
5852
- _this.hls = void 0;
5853
- _this.timer = -1;
5854
- _this.requestScheduled = -1;
5855
- _this.canLoad = false;
5856
- _this.hls = hls;
5857
- return _this;
5803
+ this.hls = void 0;
5804
+ this.timer = -1;
5805
+ this.requestScheduled = -1;
5806
+ this.canLoad = false;
5807
+ this.log = void 0;
5808
+ this.warn = void 0;
5809
+ this.log = logger.log.bind(logger, logPrefix + ":");
5810
+ this.warn = logger.warn.bind(logger, logPrefix + ":");
5811
+ this.hls = hls;
5858
5812
  }
5859
5813
  var _proto = BasePlaylistController.prototype;
5860
5814
  _proto.destroy = function destroy() {
@@ -5887,7 +5841,7 @@
5887
5841
  try {
5888
5842
  uri = new self.URL(attr.URI, previous.url).href;
5889
5843
  } catch (error) {
5890
- this.warn("Could not construct new URL for Rendition Report: " + error);
5844
+ logger.warn("Could not construct new URL for Rendition Report: " + error);
5891
5845
  uri = attr.URI || '';
5892
5846
  }
5893
5847
  // Use exact match. Otherwise, the last partial match, if any, will be used
@@ -5926,7 +5880,7 @@
5926
5880
  return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
5927
5881
  };
5928
5882
  _proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
5929
- var _this2 = this;
5883
+ var _this = this;
5930
5884
  var details = data.details,
5931
5885
  stats = data.stats;
5932
5886
 
@@ -6031,7 +5985,7 @@
6031
5985
  // );
6032
5986
 
6033
5987
  this.timer = self.setTimeout(function () {
6034
- return _this2.loadPlaylist(deliveryDirectives);
5988
+ return _this.loadPlaylist(deliveryDirectives);
6035
5989
  }, estimatedTimeUntilUpdate);
6036
5990
  } else {
6037
5991
  this.clearTimer();
@@ -6047,7 +6001,7 @@
6047
6001
  return new HlsUrlParameters(msn, part, skip);
6048
6002
  };
6049
6003
  _proto.checkRetry = function checkRetry(errorEvent) {
6050
- var _this3 = this;
6004
+ var _this2 = this;
6051
6005
  var errorDetails = errorEvent.details;
6052
6006
  var isTimeout = isTimeoutError(errorEvent);
6053
6007
  var errorAction = errorEvent.errorAction;
@@ -6071,7 +6025,7 @@
6071
6025
  var delay = getRetryDelay(retryConfig, retryCount);
6072
6026
  // Schedule level/track reload
6073
6027
  this.timer = self.setTimeout(function () {
6074
- return _this3.loadPlaylist();
6028
+ return _this2.loadPlaylist();
6075
6029
  }, delay);
6076
6030
  this.warn("Retrying playlist loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " after \"" + errorDetails + "\" in " + delay + "ms");
6077
6031
  }
@@ -6082,7 +6036,7 @@
6082
6036
  return retry;
6083
6037
  };
6084
6038
  return BasePlaylistController;
6085
- }(Logger);
6039
+ }();
6086
6040
 
6087
6041
  /*
6088
6042
  * compute an Exponential Weighted moving average
@@ -6456,33 +6410,30 @@
6456
6410
  }, {});
6457
6411
  }
6458
6412
 
6459
- var AbrController = /*#__PURE__*/function (_Logger) {
6460
- _inheritsLoose(AbrController, _Logger);
6413
+ var AbrController = /*#__PURE__*/function () {
6461
6414
  function AbrController(_hls) {
6462
- var _this;
6463
- _this = _Logger.call(this, 'abr', _hls.logger) || this;
6464
- _this.hls = void 0;
6465
- _this.lastLevelLoadSec = 0;
6466
- _this.lastLoadedFragLevel = -1;
6467
- _this.firstSelection = -1;
6468
- _this._nextAutoLevel = -1;
6469
- _this.nextAutoLevelKey = '';
6470
- _this.audioTracksByGroup = null;
6471
- _this.codecTiers = null;
6472
- _this.timer = -1;
6473
- _this.fragCurrent = null;
6474
- _this.partCurrent = null;
6475
- _this.bitrateTestDelay = 0;
6476
- _this.bwEstimator = void 0;
6415
+ var _this = this;
6416
+ this.hls = void 0;
6417
+ this.lastLevelLoadSec = 0;
6418
+ this.lastLoadedFragLevel = -1;
6419
+ this.firstSelection = -1;
6420
+ this._nextAutoLevel = -1;
6421
+ this.nextAutoLevelKey = '';
6422
+ this.audioTracksByGroup = null;
6423
+ this.codecTiers = null;
6424
+ this.timer = -1;
6425
+ this.fragCurrent = null;
6426
+ this.partCurrent = null;
6427
+ this.bitrateTestDelay = 0;
6428
+ this.bwEstimator = void 0;
6477
6429
  /*
6478
6430
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
6479
6431
  quickly enough to prevent underbuffering
6480
6432
  */
6481
- _this._abandonRulesCheck = function () {
6482
- var _assertThisInitialize = _assertThisInitialized(_this),
6483
- frag = _assertThisInitialize.fragCurrent,
6484
- part = _assertThisInitialize.partCurrent,
6485
- hls = _assertThisInitialize.hls;
6433
+ this._abandonRulesCheck = function () {
6434
+ var frag = _this.fragCurrent,
6435
+ part = _this.partCurrent,
6436
+ hls = _this.hls;
6486
6437
  var autoLevelEnabled = hls.autoLevelEnabled,
6487
6438
  media = hls.media;
6488
6439
  if (!frag || !media) {
@@ -6523,7 +6474,7 @@
6523
6474
  var bwEstimate = _this.getBwEstimate();
6524
6475
  var levels = hls.levels;
6525
6476
  var level = levels[frag.level];
6526
- var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.maxBitrate / 8));
6477
+ var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.averageBitrate / 8));
6527
6478
  var timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
6528
6479
  if (timeStreaming < 1 && loadedFirstByte) {
6529
6480
  timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
@@ -6566,27 +6517,26 @@
6566
6517
  // If there has been no loading progress, sample TTFB
6567
6518
  _this.bwEstimator.sampleTTFB(timeLoading);
6568
6519
  }
6569
- var nextLoadLevelBitrate = levels[nextLoadLevel].bitrate;
6520
+ var nextLoadLevelBitrate = levels[nextLoadLevel].maxBitrate;
6570
6521
  if (_this.getBwEstimate() * _this.hls.config.abrBandWidthUpFactor > nextLoadLevelBitrate) {
6571
6522
  _this.resetEstimator(nextLoadLevelBitrate);
6572
6523
  }
6573
6524
  _this.clearTimer();
6574
- _this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly;\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");
6525
+ logger.warn("[abr] Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly;\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");
6575
6526
  hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
6576
6527
  frag: frag,
6577
6528
  part: part,
6578
6529
  stats: stats
6579
6530
  });
6580
6531
  };
6581
- _this.hls = _hls;
6582
- _this.bwEstimator = _this.initEstimator();
6583
- _this.registerListeners();
6584
- return _this;
6532
+ this.hls = _hls;
6533
+ this.bwEstimator = this.initEstimator();
6534
+ this.registerListeners();
6585
6535
  }
6586
6536
  var _proto = AbrController.prototype;
6587
6537
  _proto.resetEstimator = function resetEstimator(abrEwmaDefaultEstimate) {
6588
6538
  if (abrEwmaDefaultEstimate) {
6589
- this.log("setting initial bwe to " + abrEwmaDefaultEstimate);
6539
+ logger.log("setting initial bwe to " + abrEwmaDefaultEstimate);
6590
6540
  this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
6591
6541
  }
6592
6542
  this.firstSelection = -1;
@@ -6838,13 +6788,13 @@
6838
6788
  // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
6839
6789
  var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
6840
6790
  maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
6841
- this.info("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
6791
+ logger.info("[abr] bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
6842
6792
  // don't use conservative factor on bitrate test
6843
6793
  bwFactor = bwUpFactor = 1;
6844
6794
  }
6845
6795
  }
6846
6796
  var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
6847
- this.info((bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
6797
+ logger.info("[abr] " + (bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
6848
6798
  if (bestLevel > -1) {
6849
6799
  return bestLevel;
6850
6800
  }
@@ -6900,7 +6850,7 @@
6900
6850
  currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
6901
6851
  currentFrameRate = minFramerate;
6902
6852
  currentBw = Math.max(currentBw, minBitrate);
6903
- this.log("picked start tier " + JSON.stringify(startTier));
6853
+ logger.log("[abr] picked start tier " + JSON.stringify(startTier));
6904
6854
  } else {
6905
6855
  currentCodecSet = level == null ? void 0 : level.codecSet;
6906
6856
  currentVideoRange = level == null ? void 0 : level.videoRange;
@@ -6953,9 +6903,9 @@
6953
6903
  var forcedAutoLevel = _this2.forcedAutoLevel;
6954
6904
  if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
6955
6905
  if (levelsSkipped.length) {
6956
- _this2.trace("Skipped level(s) " + levelsSkipped.join(',') + " of " + maxAutoLevel + " max with CODECS and VIDEO-RANGE:\"" + levels[levelsSkipped[0]].codecs + "\" " + levels[levelsSkipped[0]].videoRange + "; not compatible with \"" + level.codecs + "\" " + currentVideoRange);
6906
+ logger.trace("[abr] Skipped level(s) " + levelsSkipped.join(',') + " of " + maxAutoLevel + " max with CODECS and VIDEO-RANGE:\"" + levels[levelsSkipped[0]].codecs + "\" " + levels[levelsSkipped[0]].videoRange + "; not compatible with \"" + level.codecs + "\" " + currentVideoRange);
6957
6907
  }
6958
- _this2.info("switch candidate:" + selectionBaseLevel + "->" + i + " adjustedbw(" + Math.round(adjustedbw) + ")-bitrate=" + Math.round(adjustedbw - bitrate) + " ttfb:" + ttfbEstimateSec.toFixed(1) + " avgDuration:" + avgDuration.toFixed(1) + " maxFetchDuration:" + maxFetchDuration.toFixed(1) + " fetchDuration:" + fetchDuration.toFixed(1) + " firstSelection:" + firstSelection + " codecSet:" + currentCodecSet + " videoRange:" + currentVideoRange + " hls.loadLevel:" + loadLevel);
6908
+ logger.info("[abr] switch candidate:" + selectionBaseLevel + "->" + i + " adjustedbw(" + Math.round(adjustedbw) + ")-bitrate=" + Math.round(adjustedbw - bitrate) + " ttfb:" + ttfbEstimateSec.toFixed(1) + " avgDuration:" + avgDuration.toFixed(1) + " maxFetchDuration:" + maxFetchDuration.toFixed(1) + " fetchDuration:" + fetchDuration.toFixed(1) + " firstSelection:" + firstSelection + " codecSet:" + currentCodecSet + " videoRange:" + currentVideoRange + " hls.loadLevel:" + loadLevel);
6959
6909
  }
6960
6910
  if (firstSelection) {
6961
6911
  _this2.firstSelection = i;
@@ -6989,7 +6939,7 @@
6989
6939
  }
6990
6940
  var firstLevel = this.hls.firstLevel;
6991
6941
  var clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
6992
- this.warn("Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
6942
+ logger.warn("[abr] Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
6993
6943
  return clamped;
6994
6944
  }
6995
6945
  }, {
@@ -7039,7 +6989,7 @@
7039
6989
  }
7040
6990
  }]);
7041
6991
  return AbrController;
7042
- }(Logger);
6992
+ }();
7043
6993
 
7044
6994
  /**
7045
6995
  * Provides methods dealing with buffer length retrieval for example.
@@ -7260,57 +7210,57 @@
7260
7210
  }();
7261
7211
 
7262
7212
  var VIDEO_CODEC_PROFILE_REPLACE = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;
7263
- var BufferController = /*#__PURE__*/function (_Logger) {
7264
- _inheritsLoose(BufferController, _Logger);
7213
+ var BufferController = /*#__PURE__*/function () {
7265
7214
  function BufferController(hls) {
7266
- var _this;
7267
- _this = _Logger.call(this, 'buffer-controller', hls.logger) || this;
7215
+ var _this = this;
7268
7216
  // The level details used to determine duration, target-duration and live
7269
- _this.details = null;
7217
+ this.details = null;
7270
7218
  // cache the self generated object url to detect hijack of video tag
7271
- _this._objectUrl = null;
7219
+ this._objectUrl = null;
7272
7220
  // A queue of buffer operations which require the SourceBuffer to not be updating upon execution
7273
- _this.operationQueue = void 0;
7221
+ this.operationQueue = void 0;
7274
7222
  // References to event listeners for each SourceBuffer, so that they can be referenced for event removal
7275
- _this.listeners = void 0;
7276
- _this.hls = void 0;
7223
+ this.listeners = void 0;
7224
+ this.hls = void 0;
7277
7225
  // The number of BUFFER_CODEC events received before any sourceBuffers are created
7278
- _this.bufferCodecEventsExpected = 0;
7226
+ this.bufferCodecEventsExpected = 0;
7279
7227
  // The total number of BUFFER_CODEC events received
7280
- _this._bufferCodecEventsTotal = 0;
7228
+ this._bufferCodecEventsTotal = 0;
7281
7229
  // A reference to the attached media element
7282
- _this.media = null;
7230
+ this.media = null;
7283
7231
  // A reference to the active media source
7284
- _this.mediaSource = null;
7232
+ this.mediaSource = null;
7285
7233
  // Last MP3 audio chunk appended
7286
- _this.lastMpegAudioChunk = null;
7287
- _this.appendSource = void 0;
7234
+ this.lastMpegAudioChunk = null;
7235
+ this.appendSource = void 0;
7288
7236
  // counters
7289
- _this.appendErrors = {
7237
+ this.appendErrors = {
7290
7238
  audio: 0,
7291
7239
  video: 0,
7292
7240
  audiovideo: 0
7293
7241
  };
7294
- _this.tracks = {};
7295
- _this.pendingTracks = {};
7296
- _this.sourceBuffer = void 0;
7297
- _this._onEndStreaming = function (event) {
7242
+ this.tracks = {};
7243
+ this.pendingTracks = {};
7244
+ this.sourceBuffer = void 0;
7245
+ this.log = void 0;
7246
+ this.warn = void 0;
7247
+ this.error = void 0;
7248
+ this._onEndStreaming = function (event) {
7298
7249
  if (!_this.hls) {
7299
7250
  return;
7300
7251
  }
7301
7252
  _this.hls.pauseBuffering();
7302
7253
  };
7303
- _this._onStartStreaming = function (event) {
7254
+ this._onStartStreaming = function (event) {
7304
7255
  if (!_this.hls) {
7305
7256
  return;
7306
7257
  }
7307
7258
  _this.hls.resumeBuffering();
7308
7259
  };
7309
7260
  // Keep as arrow functions so that we can directly reference these functions directly as event listeners
7310
- _this._onMediaSourceOpen = function () {
7311
- var _assertThisInitialize = _assertThisInitialized(_this),
7312
- media = _assertThisInitialize.media,
7313
- mediaSource = _assertThisInitialize.mediaSource;
7261
+ this._onMediaSourceOpen = function () {
7262
+ var media = _this.media,
7263
+ mediaSource = _this.mediaSource;
7314
7264
  _this.log('Media source opened');
7315
7265
  if (media) {
7316
7266
  media.removeEventListener('emptied', _this._onMediaEmptied);
@@ -7326,25 +7276,27 @@
7326
7276
  }
7327
7277
  _this.checkPendingTracks();
7328
7278
  };
7329
- _this._onMediaSourceClose = function () {
7279
+ this._onMediaSourceClose = function () {
7330
7280
  _this.log('Media source closed');
7331
7281
  };
7332
- _this._onMediaSourceEnded = function () {
7282
+ this._onMediaSourceEnded = function () {
7333
7283
  _this.log('Media source ended');
7334
7284
  };
7335
- _this._onMediaEmptied = function () {
7336
- var _assertThisInitialize2 = _assertThisInitialized(_this),
7337
- mediaSrc = _assertThisInitialize2.mediaSrc,
7338
- _objectUrl = _assertThisInitialize2._objectUrl;
7285
+ this._onMediaEmptied = function () {
7286
+ var mediaSrc = _this.mediaSrc,
7287
+ _objectUrl = _this._objectUrl;
7339
7288
  if (mediaSrc !== _objectUrl) {
7340
- _this.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
7289
+ logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
7341
7290
  }
7342
7291
  };
7343
- _this.hls = hls;
7344
- _this.appendSource = hls.config.preferManagedMediaSource;
7345
- _this._initSourceBuffer();
7346
- _this.registerListeners();
7347
- return _this;
7292
+ this.hls = hls;
7293
+ var logPrefix = '[buffer-controller]';
7294
+ this.appendSource = hls.config.preferManagedMediaSource;
7295
+ this.log = logger.log.bind(logger, logPrefix);
7296
+ this.warn = logger.warn.bind(logger, logPrefix);
7297
+ this.error = logger.error.bind(logger, logPrefix);
7298
+ this._initSourceBuffer();
7299
+ this.registerListeners();
7348
7300
  }
7349
7301
  var _proto = BufferController.prototype;
7350
7302
  _proto.hasSourceTypes = function hasSourceTypes() {
@@ -7356,12 +7308,6 @@
7356
7308
  this.lastMpegAudioChunk = null;
7357
7309
  // @ts-ignore
7358
7310
  this.hls = null;
7359
- // @ts-ignore
7360
- this._onMediaSourceOpen = this._onMediaSourceClose = null;
7361
- // @ts-ignore
7362
- this._onMediaSourceEnded = null;
7363
- // @ts-ignore
7364
- this._onStartStreaming = this._onEndStreaming = null;
7365
7311
  };
7366
7312
  _proto.registerListeners = function registerListeners() {
7367
7313
  var hls = this.hls;
@@ -8222,7 +8168,7 @@
8222
8168
  }
8223
8169
  }]);
8224
8170
  return BufferController;
8225
- }(Logger);
8171
+ }();
8226
8172
  function removeSourceChildren(node) {
8227
8173
  var sourceChildren = node.querySelectorAll('source');
8228
8174
  [].slice.call(sourceChildren).forEach(function (source) {
@@ -8346,7 +8292,7 @@
8346
8292
  var hls = this.hls;
8347
8293
  var maxLevel = this.getMaxLevel(levels.length - 1);
8348
8294
  if (maxLevel !== this.autoLevelCapping) {
8349
- hls.logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
8295
+ logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
8350
8296
  }
8351
8297
  hls.autoLevelCapping = maxLevel;
8352
8298
  if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
@@ -8536,10 +8482,10 @@
8536
8482
  totalDroppedFrames: droppedFrames
8537
8483
  });
8538
8484
  if (droppedFPS > 0) {
8539
- // hls.logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
8485
+ // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
8540
8486
  if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
8541
8487
  var currentLevel = hls.currentLevel;
8542
- hls.logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
8488
+ logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
8543
8489
  if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
8544
8490
  currentLevel = currentLevel - 1;
8545
8491
  hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
@@ -8573,28 +8519,26 @@
8573
8519
  }();
8574
8520
 
8575
8521
  var PATHWAY_PENALTY_DURATION_MS = 300000;
8576
- var ContentSteeringController = /*#__PURE__*/function (_Logger) {
8577
- _inheritsLoose(ContentSteeringController, _Logger);
8522
+ var ContentSteeringController = /*#__PURE__*/function () {
8578
8523
  function ContentSteeringController(hls) {
8579
- var _this;
8580
- _this = _Logger.call(this, 'content-steering', hls.logger) || this;
8581
- _this.hls = void 0;
8582
- _this.loader = null;
8583
- _this.uri = null;
8584
- _this.pathwayId = '.';
8585
- _this.pathwayPriority = null;
8586
- _this.timeToLoad = 300;
8587
- _this.reloadTimer = -1;
8588
- _this.updated = 0;
8589
- _this.started = false;
8590
- _this.enabled = true;
8591
- _this.levels = null;
8592
- _this.audioTracks = null;
8593
- _this.subtitleTracks = null;
8594
- _this.penalizedPathways = {};
8595
- _this.hls = hls;
8596
- _this.registerListeners();
8597
- return _this;
8524
+ this.hls = void 0;
8525
+ this.log = void 0;
8526
+ this.loader = null;
8527
+ this.uri = null;
8528
+ this.pathwayId = '.';
8529
+ this.pathwayPriority = null;
8530
+ this.timeToLoad = 300;
8531
+ this.reloadTimer = -1;
8532
+ this.updated = 0;
8533
+ this.started = false;
8534
+ this.enabled = true;
8535
+ this.levels = null;
8536
+ this.audioTracks = null;
8537
+ this.subtitleTracks = null;
8538
+ this.penalizedPathways = {};
8539
+ this.hls = hls;
8540
+ this.log = logger.log.bind(logger, "[content-steering]:");
8541
+ this.registerListeners();
8598
8542
  }
8599
8543
  var _proto = ContentSteeringController.prototype;
8600
8544
  _proto.registerListeners = function registerListeners() {
@@ -8715,7 +8659,7 @@
8715
8659
  errorAction.resolved = this.pathwayId !== errorPathway;
8716
8660
  }
8717
8661
  if (!errorAction.resolved) {
8718
- this.warn("Could not resolve " + data.details + " (\"" + data.error.message + "\") with content-steering for Pathway: " + errorPathway + " levels: " + (levels ? levels.length : levels) + " priorities: " + JSON.stringify(pathwayPriority) + " penalized: " + JSON.stringify(this.penalizedPathways));
8662
+ logger.warn("Could not resolve " + data.details + " (\"" + data.error.message + "\") with content-steering for Pathway: " + errorPathway + " levels: " + (levels ? levels.length : levels) + " priorities: " + JSON.stringify(pathwayPriority) + " penalized: " + JSON.stringify(this.penalizedPathways));
8719
8663
  }
8720
8664
  }
8721
8665
  };
@@ -8795,7 +8739,7 @@
8795
8739
  return defaultPathway;
8796
8740
  };
8797
8741
  _proto.clonePathways = function clonePathways(pathwayClones) {
8798
- var _this2 = this;
8742
+ var _this = this;
8799
8743
  var levels = this.levels;
8800
8744
  if (!levels) {
8801
8745
  return;
@@ -8811,7 +8755,7 @@
8811
8755
  })) {
8812
8756
  return;
8813
8757
  }
8814
- var clonedVariants = _this2.getLevelsForPathway(baseId).map(function (baseLevel) {
8758
+ var clonedVariants = _this.getLevelsForPathway(baseId).map(function (baseLevel) {
8815
8759
  var attributes = new AttrList(baseLevel.attrs);
8816
8760
  attributes['PATHWAY-ID'] = cloneId;
8817
8761
  var clonedAudioGroupId = attributes.AUDIO && attributes.AUDIO + "_clone_" + cloneId;
@@ -8848,12 +8792,12 @@
8848
8792
  return clonedLevel;
8849
8793
  });
8850
8794
  levels.push.apply(levels, clonedVariants);
8851
- cloneRenditionGroups(_this2.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
8852
- cloneRenditionGroups(_this2.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
8795
+ cloneRenditionGroups(_this.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
8796
+ cloneRenditionGroups(_this.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
8853
8797
  });
8854
8798
  };
8855
8799
  _proto.loadSteeringManifest = function loadSteeringManifest(uri) {
8856
- var _this3 = this;
8800
+ var _this2 = this;
8857
8801
  var config = this.hls.config;
8858
8802
  var Loader = config.loader;
8859
8803
  if (this.loader) {
@@ -8888,87 +8832,87 @@
8888
8832
  };
8889
8833
  var callbacks = {
8890
8834
  onSuccess: function onSuccess(response, stats, context, networkDetails) {
8891
- _this3.log("Loaded steering manifest: \"" + url + "\"");
8835
+ _this2.log("Loaded steering manifest: \"" + url + "\"");
8892
8836
  var steeringData = response.data;
8893
- if ((steeringData == null ? void 0 : steeringData.VERSION) !== 1) {
8894
- _this3.log("Steering VERSION " + steeringData.VERSION + " not supported!");
8837
+ if (steeringData.VERSION !== 1) {
8838
+ _this2.log("Steering VERSION " + steeringData.VERSION + " not supported!");
8895
8839
  return;
8896
8840
  }
8897
- _this3.updated = performance.now();
8898
- _this3.timeToLoad = steeringData.TTL;
8841
+ _this2.updated = performance.now();
8842
+ _this2.timeToLoad = steeringData.TTL;
8899
8843
  var reloadUri = steeringData['RELOAD-URI'],
8900
8844
  pathwayClones = steeringData['PATHWAY-CLONES'],
8901
8845
  pathwayPriority = steeringData['PATHWAY-PRIORITY'];
8902
8846
  if (reloadUri) {
8903
8847
  try {
8904
- _this3.uri = new self.URL(reloadUri, url).href;
8848
+ _this2.uri = new self.URL(reloadUri, url).href;
8905
8849
  } catch (error) {
8906
- _this3.enabled = false;
8907
- _this3.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
8850
+ _this2.enabled = false;
8851
+ _this2.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
8908
8852
  return;
8909
8853
  }
8910
8854
  }
8911
- _this3.scheduleRefresh(_this3.uri || context.url);
8855
+ _this2.scheduleRefresh(_this2.uri || context.url);
8912
8856
  if (pathwayClones) {
8913
- _this3.clonePathways(pathwayClones);
8857
+ _this2.clonePathways(pathwayClones);
8914
8858
  }
8915
8859
  var loadedSteeringData = {
8916
8860
  steeringManifest: steeringData,
8917
8861
  url: url.toString()
8918
8862
  };
8919
- _this3.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
8863
+ _this2.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
8920
8864
  if (pathwayPriority) {
8921
- _this3.updatePathwayPriority(pathwayPriority);
8865
+ _this2.updatePathwayPriority(pathwayPriority);
8922
8866
  }
8923
8867
  },
8924
8868
  onError: function onError(error, context, networkDetails, stats) {
8925
- _this3.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
8926
- _this3.stopLoad();
8869
+ _this2.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
8870
+ _this2.stopLoad();
8927
8871
  if (error.code === 410) {
8928
- _this3.enabled = false;
8929
- _this3.log("Steering manifest " + context.url + " no longer available");
8872
+ _this2.enabled = false;
8873
+ _this2.log("Steering manifest " + context.url + " no longer available");
8930
8874
  return;
8931
8875
  }
8932
- var ttl = _this3.timeToLoad * 1000;
8876
+ var ttl = _this2.timeToLoad * 1000;
8933
8877
  if (error.code === 429) {
8934
- var loader = _this3.loader;
8878
+ var loader = _this2.loader;
8935
8879
  if (typeof (loader == null ? void 0 : loader.getResponseHeader) === 'function') {
8936
8880
  var retryAfter = loader.getResponseHeader('Retry-After');
8937
8881
  if (retryAfter) {
8938
8882
  ttl = parseFloat(retryAfter) * 1000;
8939
8883
  }
8940
8884
  }
8941
- _this3.log("Steering manifest " + context.url + " rate limited");
8885
+ _this2.log("Steering manifest " + context.url + " rate limited");
8942
8886
  return;
8943
8887
  }
8944
- _this3.scheduleRefresh(_this3.uri || context.url, ttl);
8888
+ _this2.scheduleRefresh(_this2.uri || context.url, ttl);
8945
8889
  },
8946
8890
  onTimeout: function onTimeout(stats, context, networkDetails) {
8947
- _this3.log("Timeout loading steering manifest (" + context.url + ")");
8948
- _this3.scheduleRefresh(_this3.uri || context.url);
8891
+ _this2.log("Timeout loading steering manifest (" + context.url + ")");
8892
+ _this2.scheduleRefresh(_this2.uri || context.url);
8949
8893
  }
8950
8894
  };
8951
8895
  this.log("Requesting steering manifest: " + url);
8952
8896
  this.loader.load(context, loaderConfig, callbacks);
8953
8897
  };
8954
8898
  _proto.scheduleRefresh = function scheduleRefresh(uri, ttlMs) {
8955
- var _this4 = this;
8899
+ var _this3 = this;
8956
8900
  if (ttlMs === void 0) {
8957
8901
  ttlMs = this.timeToLoad * 1000;
8958
8902
  }
8959
8903
  this.clearTimeout();
8960
8904
  this.reloadTimer = self.setTimeout(function () {
8961
- var _this4$hls;
8962
- var media = (_this4$hls = _this4.hls) == null ? void 0 : _this4$hls.media;
8905
+ var _this3$hls;
8906
+ var media = (_this3$hls = _this3.hls) == null ? void 0 : _this3$hls.media;
8963
8907
  if (media && !media.ended) {
8964
- _this4.loadSteeringManifest(uri);
8908
+ _this3.loadSteeringManifest(uri);
8965
8909
  return;
8966
8910
  }
8967
- _this4.scheduleRefresh(uri, _this4.timeToLoad * 1000);
8911
+ _this3.scheduleRefresh(uri, _this3.timeToLoad * 1000);
8968
8912
  }, ttlMs);
8969
8913
  };
8970
8914
  return ContentSteeringController;
8971
- }(Logger);
8915
+ }();
8972
8916
  function cloneRenditionGroups(tracks, groupCloneMap, uriReplacement, cloneId) {
8973
8917
  if (!tracks) {
8974
8918
  return;
@@ -9835,7 +9779,7 @@
9835
9779
  /**
9836
9780
  * @ignore
9837
9781
  */
9838
- function mergeConfig(defaultConfig, userConfig, logger) {
9782
+ function mergeConfig(defaultConfig, userConfig) {
9839
9783
  if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
9840
9784
  throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
9841
9785
  }
@@ -9905,7 +9849,7 @@
9905
9849
  /**
9906
9850
  * @ignore
9907
9851
  */
9908
- function enableStreamingMode(config, logger) {
9852
+ function enableStreamingMode(config) {
9909
9853
  var currentLoader = config.loader;
9910
9854
  if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
9911
9855
  // If a developer has configured their own loader, respect that choice
@@ -9922,11 +9866,12 @@
9922
9866
  }
9923
9867
  }
9924
9868
 
9869
+ var chromeOrFirefox;
9925
9870
  var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
9926
9871
  _inheritsLoose(LevelController, _BasePlaylistControll);
9927
9872
  function LevelController(hls, contentSteeringController) {
9928
9873
  var _this;
9929
- _this = _BasePlaylistControll.call(this, hls, 'level-controller') || this;
9874
+ _this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
9930
9875
  _this._levels = [];
9931
9876
  _this._firstLevel = -1;
9932
9877
  _this._maxAutoLevel = -1;
@@ -9995,13 +9940,21 @@
9995
9940
  var videoCodecFound = false;
9996
9941
  var audioCodecFound = false;
9997
9942
  data.levels.forEach(function (levelParsed) {
9998
- var _videoCodec;
9943
+ var _audioCodec, _videoCodec;
9999
9944
  var attributes = levelParsed.attrs;
9945
+
9946
+ // erase audio codec info if browser does not support mp4a.40.34.
9947
+ // demuxer will autodetect codec and fallback to mpeg/audio
10000
9948
  var audioCodec = levelParsed.audioCodec,
10001
9949
  videoCodec = levelParsed.videoCodec;
9950
+ if (((_audioCodec = audioCodec) == null ? void 0 : _audioCodec.indexOf('mp4a.40.34')) !== -1) {
9951
+ chromeOrFirefox || (chromeOrFirefox = /chrome|firefox/i.test(navigator.userAgent));
9952
+ if (chromeOrFirefox) {
9953
+ levelParsed.audioCodec = audioCodec = undefined;
9954
+ }
9955
+ }
10002
9956
  if (audioCodec) {
10003
- // Returns empty and set to undefined for 'mp4a.40.34' with fallback to 'audio/mpeg' SourceBuffer
10004
- levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource) || undefined;
9957
+ levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource);
10005
9958
  }
10006
9959
  if (((_videoCodec = videoCodec) == null ? void 0 : _videoCodec.indexOf('avc1')) === 0) {
10007
9960
  videoCodec = levelParsed.videoCodec = convertAVC1ToAVCOTI(videoCodec);
@@ -10124,8 +10077,8 @@
10124
10077
  return _valueB - _valueA;
10125
10078
  }
10126
10079
  }
10127
- if (a.bitrate !== b.bitrate) {
10128
- return a.bitrate - b.bitrate;
10080
+ if (a.averageBitrate !== b.averageBitrate) {
10081
+ return a.averageBitrate - b.averageBitrate;
10129
10082
  }
10130
10083
  return 0;
10131
10084
  });
@@ -11148,8 +11101,8 @@
11148
11101
  var _frag$decryptdata;
11149
11102
  var byteRangeStart = start;
11150
11103
  var byteRangeEnd = end;
11151
- if (frag.sn === 'initSegment' && isMethodFullSegmentAesCbc((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method)) {
11152
- // MAP segment encrypted with method 'AES-128' or 'AES-256' (cbc), when served with HTTP Range,
11104
+ if (frag.sn === 'initSegment' && ((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method) === 'AES-128') {
11105
+ // MAP segment encrypted with method 'AES-128', when served with HTTP Range,
11153
11106
  // has the unencrypted size specified in the range.
11154
11107
  // Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
11155
11108
  var fragmentLen = end - start;
@@ -11182,9 +11135,6 @@
11182
11135
  (part ? part : frag).stats.aborted = true;
11183
11136
  return new LoadError(errorData);
11184
11137
  }
11185
- function isMethodFullSegmentAesCbc(method) {
11186
- return method === 'AES-128' || method === 'AES-256';
11187
- }
11188
11138
  var LoadError = /*#__PURE__*/function (_Error) {
11189
11139
  _inheritsLoose(LoadError, _Error);
11190
11140
  function LoadError(data) {
@@ -11341,8 +11291,6 @@
11341
11291
  }
11342
11292
  return this.loadKeyEME(keyInfo, frag);
11343
11293
  case 'AES-128':
11344
- case 'AES-256':
11345
- case 'AES-256-CTR':
11346
11294
  return this.loadKeyHTTP(keyInfo, frag);
11347
11295
  default:
11348
11296
  return Promise.reject(this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, new Error("Key supplied with unsupported METHOD: \"" + decryptdata.method + "\"")));
@@ -11476,17 +11424,13 @@
11476
11424
  * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
11477
11425
  * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
11478
11426
  */
11479
- var TaskLoop = /*#__PURE__*/function (_Logger) {
11480
- _inheritsLoose(TaskLoop, _Logger);
11481
- function TaskLoop(label, logger) {
11482
- var _this;
11483
- _this = _Logger.call(this, label, logger) || this;
11484
- _this._boundTick = void 0;
11485
- _this._tickTimer = null;
11486
- _this._tickInterval = null;
11487
- _this._tickCallCount = 0;
11488
- _this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
11489
- return _this;
11427
+ var TaskLoop = /*#__PURE__*/function () {
11428
+ function TaskLoop() {
11429
+ this._boundTick = void 0;
11430
+ this._tickTimer = null;
11431
+ this._tickInterval = null;
11432
+ this._tickCallCount = 0;
11433
+ this._boundTick = this.tick.bind(this);
11490
11434
  }
11491
11435
  var _proto = TaskLoop.prototype;
11492
11436
  _proto.destroy = function destroy() {
@@ -11572,7 +11516,7 @@
11572
11516
  */;
11573
11517
  _proto.doTick = function doTick() {};
11574
11518
  return TaskLoop;
11575
- }(Logger);
11519
+ }();
11576
11520
 
11577
11521
  var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) {
11578
11522
  if (size === void 0) {
@@ -11758,65 +11702,37 @@
11758
11702
  }
11759
11703
 
11760
11704
  var AESCrypto = /*#__PURE__*/function () {
11761
- function AESCrypto(subtle, iv, aesMode) {
11705
+ function AESCrypto(subtle, iv) {
11762
11706
  this.subtle = void 0;
11763
11707
  this.aesIV = void 0;
11764
- this.aesMode = void 0;
11765
11708
  this.subtle = subtle;
11766
11709
  this.aesIV = iv;
11767
- this.aesMode = aesMode;
11768
11710
  }
11769
11711
  var _proto = AESCrypto.prototype;
11770
11712
  _proto.decrypt = function decrypt(data, key) {
11771
- switch (this.aesMode) {
11772
- case DecrypterAesMode.cbc:
11773
- return this.subtle.decrypt({
11774
- name: 'AES-CBC',
11775
- iv: this.aesIV
11776
- }, key, data);
11777
- case DecrypterAesMode.ctr:
11778
- return this.subtle.decrypt({
11779
- name: 'AES-CTR',
11780
- counter: this.aesIV,
11781
- length: 64
11782
- },
11783
- //64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
11784
- key, data);
11785
- default:
11786
- throw new Error("[AESCrypto] invalid aes mode " + this.aesMode);
11787
- }
11713
+ return this.subtle.decrypt({
11714
+ name: 'AES-CBC',
11715
+ iv: this.aesIV
11716
+ }, key, data);
11788
11717
  };
11789
11718
  return AESCrypto;
11790
11719
  }();
11791
11720
 
11792
11721
  var FastAESKey = /*#__PURE__*/function () {
11793
- function FastAESKey(subtle, key, aesMode) {
11722
+ function FastAESKey(subtle, key) {
11794
11723
  this.subtle = void 0;
11795
11724
  this.key = void 0;
11796
- this.aesMode = void 0;
11797
11725
  this.subtle = subtle;
11798
11726
  this.key = key;
11799
- this.aesMode = aesMode;
11800
11727
  }
11801
11728
  var _proto = FastAESKey.prototype;
11802
11729
  _proto.expandKey = function expandKey() {
11803
- var subtleAlgoName = getSubtleAlgoName(this.aesMode);
11804
11730
  return this.subtle.importKey('raw', this.key, {
11805
- name: subtleAlgoName
11731
+ name: 'AES-CBC'
11806
11732
  }, false, ['encrypt', 'decrypt']);
11807
11733
  };
11808
11734
  return FastAESKey;
11809
11735
  }();
11810
- function getSubtleAlgoName(aesMode) {
11811
- switch (aesMode) {
11812
- case DecrypterAesMode.cbc:
11813
- return 'AES-CBC';
11814
- case DecrypterAesMode.ctr:
11815
- return 'AES-CTR';
11816
- default:
11817
- throw new Error("[FastAESKey] invalid aes mode " + aesMode);
11818
- }
11819
- }
11820
11736
 
11821
11737
  // PKCS7
11822
11738
  function removePadding(array) {
@@ -12069,8 +11985,7 @@
12069
11985
  this.currentIV = null;
12070
11986
  this.currentResult = null;
12071
11987
  this.useSoftware = void 0;
12072
- this.enableSoftwareAES = void 0;
12073
- this.enableSoftwareAES = config.enableSoftwareAES;
11988
+ this.useSoftware = config.enableSoftwareAES;
12074
11989
  this.removePKCS7Padding = removePKCS7Padding;
12075
11990
  // built in decryptor expects PKCS7 padding
12076
11991
  if (removePKCS7Padding) {
@@ -12083,7 +11998,9 @@
12083
11998
  /* no-op */
12084
11999
  }
12085
12000
  }
12086
- this.useSoftware = this.subtle === null;
12001
+ if (this.subtle === null) {
12002
+ this.useSoftware = true;
12003
+ }
12087
12004
  }
12088
12005
  var _proto = Decrypter.prototype;
12089
12006
  _proto.destroy = function destroy() {
@@ -12120,11 +12037,11 @@
12120
12037
  this.softwareDecrypter = null;
12121
12038
  }
12122
12039
  };
12123
- _proto.decrypt = function decrypt(data, key, iv, aesMode) {
12040
+ _proto.decrypt = function decrypt(data, key, iv) {
12124
12041
  var _this = this;
12125
12042
  if (this.useSoftware) {
12126
12043
  return new Promise(function (resolve, reject) {
12127
- _this.softwareDecrypt(new Uint8Array(data), key, iv, aesMode);
12044
+ _this.softwareDecrypt(new Uint8Array(data), key, iv);
12128
12045
  var decryptResult = _this.flush();
12129
12046
  if (decryptResult) {
12130
12047
  resolve(decryptResult.buffer);
@@ -12133,20 +12050,16 @@
12133
12050
  }
12134
12051
  });
12135
12052
  }
12136
- return this.webCryptoDecrypt(new Uint8Array(data), key, iv, aesMode);
12053
+ return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
12137
12054
  }
12138
12055
 
12139
12056
  // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
12140
12057
  // data is handled in the flush() call
12141
12058
  ;
12142
- _proto.softwareDecrypt = function softwareDecrypt(data, key, iv, aesMode) {
12059
+ _proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
12143
12060
  var currentIV = this.currentIV,
12144
12061
  currentResult = this.currentResult,
12145
12062
  remainderData = this.remainderData;
12146
- if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
12147
- logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
12148
- return null;
12149
- }
12150
12063
  this.logOnce('JS AES decrypt');
12151
12064
  // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
12152
12065
  // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
@@ -12179,12 +12092,12 @@
12179
12092
  }
12180
12093
  return result;
12181
12094
  };
12182
- _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv, aesMode) {
12095
+ _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
12183
12096
  var _this2 = this;
12184
12097
  var subtle = this.subtle;
12185
12098
  if (this.key !== key || !this.fastAesKey) {
12186
12099
  this.key = key;
12187
- this.fastAesKey = new FastAESKey(subtle, key, aesMode);
12100
+ this.fastAesKey = new FastAESKey(subtle, key);
12188
12101
  }
12189
12102
  return this.fastAesKey.expandKey().then(function (aesKey) {
12190
12103
  // decrypt using web crypto
@@ -12192,25 +12105,22 @@
12192
12105
  return Promise.reject(new Error('web crypto not initialized'));
12193
12106
  }
12194
12107
  _this2.logOnce('WebCrypto AES decrypt');
12195
- var crypto = new AESCrypto(subtle, new Uint8Array(iv), aesMode);
12108
+ var crypto = new AESCrypto(subtle, new Uint8Array(iv));
12196
12109
  return crypto.decrypt(data.buffer, aesKey);
12197
12110
  }).catch(function (err) {
12198
12111
  logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
12199
- return _this2.onWebCryptoError(data, key, iv, aesMode);
12112
+ return _this2.onWebCryptoError(data, key, iv);
12200
12113
  });
12201
12114
  };
12202
- _proto.onWebCryptoError = function onWebCryptoError(data, key, iv, aesMode) {
12203
- var enableSoftwareAES = this.enableSoftwareAES;
12204
- if (enableSoftwareAES) {
12205
- this.useSoftware = true;
12206
- this.logEnabled = true;
12207
- this.softwareDecrypt(data, key, iv, aesMode);
12208
- var decryptResult = this.flush();
12209
- if (decryptResult) {
12210
- return decryptResult.buffer;
12211
- }
12115
+ _proto.onWebCryptoError = function onWebCryptoError(data, key, iv) {
12116
+ this.useSoftware = true;
12117
+ this.logEnabled = true;
12118
+ this.softwareDecrypt(data, key, iv);
12119
+ var decryptResult = this.flush();
12120
+ if (decryptResult) {
12121
+ return decryptResult.buffer;
12212
12122
  }
12213
- throw new Error('WebCrypto' + (enableSoftwareAES ? ' and softwareDecrypt' : '') + ': failed to decrypt data');
12123
+ throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
12214
12124
  };
12215
12125
  _proto.getValidChunk = function getValidChunk(data) {
12216
12126
  var currentChunk = data;
@@ -12264,7 +12174,7 @@
12264
12174
  _inheritsLoose(BaseStreamController, _TaskLoop);
12265
12175
  function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix, playlistType) {
12266
12176
  var _this;
12267
- _this = _TaskLoop.call(this, logPrefix, hls.logger) || this;
12177
+ _this = _TaskLoop.call(this) || this;
12268
12178
  _this.hls = void 0;
12269
12179
  _this.fragPrevious = null;
12270
12180
  _this.fragCurrent = null;
@@ -12289,81 +12199,25 @@
12289
12199
  _this.startFragRequested = false;
12290
12200
  _this.decrypter = void 0;
12291
12201
  _this.initPTS = [];
12292
- _this.onMediaSeeking = function () {
12293
- var _assertThisInitialize = _assertThisInitialized(_this),
12294
- config = _assertThisInitialize.config,
12295
- fragCurrent = _assertThisInitialize.fragCurrent,
12296
- media = _assertThisInitialize.media,
12297
- mediaBuffer = _assertThisInitialize.mediaBuffer,
12298
- state = _assertThisInitialize.state;
12299
- var currentTime = media ? media.currentTime : 0;
12300
- var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
12301
- _this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
12302
- if (_this.state === State.ENDED) {
12303
- _this.resetLoadingState();
12304
- } else if (fragCurrent) {
12305
- // Seeking while frag load is in progress
12306
- var tolerance = config.maxFragLookUpTolerance;
12307
- var fragStartOffset = fragCurrent.start - tolerance;
12308
- var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
12309
- // if seeking out of buffered range or into new one
12310
- if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
12311
- var pastFragment = currentTime > fragEndOffset;
12312
- // if the seek position is outside the current fragment range
12313
- if (currentTime < fragStartOffset || pastFragment) {
12314
- if (pastFragment && fragCurrent.loader) {
12315
- _this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
12316
- fragCurrent.abortRequests();
12317
- _this.resetLoadingState();
12318
- }
12319
- _this.fragPrevious = null;
12320
- }
12321
- }
12322
- }
12323
- if (media) {
12324
- // Remove gap fragments
12325
- _this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, _this.playlistType, true);
12326
- _this.lastCurrentTime = currentTime;
12327
- }
12328
-
12329
- // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
12330
- if (!_this.loadedmetadata && !bufferInfo.len) {
12331
- _this.nextLoadPosition = _this.startPosition = currentTime;
12332
- }
12333
-
12334
- // Async tick to speed up processing
12335
- _this.tickImmediate();
12336
- };
12337
- _this.onMediaEnded = function () {
12338
- // reset startPosition and lastCurrentTime to restart playback @ stream beginning
12339
- _this.startPosition = _this.lastCurrentTime = 0;
12340
- };
12202
+ _this.onvseeking = null;
12203
+ _this.onvended = null;
12204
+ _this.logPrefix = '';
12205
+ _this.log = void 0;
12206
+ _this.warn = void 0;
12341
12207
  _this.playlistType = playlistType;
12208
+ _this.logPrefix = logPrefix;
12209
+ _this.log = logger.log.bind(logger, logPrefix + ":");
12210
+ _this.warn = logger.warn.bind(logger, logPrefix + ":");
12342
12211
  _this.hls = hls;
12343
12212
  _this.fragmentLoader = new FragmentLoader(hls.config);
12344
12213
  _this.keyLoader = keyLoader;
12345
12214
  _this.fragmentTracker = fragmentTracker;
12346
12215
  _this.config = hls.config;
12347
12216
  _this.decrypter = new Decrypter(hls.config);
12217
+ hls.on(Events.MANIFEST_LOADED, _this.onManifestLoaded, _assertThisInitialized(_this));
12348
12218
  return _this;
12349
12219
  }
12350
12220
  var _proto = BaseStreamController.prototype;
12351
- _proto.registerListeners = function registerListeners() {
12352
- var hls = this.hls;
12353
- hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
12354
- hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
12355
- hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
12356
- hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
12357
- hls.on(Events.ERROR, this.onError, this);
12358
- };
12359
- _proto.unregisterListeners = function unregisterListeners() {
12360
- var hls = this.hls;
12361
- hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
12362
- hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
12363
- hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
12364
- hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
12365
- hls.off(Events.ERROR, this.onError, this);
12366
- };
12367
12221
  _proto.doTick = function doTick() {
12368
12222
  this.onTickEnd();
12369
12223
  };
@@ -12417,8 +12271,10 @@
12417
12271
  };
12418
12272
  _proto.onMediaAttached = function onMediaAttached(event, data) {
12419
12273
  var media = this.media = this.mediaBuffer = data.media;
12420
- media.addEventListener('seeking', this.onMediaSeeking);
12421
- media.addEventListener('ended', this.onMediaEnded);
12274
+ this.onvseeking = this.onMediaSeeking.bind(this);
12275
+ this.onvended = this.onMediaEnded.bind(this);
12276
+ media.addEventListener('seeking', this.onvseeking);
12277
+ media.addEventListener('ended', this.onvended);
12422
12278
  var config = this.config;
12423
12279
  if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
12424
12280
  this.startLoad(config.startPosition);
@@ -12432,9 +12288,10 @@
12432
12288
  }
12433
12289
 
12434
12290
  // remove video listeners
12435
- if (media) {
12436
- media.removeEventListener('seeking', this.onMediaSeeking);
12437
- media.removeEventListener('ended', this.onMediaEnded);
12291
+ if (media && this.onvseeking && this.onvended) {
12292
+ media.removeEventListener('seeking', this.onvseeking);
12293
+ media.removeEventListener('ended', this.onvended);
12294
+ this.onvseeking = this.onvended = null;
12438
12295
  }
12439
12296
  if (this.keyLoader) {
12440
12297
  this.keyLoader.detach();
@@ -12444,8 +12301,54 @@
12444
12301
  this.fragmentTracker.removeAllFragments();
12445
12302
  this.stopLoad();
12446
12303
  };
12447
- _proto.onManifestLoading = function onManifestLoading() {};
12448
- _proto.onError = function onError(event, data) {};
12304
+ _proto.onMediaSeeking = function onMediaSeeking() {
12305
+ var config = this.config,
12306
+ fragCurrent = this.fragCurrent,
12307
+ media = this.media,
12308
+ mediaBuffer = this.mediaBuffer,
12309
+ state = this.state;
12310
+ var currentTime = media ? media.currentTime : 0;
12311
+ var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
12312
+ this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
12313
+ if (this.state === State.ENDED) {
12314
+ this.resetLoadingState();
12315
+ } else if (fragCurrent) {
12316
+ // Seeking while frag load is in progress
12317
+ var tolerance = config.maxFragLookUpTolerance;
12318
+ var fragStartOffset = fragCurrent.start - tolerance;
12319
+ var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
12320
+ // if seeking out of buffered range or into new one
12321
+ if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
12322
+ var pastFragment = currentTime > fragEndOffset;
12323
+ // if the seek position is outside the current fragment range
12324
+ if (currentTime < fragStartOffset || pastFragment) {
12325
+ if (pastFragment && fragCurrent.loader) {
12326
+ this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
12327
+ fragCurrent.abortRequests();
12328
+ this.resetLoadingState();
12329
+ }
12330
+ this.fragPrevious = null;
12331
+ }
12332
+ }
12333
+ }
12334
+ if (media) {
12335
+ // Remove gap fragments
12336
+ this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
12337
+ this.lastCurrentTime = currentTime;
12338
+ }
12339
+
12340
+ // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
12341
+ if (!this.loadedmetadata && !bufferInfo.len) {
12342
+ this.nextLoadPosition = this.startPosition = currentTime;
12343
+ }
12344
+
12345
+ // Async tick to speed up processing
12346
+ this.tickImmediate();
12347
+ };
12348
+ _proto.onMediaEnded = function onMediaEnded() {
12349
+ // reset startPosition and lastCurrentTime to restart playback @ stream beginning
12350
+ this.startPosition = this.lastCurrentTime = 0;
12351
+ };
12449
12352
  _proto.onManifestLoaded = function onManifestLoaded(event, data) {
12450
12353
  this.startTimeOffset = data.startTimeOffset;
12451
12354
  this.initPTS = [];
@@ -12455,7 +12358,7 @@
12455
12358
  this.stopLoad();
12456
12359
  _TaskLoop.prototype.onHandlerDestroying.call(this);
12457
12360
  // @ts-ignore
12458
- this.hls = this.onMediaSeeking = this.onMediaEnded = null;
12361
+ this.hls = null;
12459
12362
  };
12460
12363
  _proto.onHandlerDestroyed = function onHandlerDestroyed() {
12461
12364
  this.state = State.STOPPED;
@@ -12585,10 +12488,10 @@
12585
12488
  var decryptData = frag.decryptdata;
12586
12489
 
12587
12490
  // check to see if the payload needs to be decrypted
12588
- if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && isFullSegmentEncryption(decryptData.method)) {
12491
+ if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
12589
12492
  var startTime = self.performance.now();
12590
12493
  // decrypt init segment data
12591
- return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer, getAesModeFromFullSegmentMethod(decryptData.method)).catch(function (err) {
12494
+ return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
12592
12495
  hls.trigger(Events.ERROR, {
12593
12496
  type: ErrorTypes.MEDIA_ERROR,
12594
12497
  details: ErrorDetails.FRAG_DECRYPT_ERROR,
@@ -12701,7 +12604,7 @@
12701
12604
  }
12702
12605
  var keyLoadingPromise = null;
12703
12606
  if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
12704
- this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track') + " " + frag.level);
12607
+ this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level);
12705
12608
  this.state = State.KEY_LOADING;
12706
12609
  this.fragCurrent = frag;
12707
12610
  keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
@@ -12732,7 +12635,7 @@
12732
12635
  var partIndex = this.getNextPart(partList, frag, targetBufferTime);
12733
12636
  if (partIndex > -1) {
12734
12637
  var part = partList[partIndex];
12735
- this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
12638
+ this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
12736
12639
  this.nextLoadPosition = part.start + part.duration;
12737
12640
  this.state = State.FRAG_LOADING;
12738
12641
  var _result;
@@ -12765,7 +12668,7 @@
12765
12668
  }
12766
12669
  }
12767
12670
  }
12768
- this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
12671
+ this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
12769
12672
  // Don't update nextLoadPosition for fragments which are not buffered
12770
12673
  if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
12771
12674
  this.nextLoadPosition = frag.start + frag.duration;
@@ -13326,7 +13229,7 @@
13326
13229
  errorAction.resolved = true;
13327
13230
  }
13328
13231
  } else {
13329
- this.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
13232
+ logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
13330
13233
  return;
13331
13234
  }
13332
13235
  } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
@@ -13716,7 +13619,6 @@
13716
13619
  */
13717
13620
  function getAudioConfig(observer, data, offset, audioCodec) {
13718
13621
  var adtsObjectType;
13719
- var originalAdtsObjectType;
13720
13622
  var adtsExtensionSamplingIndex;
13721
13623
  var adtsChannelConfig;
13722
13624
  var config;
@@ -13724,7 +13626,7 @@
13724
13626
  var manifestCodec = audioCodec;
13725
13627
  var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
13726
13628
  // byte 2
13727
- adtsObjectType = originalAdtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
13629
+ adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
13728
13630
  var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
13729
13631
  if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
13730
13632
  var error = new Error("invalid ADTS sampling index:" + adtsSamplingIndex);
@@ -13741,8 +13643,8 @@
13741
13643
  // byte 3
13742
13644
  adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
13743
13645
  logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
13744
- // Firefox and Pale Moon: freq less than 24kHz = AAC SBR (HE-AAC)
13745
- if (/firefox|palemoon/i.test(userAgent)) {
13646
+ // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
13647
+ if (/firefox/i.test(userAgent)) {
13746
13648
  if (adtsSamplingIndex >= 6) {
13747
13649
  adtsObjectType = 5;
13748
13650
  config = new Array(4);
@@ -13836,7 +13738,6 @@
13836
13738
  samplerate: adtsSamplingRates[adtsSamplingIndex],
13837
13739
  channelCount: adtsChannelConfig,
13838
13740
  codec: 'mp4a.40.' + adtsObjectType,
13839
- parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
13840
13741
  manifestCodec: manifestCodec
13841
13742
  };
13842
13743
  }
@@ -13891,8 +13792,7 @@
13891
13792
  track.channelCount = config.channelCount;
13892
13793
  track.codec = config.codec;
13893
13794
  track.manifestCodec = config.manifestCodec;
13894
- track.parsedCodec = config.parsedCodec;
13895
- logger.log("parsed codec:" + track.parsedCodec + ", codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
13795
+ logger.log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
13896
13796
  }
13897
13797
  }
13898
13798
  function getFrameDuration(samplerate) {
@@ -14979,7 +14879,7 @@
14979
14879
  }
14980
14880
  var _proto = SampleAesDecrypter.prototype;
14981
14881
  _proto.decryptBuffer = function decryptBuffer(encryptedData) {
14982
- return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer, DecrypterAesMode.cbc);
14882
+ return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer);
14983
14883
  }
14984
14884
 
14985
14885
  // AAC - encrypt all full 16 bytes blocks starting from offset 16
@@ -17208,7 +17108,7 @@
17208
17108
  logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
17209
17109
  for (var j = 0; j < missing; j++) {
17210
17110
  var newStamp = Math.max(nextPts, 0);
17211
- var fillFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
17111
+ var fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
17212
17112
  if (!fillFrame) {
17213
17113
  logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
17214
17114
  fillFrame = sample.unit.subarray();
@@ -17336,7 +17236,7 @@
17336
17236
  // samples count of this segment's duration
17337
17237
  var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
17338
17238
  // silent frame
17339
- var silentFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
17239
+ var silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
17340
17240
  logger.warn('[mp4-remuxer]: remux empty Audio');
17341
17241
  // Can't remux if we can't generate a silent frame...
17342
17242
  if (!silentFrame) {
@@ -17723,15 +17623,13 @@
17723
17623
  duration = transmuxConfig.duration,
17724
17624
  initSegmentData = transmuxConfig.initSegmentData;
17725
17625
  var keyData = getEncryptionType(uintData, decryptdata);
17726
- if (keyData && isFullSegmentEncryption(keyData.method)) {
17626
+ if (keyData && keyData.method === 'AES-128') {
17727
17627
  var decrypter = this.getDecrypter();
17728
- var aesMode = getAesModeFromFullSegmentMethod(keyData.method);
17729
-
17730
17628
  // Software decryption is synchronous; webCrypto is not
17731
17629
  if (decrypter.isSync()) {
17732
17630
  // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
17733
17631
  // data is handled in the flush() call
17734
- var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode);
17632
+ var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
17735
17633
  // For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
17736
17634
  var loadingParts = chunkMeta.part > -1;
17737
17635
  if (loadingParts) {
@@ -17743,7 +17641,7 @@
17743
17641
  }
17744
17642
  uintData = new Uint8Array(decryptedData);
17745
17643
  } else {
17746
- this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode).then(function (decryptedData) {
17644
+ this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) {
17747
17645
  // Calling push here is important; if flush() is called while this is still resolving, this ensures that
17748
17646
  // the decrypted data has been transmuxed
17749
17647
  var result = _this.push(decryptedData, null, chunkMeta);
@@ -18364,7 +18262,7 @@
18364
18262
  observer.on(Events.ERROR, forwardMessage);
18365
18263
 
18366
18264
  // forward logger events to main thread
18367
- var forwardWorkerLogs = function forwardWorkerLogs(logger) {
18265
+ var forwardWorkerLogs = function forwardWorkerLogs() {
18368
18266
  var _loop = function _loop(logFn) {
18369
18267
  var func = function func(message) {
18370
18268
  forwardMessage('workerLog', {
@@ -18385,8 +18283,8 @@
18385
18283
  {
18386
18284
  var config = JSON.parse(data.config);
18387
18285
  self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor, data.id);
18388
- var logger = enableLogs(config.debug, data.id);
18389
- forwardWorkerLogs(logger);
18286
+ enableLogs(config.debug, data.id);
18287
+ forwardWorkerLogs();
18390
18288
  forwardMessage('init', null);
18391
18289
  break;
18392
18290
  }
@@ -18560,7 +18458,16 @@
18560
18458
  this.observer = new EventEmitter();
18561
18459
  this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
18562
18460
  this.observer.on(Events.ERROR, forwardMessage);
18563
- var m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
18461
+ var MediaSource = getMediaSource(config.preferManagedMediaSource) || {
18462
+ isTypeSupported: function isTypeSupported() {
18463
+ return false;
18464
+ }
18465
+ };
18466
+ var m2tsTypeSupported = {
18467
+ mpeg: MediaSource.isTypeSupported('audio/mpeg'),
18468
+ mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
18469
+ ac3: false
18470
+ };
18564
18471
 
18565
18472
  // navigator.vendor is not always available in Web Worker
18566
18473
  // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
@@ -18817,25 +18724,21 @@
18817
18724
  var MAX_START_GAP_JUMP = 2.0;
18818
18725
  var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
18819
18726
  var SKIP_BUFFER_RANGE_START = 0.05;
18820
- var GapController = /*#__PURE__*/function (_Logger) {
18821
- _inheritsLoose(GapController, _Logger);
18727
+ var GapController = /*#__PURE__*/function () {
18822
18728
  function GapController(config, media, fragmentTracker, hls) {
18823
- var _this;
18824
- _this = _Logger.call(this, 'gap-controller', hls.logger) || this;
18825
- _this.config = void 0;
18826
- _this.media = null;
18827
- _this.fragmentTracker = void 0;
18828
- _this.hls = void 0;
18829
- _this.nudgeRetry = 0;
18830
- _this.stallReported = false;
18831
- _this.stalled = null;
18832
- _this.moved = false;
18833
- _this.seeking = false;
18834
- _this.config = config;
18835
- _this.media = media;
18836
- _this.fragmentTracker = fragmentTracker;
18837
- _this.hls = hls;
18838
- return _this;
18729
+ this.config = void 0;
18730
+ this.media = null;
18731
+ this.fragmentTracker = void 0;
18732
+ this.hls = void 0;
18733
+ this.nudgeRetry = 0;
18734
+ this.stallReported = false;
18735
+ this.stalled = null;
18736
+ this.moved = false;
18737
+ this.seeking = false;
18738
+ this.config = config;
18739
+ this.media = media;
18740
+ this.fragmentTracker = fragmentTracker;
18741
+ this.hls = hls;
18839
18742
  }
18840
18743
  var _proto = GapController.prototype;
18841
18744
  _proto.destroy = function destroy() {
@@ -18873,7 +18776,7 @@
18873
18776
  // The playhead is now moving, but was previously stalled
18874
18777
  if (this.stallReported) {
18875
18778
  var _stalledDuration = self.performance.now() - stalled;
18876
- this.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
18779
+ logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
18877
18780
  this.stallReported = false;
18878
18781
  }
18879
18782
  this.stalled = null;
@@ -18982,7 +18885,7 @@
18982
18885
  // needs to cross some sort of threshold covering all source-buffers content
18983
18886
  // to start playing properly.
18984
18887
  if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
18985
- this.warn('Trying to nudge playhead over buffer-hole');
18888
+ logger.warn('Trying to nudge playhead over buffer-hole');
18986
18889
  // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
18987
18890
  // We only try to jump the hole if it's under the configured size
18988
18891
  // Reset stalled so to rearm watchdog timer
@@ -19004,7 +18907,7 @@
19004
18907
  // Report stalled error once
19005
18908
  this.stallReported = true;
19006
18909
  var error = new Error("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
19007
- this.warn(error.message);
18910
+ logger.warn(error.message);
19008
18911
  hls.trigger(Events.ERROR, {
19009
18912
  type: ErrorTypes.MEDIA_ERROR,
19010
18913
  details: ErrorDetails.BUFFER_STALLED_ERROR,
@@ -19068,7 +18971,7 @@
19068
18971
  }
19069
18972
  }
19070
18973
  var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
19071
- this.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
18974
+ logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
19072
18975
  this.moved = true;
19073
18976
  this.stalled = null;
19074
18977
  media.currentTime = targetTime;
@@ -19107,7 +19010,7 @@
19107
19010
  var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
19108
19011
  // playback stalled in buffered area ... let's nudge currentTime to try to overcome this
19109
19012
  var error = new Error("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
19110
- this.warn(error.message);
19013
+ logger.warn(error.message);
19111
19014
  media.currentTime = targetTime;
19112
19015
  hls.trigger(Events.ERROR, {
19113
19016
  type: ErrorTypes.MEDIA_ERROR,
@@ -19117,7 +19020,7 @@
19117
19020
  });
19118
19021
  } else {
19119
19022
  var _error = new Error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
19120
- this.error(_error.message);
19023
+ logger.error(_error.message);
19121
19024
  hls.trigger(Events.ERROR, {
19122
19025
  type: ErrorTypes.MEDIA_ERROR,
19123
19026
  details: ErrorDetails.BUFFER_STALLED_ERROR,
@@ -19127,14 +19030,14 @@
19127
19030
  }
19128
19031
  };
19129
19032
  return GapController;
19130
- }(Logger);
19033
+ }();
19131
19034
 
19132
19035
  var TICK_INTERVAL = 100; // how often to tick in ms
19133
19036
  var StreamController = /*#__PURE__*/function (_BaseStreamController) {
19134
19037
  _inheritsLoose(StreamController, _BaseStreamController);
19135
19038
  function StreamController(hls, fragmentTracker, keyLoader) {
19136
19039
  var _this;
19137
- _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'stream-controller', PlaylistLevelType.MAIN) || this;
19040
+ _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[stream-controller]', PlaylistLevelType.MAIN) || this;
19138
19041
  _this.audioCodecSwap = false;
19139
19042
  _this.gapController = null;
19140
19043
  _this.level = -1;
@@ -19142,43 +19045,27 @@
19142
19045
  _this.altAudio = false;
19143
19046
  _this.audioOnly = false;
19144
19047
  _this.fragPlaying = null;
19048
+ _this.onvplaying = null;
19049
+ _this.onvseeked = null;
19145
19050
  _this.fragLastKbps = 0;
19146
19051
  _this.couldBacktrack = false;
19147
19052
  _this.backtrackFragment = null;
19148
19053
  _this.audioCodecSwitch = false;
19149
19054
  _this.videoBuffer = null;
19150
- _this.onMediaPlaying = function () {
19151
- // tick to speed up FRAG_CHANGED triggering
19152
- _this.tick();
19153
- };
19154
- _this.onMediaSeeked = function () {
19155
- var media = _this.media;
19156
- var currentTime = media ? media.currentTime : null;
19157
- if (isFiniteNumber(currentTime)) {
19158
- _this.log("Media seeked to " + currentTime.toFixed(3));
19159
- }
19160
-
19161
- // If seeked was issued before buffer was appended do not tick immediately
19162
- var bufferInfo = _this.getMainFwdBufferInfo();
19163
- if (bufferInfo === null || bufferInfo.len === 0) {
19164
- _this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
19165
- return;
19166
- }
19167
-
19168
- // tick to speed up FRAG_CHANGED triggering
19169
- _this.tick();
19170
- };
19171
- _this.registerListeners();
19055
+ _this._registerListeners();
19172
19056
  return _this;
19173
19057
  }
19174
19058
  var _proto = StreamController.prototype;
19175
- _proto.registerListeners = function registerListeners() {
19176
- _BaseStreamController.prototype.registerListeners.call(this);
19059
+ _proto._registerListeners = function _registerListeners() {
19177
19060
  var hls = this.hls;
19061
+ hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
19062
+ hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
19063
+ hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
19178
19064
  hls.on(Events.MANIFEST_PARSED, this.onManifestParsed, this);
19179
19065
  hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
19180
19066
  hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
19181
19067
  hls.on(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
19068
+ hls.on(Events.ERROR, this.onError, this);
19182
19069
  hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
19183
19070
  hls.on(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
19184
19071
  hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
@@ -19186,12 +19073,15 @@
19186
19073
  hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
19187
19074
  hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
19188
19075
  };
19189
- _proto.unregisterListeners = function unregisterListeners() {
19190
- _BaseStreamController.prototype.unregisterListeners.call(this);
19076
+ _proto._unregisterListeners = function _unregisterListeners() {
19191
19077
  var hls = this.hls;
19078
+ hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
19079
+ hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
19080
+ hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
19192
19081
  hls.off(Events.MANIFEST_PARSED, this.onManifestParsed, this);
19193
19082
  hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
19194
19083
  hls.off(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
19084
+ hls.off(Events.ERROR, this.onError, this);
19195
19085
  hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
19196
19086
  hls.off(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
19197
19087
  hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
@@ -19200,9 +19090,7 @@
19200
19090
  hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
19201
19091
  };
19202
19092
  _proto.onHandlerDestroying = function onHandlerDestroying() {
19203
- // @ts-ignore
19204
- this.onMediaPlaying = this.onMediaSeeked = null;
19205
- this.unregisterListeners();
19093
+ this._unregisterListeners();
19206
19094
  _BaseStreamController.prototype.onHandlerDestroying.call(this);
19207
19095
  };
19208
19096
  _proto.startLoad = function startLoad(startPosition) {
@@ -19517,15 +19405,18 @@
19517
19405
  _proto.onMediaAttached = function onMediaAttached(event, data) {
19518
19406
  _BaseStreamController.prototype.onMediaAttached.call(this, event, data);
19519
19407
  var media = data.media;
19520
- media.addEventListener('playing', this.onMediaPlaying);
19521
- media.addEventListener('seeked', this.onMediaSeeked);
19408
+ this.onvplaying = this.onMediaPlaying.bind(this);
19409
+ this.onvseeked = this.onMediaSeeked.bind(this);
19410
+ media.addEventListener('playing', this.onvplaying);
19411
+ media.addEventListener('seeked', this.onvseeked);
19522
19412
  this.gapController = new GapController(this.config, media, this.fragmentTracker, this.hls);
19523
19413
  };
19524
19414
  _proto.onMediaDetaching = function onMediaDetaching() {
19525
19415
  var media = this.media;
19526
- if (media) {
19527
- media.removeEventListener('playing', this.onMediaPlaying);
19528
- media.removeEventListener('seeked', this.onMediaSeeked);
19416
+ if (media && this.onvplaying && this.onvseeked) {
19417
+ media.removeEventListener('playing', this.onvplaying);
19418
+ media.removeEventListener('seeked', this.onvseeked);
19419
+ this.onvplaying = this.onvseeked = null;
19529
19420
  this.videoBuffer = null;
19530
19421
  }
19531
19422
  this.fragPlaying = null;
@@ -19535,6 +19426,27 @@
19535
19426
  }
19536
19427
  _BaseStreamController.prototype.onMediaDetaching.call(this);
19537
19428
  };
19429
+ _proto.onMediaPlaying = function onMediaPlaying() {
19430
+ // tick to speed up FRAG_CHANGED triggering
19431
+ this.tick();
19432
+ };
19433
+ _proto.onMediaSeeked = function onMediaSeeked() {
19434
+ var media = this.media;
19435
+ var currentTime = media ? media.currentTime : null;
19436
+ if (isFiniteNumber(currentTime)) {
19437
+ this.log("Media seeked to " + currentTime.toFixed(3));
19438
+ }
19439
+
19440
+ // If seeked was issued before buffer was appended do not tick immediately
19441
+ var bufferInfo = this.getMainFwdBufferInfo();
19442
+ if (bufferInfo === null || bufferInfo.len === 0) {
19443
+ this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
19444
+ return;
19445
+ }
19446
+
19447
+ // tick to speed up FRAG_CHANGED triggering
19448
+ this.tick();
19449
+ };
19538
19450
  _proto.onManifestLoading = function onManifestLoading() {
19539
19451
  // reset buffer on manifest loading
19540
19452
  this.log('Trigger BUFFER_RESET');
@@ -20281,10 +20193,6 @@
20281
20193
  * The configuration object provided on player instantiation.
20282
20194
  */
20283
20195
  this.userConfig = void 0;
20284
- /**
20285
- * The logger functions used by this player instance, configured on player instantiation.
20286
- */
20287
- this.logger = void 0;
20288
20196
  this.coreComponents = void 0;
20289
20197
  this.networkControllers = void 0;
20290
20198
  this.started = false;
@@ -20304,11 +20212,11 @@
20304
20212
  this._media = null;
20305
20213
  this.url = null;
20306
20214
  this.triggeringException = void 0;
20307
- var logger = this.logger = enableLogs(userConfig.debug || false, 'Hls instance');
20308
- var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig, logger);
20215
+ enableLogs(userConfig.debug || false, 'Hls instance');
20216
+ var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig);
20309
20217
  this.userConfig = userConfig;
20310
20218
  if (config.progressive) {
20311
- enableStreamingMode(config, logger);
20219
+ enableStreamingMode(config);
20312
20220
  }
20313
20221
 
20314
20222
  // core controllers and network loaders
@@ -20416,7 +20324,7 @@
20416
20324
  try {
20417
20325
  return this.emit(event, event, eventObject);
20418
20326
  } catch (error) {
20419
- this.logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
20327
+ logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
20420
20328
  // Prevent recursion in error event handlers that throw #5497
20421
20329
  if (!this.triggeringException) {
20422
20330
  this.triggeringException = true;
@@ -20442,7 +20350,7 @@
20442
20350
  * Dispose of the instance
20443
20351
  */;
20444
20352
  _proto.destroy = function destroy() {
20445
- this.logger.log('destroy');
20353
+ logger.log('destroy');
20446
20354
  this.trigger(Events.DESTROYING, undefined);
20447
20355
  this.detachMedia();
20448
20356
  this.removeAllListeners();
@@ -20467,7 +20375,7 @@
20467
20375
  * Attaches Hls.js to a media element
20468
20376
  */;
20469
20377
  _proto.attachMedia = function attachMedia(media) {
20470
- this.logger.log('attachMedia');
20378
+ logger.log('attachMedia');
20471
20379
  this._media = media;
20472
20380
  this.trigger(Events.MEDIA_ATTACHING, {
20473
20381
  media: media
@@ -20478,7 +20386,7 @@
20478
20386
  * Detach Hls.js from the media
20479
20387
  */;
20480
20388
  _proto.detachMedia = function detachMedia() {
20481
- this.logger.log('detachMedia');
20389
+ logger.log('detachMedia');
20482
20390
  this.trigger(Events.MEDIA_DETACHING, undefined);
20483
20391
  this._media = null;
20484
20392
  }
@@ -20495,7 +20403,7 @@
20495
20403
  });
20496
20404
  this._autoLevelCapping = -1;
20497
20405
  this._maxHdcpLevel = null;
20498
- this.logger.log("loadSource:" + loadingSource);
20406
+ logger.log("loadSource:" + loadingSource);
20499
20407
  if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
20500
20408
  this.detachMedia();
20501
20409
  this.attachMedia(media);
@@ -20517,7 +20425,7 @@
20517
20425
  if (startPosition === void 0) {
20518
20426
  startPosition = -1;
20519
20427
  }
20520
- this.logger.log("startLoad(" + startPosition + ")");
20428
+ logger.log("startLoad(" + startPosition + ")");
20521
20429
  this.started = true;
20522
20430
  this.networkControllers.forEach(function (controller) {
20523
20431
  controller.startLoad(startPosition);
@@ -20528,7 +20436,7 @@
20528
20436
  * Stop loading of any stream data.
20529
20437
  */;
20530
20438
  _proto.stopLoad = function stopLoad() {
20531
- this.logger.log('stopLoad');
20439
+ logger.log('stopLoad');
20532
20440
  this.started = false;
20533
20441
  this.networkControllers.forEach(function (controller) {
20534
20442
  controller.stopLoad();
@@ -20564,7 +20472,7 @@
20564
20472
  * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
20565
20473
  */;
20566
20474
  _proto.swapAudioCodec = function swapAudioCodec() {
20567
- this.logger.log('swapAudioCodec');
20475
+ logger.log('swapAudioCodec');
20568
20476
  this.streamController.swapAudioCodec();
20569
20477
  }
20570
20478
 
@@ -20575,7 +20483,7 @@
20575
20483
  * Automatic recovery of media-errors by this process is configurable.
20576
20484
  */;
20577
20485
  _proto.recoverMediaError = function recoverMediaError() {
20578
- this.logger.log('recoverMediaError');
20486
+ logger.log('recoverMediaError');
20579
20487
  var media = this._media;
20580
20488
  this.detachMedia();
20581
20489
  if (media) {
@@ -20630,7 +20538,7 @@
20630
20538
  * Set quality level index immediately. This will flush the current buffer to replace the quality asap. That means playback will interrupt at least shortly to re-buffer and re-sync eventually. Set to -1 for automatic level selection.
20631
20539
  */,
20632
20540
  set: function set(newLevel) {
20633
- this.logger.log("set currentLevel:" + newLevel);
20541
+ logger.log("set currentLevel:" + newLevel);
20634
20542
  this.levelController.manualLevel = newLevel;
20635
20543
  this.streamController.immediateLevelSwitch();
20636
20544
  }
@@ -20651,7 +20559,7 @@
20651
20559
  * @param newLevel - Pass -1 for automatic level selection
20652
20560
  */,
20653
20561
  set: function set(newLevel) {
20654
- this.logger.log("set nextLevel:" + newLevel);
20562
+ logger.log("set nextLevel:" + newLevel);
20655
20563
  this.levelController.manualLevel = newLevel;
20656
20564
  this.streamController.nextLevelSwitch();
20657
20565
  }
@@ -20672,7 +20580,7 @@
20672
20580
  * @param newLevel - Pass -1 for automatic level selection
20673
20581
  */,
20674
20582
  set: function set(newLevel) {
20675
- this.logger.log("set loadLevel:" + newLevel);
20583
+ logger.log("set loadLevel:" + newLevel);
20676
20584
  this.levelController.manualLevel = newLevel;
20677
20585
  }
20678
20586
 
@@ -20707,7 +20615,7 @@
20707
20615
  * Sets "first-level", see getter.
20708
20616
  */,
20709
20617
  set: function set(newLevel) {
20710
- this.logger.log("set firstLevel:" + newLevel);
20618
+ logger.log("set firstLevel:" + newLevel);
20711
20619
  this.levelController.firstLevel = newLevel;
20712
20620
  }
20713
20621
 
@@ -20734,7 +20642,7 @@
20734
20642
  * (determined from download of first segment)
20735
20643
  */,
20736
20644
  set: function set(newLevel) {
20737
- this.logger.log("set startLevel:" + newLevel);
20645
+ logger.log("set startLevel:" + newLevel);
20738
20646
  // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
20739
20647
  if (newLevel !== -1) {
20740
20648
  newLevel = Math.max(newLevel, this.minAutoLevel);
@@ -20787,7 +20695,7 @@
20787
20695
  */
20788
20696
  function set(newLevel) {
20789
20697
  if (this._autoLevelCapping !== newLevel) {
20790
- this.logger.log("set autoLevelCapping:" + newLevel);
20698
+ logger.log("set autoLevelCapping:" + newLevel);
20791
20699
  this._autoLevelCapping = newLevel;
20792
20700
  this.levelController.checkMaxAutoUpdated();
20793
20701
  }
@@ -21112,7 +21020,7 @@
21112
21020
  * Get the video-dev/hls.js package version.
21113
21021
  */
21114
21022
  function get() {
21115
- return "1.5.2-0.canary.9924";
21023
+ return "1.5.2";
21116
21024
  }
21117
21025
  }, {
21118
21026
  key: "Events",