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.js CHANGED
@@ -507,21 +507,6 @@
507
507
  return ErrorDetails;
508
508
  }({});
509
509
 
510
- var Logger = function Logger(label, logger) {
511
- this.trace = void 0;
512
- this.debug = void 0;
513
- this.log = void 0;
514
- this.warn = void 0;
515
- this.info = void 0;
516
- this.error = void 0;
517
- var lb = "[" + label + "]:";
518
- this.trace = noop;
519
- this.debug = logger.debug.bind(null, lb);
520
- this.log = logger.log.bind(null, lb);
521
- this.warn = logger.warn.bind(null, lb);
522
- this.info = logger.info.bind(null, lb);
523
- this.error = logger.error.bind(null, lb);
524
- };
525
510
  var noop = function noop() {};
526
511
  var fakeLogger = {
527
512
  trace: noop,
@@ -531,9 +516,7 @@
531
516
  info: noop,
532
517
  error: noop
533
518
  };
534
- function createLogger() {
535
- return _extends({}, fakeLogger);
536
- }
519
+ var exportedLogger = fakeLogger;
537
520
 
538
521
  // let lastCallTime;
539
522
  // function formatMsgWithTimeInfo(type, msg) {
@@ -544,36 +527,38 @@
544
527
  // return msg;
545
528
  // }
546
529
 
547
- function consolePrintFn(type, id) {
530
+ function consolePrintFn(type) {
548
531
  var func = self.console[type];
549
- return func ? func.bind(self.console, (id ? '[' + id + '] ' : '') + "[" + type + "] >") : noop;
532
+ if (func) {
533
+ return func.bind(self.console, "[" + type + "] >");
534
+ }
535
+ return noop;
550
536
  }
551
- function getLoggerFn(key, debugConfig, id) {
552
- return debugConfig[key] ? debugConfig[key].bind(debugConfig) : consolePrintFn(key, id);
537
+ function exportLoggerFunctions(debugConfig) {
538
+ for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
539
+ functions[_key - 1] = arguments[_key];
540
+ }
541
+ functions.forEach(function (type) {
542
+ exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
543
+ });
553
544
  }
554
- var exportedLogger = createLogger();
555
- function enableLogs(debugConfig, context, id) {
545
+ function enableLogs(debugConfig, id) {
556
546
  // check that console is available
557
- var newLogger = createLogger();
558
547
  if (typeof console === 'object' && debugConfig === true || typeof debugConfig === 'object') {
559
- var keys = [
548
+ exportLoggerFunctions(debugConfig,
560
549
  // Remove out from list here to hard-disable a log-level
561
550
  // 'trace',
562
- 'debug', 'log', 'info', 'warn', 'error'];
563
- keys.forEach(function (key) {
564
- newLogger[key] = getLoggerFn(key, debugConfig, id);
565
- });
551
+ 'debug', 'log', 'info', 'warn', 'error');
566
552
  // Some browsers don't allow to use bind on console object anyway
567
553
  // fallback to default if needed
568
554
  try {
569
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9924");
555
+ exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.2");
570
556
  } catch (e) {
571
- /* log fn threw an exception. All logger methods are no-ops. */
572
- return createLogger();
557
+ exportedLogger = fakeLogger;
573
558
  }
559
+ } else {
560
+ exportedLogger = fakeLogger;
574
561
  }
575
- exportedLogger = newLogger;
576
- return newLogger;
577
562
  }
578
563
  var logger = exportedLogger;
579
564
 
@@ -1268,26 +1253,6 @@
1268
1253
  });
1269
1254
  }
1270
1255
 
1271
- var DecrypterAesMode = {
1272
- cbc: 0,
1273
- ctr: 1
1274
- };
1275
-
1276
- function isFullSegmentEncryption(method) {
1277
- return method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR';
1278
- }
1279
- function getAesModeFromFullSegmentMethod(method) {
1280
- switch (method) {
1281
- case 'AES-128':
1282
- case 'AES-256':
1283
- return DecrypterAesMode.cbc;
1284
- case 'AES-256-CTR':
1285
- return DecrypterAesMode.ctr;
1286
- default:
1287
- throw new Error("invalid full segment method " + method);
1288
- }
1289
- }
1290
-
1291
1256
  /** returns `undefined` is `self` is missing, e.g. in node */
1292
1257
  var optionalSelf = typeof self !== 'undefined' ? self : undefined;
1293
1258
 
@@ -2946,13 +2911,13 @@
2946
2911
  this.keyFormatVersions = formatversions;
2947
2912
  this.iv = iv;
2948
2913
  this.encrypted = method ? method !== 'NONE' : false;
2949
- this.isCommonEncryption = this.encrypted && !isFullSegmentEncryption(method);
2914
+ this.isCommonEncryption = this.encrypted && method !== 'AES-128';
2950
2915
  }
2951
2916
  var _proto = LevelKey.prototype;
2952
2917
  _proto.isSupported = function isSupported() {
2953
2918
  // If it's Segment encryption or No encryption, just select that key system
2954
2919
  if (this.method) {
2955
- if (isFullSegmentEncryption(this.method) || this.method === 'NONE') {
2920
+ if (this.method === 'AES-128' || this.method === 'NONE') {
2956
2921
  return true;
2957
2922
  }
2958
2923
  if (this.keyFormat === 'identity') {
@@ -2974,13 +2939,14 @@
2974
2939
  if (!this.encrypted || !this.uri) {
2975
2940
  return null;
2976
2941
  }
2977
- if (isFullSegmentEncryption(this.method) && this.uri && !this.iv) {
2942
+ if (this.method === 'AES-128' && this.uri && !this.iv) {
2978
2943
  if (typeof sn !== 'number') {
2979
2944
  // We are fetching decryption data for a initialization segment
2980
- // If the segment was encrypted with AES-128/256
2945
+ // If the segment was encrypted with AES-128
2981
2946
  // It must have an IV defined. We cannot substitute the Segment Number in.
2982
- logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
2983
-
2947
+ if (this.method === 'AES-128' && !this.iv) {
2948
+ logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
2949
+ }
2984
2950
  // Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
2985
2951
  sn = 0;
2986
2952
  }
@@ -3274,28 +3240,23 @@
3274
3240
  if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
3275
3241
  return CODEC_COMPATIBLE_NAMES[lowerCaseCodec];
3276
3242
  }
3243
+
3244
+ // Idealy fLaC and Opus would be first (spec-compliant) but
3245
+ // some browsers will report that fLaC is supported then fail.
3246
+ // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
3277
3247
  var codecsToCheck = {
3278
- // Idealy fLaC and Opus would be first (spec-compliant) but
3279
- // some browsers will report that fLaC is supported then fail.
3280
- // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
3281
3248
  flac: ['flac', 'fLaC', 'FLAC'],
3282
- opus: ['opus', 'Opus'],
3283
- // Replace audio codec info if browser does not support mp4a.40.34,
3284
- // and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs="mp3"'
3285
- 'mp4a.40.34': ['mp3']
3249
+ opus: ['opus', 'Opus']
3286
3250
  }[lowerCaseCodec];
3287
3251
  for (var i = 0; i < codecsToCheck.length; i++) {
3288
- var _getMediaSource;
3289
3252
  if (isCodecMediaSourceSupported(codecsToCheck[i], 'audio', preferManagedMediaSource)) {
3290
3253
  CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];
3291
3254
  return codecsToCheck[i];
3292
- } else if (codecsToCheck[i] === 'mp3' && (_getMediaSource = getMediaSource(preferManagedMediaSource)) != null && _getMediaSource.isTypeSupported('audio/mpeg')) {
3293
- return '';
3294
3255
  }
3295
3256
  }
3296
3257
  return lowerCaseCodec;
3297
3258
  }
3298
- var AUDIO_CODEC_REGEXP = /flac|opus|mp4a\.40\.34/i;
3259
+ var AUDIO_CODEC_REGEXP = /flac|opus/i;
3299
3260
  function getCodecCompatibleName(codec, preferManagedMediaSource) {
3300
3261
  if (preferManagedMediaSource === void 0) {
3301
3262
  preferManagedMediaSource = true;
@@ -3323,18 +3284,6 @@
3323
3284
  }
3324
3285
  return codec;
3325
3286
  }
3326
- function getM2TSSupportedAudioTypes(preferManagedMediaSource) {
3327
- var MediaSource = getMediaSource(preferManagedMediaSource) || {
3328
- isTypeSupported: function isTypeSupported() {
3329
- return false;
3330
- }
3331
- };
3332
- return {
3333
- mpeg: MediaSource.isTypeSupported('audio/mpeg'),
3334
- mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
3335
- ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"')
3336
- };
3337
- }
3338
3287
 
3339
3288
  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;
3340
3289
  var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
@@ -4998,43 +4947,8 @@
4998
4947
  this.currentTime = 0;
4999
4948
  this.stallCount = 0;
5000
4949
  this._latency = null;
5001
- this.onTimeupdate = function () {
5002
- var media = _this.media,
5003
- levelDetails = _this.levelDetails;
5004
- if (!media || !levelDetails) {
5005
- return;
5006
- }
5007
- _this.currentTime = media.currentTime;
5008
- var latency = _this.computeLatency();
5009
- if (latency === null) {
5010
- return;
5011
- }
5012
- _this._latency = latency;
5013
-
5014
- // Adapt playbackRate to meet target latency in low-latency mode
5015
- var _this$config = _this.config,
5016
- lowLatencyMode = _this$config.lowLatencyMode,
5017
- maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
5018
- if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
5019
- return;
5020
- }
5021
- var targetLatency = _this.targetLatency;
5022
- if (targetLatency === null) {
5023
- return;
5024
- }
5025
- var distanceFromTarget = latency - targetLatency;
5026
- // Only adjust playbackRate when within one target duration of targetLatency
5027
- // and more than one second from under-buffering.
5028
- // Playback further than one target duration from target can be considered DVR playback.
5029
- var liveMinLatencyDuration = Math.min(_this.maxLatency, targetLatency + levelDetails.targetduration);
5030
- var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
5031
- if (inLiveRange && distanceFromTarget > 0.05 && _this.forwardBufferLength > 1) {
5032
- var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
5033
- var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - _this.edgeStalled)) * 20) / 20;
5034
- media.playbackRate = Math.min(max, Math.max(1, rate));
5035
- } else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
5036
- media.playbackRate = 1;
5037
- }
4950
+ this.timeupdateHandler = function () {
4951
+ return _this.timeupdate();
5038
4952
  };
5039
4953
  this.hls = hls;
5040
4954
  this.config = hls.config;
@@ -5046,7 +4960,7 @@
5046
4960
  this.onMediaDetaching();
5047
4961
  this.levelDetails = null;
5048
4962
  // @ts-ignore
5049
- this.hls = null;
4963
+ this.hls = this.timeupdateHandler = null;
5050
4964
  };
5051
4965
  _proto.registerListeners = function registerListeners() {
5052
4966
  this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
@@ -5064,11 +4978,11 @@
5064
4978
  };
5065
4979
  _proto.onMediaAttached = function onMediaAttached(event, data) {
5066
4980
  this.media = data.media;
5067
- this.media.addEventListener('timeupdate', this.onTimeupdate);
4981
+ this.media.addEventListener('timeupdate', this.timeupdateHandler);
5068
4982
  };
5069
4983
  _proto.onMediaDetaching = function onMediaDetaching() {
5070
4984
  if (this.media) {
5071
- this.media.removeEventListener('timeupdate', this.onTimeupdate);
4985
+ this.media.removeEventListener('timeupdate', this.timeupdateHandler);
5072
4986
  this.media = null;
5073
4987
  }
5074
4988
  };
@@ -5081,10 +4995,10 @@
5081
4995
  var details = _ref.details;
5082
4996
  this.levelDetails = details;
5083
4997
  if (details.advanced) {
5084
- this.onTimeupdate();
4998
+ this.timeupdate();
5085
4999
  }
5086
5000
  if (!details.live && this.media) {
5087
- this.media.removeEventListener('timeupdate', this.onTimeupdate);
5001
+ this.media.removeEventListener('timeupdate', this.timeupdateHandler);
5088
5002
  }
5089
5003
  };
5090
5004
  _proto.onError = function onError(event, data) {
@@ -5094,7 +5008,45 @@
5094
5008
  }
5095
5009
  this.stallCount++;
5096
5010
  if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
5097
- this.hls.logger.warn('[latency-controller]: Stall detected, adjusting target latency');
5011
+ logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
5012
+ }
5013
+ };
5014
+ _proto.timeupdate = function timeupdate() {
5015
+ var media = this.media,
5016
+ levelDetails = this.levelDetails;
5017
+ if (!media || !levelDetails) {
5018
+ return;
5019
+ }
5020
+ this.currentTime = media.currentTime;
5021
+ var latency = this.computeLatency();
5022
+ if (latency === null) {
5023
+ return;
5024
+ }
5025
+ this._latency = latency;
5026
+
5027
+ // Adapt playbackRate to meet target latency in low-latency mode
5028
+ var _this$config = this.config,
5029
+ lowLatencyMode = _this$config.lowLatencyMode,
5030
+ maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
5031
+ if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
5032
+ return;
5033
+ }
5034
+ var targetLatency = this.targetLatency;
5035
+ if (targetLatency === null) {
5036
+ return;
5037
+ }
5038
+ var distanceFromTarget = latency - targetLatency;
5039
+ // Only adjust playbackRate when within one target duration of targetLatency
5040
+ // and more than one second from under-buffering.
5041
+ // Playback further than one target duration from target can be considered DVR playback.
5042
+ var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration);
5043
+ var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
5044
+ if (inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) {
5045
+ var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
5046
+ var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20;
5047
+ media.playbackRate = Math.min(max, Math.max(1, rate));
5048
+ } else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
5049
+ media.playbackRate = 1;
5098
5050
  }
5099
5051
  };
5100
5052
  _proto.estimateLiveEdge = function estimateLiveEdge() {
@@ -6002,17 +5954,19 @@
6002
5954
  MoveAllAlternatesMatchingHDCP: 2,
6003
5955
  SwitchToSDR: 4
6004
5956
  }; // Reserved for future use
6005
- var ErrorController = /*#__PURE__*/function (_Logger) {
6006
- _inheritsLoose(ErrorController, _Logger);
5957
+ var ErrorController = /*#__PURE__*/function () {
6007
5958
  function ErrorController(hls) {
6008
- var _this;
6009
- _this = _Logger.call(this, 'error-controller', hls.logger) || this;
6010
- _this.hls = void 0;
6011
- _this.playlistError = 0;
6012
- _this.penalizedRenditions = {};
6013
- _this.hls = hls;
6014
- _this.registerListeners();
6015
- return _this;
5959
+ this.hls = void 0;
5960
+ this.playlistError = 0;
5961
+ this.penalizedRenditions = {};
5962
+ this.log = void 0;
5963
+ this.warn = void 0;
5964
+ this.error = void 0;
5965
+ this.hls = hls;
5966
+ this.log = logger.log.bind(logger, "[info]:");
5967
+ this.warn = logger.warn.bind(logger, "[warning]:");
5968
+ this.error = logger.error.bind(logger, "[error]:");
5969
+ this.registerListeners();
6016
5970
  }
6017
5971
  var _proto = ErrorController.prototype;
6018
5972
  _proto.registerListeners = function registerListeners() {
@@ -6368,19 +6322,19 @@
6368
6322
  }
6369
6323
  };
6370
6324
  return ErrorController;
6371
- }(Logger);
6325
+ }();
6372
6326
 
6373
- var BasePlaylistController = /*#__PURE__*/function (_Logger) {
6374
- _inheritsLoose(BasePlaylistController, _Logger);
6327
+ var BasePlaylistController = /*#__PURE__*/function () {
6375
6328
  function BasePlaylistController(hls, logPrefix) {
6376
- var _this;
6377
- _this = _Logger.call(this, logPrefix, hls.logger) || this;
6378
- _this.hls = void 0;
6379
- _this.timer = -1;
6380
- _this.requestScheduled = -1;
6381
- _this.canLoad = false;
6382
- _this.hls = hls;
6383
- return _this;
6329
+ this.hls = void 0;
6330
+ this.timer = -1;
6331
+ this.requestScheduled = -1;
6332
+ this.canLoad = false;
6333
+ this.log = void 0;
6334
+ this.warn = void 0;
6335
+ this.log = logger.log.bind(logger, logPrefix + ":");
6336
+ this.warn = logger.warn.bind(logger, logPrefix + ":");
6337
+ this.hls = hls;
6384
6338
  }
6385
6339
  var _proto = BasePlaylistController.prototype;
6386
6340
  _proto.destroy = function destroy() {
@@ -6413,7 +6367,7 @@
6413
6367
  try {
6414
6368
  uri = new self.URL(attr.URI, previous.url).href;
6415
6369
  } catch (error) {
6416
- this.warn("Could not construct new URL for Rendition Report: " + error);
6370
+ logger.warn("Could not construct new URL for Rendition Report: " + error);
6417
6371
  uri = attr.URI || '';
6418
6372
  }
6419
6373
  // Use exact match. Otherwise, the last partial match, if any, will be used
@@ -6452,7 +6406,7 @@
6452
6406
  return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
6453
6407
  };
6454
6408
  _proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
6455
- var _this2 = this;
6409
+ var _this = this;
6456
6410
  var details = data.details,
6457
6411
  stats = data.stats;
6458
6412
 
@@ -6557,7 +6511,7 @@
6557
6511
  // );
6558
6512
 
6559
6513
  this.timer = self.setTimeout(function () {
6560
- return _this2.loadPlaylist(deliveryDirectives);
6514
+ return _this.loadPlaylist(deliveryDirectives);
6561
6515
  }, estimatedTimeUntilUpdate);
6562
6516
  } else {
6563
6517
  this.clearTimer();
@@ -6573,7 +6527,7 @@
6573
6527
  return new HlsUrlParameters(msn, part, skip);
6574
6528
  };
6575
6529
  _proto.checkRetry = function checkRetry(errorEvent) {
6576
- var _this3 = this;
6530
+ var _this2 = this;
6577
6531
  var errorDetails = errorEvent.details;
6578
6532
  var isTimeout = isTimeoutError(errorEvent);
6579
6533
  var errorAction = errorEvent.errorAction;
@@ -6597,7 +6551,7 @@
6597
6551
  var delay = getRetryDelay(retryConfig, retryCount);
6598
6552
  // Schedule level/track reload
6599
6553
  this.timer = self.setTimeout(function () {
6600
- return _this3.loadPlaylist();
6554
+ return _this2.loadPlaylist();
6601
6555
  }, delay);
6602
6556
  this.warn("Retrying playlist loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " after \"" + errorDetails + "\" in " + delay + "ms");
6603
6557
  }
@@ -6608,7 +6562,7 @@
6608
6562
  return retry;
6609
6563
  };
6610
6564
  return BasePlaylistController;
6611
- }(Logger);
6565
+ }();
6612
6566
 
6613
6567
  /*
6614
6568
  * compute an Exponential Weighted moving average
@@ -7210,33 +7164,30 @@
7210
7164
  return -1;
7211
7165
  }
7212
7166
 
7213
- var AbrController = /*#__PURE__*/function (_Logger) {
7214
- _inheritsLoose(AbrController, _Logger);
7167
+ var AbrController = /*#__PURE__*/function () {
7215
7168
  function AbrController(_hls) {
7216
- var _this;
7217
- _this = _Logger.call(this, 'abr', _hls.logger) || this;
7218
- _this.hls = void 0;
7219
- _this.lastLevelLoadSec = 0;
7220
- _this.lastLoadedFragLevel = -1;
7221
- _this.firstSelection = -1;
7222
- _this._nextAutoLevel = -1;
7223
- _this.nextAutoLevelKey = '';
7224
- _this.audioTracksByGroup = null;
7225
- _this.codecTiers = null;
7226
- _this.timer = -1;
7227
- _this.fragCurrent = null;
7228
- _this.partCurrent = null;
7229
- _this.bitrateTestDelay = 0;
7230
- _this.bwEstimator = void 0;
7169
+ var _this = this;
7170
+ this.hls = void 0;
7171
+ this.lastLevelLoadSec = 0;
7172
+ this.lastLoadedFragLevel = -1;
7173
+ this.firstSelection = -1;
7174
+ this._nextAutoLevel = -1;
7175
+ this.nextAutoLevelKey = '';
7176
+ this.audioTracksByGroup = null;
7177
+ this.codecTiers = null;
7178
+ this.timer = -1;
7179
+ this.fragCurrent = null;
7180
+ this.partCurrent = null;
7181
+ this.bitrateTestDelay = 0;
7182
+ this.bwEstimator = void 0;
7231
7183
  /*
7232
7184
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
7233
7185
  quickly enough to prevent underbuffering
7234
7186
  */
7235
- _this._abandonRulesCheck = function () {
7236
- var _assertThisInitialize = _assertThisInitialized(_this),
7237
- frag = _assertThisInitialize.fragCurrent,
7238
- part = _assertThisInitialize.partCurrent,
7239
- hls = _assertThisInitialize.hls;
7187
+ this._abandonRulesCheck = function () {
7188
+ var frag = _this.fragCurrent,
7189
+ part = _this.partCurrent,
7190
+ hls = _this.hls;
7240
7191
  var autoLevelEnabled = hls.autoLevelEnabled,
7241
7192
  media = hls.media;
7242
7193
  if (!frag || !media) {
@@ -7277,7 +7228,7 @@
7277
7228
  var bwEstimate = _this.getBwEstimate();
7278
7229
  var levels = hls.levels;
7279
7230
  var level = levels[frag.level];
7280
- var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.maxBitrate / 8));
7231
+ var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.averageBitrate / 8));
7281
7232
  var timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
7282
7233
  if (timeStreaming < 1 && loadedFirstByte) {
7283
7234
  timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
@@ -7320,27 +7271,26 @@
7320
7271
  // If there has been no loading progress, sample TTFB
7321
7272
  _this.bwEstimator.sampleTTFB(timeLoading);
7322
7273
  }
7323
- var nextLoadLevelBitrate = levels[nextLoadLevel].bitrate;
7274
+ var nextLoadLevelBitrate = levels[nextLoadLevel].maxBitrate;
7324
7275
  if (_this.getBwEstimate() * _this.hls.config.abrBandWidthUpFactor > nextLoadLevelBitrate) {
7325
7276
  _this.resetEstimator(nextLoadLevelBitrate);
7326
7277
  }
7327
7278
  _this.clearTimer();
7328
- _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");
7279
+ 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");
7329
7280
  hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
7330
7281
  frag: frag,
7331
7282
  part: part,
7332
7283
  stats: stats
7333
7284
  });
7334
7285
  };
7335
- _this.hls = _hls;
7336
- _this.bwEstimator = _this.initEstimator();
7337
- _this.registerListeners();
7338
- return _this;
7286
+ this.hls = _hls;
7287
+ this.bwEstimator = this.initEstimator();
7288
+ this.registerListeners();
7339
7289
  }
7340
7290
  var _proto = AbrController.prototype;
7341
7291
  _proto.resetEstimator = function resetEstimator(abrEwmaDefaultEstimate) {
7342
7292
  if (abrEwmaDefaultEstimate) {
7343
- this.log("setting initial bwe to " + abrEwmaDefaultEstimate);
7293
+ logger.log("setting initial bwe to " + abrEwmaDefaultEstimate);
7344
7294
  this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
7345
7295
  }
7346
7296
  this.firstSelection = -1;
@@ -7592,13 +7542,13 @@
7592
7542
  // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
7593
7543
  var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
7594
7544
  maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
7595
- this.info("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
7545
+ logger.info("[abr] bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
7596
7546
  // don't use conservative factor on bitrate test
7597
7547
  bwFactor = bwUpFactor = 1;
7598
7548
  }
7599
7549
  }
7600
7550
  var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
7601
- this.info((bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
7551
+ logger.info("[abr] " + (bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
7602
7552
  if (bestLevel > -1) {
7603
7553
  return bestLevel;
7604
7554
  }
@@ -7654,7 +7604,7 @@
7654
7604
  currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
7655
7605
  currentFrameRate = minFramerate;
7656
7606
  currentBw = Math.max(currentBw, minBitrate);
7657
- this.log("picked start tier " + JSON.stringify(startTier));
7607
+ logger.log("[abr] picked start tier " + JSON.stringify(startTier));
7658
7608
  } else {
7659
7609
  currentCodecSet = level == null ? void 0 : level.codecSet;
7660
7610
  currentVideoRange = level == null ? void 0 : level.videoRange;
@@ -7678,11 +7628,11 @@
7678
7628
  var levels = _this2.hls.levels;
7679
7629
  var index = levels.indexOf(levelInfo);
7680
7630
  if (decodingInfo.error) {
7681
- _this2.warn("MediaCapabilities decodingInfo error: \"" + decodingInfo.error + "\" for level " + index + " " + JSON.stringify(decodingInfo));
7631
+ logger.warn("[abr] MediaCapabilities decodingInfo error: \"" + decodingInfo.error + "\" for level " + index + " " + JSON.stringify(decodingInfo));
7682
7632
  } else if (!decodingInfo.supported) {
7683
- _this2.warn("Unsupported MediaCapabilities decodingInfo result for level " + index + " " + JSON.stringify(decodingInfo));
7633
+ logger.warn("[abr] Unsupported MediaCapabilities decodingInfo result for level " + index + " " + JSON.stringify(decodingInfo));
7684
7634
  if (index > -1 && levels.length > 1) {
7685
- _this2.log("Removing unsupported level " + index);
7635
+ logger.log("[abr] Removing unsupported level " + index);
7686
7636
  _this2.hls.removeLevel(index);
7687
7637
  }
7688
7638
  }
@@ -7729,9 +7679,9 @@
7729
7679
  var forcedAutoLevel = _this2.forcedAutoLevel;
7730
7680
  if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
7731
7681
  if (levelsSkipped.length) {
7732
- _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);
7682
+ 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);
7733
7683
  }
7734
- _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);
7684
+ 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);
7735
7685
  }
7736
7686
  if (firstSelection) {
7737
7687
  _this2.firstSelection = i;
@@ -7765,7 +7715,7 @@
7765
7715
  }
7766
7716
  var firstLevel = this.hls.firstLevel;
7767
7717
  var clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
7768
- this.warn("Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
7718
+ logger.warn("[abr] Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
7769
7719
  return clamped;
7770
7720
  }
7771
7721
  }, {
@@ -7815,7 +7765,7 @@
7815
7765
  }
7816
7766
  }]);
7817
7767
  return AbrController;
7818
- }(Logger);
7768
+ }();
7819
7769
 
7820
7770
  /**
7821
7771
  * @ignore
@@ -7846,17 +7796,13 @@
7846
7796
  * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
7847
7797
  * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
7848
7798
  */
7849
- var TaskLoop = /*#__PURE__*/function (_Logger) {
7850
- _inheritsLoose(TaskLoop, _Logger);
7851
- function TaskLoop(label, logger) {
7852
- var _this;
7853
- _this = _Logger.call(this, label, logger) || this;
7854
- _this._boundTick = void 0;
7855
- _this._tickTimer = null;
7856
- _this._tickInterval = null;
7857
- _this._tickCallCount = 0;
7858
- _this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
7859
- return _this;
7799
+ var TaskLoop = /*#__PURE__*/function () {
7800
+ function TaskLoop() {
7801
+ this._boundTick = void 0;
7802
+ this._tickTimer = null;
7803
+ this._tickInterval = null;
7804
+ this._tickCallCount = 0;
7805
+ this._boundTick = this.tick.bind(this);
7860
7806
  }
7861
7807
  var _proto = TaskLoop.prototype;
7862
7808
  _proto.destroy = function destroy() {
@@ -7942,7 +7888,7 @@
7942
7888
  */;
7943
7889
  _proto.doTick = function doTick() {};
7944
7890
  return TaskLoop;
7945
- }(Logger);
7891
+ }();
7946
7892
 
7947
7893
  var FragmentState = {
7948
7894
  NOT_LOADED: "NOT_LOADED",
@@ -8961,8 +8907,8 @@
8961
8907
  var _frag$decryptdata;
8962
8908
  var byteRangeStart = start;
8963
8909
  var byteRangeEnd = end;
8964
- if (frag.sn === 'initSegment' && isMethodFullSegmentAesCbc((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method)) {
8965
- // MAP segment encrypted with method 'AES-128' or 'AES-256' (cbc), when served with HTTP Range,
8910
+ if (frag.sn === 'initSegment' && ((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method) === 'AES-128') {
8911
+ // MAP segment encrypted with method 'AES-128', when served with HTTP Range,
8966
8912
  // has the unencrypted size specified in the range.
8967
8913
  // Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
8968
8914
  var fragmentLen = end - start;
@@ -8995,9 +8941,6 @@
8995
8941
  (part ? part : frag).stats.aborted = true;
8996
8942
  return new LoadError(errorData);
8997
8943
  }
8998
- function isMethodFullSegmentAesCbc(method) {
8999
- return method === 'AES-128' || method === 'AES-256';
9000
- }
9001
8944
  var LoadError = /*#__PURE__*/function (_Error) {
9002
8945
  _inheritsLoose(LoadError, _Error);
9003
8946
  function LoadError(data) {
@@ -9011,65 +8954,37 @@
9011
8954
  }( /*#__PURE__*/_wrapNativeSuper(Error));
9012
8955
 
9013
8956
  var AESCrypto = /*#__PURE__*/function () {
9014
- function AESCrypto(subtle, iv, aesMode) {
8957
+ function AESCrypto(subtle, iv) {
9015
8958
  this.subtle = void 0;
9016
8959
  this.aesIV = void 0;
9017
- this.aesMode = void 0;
9018
8960
  this.subtle = subtle;
9019
8961
  this.aesIV = iv;
9020
- this.aesMode = aesMode;
9021
8962
  }
9022
8963
  var _proto = AESCrypto.prototype;
9023
8964
  _proto.decrypt = function decrypt(data, key) {
9024
- switch (this.aesMode) {
9025
- case DecrypterAesMode.cbc:
9026
- return this.subtle.decrypt({
9027
- name: 'AES-CBC',
9028
- iv: this.aesIV
9029
- }, key, data);
9030
- case DecrypterAesMode.ctr:
9031
- return this.subtle.decrypt({
9032
- name: 'AES-CTR',
9033
- counter: this.aesIV,
9034
- length: 64
9035
- },
9036
- //64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
9037
- key, data);
9038
- default:
9039
- throw new Error("[AESCrypto] invalid aes mode " + this.aesMode);
9040
- }
8965
+ return this.subtle.decrypt({
8966
+ name: 'AES-CBC',
8967
+ iv: this.aesIV
8968
+ }, key, data);
9041
8969
  };
9042
8970
  return AESCrypto;
9043
8971
  }();
9044
8972
 
9045
8973
  var FastAESKey = /*#__PURE__*/function () {
9046
- function FastAESKey(subtle, key, aesMode) {
8974
+ function FastAESKey(subtle, key) {
9047
8975
  this.subtle = void 0;
9048
8976
  this.key = void 0;
9049
- this.aesMode = void 0;
9050
8977
  this.subtle = subtle;
9051
8978
  this.key = key;
9052
- this.aesMode = aesMode;
9053
8979
  }
9054
8980
  var _proto = FastAESKey.prototype;
9055
8981
  _proto.expandKey = function expandKey() {
9056
- var subtleAlgoName = getSubtleAlgoName(this.aesMode);
9057
8982
  return this.subtle.importKey('raw', this.key, {
9058
- name: subtleAlgoName
8983
+ name: 'AES-CBC'
9059
8984
  }, false, ['encrypt', 'decrypt']);
9060
8985
  };
9061
8986
  return FastAESKey;
9062
8987
  }();
9063
- function getSubtleAlgoName(aesMode) {
9064
- switch (aesMode) {
9065
- case DecrypterAesMode.cbc:
9066
- return 'AES-CBC';
9067
- case DecrypterAesMode.ctr:
9068
- return 'AES-CTR';
9069
- default:
9070
- throw new Error("[FastAESKey] invalid aes mode " + aesMode);
9071
- }
9072
- }
9073
8988
 
9074
8989
  // PKCS7
9075
8990
  function removePadding(array) {
@@ -9322,8 +9237,7 @@
9322
9237
  this.currentIV = null;
9323
9238
  this.currentResult = null;
9324
9239
  this.useSoftware = void 0;
9325
- this.enableSoftwareAES = void 0;
9326
- this.enableSoftwareAES = config.enableSoftwareAES;
9240
+ this.useSoftware = config.enableSoftwareAES;
9327
9241
  this.removePKCS7Padding = removePKCS7Padding;
9328
9242
  // built in decryptor expects PKCS7 padding
9329
9243
  if (removePKCS7Padding) {
@@ -9336,7 +9250,9 @@
9336
9250
  /* no-op */
9337
9251
  }
9338
9252
  }
9339
- this.useSoftware = this.subtle === null;
9253
+ if (this.subtle === null) {
9254
+ this.useSoftware = true;
9255
+ }
9340
9256
  }
9341
9257
  var _proto = Decrypter.prototype;
9342
9258
  _proto.destroy = function destroy() {
@@ -9373,11 +9289,11 @@
9373
9289
  this.softwareDecrypter = null;
9374
9290
  }
9375
9291
  };
9376
- _proto.decrypt = function decrypt(data, key, iv, aesMode) {
9292
+ _proto.decrypt = function decrypt(data, key, iv) {
9377
9293
  var _this = this;
9378
9294
  if (this.useSoftware) {
9379
9295
  return new Promise(function (resolve, reject) {
9380
- _this.softwareDecrypt(new Uint8Array(data), key, iv, aesMode);
9296
+ _this.softwareDecrypt(new Uint8Array(data), key, iv);
9381
9297
  var decryptResult = _this.flush();
9382
9298
  if (decryptResult) {
9383
9299
  resolve(decryptResult.buffer);
@@ -9386,20 +9302,16 @@
9386
9302
  }
9387
9303
  });
9388
9304
  }
9389
- return this.webCryptoDecrypt(new Uint8Array(data), key, iv, aesMode);
9305
+ return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
9390
9306
  }
9391
9307
 
9392
9308
  // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
9393
9309
  // data is handled in the flush() call
9394
9310
  ;
9395
- _proto.softwareDecrypt = function softwareDecrypt(data, key, iv, aesMode) {
9311
+ _proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
9396
9312
  var currentIV = this.currentIV,
9397
9313
  currentResult = this.currentResult,
9398
9314
  remainderData = this.remainderData;
9399
- if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
9400
- logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
9401
- return null;
9402
- }
9403
9315
  this.logOnce('JS AES decrypt');
9404
9316
  // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
9405
9317
  // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
@@ -9432,12 +9344,12 @@
9432
9344
  }
9433
9345
  return result;
9434
9346
  };
9435
- _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv, aesMode) {
9347
+ _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
9436
9348
  var _this2 = this;
9437
9349
  var subtle = this.subtle;
9438
9350
  if (this.key !== key || !this.fastAesKey) {
9439
9351
  this.key = key;
9440
- this.fastAesKey = new FastAESKey(subtle, key, aesMode);
9352
+ this.fastAesKey = new FastAESKey(subtle, key);
9441
9353
  }
9442
9354
  return this.fastAesKey.expandKey().then(function (aesKey) {
9443
9355
  // decrypt using web crypto
@@ -9445,25 +9357,22 @@
9445
9357
  return Promise.reject(new Error('web crypto not initialized'));
9446
9358
  }
9447
9359
  _this2.logOnce('WebCrypto AES decrypt');
9448
- var crypto = new AESCrypto(subtle, new Uint8Array(iv), aesMode);
9360
+ var crypto = new AESCrypto(subtle, new Uint8Array(iv));
9449
9361
  return crypto.decrypt(data.buffer, aesKey);
9450
9362
  }).catch(function (err) {
9451
9363
  logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
9452
- return _this2.onWebCryptoError(data, key, iv, aesMode);
9364
+ return _this2.onWebCryptoError(data, key, iv);
9453
9365
  });
9454
9366
  };
9455
- _proto.onWebCryptoError = function onWebCryptoError(data, key, iv, aesMode) {
9456
- var enableSoftwareAES = this.enableSoftwareAES;
9457
- if (enableSoftwareAES) {
9458
- this.useSoftware = true;
9459
- this.logEnabled = true;
9460
- this.softwareDecrypt(data, key, iv, aesMode);
9461
- var decryptResult = this.flush();
9462
- if (decryptResult) {
9463
- return decryptResult.buffer;
9464
- }
9367
+ _proto.onWebCryptoError = function onWebCryptoError(data, key, iv) {
9368
+ this.useSoftware = true;
9369
+ this.logEnabled = true;
9370
+ this.softwareDecrypt(data, key, iv);
9371
+ var decryptResult = this.flush();
9372
+ if (decryptResult) {
9373
+ return decryptResult.buffer;
9465
9374
  }
9466
- throw new Error('WebCrypto' + (enableSoftwareAES ? ' and softwareDecrypt' : '') + ': failed to decrypt data');
9375
+ throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
9467
9376
  };
9468
9377
  _proto.getValidChunk = function getValidChunk(data) {
9469
9378
  var currentChunk = data;
@@ -9517,7 +9426,7 @@
9517
9426
  _inheritsLoose(BaseStreamController, _TaskLoop);
9518
9427
  function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix, playlistType) {
9519
9428
  var _this;
9520
- _this = _TaskLoop.call(this, logPrefix, hls.logger) || this;
9429
+ _this = _TaskLoop.call(this) || this;
9521
9430
  _this.hls = void 0;
9522
9431
  _this.fragPrevious = null;
9523
9432
  _this.fragCurrent = null;
@@ -9542,81 +9451,25 @@
9542
9451
  _this.startFragRequested = false;
9543
9452
  _this.decrypter = void 0;
9544
9453
  _this.initPTS = [];
9545
- _this.onMediaSeeking = function () {
9546
- var _assertThisInitialize = _assertThisInitialized(_this),
9547
- config = _assertThisInitialize.config,
9548
- fragCurrent = _assertThisInitialize.fragCurrent,
9549
- media = _assertThisInitialize.media,
9550
- mediaBuffer = _assertThisInitialize.mediaBuffer,
9551
- state = _assertThisInitialize.state;
9552
- var currentTime = media ? media.currentTime : 0;
9553
- var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
9554
- _this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
9555
- if (_this.state === State.ENDED) {
9556
- _this.resetLoadingState();
9557
- } else if (fragCurrent) {
9558
- // Seeking while frag load is in progress
9559
- var tolerance = config.maxFragLookUpTolerance;
9560
- var fragStartOffset = fragCurrent.start - tolerance;
9561
- var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
9562
- // if seeking out of buffered range or into new one
9563
- if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
9564
- var pastFragment = currentTime > fragEndOffset;
9565
- // if the seek position is outside the current fragment range
9566
- if (currentTime < fragStartOffset || pastFragment) {
9567
- if (pastFragment && fragCurrent.loader) {
9568
- _this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
9569
- fragCurrent.abortRequests();
9570
- _this.resetLoadingState();
9571
- }
9572
- _this.fragPrevious = null;
9573
- }
9574
- }
9575
- }
9576
- if (media) {
9577
- // Remove gap fragments
9578
- _this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, _this.playlistType, true);
9579
- _this.lastCurrentTime = currentTime;
9580
- }
9581
-
9582
- // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
9583
- if (!_this.loadedmetadata && !bufferInfo.len) {
9584
- _this.nextLoadPosition = _this.startPosition = currentTime;
9585
- }
9586
-
9587
- // Async tick to speed up processing
9588
- _this.tickImmediate();
9589
- };
9590
- _this.onMediaEnded = function () {
9591
- // reset startPosition and lastCurrentTime to restart playback @ stream beginning
9592
- _this.startPosition = _this.lastCurrentTime = 0;
9593
- };
9454
+ _this.onvseeking = null;
9455
+ _this.onvended = null;
9456
+ _this.logPrefix = '';
9457
+ _this.log = void 0;
9458
+ _this.warn = void 0;
9594
9459
  _this.playlistType = playlistType;
9460
+ _this.logPrefix = logPrefix;
9461
+ _this.log = logger.log.bind(logger, logPrefix + ":");
9462
+ _this.warn = logger.warn.bind(logger, logPrefix + ":");
9595
9463
  _this.hls = hls;
9596
9464
  _this.fragmentLoader = new FragmentLoader(hls.config);
9597
9465
  _this.keyLoader = keyLoader;
9598
9466
  _this.fragmentTracker = fragmentTracker;
9599
9467
  _this.config = hls.config;
9600
9468
  _this.decrypter = new Decrypter(hls.config);
9469
+ hls.on(Events.MANIFEST_LOADED, _this.onManifestLoaded, _assertThisInitialized(_this));
9601
9470
  return _this;
9602
9471
  }
9603
9472
  var _proto = BaseStreamController.prototype;
9604
- _proto.registerListeners = function registerListeners() {
9605
- var hls = this.hls;
9606
- hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
9607
- hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
9608
- hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
9609
- hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
9610
- hls.on(Events.ERROR, this.onError, this);
9611
- };
9612
- _proto.unregisterListeners = function unregisterListeners() {
9613
- var hls = this.hls;
9614
- hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
9615
- hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
9616
- hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
9617
- hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
9618
- hls.off(Events.ERROR, this.onError, this);
9619
- };
9620
9473
  _proto.doTick = function doTick() {
9621
9474
  this.onTickEnd();
9622
9475
  };
@@ -9670,8 +9523,10 @@
9670
9523
  };
9671
9524
  _proto.onMediaAttached = function onMediaAttached(event, data) {
9672
9525
  var media = this.media = this.mediaBuffer = data.media;
9673
- media.addEventListener('seeking', this.onMediaSeeking);
9674
- media.addEventListener('ended', this.onMediaEnded);
9526
+ this.onvseeking = this.onMediaSeeking.bind(this);
9527
+ this.onvended = this.onMediaEnded.bind(this);
9528
+ media.addEventListener('seeking', this.onvseeking);
9529
+ media.addEventListener('ended', this.onvended);
9675
9530
  var config = this.config;
9676
9531
  if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
9677
9532
  this.startLoad(config.startPosition);
@@ -9685,9 +9540,10 @@
9685
9540
  }
9686
9541
 
9687
9542
  // remove video listeners
9688
- if (media) {
9689
- media.removeEventListener('seeking', this.onMediaSeeking);
9690
- media.removeEventListener('ended', this.onMediaEnded);
9543
+ if (media && this.onvseeking && this.onvended) {
9544
+ media.removeEventListener('seeking', this.onvseeking);
9545
+ media.removeEventListener('ended', this.onvended);
9546
+ this.onvseeking = this.onvended = null;
9691
9547
  }
9692
9548
  if (this.keyLoader) {
9693
9549
  this.keyLoader.detach();
@@ -9697,8 +9553,54 @@
9697
9553
  this.fragmentTracker.removeAllFragments();
9698
9554
  this.stopLoad();
9699
9555
  };
9700
- _proto.onManifestLoading = function onManifestLoading() {};
9701
- _proto.onError = function onError(event, data) {};
9556
+ _proto.onMediaSeeking = function onMediaSeeking() {
9557
+ var config = this.config,
9558
+ fragCurrent = this.fragCurrent,
9559
+ media = this.media,
9560
+ mediaBuffer = this.mediaBuffer,
9561
+ state = this.state;
9562
+ var currentTime = media ? media.currentTime : 0;
9563
+ var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
9564
+ this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
9565
+ if (this.state === State.ENDED) {
9566
+ this.resetLoadingState();
9567
+ } else if (fragCurrent) {
9568
+ // Seeking while frag load is in progress
9569
+ var tolerance = config.maxFragLookUpTolerance;
9570
+ var fragStartOffset = fragCurrent.start - tolerance;
9571
+ var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
9572
+ // if seeking out of buffered range or into new one
9573
+ if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
9574
+ var pastFragment = currentTime > fragEndOffset;
9575
+ // if the seek position is outside the current fragment range
9576
+ if (currentTime < fragStartOffset || pastFragment) {
9577
+ if (pastFragment && fragCurrent.loader) {
9578
+ this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
9579
+ fragCurrent.abortRequests();
9580
+ this.resetLoadingState();
9581
+ }
9582
+ this.fragPrevious = null;
9583
+ }
9584
+ }
9585
+ }
9586
+ if (media) {
9587
+ // Remove gap fragments
9588
+ this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
9589
+ this.lastCurrentTime = currentTime;
9590
+ }
9591
+
9592
+ // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
9593
+ if (!this.loadedmetadata && !bufferInfo.len) {
9594
+ this.nextLoadPosition = this.startPosition = currentTime;
9595
+ }
9596
+
9597
+ // Async tick to speed up processing
9598
+ this.tickImmediate();
9599
+ };
9600
+ _proto.onMediaEnded = function onMediaEnded() {
9601
+ // reset startPosition and lastCurrentTime to restart playback @ stream beginning
9602
+ this.startPosition = this.lastCurrentTime = 0;
9603
+ };
9702
9604
  _proto.onManifestLoaded = function onManifestLoaded(event, data) {
9703
9605
  this.startTimeOffset = data.startTimeOffset;
9704
9606
  this.initPTS = [];
@@ -9708,7 +9610,7 @@
9708
9610
  this.stopLoad();
9709
9611
  _TaskLoop.prototype.onHandlerDestroying.call(this);
9710
9612
  // @ts-ignore
9711
- this.hls = this.onMediaSeeking = this.onMediaEnded = null;
9613
+ this.hls = null;
9712
9614
  };
9713
9615
  _proto.onHandlerDestroyed = function onHandlerDestroyed() {
9714
9616
  this.state = State.STOPPED;
@@ -9838,10 +9740,10 @@
9838
9740
  var decryptData = frag.decryptdata;
9839
9741
 
9840
9742
  // check to see if the payload needs to be decrypted
9841
- if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && isFullSegmentEncryption(decryptData.method)) {
9743
+ if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
9842
9744
  var startTime = self.performance.now();
9843
9745
  // decrypt init segment data
9844
- return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer, getAesModeFromFullSegmentMethod(decryptData.method)).catch(function (err) {
9746
+ return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
9845
9747
  hls.trigger(Events.ERROR, {
9846
9748
  type: ErrorTypes.MEDIA_ERROR,
9847
9749
  details: ErrorDetails.FRAG_DECRYPT_ERROR,
@@ -9954,7 +9856,7 @@
9954
9856
  }
9955
9857
  var keyLoadingPromise = null;
9956
9858
  if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
9957
- this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track') + " " + frag.level);
9859
+ this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level);
9958
9860
  this.state = State.KEY_LOADING;
9959
9861
  this.fragCurrent = frag;
9960
9862
  keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
@@ -9985,7 +9887,7 @@
9985
9887
  var partIndex = this.getNextPart(partList, frag, targetBufferTime);
9986
9888
  if (partIndex > -1) {
9987
9889
  var part = partList[partIndex];
9988
- 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)));
9890
+ 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)));
9989
9891
  this.nextLoadPosition = part.start + part.duration;
9990
9892
  this.state = State.FRAG_LOADING;
9991
9893
  var _result;
@@ -10018,7 +9920,7 @@
10018
9920
  }
10019
9921
  }
10020
9922
  }
10021
- 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)));
9923
+ 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)));
10022
9924
  // Don't update nextLoadPosition for fragments which are not buffered
10023
9925
  if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
10024
9926
  this.nextLoadPosition = frag.start + frag.duration;
@@ -10579,7 +10481,7 @@
10579
10481
  errorAction.resolved = true;
10580
10482
  }
10581
10483
  } else {
10582
- this.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
10484
+ logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
10583
10485
  return;
10584
10486
  }
10585
10487
  } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
@@ -10979,7 +10881,6 @@
10979
10881
  */
10980
10882
  function getAudioConfig(observer, data, offset, audioCodec) {
10981
10883
  var adtsObjectType;
10982
- var originalAdtsObjectType;
10983
10884
  var adtsExtensionSamplingIndex;
10984
10885
  var adtsChannelConfig;
10985
10886
  var config;
@@ -10987,7 +10888,7 @@
10987
10888
  var manifestCodec = audioCodec;
10988
10889
  var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
10989
10890
  // byte 2
10990
- adtsObjectType = originalAdtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
10891
+ adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
10991
10892
  var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
10992
10893
  if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
10993
10894
  var error = new Error("invalid ADTS sampling index:" + adtsSamplingIndex);
@@ -11004,8 +10905,8 @@
11004
10905
  // byte 3
11005
10906
  adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
11006
10907
  logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
11007
- // Firefox and Pale Moon: freq less than 24kHz = AAC SBR (HE-AAC)
11008
- if (/firefox|palemoon/i.test(userAgent)) {
10908
+ // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
10909
+ if (/firefox/i.test(userAgent)) {
11009
10910
  if (adtsSamplingIndex >= 6) {
11010
10911
  adtsObjectType = 5;
11011
10912
  config = new Array(4);
@@ -11099,7 +11000,6 @@
11099
11000
  samplerate: adtsSamplingRates[adtsSamplingIndex],
11100
11001
  channelCount: adtsChannelConfig,
11101
11002
  codec: 'mp4a.40.' + adtsObjectType,
11102
- parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
11103
11003
  manifestCodec: manifestCodec
11104
11004
  };
11105
11005
  }
@@ -11154,8 +11054,7 @@
11154
11054
  track.channelCount = config.channelCount;
11155
11055
  track.codec = config.codec;
11156
11056
  track.manifestCodec = config.manifestCodec;
11157
- track.parsedCodec = config.parsedCodec;
11158
- logger.log("parsed codec:" + track.parsedCodec + ", codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
11057
+ logger.log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
11159
11058
  }
11160
11059
  }
11161
11060
  function getFrameDuration(samplerate) {
@@ -12360,7 +12259,7 @@
12360
12259
  }
12361
12260
  var _proto = SampleAesDecrypter.prototype;
12362
12261
  _proto.decryptBuffer = function decryptBuffer(encryptedData) {
12363
- return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer, DecrypterAesMode.cbc);
12262
+ return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer);
12364
12263
  }
12365
12264
 
12366
12265
  // AAC - encrypt all full 16 bytes blocks starting from offset 16
@@ -14639,7 +14538,7 @@
14639
14538
  logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
14640
14539
  for (var j = 0; j < missing; j++) {
14641
14540
  var newStamp = Math.max(nextPts, 0);
14642
- var fillFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
14541
+ var fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
14643
14542
  if (!fillFrame) {
14644
14543
  logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
14645
14544
  fillFrame = sample.unit.subarray();
@@ -14767,7 +14666,7 @@
14767
14666
  // samples count of this segment's duration
14768
14667
  var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
14769
14668
  // silent frame
14770
- var silentFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
14669
+ var silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
14771
14670
  logger.warn('[mp4-remuxer]: remux empty Audio');
14772
14671
  // Can't remux if we can't generate a silent frame...
14773
14672
  if (!silentFrame) {
@@ -15157,15 +15056,13 @@
15157
15056
  duration = transmuxConfig.duration,
15158
15057
  initSegmentData = transmuxConfig.initSegmentData;
15159
15058
  var keyData = getEncryptionType(uintData, decryptdata);
15160
- if (keyData && isFullSegmentEncryption(keyData.method)) {
15059
+ if (keyData && keyData.method === 'AES-128') {
15161
15060
  var decrypter = this.getDecrypter();
15162
- var aesMode = getAesModeFromFullSegmentMethod(keyData.method);
15163
-
15164
15061
  // Software decryption is synchronous; webCrypto is not
15165
15062
  if (decrypter.isSync()) {
15166
15063
  // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
15167
15064
  // data is handled in the flush() call
15168
- var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode);
15065
+ var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
15169
15066
  // For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
15170
15067
  var loadingParts = chunkMeta.part > -1;
15171
15068
  if (loadingParts) {
@@ -15177,7 +15074,7 @@
15177
15074
  }
15178
15075
  uintData = new Uint8Array(decryptedData);
15179
15076
  } else {
15180
- this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode).then(function (decryptedData) {
15077
+ this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) {
15181
15078
  // Calling push here is important; if flush() is called while this is still resolving, this ensures that
15182
15079
  // the decrypted data has been transmuxed
15183
15080
  var result = _this.push(decryptedData, null, chunkMeta);
@@ -15798,7 +15695,7 @@
15798
15695
  observer.on(Events.ERROR, forwardMessage);
15799
15696
 
15800
15697
  // forward logger events to main thread
15801
- var forwardWorkerLogs = function forwardWorkerLogs(logger) {
15698
+ var forwardWorkerLogs = function forwardWorkerLogs() {
15802
15699
  var _loop = function _loop(logFn) {
15803
15700
  var func = function func(message) {
15804
15701
  forwardMessage('workerLog', {
@@ -15819,8 +15716,8 @@
15819
15716
  {
15820
15717
  var config = JSON.parse(data.config);
15821
15718
  self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor, data.id);
15822
- var logger = enableLogs(config.debug, data.id);
15823
- forwardWorkerLogs(logger);
15719
+ enableLogs(config.debug, data.id);
15720
+ forwardWorkerLogs();
15824
15721
  forwardMessage('init', null);
15825
15722
  break;
15826
15723
  }
@@ -15994,7 +15891,16 @@
15994
15891
  this.observer = new EventEmitter();
15995
15892
  this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
15996
15893
  this.observer.on(Events.ERROR, forwardMessage);
15997
- var m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
15894
+ var MediaSource = getMediaSource(config.preferManagedMediaSource) || {
15895
+ isTypeSupported: function isTypeSupported() {
15896
+ return false;
15897
+ }
15898
+ };
15899
+ var m2tsTypeSupported = {
15900
+ mpeg: MediaSource.isTypeSupported('audio/mpeg'),
15901
+ mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
15902
+ ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"')
15903
+ };
15998
15904
 
15999
15905
  // navigator.vendor is not always available in Web Worker
16000
15906
  // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
@@ -16278,7 +16184,7 @@
16278
16184
  _inheritsLoose(AudioStreamController, _BaseStreamController);
16279
16185
  function AudioStreamController(hls, fragmentTracker, keyLoader) {
16280
16186
  var _this;
16281
- _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'audio-stream-controller', PlaylistLevelType.AUDIO) || this;
16187
+ _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[audio-stream-controller]', PlaylistLevelType.AUDIO) || this;
16282
16188
  _this.videoBuffer = null;
16283
16189
  _this.videoTrackCC = -1;
16284
16190
  _this.waitingVideoCC = -1;
@@ -16290,24 +16196,27 @@
16290
16196
  _this.flushing = false;
16291
16197
  _this.bufferFlushed = false;
16292
16198
  _this.cachedTrackLoadedData = null;
16293
- _this.registerListeners();
16199
+ _this._registerListeners();
16294
16200
  return _this;
16295
16201
  }
16296
16202
  var _proto = AudioStreamController.prototype;
16297
16203
  _proto.onHandlerDestroying = function onHandlerDestroying() {
16298
- this.unregisterListeners();
16204
+ this._unregisterListeners();
16299
16205
  _BaseStreamController.prototype.onHandlerDestroying.call(this);
16300
16206
  this.mainDetails = null;
16301
16207
  this.bufferedTrack = null;
16302
16208
  this.switchingTrack = null;
16303
16209
  };
16304
- _proto.registerListeners = function registerListeners() {
16305
- _BaseStreamController.prototype.registerListeners.call(this);
16210
+ _proto._registerListeners = function _registerListeners() {
16306
16211
  var hls = this.hls;
16212
+ hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
16213
+ hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
16214
+ hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
16307
16215
  hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
16308
16216
  hls.on(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
16309
16217
  hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
16310
16218
  hls.on(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
16219
+ hls.on(Events.ERROR, this.onError, this);
16311
16220
  hls.on(Events.BUFFER_RESET, this.onBufferReset, this);
16312
16221
  hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
16313
16222
  hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
@@ -16315,16 +16224,16 @@
16315
16224
  hls.on(Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
16316
16225
  hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
16317
16226
  };
16318
- _proto.unregisterListeners = function unregisterListeners() {
16227
+ _proto._unregisterListeners = function _unregisterListeners() {
16319
16228
  var hls = this.hls;
16320
- if (!hls) {
16321
- return;
16322
- }
16323
- _BaseStreamController.prototype.unregisterListeners.call(this);
16229
+ hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
16230
+ hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
16231
+ hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
16324
16232
  hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
16325
16233
  hls.off(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
16326
16234
  hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
16327
16235
  hls.off(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
16236
+ hls.off(Events.ERROR, this.onError, this);
16328
16237
  hls.off(Events.BUFFER_RESET, this.onBufferReset, this);
16329
16238
  hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
16330
16239
  hls.off(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
@@ -17017,7 +16926,7 @@
17017
16926
  _inheritsLoose(AudioTrackController, _BasePlaylistControll);
17018
16927
  function AudioTrackController(hls) {
17019
16928
  var _this;
17020
- _this = _BasePlaylistControll.call(this, hls, 'audio-track-controller') || this;
16929
+ _this = _BasePlaylistControll.call(this, hls, '[audio-track-controller]') || this;
17021
16930
  _this.tracks = [];
17022
16931
  _this.groupIds = null;
17023
16932
  _this.tracksInGroup = [];
@@ -17346,23 +17255,26 @@
17346
17255
  _inheritsLoose(SubtitleStreamController, _BaseStreamController);
17347
17256
  function SubtitleStreamController(hls, fragmentTracker, keyLoader) {
17348
17257
  var _this;
17349
- _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'subtitle-stream-controller', PlaylistLevelType.SUBTITLE) || this;
17258
+ _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[subtitle-stream-controller]', PlaylistLevelType.SUBTITLE) || this;
17350
17259
  _this.currentTrackId = -1;
17351
17260
  _this.tracksBuffered = [];
17352
17261
  _this.mainDetails = null;
17353
- _this.registerListeners();
17262
+ _this._registerListeners();
17354
17263
  return _this;
17355
17264
  }
17356
17265
  var _proto = SubtitleStreamController.prototype;
17357
17266
  _proto.onHandlerDestroying = function onHandlerDestroying() {
17358
- this.unregisterListeners();
17267
+ this._unregisterListeners();
17359
17268
  _BaseStreamController.prototype.onHandlerDestroying.call(this);
17360
17269
  this.mainDetails = null;
17361
17270
  };
17362
- _proto.registerListeners = function registerListeners() {
17363
- _BaseStreamController.prototype.registerListeners.call(this);
17271
+ _proto._registerListeners = function _registerListeners() {
17364
17272
  var hls = this.hls;
17273
+ hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
17274
+ hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
17275
+ hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
17365
17276
  hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
17277
+ hls.on(Events.ERROR, this.onError, this);
17366
17278
  hls.on(Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
17367
17279
  hls.on(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
17368
17280
  hls.on(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
@@ -17370,10 +17282,13 @@
17370
17282
  hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
17371
17283
  hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
17372
17284
  };
17373
- _proto.unregisterListeners = function unregisterListeners() {
17374
- _BaseStreamController.prototype.unregisterListeners.call(this);
17285
+ _proto._unregisterListeners = function _unregisterListeners() {
17375
17286
  var hls = this.hls;
17287
+ hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
17288
+ hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
17289
+ hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
17376
17290
  hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
17291
+ hls.off(Events.ERROR, this.onError, this);
17377
17292
  hls.off(Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
17378
17293
  hls.off(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
17379
17294
  hls.off(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
@@ -17596,10 +17511,10 @@
17596
17511
  return;
17597
17512
  }
17598
17513
  // check to see if the payload needs to be decrypted
17599
- if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && isFullSegmentEncryption(decryptData.method)) {
17514
+ if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
17600
17515
  var startTime = performance.now();
17601
17516
  // decrypt the subtitles
17602
- this.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer, getAesModeFromFullSegmentMethod(decryptData.method)).catch(function (err) {
17517
+ this.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
17603
17518
  hls.trigger(Events.ERROR, {
17604
17519
  type: ErrorTypes.MEDIA_ERROR,
17605
17520
  details: ErrorDetails.FRAG_DECRYPT_ERROR,
@@ -17731,7 +17646,7 @@
17731
17646
  _inheritsLoose(SubtitleTrackController, _BasePlaylistControll);
17732
17647
  function SubtitleTrackController(hls) {
17733
17648
  var _this;
17734
- _this = _BasePlaylistControll.call(this, hls, 'subtitle-track-controller') || this;
17649
+ _this = _BasePlaylistControll.call(this, hls, '[subtitle-track-controller]') || this;
17735
17650
  _this.media = null;
17736
17651
  _this.tracks = [];
17737
17652
  _this.groupIds = null;
@@ -17740,12 +17655,12 @@
17740
17655
  _this.currentTrack = null;
17741
17656
  _this.selectDefaultTrack = true;
17742
17657
  _this.queuedDefaultTrack = -1;
17743
- _this.useTextTrackPolling = false;
17744
- _this.subtitlePollingInterval = -1;
17745
- _this._subtitleDisplay = true;
17746
17658
  _this.asyncPollTrackChange = function () {
17747
17659
  return _this.pollTrackChange(0);
17748
17660
  };
17661
+ _this.useTextTrackPolling = false;
17662
+ _this.subtitlePollingInterval = -1;
17663
+ _this._subtitleDisplay = true;
17749
17664
  _this.onTextTracksChanged = function () {
17750
17665
  if (!_this.useTextTrackPolling) {
17751
17666
  self.clearInterval(_this.subtitlePollingInterval);
@@ -17781,7 +17696,6 @@
17781
17696
  this.tracks.length = 0;
17782
17697
  this.tracksInGroup.length = 0;
17783
17698
  this.currentTrack = null;
17784
- // @ts-ignore
17785
17699
  this.onTextTracksChanged = this.asyncPollTrackChange = null;
17786
17700
  _BasePlaylistControll.prototype.destroy.call(this);
17787
17701
  };
@@ -18255,57 +18169,57 @@
18255
18169
  }();
18256
18170
 
18257
18171
  var VIDEO_CODEC_PROFILE_REPLACE = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;
18258
- var BufferController = /*#__PURE__*/function (_Logger) {
18259
- _inheritsLoose(BufferController, _Logger);
18172
+ var BufferController = /*#__PURE__*/function () {
18260
18173
  function BufferController(hls) {
18261
- var _this;
18262
- _this = _Logger.call(this, 'buffer-controller', hls.logger) || this;
18174
+ var _this = this;
18263
18175
  // The level details used to determine duration, target-duration and live
18264
- _this.details = null;
18176
+ this.details = null;
18265
18177
  // cache the self generated object url to detect hijack of video tag
18266
- _this._objectUrl = null;
18178
+ this._objectUrl = null;
18267
18179
  // A queue of buffer operations which require the SourceBuffer to not be updating upon execution
18268
- _this.operationQueue = void 0;
18180
+ this.operationQueue = void 0;
18269
18181
  // References to event listeners for each SourceBuffer, so that they can be referenced for event removal
18270
- _this.listeners = void 0;
18271
- _this.hls = void 0;
18182
+ this.listeners = void 0;
18183
+ this.hls = void 0;
18272
18184
  // The number of BUFFER_CODEC events received before any sourceBuffers are created
18273
- _this.bufferCodecEventsExpected = 0;
18185
+ this.bufferCodecEventsExpected = 0;
18274
18186
  // The total number of BUFFER_CODEC events received
18275
- _this._bufferCodecEventsTotal = 0;
18187
+ this._bufferCodecEventsTotal = 0;
18276
18188
  // A reference to the attached media element
18277
- _this.media = null;
18189
+ this.media = null;
18278
18190
  // A reference to the active media source
18279
- _this.mediaSource = null;
18191
+ this.mediaSource = null;
18280
18192
  // Last MP3 audio chunk appended
18281
- _this.lastMpegAudioChunk = null;
18282
- _this.appendSource = void 0;
18193
+ this.lastMpegAudioChunk = null;
18194
+ this.appendSource = void 0;
18283
18195
  // counters
18284
- _this.appendErrors = {
18196
+ this.appendErrors = {
18285
18197
  audio: 0,
18286
18198
  video: 0,
18287
18199
  audiovideo: 0
18288
18200
  };
18289
- _this.tracks = {};
18290
- _this.pendingTracks = {};
18291
- _this.sourceBuffer = void 0;
18292
- _this._onEndStreaming = function (event) {
18201
+ this.tracks = {};
18202
+ this.pendingTracks = {};
18203
+ this.sourceBuffer = void 0;
18204
+ this.log = void 0;
18205
+ this.warn = void 0;
18206
+ this.error = void 0;
18207
+ this._onEndStreaming = function (event) {
18293
18208
  if (!_this.hls) {
18294
18209
  return;
18295
18210
  }
18296
18211
  _this.hls.pauseBuffering();
18297
18212
  };
18298
- _this._onStartStreaming = function (event) {
18213
+ this._onStartStreaming = function (event) {
18299
18214
  if (!_this.hls) {
18300
18215
  return;
18301
18216
  }
18302
18217
  _this.hls.resumeBuffering();
18303
18218
  };
18304
18219
  // Keep as arrow functions so that we can directly reference these functions directly as event listeners
18305
- _this._onMediaSourceOpen = function () {
18306
- var _assertThisInitialize = _assertThisInitialized(_this),
18307
- media = _assertThisInitialize.media,
18308
- mediaSource = _assertThisInitialize.mediaSource;
18220
+ this._onMediaSourceOpen = function () {
18221
+ var media = _this.media,
18222
+ mediaSource = _this.mediaSource;
18309
18223
  _this.log('Media source opened');
18310
18224
  if (media) {
18311
18225
  media.removeEventListener('emptied', _this._onMediaEmptied);
@@ -18321,25 +18235,27 @@
18321
18235
  }
18322
18236
  _this.checkPendingTracks();
18323
18237
  };
18324
- _this._onMediaSourceClose = function () {
18238
+ this._onMediaSourceClose = function () {
18325
18239
  _this.log('Media source closed');
18326
18240
  };
18327
- _this._onMediaSourceEnded = function () {
18241
+ this._onMediaSourceEnded = function () {
18328
18242
  _this.log('Media source ended');
18329
18243
  };
18330
- _this._onMediaEmptied = function () {
18331
- var _assertThisInitialize2 = _assertThisInitialized(_this),
18332
- mediaSrc = _assertThisInitialize2.mediaSrc,
18333
- _objectUrl = _assertThisInitialize2._objectUrl;
18244
+ this._onMediaEmptied = function () {
18245
+ var mediaSrc = _this.mediaSrc,
18246
+ _objectUrl = _this._objectUrl;
18334
18247
  if (mediaSrc !== _objectUrl) {
18335
- _this.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
18248
+ logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
18336
18249
  }
18337
18250
  };
18338
- _this.hls = hls;
18339
- _this.appendSource = hls.config.preferManagedMediaSource;
18340
- _this._initSourceBuffer();
18341
- _this.registerListeners();
18342
- return _this;
18251
+ this.hls = hls;
18252
+ var logPrefix = '[buffer-controller]';
18253
+ this.appendSource = hls.config.preferManagedMediaSource;
18254
+ this.log = logger.log.bind(logger, logPrefix);
18255
+ this.warn = logger.warn.bind(logger, logPrefix);
18256
+ this.error = logger.error.bind(logger, logPrefix);
18257
+ this._initSourceBuffer();
18258
+ this.registerListeners();
18343
18259
  }
18344
18260
  var _proto = BufferController.prototype;
18345
18261
  _proto.hasSourceTypes = function hasSourceTypes() {
@@ -18351,12 +18267,6 @@
18351
18267
  this.lastMpegAudioChunk = null;
18352
18268
  // @ts-ignore
18353
18269
  this.hls = null;
18354
- // @ts-ignore
18355
- this._onMediaSourceOpen = this._onMediaSourceClose = null;
18356
- // @ts-ignore
18357
- this._onMediaSourceEnded = null;
18358
- // @ts-ignore
18359
- this._onStartStreaming = this._onEndStreaming = null;
18360
18270
  };
18361
18271
  _proto.registerListeners = function registerListeners() {
18362
18272
  var hls = this.hls;
@@ -19217,7 +19127,7 @@
19217
19127
  }
19218
19128
  }]);
19219
19129
  return BufferController;
19220
- }(Logger);
19130
+ }();
19221
19131
  function removeSourceChildren(node) {
19222
19132
  var sourceChildren = node.querySelectorAll('source');
19223
19133
  [].slice.call(sourceChildren).forEach(function (source) {
@@ -21656,12 +21566,14 @@
21656
21566
  this.cea608Parser1 = this.cea608Parser2 = undefined;
21657
21567
  };
21658
21568
  _proto.initCea608Parsers = function initCea608Parsers() {
21659
- var channel1 = new OutputFilter(this, 'textTrack1');
21660
- var channel2 = new OutputFilter(this, 'textTrack2');
21661
- var channel3 = new OutputFilter(this, 'textTrack3');
21662
- var channel4 = new OutputFilter(this, 'textTrack4');
21663
- this.cea608Parser1 = new Cea608Parser(1, channel1, channel2);
21664
- this.cea608Parser2 = new Cea608Parser(3, channel3, channel4);
21569
+ if (this.config.enableCEA708Captions && (!this.cea608Parser1 || !this.cea608Parser2)) {
21570
+ var channel1 = new OutputFilter(this, 'textTrack1');
21571
+ var channel2 = new OutputFilter(this, 'textTrack2');
21572
+ var channel3 = new OutputFilter(this, 'textTrack3');
21573
+ var channel4 = new OutputFilter(this, 'textTrack4');
21574
+ this.cea608Parser1 = new Cea608Parser(1, channel1, channel2);
21575
+ this.cea608Parser2 = new Cea608Parser(3, channel3, channel4);
21576
+ }
21665
21577
  };
21666
21578
  _proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) {
21667
21579
  // skip cues which overlap more than 50% with previously parsed time ranges
@@ -21896,7 +21808,7 @@
21896
21808
  return t.label;
21897
21809
  });
21898
21810
  if (unusedTextTracks.length) {
21899
- this.hls.logger.warn("Media element contains unused subtitle tracks: " + unusedTextTracks.join(', ') + ". Replace media element for each source to clear TextTracks and captions menu.");
21811
+ logger.warn("Media element contains unused subtitle tracks: " + unusedTextTracks.join(', ') + ". Replace media element for each source to clear TextTracks and captions menu.");
21900
21812
  }
21901
21813
  }
21902
21814
  } else if (this.tracks.length) {
@@ -21942,20 +21854,23 @@
21942
21854
  return level == null ? void 0 : level.attrs['CLOSED-CAPTIONS'];
21943
21855
  };
21944
21856
  _proto.onFragLoading = function onFragLoading(event, data) {
21857
+ this.initCea608Parsers();
21858
+ var cea608Parser1 = this.cea608Parser1,
21859
+ cea608Parser2 = this.cea608Parser2,
21860
+ lastCc = this.lastCc,
21861
+ lastSn = this.lastSn,
21862
+ lastPartIndex = this.lastPartIndex;
21863
+ if (!this.enabled || !cea608Parser1 || !cea608Parser2) {
21864
+ return;
21865
+ }
21945
21866
  // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
21946
- if (this.enabled && data.frag.type === PlaylistLevelType.MAIN) {
21867
+ if (data.frag.type === PlaylistLevelType.MAIN) {
21947
21868
  var _data$part$index, _data$part;
21948
- var cea608Parser1 = this.cea608Parser1,
21949
- cea608Parser2 = this.cea608Parser2,
21950
- lastSn = this.lastSn;
21951
- if (!cea608Parser1 || !cea608Parser2) {
21952
- return;
21953
- }
21954
21869
  var _data$frag = data.frag,
21955
21870
  cc = _data$frag.cc,
21956
21871
  sn = _data$frag.sn;
21957
- var partIndex = (_data$part$index = (_data$part = data.part) == null ? void 0 : _data$part.index) != null ? _data$part$index : -1;
21958
- if (!(sn === lastSn + 1 || sn === lastSn && partIndex === this.lastPartIndex + 1 || cc === this.lastCc)) {
21872
+ var partIndex = (_data$part$index = data == null ? void 0 : (_data$part = data.part) == null ? void 0 : _data$part.index) != null ? _data$part$index : -1;
21873
+ if (!(sn === lastSn + 1 || sn === lastSn && partIndex === lastPartIndex + 1 || cc === lastCc)) {
21959
21874
  cea608Parser1.reset();
21960
21875
  cea608Parser2.reset();
21961
21876
  }
@@ -22011,7 +21926,7 @@
22011
21926
  frag: frag
22012
21927
  });
22013
21928
  }, function (error) {
22014
- hls.logger.log("Failed to parse IMSC1: " + error);
21929
+ logger.log("Failed to parse IMSC1: " + error);
22015
21930
  hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
22016
21931
  success: false,
22017
21932
  frag: frag,
@@ -22049,7 +21964,7 @@
22049
21964
  _this5._fallbackToIMSC1(frag, payload);
22050
21965
  }
22051
21966
  // Something went wrong while parsing. Trigger event with success false.
22052
- hls.logger.log("Failed to parse VTT cue: " + error);
21967
+ logger.log("Failed to parse VTT cue: " + error);
22053
21968
  if (missingInitPTS && maxAvCC > frag.cc) {
22054
21969
  return;
22055
21970
  }
@@ -22111,7 +22026,10 @@
22111
22026
  this.captionsTracks = {};
22112
22027
  };
22113
22028
  _proto.onFragParsingUserdata = function onFragParsingUserdata(event, data) {
22114
- if (!this.enabled || !this.config.enableCEA708Captions) {
22029
+ this.initCea608Parsers();
22030
+ var cea608Parser1 = this.cea608Parser1,
22031
+ cea608Parser2 = this.cea608Parser2;
22032
+ if (!this.enabled || !cea608Parser1 || !cea608Parser2) {
22115
22033
  return;
22116
22034
  }
22117
22035
  var frag = data.frag,
@@ -22124,12 +22042,9 @@
22124
22042
  for (var i = 0; i < samples.length; i++) {
22125
22043
  var ccBytes = samples[i].bytes;
22126
22044
  if (ccBytes) {
22127
- if (!this.cea608Parser1) {
22128
- this.initCea608Parsers();
22129
- }
22130
22045
  var ccdatas = this.extractCea608Data(ccBytes);
22131
- this.cea608Parser1.addData(samples[i].pts, ccdatas[0]);
22132
- this.cea608Parser2.addData(samples[i].pts, ccdatas[1]);
22046
+ cea608Parser1.addData(samples[i].pts, ccdatas[0]);
22047
+ cea608Parser2.addData(samples[i].pts, ccdatas[1]);
22133
22048
  }
22134
22049
  }
22135
22050
  };
@@ -22321,7 +22236,7 @@
22321
22236
  var hls = this.hls;
22322
22237
  var maxLevel = this.getMaxLevel(levels.length - 1);
22323
22238
  if (maxLevel !== this.autoLevelCapping) {
22324
- hls.logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
22239
+ logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
22325
22240
  }
22326
22241
  hls.autoLevelCapping = maxLevel;
22327
22242
  if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
@@ -22511,10 +22426,10 @@
22511
22426
  totalDroppedFrames: droppedFrames
22512
22427
  });
22513
22428
  if (droppedFPS > 0) {
22514
- // hls.logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
22429
+ // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
22515
22430
  if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
22516
22431
  var currentLevel = hls.currentLevel;
22517
- hls.logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
22432
+ logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
22518
22433
  if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
22519
22434
  currentLevel = currentLevel - 1;
22520
22435
  hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
@@ -22547,6 +22462,7 @@
22547
22462
  return FPSController;
22548
22463
  }();
22549
22464
 
22465
+ var LOGGER_PREFIX = '[eme]';
22550
22466
  /**
22551
22467
  * Controller to deal with encrypted media extensions (EME)
22552
22468
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API
@@ -22554,122 +22470,26 @@
22554
22470
  * @class
22555
22471
  * @constructor
22556
22472
  */
22557
- var EMEController = /*#__PURE__*/function (_Logger) {
22558
- _inheritsLoose(EMEController, _Logger);
22473
+ var EMEController = /*#__PURE__*/function () {
22559
22474
  function EMEController(hls) {
22560
- var _this;
22561
- _this = _Logger.call(this, 'eme', hls.logger) || this;
22562
- _this.hls = void 0;
22563
- _this.config = void 0;
22564
- _this.media = null;
22565
- _this.keyFormatPromise = null;
22566
- _this.keySystemAccessPromises = {};
22567
- _this._requestLicenseFailureCount = 0;
22568
- _this.mediaKeySessions = [];
22569
- _this.keyIdToKeySessionPromise = {};
22570
- _this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
22571
- _this.onMediaEncrypted = function (event) {
22572
- var initDataType = event.initDataType,
22573
- initData = event.initData;
22574
- _this.debug("\"" + event.type + "\" event: init data type: \"" + initDataType + "\"");
22575
-
22576
- // Ignore event when initData is null
22577
- if (initData === null) {
22578
- return;
22579
- }
22580
- var keyId;
22581
- var keySystemDomain;
22582
- if (initDataType === 'sinf' && _this.config.drmSystems[KeySystems.FAIRPLAY]) {
22583
- // Match sinf keyId to playlist skd://keyId=
22584
- var json = bin2str(new Uint8Array(initData));
22585
- try {
22586
- var sinf = base64Decode(JSON.parse(json).sinf);
22587
- var tenc = parseSinf(new Uint8Array(sinf));
22588
- if (!tenc) {
22589
- return;
22590
- }
22591
- keyId = tenc.subarray(8, 24);
22592
- keySystemDomain = KeySystems.FAIRPLAY;
22593
- } catch (error) {
22594
- _this.warn('Failed to parse sinf "encrypted" event message initData');
22595
- return;
22596
- }
22597
- } else {
22598
- // Support clear-lead key-session creation (otherwise depend on playlist keys)
22599
- var psshInfo = parsePssh(initData);
22600
- if (psshInfo === null) {
22601
- return;
22602
- }
22603
- if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
22604
- keyId = psshInfo.data.subarray(8, 24);
22605
- }
22606
- keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
22607
- }
22608
- if (!keySystemDomain || !keyId) {
22609
- return;
22610
- }
22611
- var keyIdHex = Hex.hexDump(keyId);
22612
- var _assertThisInitialize = _assertThisInitialized(_this),
22613
- keyIdToKeySessionPromise = _assertThisInitialize.keyIdToKeySessionPromise,
22614
- mediaKeySessions = _assertThisInitialize.mediaKeySessions;
22615
- var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
22616
- var _loop = function _loop() {
22617
- // Match playlist key
22618
- var keyContext = mediaKeySessions[i];
22619
- var decryptdata = keyContext.decryptdata;
22620
- if (decryptdata.pssh || !decryptdata.keyId) {
22621
- return 0; // continue
22622
- }
22623
- var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
22624
- if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
22625
- keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
22626
- delete keyIdToKeySessionPromise[oldKeyIdHex];
22627
- decryptdata.pssh = new Uint8Array(initData);
22628
- decryptdata.keyId = keyId;
22629
- keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
22630
- return _this.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
22631
- });
22632
- return 1; // break
22633
- }
22634
- },
22635
- _ret;
22636
- for (var i = 0; i < mediaKeySessions.length; i++) {
22637
- _ret = _loop();
22638
- if (_ret === 0) continue;
22639
- if (_ret === 1) break;
22640
- }
22641
- if (!keySessionContextPromise) {
22642
- // Clear-lead key (not encountered in playlist)
22643
- keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = _this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref) {
22644
- var _keySystemToKeySystem;
22645
- var keySystem = _ref.keySystem,
22646
- mediaKeys = _ref.mediaKeys;
22647
- _this.throwIfDestroyed();
22648
- var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
22649
- decryptdata.pssh = new Uint8Array(initData);
22650
- decryptdata.keyId = keyId;
22651
- return _this.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22652
- _this.throwIfDestroyed();
22653
- var keySessionContext = _this.createMediaKeySessionContext({
22654
- decryptdata: decryptdata,
22655
- keySystem: keySystem,
22656
- mediaKeys: mediaKeys
22657
- });
22658
- return _this.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
22659
- });
22660
- });
22661
- }
22662
- keySessionContextPromise.catch(function (error) {
22663
- return _this.handleError(error);
22664
- });
22665
- };
22666
- _this.onWaitingForKey = function (event) {
22667
- _this.log("\"" + event.type + "\" event");
22668
- };
22669
- _this.hls = hls;
22670
- _this.config = hls.config;
22671
- _this.registerListeners();
22672
- return _this;
22475
+ this.hls = void 0;
22476
+ this.config = void 0;
22477
+ this.media = null;
22478
+ this.keyFormatPromise = null;
22479
+ this.keySystemAccessPromises = {};
22480
+ this._requestLicenseFailureCount = 0;
22481
+ this.mediaKeySessions = [];
22482
+ this.keyIdToKeySessionPromise = {};
22483
+ this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
22484
+ this.onMediaEncrypted = this._onMediaEncrypted.bind(this);
22485
+ this.onWaitingForKey = this._onWaitingForKey.bind(this);
22486
+ this.debug = logger.debug.bind(logger, LOGGER_PREFIX);
22487
+ this.log = logger.log.bind(logger, LOGGER_PREFIX);
22488
+ this.warn = logger.warn.bind(logger, LOGGER_PREFIX);
22489
+ this.error = logger.error.bind(logger, LOGGER_PREFIX);
22490
+ this.hls = hls;
22491
+ this.config = hls.config;
22492
+ this.registerListeners();
22673
22493
  }
22674
22494
  var _proto = EMEController.prototype;
22675
22495
  _proto.destroy = function destroy() {
@@ -22681,9 +22501,9 @@
22681
22501
  config.licenseXhrSetup = config.licenseResponseCallback = undefined;
22682
22502
  config.drmSystems = config.drmSystemOptions = {};
22683
22503
  // @ts-ignore
22684
- this.hls = this.config = this.keyIdToKeySessionPromise = null;
22504
+ this.hls = this.onMediaEncrypted = this.onWaitingForKey = this.keyIdToKeySessionPromise = null;
22685
22505
  // @ts-ignore
22686
- this.onMediaEncrypted = this.onWaitingForKey = null;
22506
+ this.config = null;
22687
22507
  };
22688
22508
  _proto.registerListeners = function registerListeners() {
22689
22509
  this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
@@ -22722,7 +22542,7 @@
22722
22542
  }
22723
22543
  };
22724
22544
  _proto.attemptKeySystemAccess = function attemptKeySystemAccess(keySystemsToAttempt) {
22725
- var _this2 = this;
22545
+ var _this = this;
22726
22546
  var levels = this.hls.levels;
22727
22547
  var uniqueCodec = function uniqueCodec(value, i, a) {
22728
22548
  return !!value && a.indexOf(value) === i;
@@ -22739,7 +22559,7 @@
22739
22559
  return new Promise(function (resolve, reject) {
22740
22560
  var attempt = function attempt(keySystems) {
22741
22561
  var keySystem = keySystems.shift();
22742
- _this2.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
22562
+ _this.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
22743
22563
  return resolve({
22744
22564
  keySystem: keySystem,
22745
22565
  mediaKeys: mediaKeys
@@ -22774,7 +22594,7 @@
22774
22594
  return requestMediaKeySystemAccessFunc(keySystem, supportedConfigurations);
22775
22595
  };
22776
22596
  _proto.getMediaKeysPromise = function getMediaKeysPromise(keySystem, audioCodecs, videoCodecs) {
22777
- var _this3 = this;
22597
+ var _this2 = this;
22778
22598
  // This can throw, but is caught in event handler callpath
22779
22599
  var mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this.config.drmSystemOptions);
22780
22600
  var keySystemAccessPromises = this.keySystemAccessPromises[keySystem];
@@ -22786,23 +22606,23 @@
22786
22606
  keySystemAccess: keySystemAccess
22787
22607
  };
22788
22608
  keySystemAccess.catch(function (error) {
22789
- _this3.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
22609
+ _this2.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
22790
22610
  });
22791
22611
  return keySystemAccess.then(function (mediaKeySystemAccess) {
22792
- _this3.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
22793
- var certificateRequest = _this3.fetchServerCertificate(keySystem);
22794
- _this3.log("Create media-keys for \"" + keySystem + "\"");
22612
+ _this2.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
22613
+ var certificateRequest = _this2.fetchServerCertificate(keySystem);
22614
+ _this2.log("Create media-keys for \"" + keySystem + "\"");
22795
22615
  _keySystemAccessPromises.mediaKeys = mediaKeySystemAccess.createMediaKeys().then(function (mediaKeys) {
22796
- _this3.log("Media-keys created for \"" + keySystem + "\"");
22616
+ _this2.log("Media-keys created for \"" + keySystem + "\"");
22797
22617
  return certificateRequest.then(function (certificate) {
22798
22618
  if (certificate) {
22799
- return _this3.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
22619
+ return _this2.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
22800
22620
  }
22801
22621
  return mediaKeys;
22802
22622
  });
22803
22623
  });
22804
22624
  _keySystemAccessPromises.mediaKeys.catch(function (error) {
22805
- _this3.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
22625
+ _this2.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
22806
22626
  });
22807
22627
  return _keySystemAccessPromises.mediaKeys;
22808
22628
  });
@@ -22811,10 +22631,10 @@
22811
22631
  return keySystemAccessPromises.mediaKeys;
22812
22632
  });
22813
22633
  };
22814
- _proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref2) {
22815
- var decryptdata = _ref2.decryptdata,
22816
- keySystem = _ref2.keySystem,
22817
- mediaKeys = _ref2.mediaKeys;
22634
+ _proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref) {
22635
+ var decryptdata = _ref.decryptdata,
22636
+ keySystem = _ref.keySystem,
22637
+ mediaKeys = _ref.mediaKeys;
22818
22638
  this.log("Creating key-system session \"" + keySystem + "\" keyId: " + Hex.hexDump(decryptdata.keyId || []));
22819
22639
  var mediaKeysSession = mediaKeys.createSession();
22820
22640
  var mediaKeySessionContext = {
@@ -22863,14 +22683,14 @@
22863
22683
  return this.keyFormatPromise;
22864
22684
  };
22865
22685
  _proto.getKeyFormatPromise = function getKeyFormatPromise(keyFormats) {
22866
- var _this4 = this;
22686
+ var _this3 = this;
22867
22687
  return new Promise(function (resolve, reject) {
22868
- var keySystemsInConfig = getKeySystemsForConfig(_this4.config);
22688
+ var keySystemsInConfig = getKeySystemsForConfig(_this3.config);
22869
22689
  var keySystemsToAttempt = keyFormats.map(keySystemFormatToKeySystemDomain).filter(function (value) {
22870
22690
  return !!value && keySystemsInConfig.indexOf(value) !== -1;
22871
22691
  });
22872
- return _this4.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref3) {
22873
- var keySystem = _ref3.keySystem;
22692
+ return _this3.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref2) {
22693
+ var keySystem = _ref2.keySystem;
22874
22694
  var keySystemFormat = keySystemDomainToKeySystemFormat(keySystem);
22875
22695
  if (keySystemFormat) {
22876
22696
  resolve(keySystemFormat);
@@ -22881,31 +22701,31 @@
22881
22701
  });
22882
22702
  };
22883
22703
  _proto.loadKey = function loadKey(data) {
22884
- var _this5 = this;
22704
+ var _this4 = this;
22885
22705
  var decryptdata = data.keyInfo.decryptdata;
22886
22706
  var keyId = this.getKeyIdString(decryptdata);
22887
22707
  var keyDetails = "(keyId: " + keyId + " format: \"" + decryptdata.keyFormat + "\" method: " + decryptdata.method + " uri: " + decryptdata.uri + ")";
22888
22708
  this.log("Starting session for key " + keyDetails);
22889
22709
  var keySessionContextPromise = this.keyIdToKeySessionPromise[keyId];
22890
22710
  if (!keySessionContextPromise) {
22891
- keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref4) {
22892
- var keySystem = _ref4.keySystem,
22893
- mediaKeys = _ref4.mediaKeys;
22894
- _this5.throwIfDestroyed();
22895
- _this5.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
22896
- return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22897
- _this5.throwIfDestroyed();
22898
- var keySessionContext = _this5.createMediaKeySessionContext({
22711
+ keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref3) {
22712
+ var keySystem = _ref3.keySystem,
22713
+ mediaKeys = _ref3.mediaKeys;
22714
+ _this4.throwIfDestroyed();
22715
+ _this4.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
22716
+ return _this4.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22717
+ _this4.throwIfDestroyed();
22718
+ var keySessionContext = _this4.createMediaKeySessionContext({
22899
22719
  keySystem: keySystem,
22900
22720
  mediaKeys: mediaKeys,
22901
22721
  decryptdata: decryptdata
22902
22722
  });
22903
22723
  var scheme = 'cenc';
22904
- return _this5.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
22724
+ return _this4.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
22905
22725
  });
22906
22726
  });
22907
22727
  keySessionContextPromise.catch(function (error) {
22908
- return _this5.handleError(error);
22728
+ return _this4.handleError(error);
22909
22729
  });
22910
22730
  }
22911
22731
  return keySessionContextPromise;
@@ -22956,6 +22776,104 @@
22956
22776
  }
22957
22777
  return this.attemptKeySystemAccess(keySystemsToAttempt);
22958
22778
  };
22779
+ _proto._onMediaEncrypted = function _onMediaEncrypted(event) {
22780
+ var _this5 = this;
22781
+ var initDataType = event.initDataType,
22782
+ initData = event.initData;
22783
+ this.debug("\"" + event.type + "\" event: init data type: \"" + initDataType + "\"");
22784
+
22785
+ // Ignore event when initData is null
22786
+ if (initData === null) {
22787
+ return;
22788
+ }
22789
+ var keyId;
22790
+ var keySystemDomain;
22791
+ if (initDataType === 'sinf' && this.config.drmSystems[KeySystems.FAIRPLAY]) {
22792
+ // Match sinf keyId to playlist skd://keyId=
22793
+ var json = bin2str(new Uint8Array(initData));
22794
+ try {
22795
+ var sinf = base64Decode(JSON.parse(json).sinf);
22796
+ var tenc = parseSinf(new Uint8Array(sinf));
22797
+ if (!tenc) {
22798
+ return;
22799
+ }
22800
+ keyId = tenc.subarray(8, 24);
22801
+ keySystemDomain = KeySystems.FAIRPLAY;
22802
+ } catch (error) {
22803
+ this.warn('Failed to parse sinf "encrypted" event message initData');
22804
+ return;
22805
+ }
22806
+ } else {
22807
+ // Support clear-lead key-session creation (otherwise depend on playlist keys)
22808
+ var psshInfo = parsePssh(initData);
22809
+ if (psshInfo === null) {
22810
+ return;
22811
+ }
22812
+ if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
22813
+ keyId = psshInfo.data.subarray(8, 24);
22814
+ }
22815
+ keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
22816
+ }
22817
+ if (!keySystemDomain || !keyId) {
22818
+ return;
22819
+ }
22820
+ var keyIdHex = Hex.hexDump(keyId);
22821
+ var keyIdToKeySessionPromise = this.keyIdToKeySessionPromise,
22822
+ mediaKeySessions = this.mediaKeySessions;
22823
+ var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
22824
+ var _loop = function _loop() {
22825
+ // Match playlist key
22826
+ var keyContext = mediaKeySessions[i];
22827
+ var decryptdata = keyContext.decryptdata;
22828
+ if (decryptdata.pssh || !decryptdata.keyId) {
22829
+ return 0; // continue
22830
+ }
22831
+ var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
22832
+ if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
22833
+ keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
22834
+ delete keyIdToKeySessionPromise[oldKeyIdHex];
22835
+ decryptdata.pssh = new Uint8Array(initData);
22836
+ decryptdata.keyId = keyId;
22837
+ keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
22838
+ return _this5.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
22839
+ });
22840
+ return 1; // break
22841
+ }
22842
+ },
22843
+ _ret;
22844
+ for (var i = 0; i < mediaKeySessions.length; i++) {
22845
+ _ret = _loop();
22846
+ if (_ret === 0) continue;
22847
+ if (_ret === 1) break;
22848
+ }
22849
+ if (!keySessionContextPromise) {
22850
+ // Clear-lead key (not encountered in playlist)
22851
+ keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref4) {
22852
+ var _keySystemToKeySystem;
22853
+ var keySystem = _ref4.keySystem,
22854
+ mediaKeys = _ref4.mediaKeys;
22855
+ _this5.throwIfDestroyed();
22856
+ var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
22857
+ decryptdata.pssh = new Uint8Array(initData);
22858
+ decryptdata.keyId = keyId;
22859
+ return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22860
+ _this5.throwIfDestroyed();
22861
+ var keySessionContext = _this5.createMediaKeySessionContext({
22862
+ decryptdata: decryptdata,
22863
+ keySystem: keySystem,
22864
+ mediaKeys: mediaKeys
22865
+ });
22866
+ return _this5.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
22867
+ });
22868
+ });
22869
+ }
22870
+ keySessionContextPromise.catch(function (error) {
22871
+ return _this5.handleError(error);
22872
+ });
22873
+ };
22874
+ _proto._onWaitingForKey = function _onWaitingForKey(event) {
22875
+ this.log("\"" + event.type + "\" event");
22876
+ };
22959
22877
  _proto.attemptSetMediaKeys = function attemptSetMediaKeys(keySystem, mediaKeys) {
22960
22878
  var _this6 = this;
22961
22879
  var queue = this.setMediaKeysQueue.slice();
@@ -23411,7 +23329,7 @@
23411
23329
  }
23412
23330
  };
23413
23331
  return EMEController;
23414
- }(Logger);
23332
+ }();
23415
23333
  EMEController.CDMCleanupPromise = void 0;
23416
23334
  var EMEKeyError = /*#__PURE__*/function (_Error) {
23417
23335
  _inheritsLoose(EMEKeyError, _Error);
@@ -24737,28 +24655,26 @@
24737
24655
  }();
24738
24656
 
24739
24657
  var PATHWAY_PENALTY_DURATION_MS = 300000;
24740
- var ContentSteeringController = /*#__PURE__*/function (_Logger) {
24741
- _inheritsLoose(ContentSteeringController, _Logger);
24658
+ var ContentSteeringController = /*#__PURE__*/function () {
24742
24659
  function ContentSteeringController(hls) {
24743
- var _this;
24744
- _this = _Logger.call(this, 'content-steering', hls.logger) || this;
24745
- _this.hls = void 0;
24746
- _this.loader = null;
24747
- _this.uri = null;
24748
- _this.pathwayId = '.';
24749
- _this.pathwayPriority = null;
24750
- _this.timeToLoad = 300;
24751
- _this.reloadTimer = -1;
24752
- _this.updated = 0;
24753
- _this.started = false;
24754
- _this.enabled = true;
24755
- _this.levels = null;
24756
- _this.audioTracks = null;
24757
- _this.subtitleTracks = null;
24758
- _this.penalizedPathways = {};
24759
- _this.hls = hls;
24760
- _this.registerListeners();
24761
- return _this;
24660
+ this.hls = void 0;
24661
+ this.log = void 0;
24662
+ this.loader = null;
24663
+ this.uri = null;
24664
+ this.pathwayId = '.';
24665
+ this.pathwayPriority = null;
24666
+ this.timeToLoad = 300;
24667
+ this.reloadTimer = -1;
24668
+ this.updated = 0;
24669
+ this.started = false;
24670
+ this.enabled = true;
24671
+ this.levels = null;
24672
+ this.audioTracks = null;
24673
+ this.subtitleTracks = null;
24674
+ this.penalizedPathways = {};
24675
+ this.hls = hls;
24676
+ this.log = logger.log.bind(logger, "[content-steering]:");
24677
+ this.registerListeners();
24762
24678
  }
24763
24679
  var _proto = ContentSteeringController.prototype;
24764
24680
  _proto.registerListeners = function registerListeners() {
@@ -24879,7 +24795,7 @@
24879
24795
  errorAction.resolved = this.pathwayId !== errorPathway;
24880
24796
  }
24881
24797
  if (!errorAction.resolved) {
24882
- 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));
24798
+ 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));
24883
24799
  }
24884
24800
  }
24885
24801
  };
@@ -24959,7 +24875,7 @@
24959
24875
  return defaultPathway;
24960
24876
  };
24961
24877
  _proto.clonePathways = function clonePathways(pathwayClones) {
24962
- var _this2 = this;
24878
+ var _this = this;
24963
24879
  var levels = this.levels;
24964
24880
  if (!levels) {
24965
24881
  return;
@@ -24975,7 +24891,7 @@
24975
24891
  })) {
24976
24892
  return;
24977
24893
  }
24978
- var clonedVariants = _this2.getLevelsForPathway(baseId).map(function (baseLevel) {
24894
+ var clonedVariants = _this.getLevelsForPathway(baseId).map(function (baseLevel) {
24979
24895
  var attributes = new AttrList(baseLevel.attrs);
24980
24896
  attributes['PATHWAY-ID'] = cloneId;
24981
24897
  var clonedAudioGroupId = attributes.AUDIO && attributes.AUDIO + "_clone_" + cloneId;
@@ -25012,12 +24928,12 @@
25012
24928
  return clonedLevel;
25013
24929
  });
25014
24930
  levels.push.apply(levels, clonedVariants);
25015
- cloneRenditionGroups(_this2.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
25016
- cloneRenditionGroups(_this2.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
24931
+ cloneRenditionGroups(_this.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
24932
+ cloneRenditionGroups(_this.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
25017
24933
  });
25018
24934
  };
25019
24935
  _proto.loadSteeringManifest = function loadSteeringManifest(uri) {
25020
- var _this3 = this;
24936
+ var _this2 = this;
25021
24937
  var config = this.hls.config;
25022
24938
  var Loader = config.loader;
25023
24939
  if (this.loader) {
@@ -25052,87 +24968,87 @@
25052
24968
  };
25053
24969
  var callbacks = {
25054
24970
  onSuccess: function onSuccess(response, stats, context, networkDetails) {
25055
- _this3.log("Loaded steering manifest: \"" + url + "\"");
24971
+ _this2.log("Loaded steering manifest: \"" + url + "\"");
25056
24972
  var steeringData = response.data;
25057
- if ((steeringData == null ? void 0 : steeringData.VERSION) !== 1) {
25058
- _this3.log("Steering VERSION " + steeringData.VERSION + " not supported!");
24973
+ if (steeringData.VERSION !== 1) {
24974
+ _this2.log("Steering VERSION " + steeringData.VERSION + " not supported!");
25059
24975
  return;
25060
24976
  }
25061
- _this3.updated = performance.now();
25062
- _this3.timeToLoad = steeringData.TTL;
24977
+ _this2.updated = performance.now();
24978
+ _this2.timeToLoad = steeringData.TTL;
25063
24979
  var reloadUri = steeringData['RELOAD-URI'],
25064
24980
  pathwayClones = steeringData['PATHWAY-CLONES'],
25065
24981
  pathwayPriority = steeringData['PATHWAY-PRIORITY'];
25066
24982
  if (reloadUri) {
25067
24983
  try {
25068
- _this3.uri = new self.URL(reloadUri, url).href;
24984
+ _this2.uri = new self.URL(reloadUri, url).href;
25069
24985
  } catch (error) {
25070
- _this3.enabled = false;
25071
- _this3.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
24986
+ _this2.enabled = false;
24987
+ _this2.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
25072
24988
  return;
25073
24989
  }
25074
24990
  }
25075
- _this3.scheduleRefresh(_this3.uri || context.url);
24991
+ _this2.scheduleRefresh(_this2.uri || context.url);
25076
24992
  if (pathwayClones) {
25077
- _this3.clonePathways(pathwayClones);
24993
+ _this2.clonePathways(pathwayClones);
25078
24994
  }
25079
24995
  var loadedSteeringData = {
25080
24996
  steeringManifest: steeringData,
25081
24997
  url: url.toString()
25082
24998
  };
25083
- _this3.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
24999
+ _this2.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
25084
25000
  if (pathwayPriority) {
25085
- _this3.updatePathwayPriority(pathwayPriority);
25001
+ _this2.updatePathwayPriority(pathwayPriority);
25086
25002
  }
25087
25003
  },
25088
25004
  onError: function onError(error, context, networkDetails, stats) {
25089
- _this3.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
25090
- _this3.stopLoad();
25005
+ _this2.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
25006
+ _this2.stopLoad();
25091
25007
  if (error.code === 410) {
25092
- _this3.enabled = false;
25093
- _this3.log("Steering manifest " + context.url + " no longer available");
25008
+ _this2.enabled = false;
25009
+ _this2.log("Steering manifest " + context.url + " no longer available");
25094
25010
  return;
25095
25011
  }
25096
- var ttl = _this3.timeToLoad * 1000;
25012
+ var ttl = _this2.timeToLoad * 1000;
25097
25013
  if (error.code === 429) {
25098
- var loader = _this3.loader;
25014
+ var loader = _this2.loader;
25099
25015
  if (typeof (loader == null ? void 0 : loader.getResponseHeader) === 'function') {
25100
25016
  var retryAfter = loader.getResponseHeader('Retry-After');
25101
25017
  if (retryAfter) {
25102
25018
  ttl = parseFloat(retryAfter) * 1000;
25103
25019
  }
25104
25020
  }
25105
- _this3.log("Steering manifest " + context.url + " rate limited");
25021
+ _this2.log("Steering manifest " + context.url + " rate limited");
25106
25022
  return;
25107
25023
  }
25108
- _this3.scheduleRefresh(_this3.uri || context.url, ttl);
25024
+ _this2.scheduleRefresh(_this2.uri || context.url, ttl);
25109
25025
  },
25110
25026
  onTimeout: function onTimeout(stats, context, networkDetails) {
25111
- _this3.log("Timeout loading steering manifest (" + context.url + ")");
25112
- _this3.scheduleRefresh(_this3.uri || context.url);
25027
+ _this2.log("Timeout loading steering manifest (" + context.url + ")");
25028
+ _this2.scheduleRefresh(_this2.uri || context.url);
25113
25029
  }
25114
25030
  };
25115
25031
  this.log("Requesting steering manifest: " + url);
25116
25032
  this.loader.load(context, loaderConfig, callbacks);
25117
25033
  };
25118
25034
  _proto.scheduleRefresh = function scheduleRefresh(uri, ttlMs) {
25119
- var _this4 = this;
25035
+ var _this3 = this;
25120
25036
  if (ttlMs === void 0) {
25121
25037
  ttlMs = this.timeToLoad * 1000;
25122
25038
  }
25123
25039
  this.clearTimeout();
25124
25040
  this.reloadTimer = self.setTimeout(function () {
25125
- var _this4$hls;
25126
- var media = (_this4$hls = _this4.hls) == null ? void 0 : _this4$hls.media;
25041
+ var _this3$hls;
25042
+ var media = (_this3$hls = _this3.hls) == null ? void 0 : _this3$hls.media;
25127
25043
  if (media && !media.ended) {
25128
- _this4.loadSteeringManifest(uri);
25044
+ _this3.loadSteeringManifest(uri);
25129
25045
  return;
25130
25046
  }
25131
- _this4.scheduleRefresh(uri, _this4.timeToLoad * 1000);
25047
+ _this3.scheduleRefresh(uri, _this3.timeToLoad * 1000);
25132
25048
  }, ttlMs);
25133
25049
  };
25134
25050
  return ContentSteeringController;
25135
- }(Logger);
25051
+ }();
25136
25052
  function cloneRenditionGroups(tracks, groupCloneMap, uriReplacement, cloneId) {
25137
25053
  if (!tracks) {
25138
25054
  return;
@@ -26032,7 +25948,7 @@
26032
25948
  /**
26033
25949
  * @ignore
26034
25950
  */
26035
- function mergeConfig(defaultConfig, userConfig, logger) {
25951
+ function mergeConfig(defaultConfig, userConfig) {
26036
25952
  if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
26037
25953
  throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
26038
25954
  }
@@ -26102,7 +26018,7 @@
26102
26018
  /**
26103
26019
  * @ignore
26104
26020
  */
26105
- function enableStreamingMode(config, logger) {
26021
+ function enableStreamingMode(config) {
26106
26022
  var currentLoader = config.loader;
26107
26023
  if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
26108
26024
  // If a developer has configured their own loader, respect that choice
@@ -26119,11 +26035,12 @@
26119
26035
  }
26120
26036
  }
26121
26037
 
26038
+ var chromeOrFirefox;
26122
26039
  var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
26123
26040
  _inheritsLoose(LevelController, _BasePlaylistControll);
26124
26041
  function LevelController(hls, contentSteeringController) {
26125
26042
  var _this;
26126
- _this = _BasePlaylistControll.call(this, hls, 'level-controller') || this;
26043
+ _this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
26127
26044
  _this._levels = [];
26128
26045
  _this._firstLevel = -1;
26129
26046
  _this._maxAutoLevel = -1;
@@ -26192,13 +26109,21 @@
26192
26109
  var videoCodecFound = false;
26193
26110
  var audioCodecFound = false;
26194
26111
  data.levels.forEach(function (levelParsed) {
26195
- var _videoCodec;
26112
+ var _audioCodec, _videoCodec;
26196
26113
  var attributes = levelParsed.attrs;
26114
+
26115
+ // erase audio codec info if browser does not support mp4a.40.34.
26116
+ // demuxer will autodetect codec and fallback to mpeg/audio
26197
26117
  var audioCodec = levelParsed.audioCodec,
26198
26118
  videoCodec = levelParsed.videoCodec;
26119
+ if (((_audioCodec = audioCodec) == null ? void 0 : _audioCodec.indexOf('mp4a.40.34')) !== -1) {
26120
+ chromeOrFirefox || (chromeOrFirefox = /chrome|firefox/i.test(navigator.userAgent));
26121
+ if (chromeOrFirefox) {
26122
+ levelParsed.audioCodec = audioCodec = undefined;
26123
+ }
26124
+ }
26199
26125
  if (audioCodec) {
26200
- // Returns empty and set to undefined for 'mp4a.40.34' with fallback to 'audio/mpeg' SourceBuffer
26201
- levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource) || undefined;
26126
+ levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource);
26202
26127
  }
26203
26128
  if (((_videoCodec = videoCodec) == null ? void 0 : _videoCodec.indexOf('avc1')) === 0) {
26204
26129
  videoCodec = levelParsed.videoCodec = convertAVC1ToAVCOTI(videoCodec);
@@ -26321,8 +26246,8 @@
26321
26246
  return _valueB - _valueA;
26322
26247
  }
26323
26248
  }
26324
- if (a.bitrate !== b.bitrate) {
26325
- return a.bitrate - b.bitrate;
26249
+ if (a.averageBitrate !== b.averageBitrate) {
26250
+ return a.averageBitrate - b.averageBitrate;
26326
26251
  }
26327
26252
  return 0;
26328
26253
  });
@@ -26806,8 +26731,6 @@
26806
26731
  }
26807
26732
  return this.loadKeyEME(keyInfo, frag);
26808
26733
  case 'AES-128':
26809
- case 'AES-256':
26810
- case 'AES-256-CTR':
26811
26734
  return this.loadKeyHTTP(keyInfo, frag);
26812
26735
  default:
26813
26736
  return Promise.reject(this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, new Error("Key supplied with unsupported METHOD: \"" + decryptdata.method + "\"")));
@@ -26947,25 +26870,21 @@
26947
26870
  var MAX_START_GAP_JUMP = 2.0;
26948
26871
  var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
26949
26872
  var SKIP_BUFFER_RANGE_START = 0.05;
26950
- var GapController = /*#__PURE__*/function (_Logger) {
26951
- _inheritsLoose(GapController, _Logger);
26873
+ var GapController = /*#__PURE__*/function () {
26952
26874
  function GapController(config, media, fragmentTracker, hls) {
26953
- var _this;
26954
- _this = _Logger.call(this, 'gap-controller', hls.logger) || this;
26955
- _this.config = void 0;
26956
- _this.media = null;
26957
- _this.fragmentTracker = void 0;
26958
- _this.hls = void 0;
26959
- _this.nudgeRetry = 0;
26960
- _this.stallReported = false;
26961
- _this.stalled = null;
26962
- _this.moved = false;
26963
- _this.seeking = false;
26964
- _this.config = config;
26965
- _this.media = media;
26966
- _this.fragmentTracker = fragmentTracker;
26967
- _this.hls = hls;
26968
- return _this;
26875
+ this.config = void 0;
26876
+ this.media = null;
26877
+ this.fragmentTracker = void 0;
26878
+ this.hls = void 0;
26879
+ this.nudgeRetry = 0;
26880
+ this.stallReported = false;
26881
+ this.stalled = null;
26882
+ this.moved = false;
26883
+ this.seeking = false;
26884
+ this.config = config;
26885
+ this.media = media;
26886
+ this.fragmentTracker = fragmentTracker;
26887
+ this.hls = hls;
26969
26888
  }
26970
26889
  var _proto = GapController.prototype;
26971
26890
  _proto.destroy = function destroy() {
@@ -27003,7 +26922,7 @@
27003
26922
  // The playhead is now moving, but was previously stalled
27004
26923
  if (this.stallReported) {
27005
26924
  var _stalledDuration = self.performance.now() - stalled;
27006
- this.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
26925
+ logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
27007
26926
  this.stallReported = false;
27008
26927
  }
27009
26928
  this.stalled = null;
@@ -27112,7 +27031,7 @@
27112
27031
  // needs to cross some sort of threshold covering all source-buffers content
27113
27032
  // to start playing properly.
27114
27033
  if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
27115
- this.warn('Trying to nudge playhead over buffer-hole');
27034
+ logger.warn('Trying to nudge playhead over buffer-hole');
27116
27035
  // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
27117
27036
  // We only try to jump the hole if it's under the configured size
27118
27037
  // Reset stalled so to rearm watchdog timer
@@ -27134,7 +27053,7 @@
27134
27053
  // Report stalled error once
27135
27054
  this.stallReported = true;
27136
27055
  var error = new Error("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
27137
- this.warn(error.message);
27056
+ logger.warn(error.message);
27138
27057
  hls.trigger(Events.ERROR, {
27139
27058
  type: ErrorTypes.MEDIA_ERROR,
27140
27059
  details: ErrorDetails.BUFFER_STALLED_ERROR,
@@ -27198,7 +27117,7 @@
27198
27117
  }
27199
27118
  }
27200
27119
  var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
27201
- this.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
27120
+ logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
27202
27121
  this.moved = true;
27203
27122
  this.stalled = null;
27204
27123
  media.currentTime = targetTime;
@@ -27237,7 +27156,7 @@
27237
27156
  var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
27238
27157
  // playback stalled in buffered area ... let's nudge currentTime to try to overcome this
27239
27158
  var error = new Error("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
27240
- this.warn(error.message);
27159
+ logger.warn(error.message);
27241
27160
  media.currentTime = targetTime;
27242
27161
  hls.trigger(Events.ERROR, {
27243
27162
  type: ErrorTypes.MEDIA_ERROR,
@@ -27247,7 +27166,7 @@
27247
27166
  });
27248
27167
  } else {
27249
27168
  var _error = new Error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
27250
- this.error(_error.message);
27169
+ logger.error(_error.message);
27251
27170
  hls.trigger(Events.ERROR, {
27252
27171
  type: ErrorTypes.MEDIA_ERROR,
27253
27172
  details: ErrorDetails.BUFFER_STALLED_ERROR,
@@ -27257,14 +27176,14 @@
27257
27176
  }
27258
27177
  };
27259
27178
  return GapController;
27260
- }(Logger);
27179
+ }();
27261
27180
 
27262
27181
  var TICK_INTERVAL = 100; // how often to tick in ms
27263
27182
  var StreamController = /*#__PURE__*/function (_BaseStreamController) {
27264
27183
  _inheritsLoose(StreamController, _BaseStreamController);
27265
27184
  function StreamController(hls, fragmentTracker, keyLoader) {
27266
27185
  var _this;
27267
- _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'stream-controller', PlaylistLevelType.MAIN) || this;
27186
+ _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[stream-controller]', PlaylistLevelType.MAIN) || this;
27268
27187
  _this.audioCodecSwap = false;
27269
27188
  _this.gapController = null;
27270
27189
  _this.level = -1;
@@ -27272,43 +27191,27 @@
27272
27191
  _this.altAudio = false;
27273
27192
  _this.audioOnly = false;
27274
27193
  _this.fragPlaying = null;
27194
+ _this.onvplaying = null;
27195
+ _this.onvseeked = null;
27275
27196
  _this.fragLastKbps = 0;
27276
27197
  _this.couldBacktrack = false;
27277
27198
  _this.backtrackFragment = null;
27278
27199
  _this.audioCodecSwitch = false;
27279
27200
  _this.videoBuffer = null;
27280
- _this.onMediaPlaying = function () {
27281
- // tick to speed up FRAG_CHANGED triggering
27282
- _this.tick();
27283
- };
27284
- _this.onMediaSeeked = function () {
27285
- var media = _this.media;
27286
- var currentTime = media ? media.currentTime : null;
27287
- if (isFiniteNumber(currentTime)) {
27288
- _this.log("Media seeked to " + currentTime.toFixed(3));
27289
- }
27290
-
27291
- // If seeked was issued before buffer was appended do not tick immediately
27292
- var bufferInfo = _this.getMainFwdBufferInfo();
27293
- if (bufferInfo === null || bufferInfo.len === 0) {
27294
- _this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
27295
- return;
27296
- }
27297
-
27298
- // tick to speed up FRAG_CHANGED triggering
27299
- _this.tick();
27300
- };
27301
- _this.registerListeners();
27201
+ _this._registerListeners();
27302
27202
  return _this;
27303
27203
  }
27304
27204
  var _proto = StreamController.prototype;
27305
- _proto.registerListeners = function registerListeners() {
27306
- _BaseStreamController.prototype.registerListeners.call(this);
27205
+ _proto._registerListeners = function _registerListeners() {
27307
27206
  var hls = this.hls;
27207
+ hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
27208
+ hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
27209
+ hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
27308
27210
  hls.on(Events.MANIFEST_PARSED, this.onManifestParsed, this);
27309
27211
  hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
27310
27212
  hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
27311
27213
  hls.on(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
27214
+ hls.on(Events.ERROR, this.onError, this);
27312
27215
  hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
27313
27216
  hls.on(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
27314
27217
  hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
@@ -27316,12 +27219,15 @@
27316
27219
  hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
27317
27220
  hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
27318
27221
  };
27319
- _proto.unregisterListeners = function unregisterListeners() {
27320
- _BaseStreamController.prototype.unregisterListeners.call(this);
27222
+ _proto._unregisterListeners = function _unregisterListeners() {
27321
27223
  var hls = this.hls;
27224
+ hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
27225
+ hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
27226
+ hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
27322
27227
  hls.off(Events.MANIFEST_PARSED, this.onManifestParsed, this);
27323
27228
  hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
27324
27229
  hls.off(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
27230
+ hls.off(Events.ERROR, this.onError, this);
27325
27231
  hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
27326
27232
  hls.off(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
27327
27233
  hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
@@ -27330,9 +27236,7 @@
27330
27236
  hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
27331
27237
  };
27332
27238
  _proto.onHandlerDestroying = function onHandlerDestroying() {
27333
- // @ts-ignore
27334
- this.onMediaPlaying = this.onMediaSeeked = null;
27335
- this.unregisterListeners();
27239
+ this._unregisterListeners();
27336
27240
  _BaseStreamController.prototype.onHandlerDestroying.call(this);
27337
27241
  };
27338
27242
  _proto.startLoad = function startLoad(startPosition) {
@@ -27647,15 +27551,18 @@
27647
27551
  _proto.onMediaAttached = function onMediaAttached(event, data) {
27648
27552
  _BaseStreamController.prototype.onMediaAttached.call(this, event, data);
27649
27553
  var media = data.media;
27650
- media.addEventListener('playing', this.onMediaPlaying);
27651
- media.addEventListener('seeked', this.onMediaSeeked);
27554
+ this.onvplaying = this.onMediaPlaying.bind(this);
27555
+ this.onvseeked = this.onMediaSeeked.bind(this);
27556
+ media.addEventListener('playing', this.onvplaying);
27557
+ media.addEventListener('seeked', this.onvseeked);
27652
27558
  this.gapController = new GapController(this.config, media, this.fragmentTracker, this.hls);
27653
27559
  };
27654
27560
  _proto.onMediaDetaching = function onMediaDetaching() {
27655
27561
  var media = this.media;
27656
- if (media) {
27657
- media.removeEventListener('playing', this.onMediaPlaying);
27658
- media.removeEventListener('seeked', this.onMediaSeeked);
27562
+ if (media && this.onvplaying && this.onvseeked) {
27563
+ media.removeEventListener('playing', this.onvplaying);
27564
+ media.removeEventListener('seeked', this.onvseeked);
27565
+ this.onvplaying = this.onvseeked = null;
27659
27566
  this.videoBuffer = null;
27660
27567
  }
27661
27568
  this.fragPlaying = null;
@@ -27665,6 +27572,27 @@
27665
27572
  }
27666
27573
  _BaseStreamController.prototype.onMediaDetaching.call(this);
27667
27574
  };
27575
+ _proto.onMediaPlaying = function onMediaPlaying() {
27576
+ // tick to speed up FRAG_CHANGED triggering
27577
+ this.tick();
27578
+ };
27579
+ _proto.onMediaSeeked = function onMediaSeeked() {
27580
+ var media = this.media;
27581
+ var currentTime = media ? media.currentTime : null;
27582
+ if (isFiniteNumber(currentTime)) {
27583
+ this.log("Media seeked to " + currentTime.toFixed(3));
27584
+ }
27585
+
27586
+ // If seeked was issued before buffer was appended do not tick immediately
27587
+ var bufferInfo = this.getMainFwdBufferInfo();
27588
+ if (bufferInfo === null || bufferInfo.len === 0) {
27589
+ this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
27590
+ return;
27591
+ }
27592
+
27593
+ // tick to speed up FRAG_CHANGED triggering
27594
+ this.tick();
27595
+ };
27668
27596
  _proto.onManifestLoading = function onManifestLoading() {
27669
27597
  // reset buffer on manifest loading
27670
27598
  this.log('Trigger BUFFER_RESET');
@@ -28411,10 +28339,6 @@
28411
28339
  * The configuration object provided on player instantiation.
28412
28340
  */
28413
28341
  this.userConfig = void 0;
28414
- /**
28415
- * The logger functions used by this player instance, configured on player instantiation.
28416
- */
28417
- this.logger = void 0;
28418
28342
  this.coreComponents = void 0;
28419
28343
  this.networkControllers = void 0;
28420
28344
  this.started = false;
@@ -28434,11 +28358,11 @@
28434
28358
  this._media = null;
28435
28359
  this.url = null;
28436
28360
  this.triggeringException = void 0;
28437
- var logger = this.logger = enableLogs(userConfig.debug || false, 'Hls instance');
28438
- var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig, logger);
28361
+ enableLogs(userConfig.debug || false, 'Hls instance');
28362
+ var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig);
28439
28363
  this.userConfig = userConfig;
28440
28364
  if (config.progressive) {
28441
- enableStreamingMode(config, logger);
28365
+ enableStreamingMode(config);
28442
28366
  }
28443
28367
 
28444
28368
  // core controllers and network loaders
@@ -28546,7 +28470,7 @@
28546
28470
  try {
28547
28471
  return this.emit(event, event, eventObject);
28548
28472
  } catch (error) {
28549
- this.logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
28473
+ logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
28550
28474
  // Prevent recursion in error event handlers that throw #5497
28551
28475
  if (!this.triggeringException) {
28552
28476
  this.triggeringException = true;
@@ -28572,7 +28496,7 @@
28572
28496
  * Dispose of the instance
28573
28497
  */;
28574
28498
  _proto.destroy = function destroy() {
28575
- this.logger.log('destroy');
28499
+ logger.log('destroy');
28576
28500
  this.trigger(Events.DESTROYING, undefined);
28577
28501
  this.detachMedia();
28578
28502
  this.removeAllListeners();
@@ -28597,7 +28521,7 @@
28597
28521
  * Attaches Hls.js to a media element
28598
28522
  */;
28599
28523
  _proto.attachMedia = function attachMedia(media) {
28600
- this.logger.log('attachMedia');
28524
+ logger.log('attachMedia');
28601
28525
  this._media = media;
28602
28526
  this.trigger(Events.MEDIA_ATTACHING, {
28603
28527
  media: media
@@ -28608,7 +28532,7 @@
28608
28532
  * Detach Hls.js from the media
28609
28533
  */;
28610
28534
  _proto.detachMedia = function detachMedia() {
28611
- this.logger.log('detachMedia');
28535
+ logger.log('detachMedia');
28612
28536
  this.trigger(Events.MEDIA_DETACHING, undefined);
28613
28537
  this._media = null;
28614
28538
  }
@@ -28625,7 +28549,7 @@
28625
28549
  });
28626
28550
  this._autoLevelCapping = -1;
28627
28551
  this._maxHdcpLevel = null;
28628
- this.logger.log("loadSource:" + loadingSource);
28552
+ logger.log("loadSource:" + loadingSource);
28629
28553
  if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
28630
28554
  this.detachMedia();
28631
28555
  this.attachMedia(media);
@@ -28647,7 +28571,7 @@
28647
28571
  if (startPosition === void 0) {
28648
28572
  startPosition = -1;
28649
28573
  }
28650
- this.logger.log("startLoad(" + startPosition + ")");
28574
+ logger.log("startLoad(" + startPosition + ")");
28651
28575
  this.started = true;
28652
28576
  this.networkControllers.forEach(function (controller) {
28653
28577
  controller.startLoad(startPosition);
@@ -28658,7 +28582,7 @@
28658
28582
  * Stop loading of any stream data.
28659
28583
  */;
28660
28584
  _proto.stopLoad = function stopLoad() {
28661
- this.logger.log('stopLoad');
28585
+ logger.log('stopLoad');
28662
28586
  this.started = false;
28663
28587
  this.networkControllers.forEach(function (controller) {
28664
28588
  controller.stopLoad();
@@ -28694,7 +28618,7 @@
28694
28618
  * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
28695
28619
  */;
28696
28620
  _proto.swapAudioCodec = function swapAudioCodec() {
28697
- this.logger.log('swapAudioCodec');
28621
+ logger.log('swapAudioCodec');
28698
28622
  this.streamController.swapAudioCodec();
28699
28623
  }
28700
28624
 
@@ -28705,7 +28629,7 @@
28705
28629
  * Automatic recovery of media-errors by this process is configurable.
28706
28630
  */;
28707
28631
  _proto.recoverMediaError = function recoverMediaError() {
28708
- this.logger.log('recoverMediaError');
28632
+ logger.log('recoverMediaError');
28709
28633
  var media = this._media;
28710
28634
  this.detachMedia();
28711
28635
  if (media) {
@@ -28760,7 +28684,7 @@
28760
28684
  * 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.
28761
28685
  */,
28762
28686
  set: function set(newLevel) {
28763
- this.logger.log("set currentLevel:" + newLevel);
28687
+ logger.log("set currentLevel:" + newLevel);
28764
28688
  this.levelController.manualLevel = newLevel;
28765
28689
  this.streamController.immediateLevelSwitch();
28766
28690
  }
@@ -28781,7 +28705,7 @@
28781
28705
  * @param newLevel - Pass -1 for automatic level selection
28782
28706
  */,
28783
28707
  set: function set(newLevel) {
28784
- this.logger.log("set nextLevel:" + newLevel);
28708
+ logger.log("set nextLevel:" + newLevel);
28785
28709
  this.levelController.manualLevel = newLevel;
28786
28710
  this.streamController.nextLevelSwitch();
28787
28711
  }
@@ -28802,7 +28726,7 @@
28802
28726
  * @param newLevel - Pass -1 for automatic level selection
28803
28727
  */,
28804
28728
  set: function set(newLevel) {
28805
- this.logger.log("set loadLevel:" + newLevel);
28729
+ logger.log("set loadLevel:" + newLevel);
28806
28730
  this.levelController.manualLevel = newLevel;
28807
28731
  }
28808
28732
 
@@ -28837,7 +28761,7 @@
28837
28761
  * Sets "first-level", see getter.
28838
28762
  */,
28839
28763
  set: function set(newLevel) {
28840
- this.logger.log("set firstLevel:" + newLevel);
28764
+ logger.log("set firstLevel:" + newLevel);
28841
28765
  this.levelController.firstLevel = newLevel;
28842
28766
  }
28843
28767
 
@@ -28864,7 +28788,7 @@
28864
28788
  * (determined from download of first segment)
28865
28789
  */,
28866
28790
  set: function set(newLevel) {
28867
- this.logger.log("set startLevel:" + newLevel);
28791
+ logger.log("set startLevel:" + newLevel);
28868
28792
  // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
28869
28793
  if (newLevel !== -1) {
28870
28794
  newLevel = Math.max(newLevel, this.minAutoLevel);
@@ -28917,7 +28841,7 @@
28917
28841
  */
28918
28842
  function set(newLevel) {
28919
28843
  if (this._autoLevelCapping !== newLevel) {
28920
- this.logger.log("set autoLevelCapping:" + newLevel);
28844
+ logger.log("set autoLevelCapping:" + newLevel);
28921
28845
  this._autoLevelCapping = newLevel;
28922
28846
  this.levelController.checkMaxAutoUpdated();
28923
28847
  }
@@ -29242,7 +29166,7 @@
29242
29166
  * Get the video-dev/hls.js package version.
29243
29167
  */
29244
29168
  function get() {
29245
- return "1.5.2-0.canary.9924";
29169
+ return "1.5.2";
29246
29170
  }
29247
29171
  }, {
29248
29172
  key: "Events",