hls.js 1.5.6-0.canary.9999 → 1.5.6

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 (69) hide show
  1. package/README.md +0 -1
  2. package/dist/hls-demo.js +0 -10
  3. package/dist/hls-demo.js.map +1 -1
  4. package/dist/hls.js +1169 -2069
  5. package/dist/hls.js.d.ts +51 -65
  6. package/dist/hls.js.map +1 -1
  7. package/dist/hls.light.js +875 -1158
  8. package/dist/hls.light.js.map +1 -1
  9. package/dist/hls.light.min.js +1 -1
  10. package/dist/hls.light.min.js.map +1 -1
  11. package/dist/hls.light.mjs +709 -993
  12. package/dist/hls.light.mjs.map +1 -1
  13. package/dist/hls.min.js +1 -1
  14. package/dist/hls.min.js.map +1 -1
  15. package/dist/hls.mjs +869 -1756
  16. package/dist/hls.mjs.map +1 -1
  17. package/dist/hls.worker.js +1 -1
  18. package/dist/hls.worker.js.map +1 -1
  19. package/package.json +20 -20
  20. package/src/config.ts +2 -3
  21. package/src/controller/abr-controller.ts +40 -31
  22. package/src/controller/audio-stream-controller.ts +16 -15
  23. package/src/controller/audio-track-controller.ts +1 -1
  24. package/src/controller/base-playlist-controller.ts +8 -20
  25. package/src/controller/base-stream-controller.ts +33 -149
  26. package/src/controller/buffer-controller.ts +11 -11
  27. package/src/controller/cap-level-controller.ts +2 -1
  28. package/src/controller/cmcd-controller.ts +6 -27
  29. package/src/controller/content-steering-controller.ts +6 -8
  30. package/src/controller/eme-controller.ts +22 -9
  31. package/src/controller/error-controller.ts +8 -6
  32. package/src/controller/fps-controller.ts +3 -2
  33. package/src/controller/gap-controller.ts +16 -43
  34. package/src/controller/latency-controller.ts +11 -9
  35. package/src/controller/level-controller.ts +18 -12
  36. package/src/controller/stream-controller.ts +34 -27
  37. package/src/controller/subtitle-stream-controller.ts +14 -13
  38. package/src/controller/subtitle-track-controller.ts +3 -5
  39. package/src/controller/timeline-controller.ts +30 -23
  40. package/src/crypt/aes-crypto.ts +2 -21
  41. package/src/crypt/decrypter.ts +18 -32
  42. package/src/crypt/fast-aes-key.ts +5 -24
  43. package/src/demux/audio/adts.ts +4 -9
  44. package/src/demux/sample-aes.ts +0 -2
  45. package/src/demux/transmuxer-interface.ts +12 -4
  46. package/src/demux/transmuxer-worker.ts +4 -4
  47. package/src/demux/transmuxer.ts +3 -16
  48. package/src/demux/tsdemuxer.ts +37 -71
  49. package/src/demux/video/avc-video-parser.ts +119 -208
  50. package/src/demux/video/base-video-parser.ts +2 -134
  51. package/src/demux/video/exp-golomb.ts +208 -0
  52. package/src/events.ts +0 -7
  53. package/src/hls.ts +34 -42
  54. package/src/loader/fragment-loader.ts +2 -9
  55. package/src/loader/key-loader.ts +0 -2
  56. package/src/loader/level-key.ts +9 -10
  57. package/src/loader/playlist-loader.ts +5 -4
  58. package/src/remux/mp4-generator.ts +1 -196
  59. package/src/remux/mp4-remuxer.ts +7 -23
  60. package/src/task-loop.ts +2 -5
  61. package/src/types/component-api.ts +0 -2
  62. package/src/types/demuxer.ts +0 -3
  63. package/src/types/events.ts +0 -4
  64. package/src/utils/codecs.ts +4 -33
  65. package/src/utils/logger.ts +24 -54
  66. package/src/utils/mp4-tools.ts +6 -4
  67. package/src/crypt/decrypter-aes-mode.ts +0 -4
  68. package/src/demux/video/hevc-video-parser.ts +0 -746
  69. package/src/utils/encryption-methods-util.ts +0 -21
package/package.json CHANGED
@@ -58,39 +58,39 @@
58
58
  "test:func:sauce": "SAUCE=1 UA=safari OS='OS X 10.15' BABEL_ENV=development mocha --require @babel/register tests/functional/auto/setup.js --timeout 40000 --exit",
59
59
  "type-check": "tsc --noEmit",
60
60
  "type-check:watch": "npm run type-check -- --watch",
61
- "prepare": "husky"
61
+ "prepare": "husky install"
62
62
  },
63
63
  "devDependencies": {
64
- "@babel/core": "7.23.9",
64
+ "@babel/core": "7.23.7",
65
65
  "@babel/helper-module-imports": "7.22.15",
66
66
  "@babel/plugin-proposal-class-properties": "7.18.6",
67
67
  "@babel/plugin-proposal-object-rest-spread": "7.20.7",
68
68
  "@babel/plugin-proposal-optional-chaining": "7.21.0",
69
69
  "@babel/plugin-transform-object-assign": "7.23.3",
70
- "@babel/preset-env": "7.23.9",
70
+ "@babel/preset-env": "7.23.7",
71
71
  "@babel/preset-typescript": "7.23.3",
72
72
  "@babel/register": "7.23.7",
73
- "@microsoft/api-documenter": "7.23.23",
74
- "@microsoft/api-extractor": "7.40.1",
73
+ "@microsoft/api-documenter": "7.23.16",
74
+ "@microsoft/api-extractor": "7.39.1",
75
75
  "@rollup/plugin-alias": "5.1.0",
76
76
  "@rollup/plugin-babel": "6.0.4",
77
77
  "@rollup/plugin-commonjs": "25.0.7",
78
78
  "@rollup/plugin-node-resolve": "15.2.3",
79
79
  "@rollup/plugin-replace": "5.0.5",
80
80
  "@rollup/plugin-terser": "0.4.4",
81
- "@rollup/plugin-typescript": "11.1.6",
82
- "@svta/common-media-library": "0.6.2",
81
+ "@rollup/plugin-typescript": "11.1.5",
82
+ "@svta/common-media-library": "0.6.1",
83
83
  "@types/chai": "4.3.11",
84
84
  "@types/chart.js": "2.9.41",
85
85
  "@types/mocha": "10.0.6",
86
86
  "@types/sinon-chai": "3.2.12",
87
- "@typescript-eslint/eslint-plugin": "6.21.0",
88
- "@typescript-eslint/parser": "6.21.0",
87
+ "@typescript-eslint/eslint-plugin": "6.17.0",
88
+ "@typescript-eslint/parser": "6.17.0",
89
89
  "babel-loader": "9.1.3",
90
90
  "babel-plugin-transform-remove-console": "6.9.4",
91
- "chai": "4.4.1",
91
+ "chai": "4.3.10",
92
92
  "chart.js": "2.9.4",
93
- "chromedriver": "121.0.0",
93
+ "chromedriver": "120.0.1",
94
94
  "doctoc": "2.2.1",
95
95
  "es-check": "7.1.1",
96
96
  "eslint": "8.56.0",
@@ -101,7 +101,7 @@
101
101
  "eslint-plugin-promise": "6.1.1",
102
102
  "eventemitter3": "5.0.1",
103
103
  "http-server": "14.1.1",
104
- "husky": "9.0.10",
104
+ "husky": "8.0.3",
105
105
  "jsonpack": "1.1.5",
106
106
  "karma": "6.4.2",
107
107
  "karma-chrome-launcher": "3.2.0",
@@ -111,24 +111,24 @@
111
111
  "karma-rollup-preprocessor": "github:jlmakes/karma-rollup-preprocessor#7a7268d91149307b3cf2888ee4e65ccd079955a3",
112
112
  "karma-sinon-chai": "2.0.2",
113
113
  "karma-sourcemap-loader": "0.4.0",
114
- "lint-staged": "15.2.2",
114
+ "lint-staged": "15.2.0",
115
115
  "markdown-styles": "3.2.0",
116
116
  "micromatch": "4.0.5",
117
117
  "mocha": "10.2.0",
118
118
  "node-fetch": "3.3.2",
119
- "npm-run-all2": "5.0.2",
120
- "prettier": "3.2.4",
119
+ "npm-run-all": "4.1.5",
120
+ "prettier": "3.1.1",
121
121
  "promise-polyfill": "8.3.0",
122
- "rollup": "4.9.6",
122
+ "rollup": "4.9.4",
123
123
  "rollup-plugin-istanbul": "5.0.0",
124
124
  "sauce-connect-launcher": "1.3.2",
125
- "selenium-webdriver": "4.17.0",
126
- "semver": "7.6.0",
125
+ "selenium-webdriver": "4.16.0",
126
+ "semver": "7.5.4",
127
127
  "sinon": "17.0.1",
128
128
  "sinon-chai": "3.7.0",
129
129
  "typescript": "5.3.3",
130
130
  "url-toolkit": "2.2.5",
131
- "wrangler": "3.26.0"
131
+ "wrangler": "3.22.4"
132
132
  },
133
- "version": "1.5.6-0.canary.9999"
133
+ "version": "1.5.6"
134
134
  }
package/src/config.ts CHANGED
@@ -17,10 +17,10 @@ import XhrLoader from './utils/xhr-loader';
17
17
  import FetchLoader, { fetchSupported } from './utils/fetch-loader';
18
18
  import Cues from './utils/cues';
19
19
  import { requestMediaKeySystemAccess } from './utils/mediakeys-helper';
20
+ import { ILogger, logger } from './utils/logger';
20
21
 
21
22
  import type Hls from './hls';
22
23
  import type { CuesInterface } from './utils/cues';
23
- import type { ILogger } from './utils/logger';
24
24
  import type { MediaKeyFunc, KeySystems } from './utils/mediakeys-helper';
25
25
  import type {
26
26
  FragmentLoaderContext,
@@ -558,7 +558,6 @@ function timelineConfig(): TimelineControllerConfig {
558
558
  export function mergeConfig(
559
559
  defaultConfig: HlsConfig,
560
560
  userConfig: Partial<HlsConfig>,
561
- logger: ILogger,
562
561
  ): HlsConfig {
563
562
  if (
564
563
  (userConfig.liveSyncDurationCount ||
@@ -665,7 +664,7 @@ function deepCpy(obj: any): any {
665
664
  /**
666
665
  * @ignore
667
666
  */
668
- export function enableStreamingMode(config: HlsConfig, logger: ILogger) {
667
+ export function enableStreamingMode(config) {
669
668
  const currentLoader = config.loader;
670
669
  if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
671
670
  // If a developer has configured their own loader, respect that choice
@@ -2,7 +2,7 @@ import EwmaBandWidthEstimator from '../utils/ewma-bandwidth-estimator';
2
2
  import { Events } from '../events';
3
3
  import { ErrorDetails } from '../errors';
4
4
  import { PlaylistLevelType } from '../types/loader';
5
- import { Logger } from '../utils/logger';
5
+ import { logger } from '../utils/logger';
6
6
  import {
7
7
  SUPPORTED_INFO_DEFAULT,
8
8
  getMediaDecodingInfoPromise,
@@ -31,7 +31,7 @@ import type {
31
31
  } from '../types/events';
32
32
  import type { AbrComponentAPI } from '../types/component-api';
33
33
 
34
- class AbrController extends Logger implements AbrComponentAPI {
34
+ class AbrController implements AbrComponentAPI {
35
35
  protected hls: Hls;
36
36
  private lastLevelLoadSec: number = 0;
37
37
  private lastLoadedFragLevel: number = -1;
@@ -48,7 +48,6 @@ class AbrController extends Logger implements AbrComponentAPI {
48
48
  public bwEstimator: EwmaBandWidthEstimator;
49
49
 
50
50
  constructor(hls: Hls) {
51
- super('abr', hls.logger);
52
51
  this.hls = hls;
53
52
  this.bwEstimator = this.initEstimator();
54
53
  this.registerListeners();
@@ -56,7 +55,7 @@ class AbrController extends Logger implements AbrComponentAPI {
56
55
 
57
56
  public resetEstimator(abrEwmaDefaultEstimate?: number) {
58
57
  if (abrEwmaDefaultEstimate) {
59
- this.log(`setting initial bwe to ${abrEwmaDefaultEstimate}`);
58
+ logger.log(`setting initial bwe to ${abrEwmaDefaultEstimate}`);
60
59
  this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
61
60
  }
62
61
  this.firstSelection = -1;
@@ -356,7 +355,7 @@ class AbrController extends Logger implements AbrComponentAPI {
356
355
  }
357
356
 
358
357
  this.clearTimer();
359
- this.warn(`Fragment ${frag.sn}${
358
+ logger.warn(`[abr] Fragment ${frag.sn}${
360
359
  part ? ' part ' + part.index : ''
361
360
  } of level ${frag.level} is loading too slowly;
362
361
  Time to underbuffer: ${bufferStarvationDelay.toFixed(3)} s
@@ -480,8 +479,8 @@ class AbrController extends Logger implements AbrComponentAPI {
480
479
  }
481
480
  const firstLevel = this.hls.firstLevel;
482
481
  const clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
483
- this.warn(
484
- `Could not find best starting auto level. Defaulting to first in playlist ${firstLevel} clamped to ${clamped}`,
482
+ logger.warn(
483
+ `[abr] Could not find best starting auto level. Defaulting to first in playlist ${firstLevel} clamped to ${clamped}`,
485
484
  );
486
485
  return clamped;
487
486
  }
@@ -534,27 +533,20 @@ class AbrController extends Logger implements AbrComponentAPI {
534
533
  }
535
534
 
536
535
  private getAutoLevelKey(): string {
537
- return `${this.getBwEstimate()}_${this.hls.mainForwardBufferInfo?.len}`;
536
+ return `${this.getBwEstimate()}_${this.getStarvationDelay().toFixed(2)}`;
538
537
  }
539
538
 
540
539
  private getNextABRAutoLevel(): number {
541
540
  const { fragCurrent, partCurrent, hls } = this;
542
- const { maxAutoLevel, config, minAutoLevel, media } = hls;
541
+ const { maxAutoLevel, config, minAutoLevel } = hls;
543
542
  const currentFragDuration = partCurrent
544
543
  ? partCurrent.duration
545
544
  : fragCurrent
546
545
  ? fragCurrent.duration
547
546
  : 0;
548
-
549
- // playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as
550
- // if we're playing back at the normal rate.
551
- const playbackRate =
552
- media && media.playbackRate !== 0 ? Math.abs(media.playbackRate) : 1.0;
553
547
  const avgbw = this.getBwEstimate();
554
548
  // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted.
555
- const bufferInfo = hls.mainForwardBufferInfo;
556
- const bufferStarvationDelay =
557
- (bufferInfo ? bufferInfo.len : 0) / playbackRate;
549
+ const bufferStarvationDelay = this.getStarvationDelay();
558
550
 
559
551
  let bwFactor = config.abrBandWidthFactor;
560
552
  let bwUpFactor = config.abrBandWidthUpFactor;
@@ -592,8 +584,8 @@ class AbrController extends Logger implements AbrComponentAPI {
592
584
  ? Math.min(currentFragDuration, config.maxLoadingDelay)
593
585
  : config.maxLoadingDelay;
594
586
  maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
595
- this.info(
596
- `bitrate test took ${Math.round(
587
+ logger.info(
588
+ `[abr] bitrate test took ${Math.round(
597
589
  1000 * bitrateTestDelay,
598
590
  )}ms, set first fragment max fetchDuration to ${Math.round(
599
591
  1000 * maxStarvationDelay,
@@ -612,8 +604,8 @@ class AbrController extends Logger implements AbrComponentAPI {
612
604
  bwFactor,
613
605
  bwUpFactor,
614
606
  );
615
- this.info(
616
- `${
607
+ logger.info(
608
+ `[abr] ${
617
609
  bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'
618
610
  }, optimal quality level ${bestLevel}`,
619
611
  );
@@ -630,6 +622,20 @@ class AbrController extends Logger implements AbrComponentAPI {
630
622
  return hls.loadLevel;
631
623
  }
632
624
 
625
+ private getStarvationDelay(): number {
626
+ const hls = this.hls;
627
+ const media = hls.media;
628
+ if (!media) {
629
+ return Infinity;
630
+ }
631
+ // playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as
632
+ // if we're playing back at the normal rate.
633
+ const playbackRate =
634
+ media && media.playbackRate !== 0 ? Math.abs(media.playbackRate) : 1.0;
635
+ const bufferInfo = hls.mainForwardBufferInfo;
636
+ return (bufferInfo ? bufferInfo.len : 0) / playbackRate;
637
+ }
638
+
633
639
  private getBwEstimate(): number {
634
640
  return this.bwEstimator.canEstimate()
635
641
  ? this.bwEstimator.getEstimate()
@@ -692,7 +698,7 @@ class AbrController extends Logger implements AbrComponentAPI {
692
698
  : videoRanges[0];
693
699
  currentFrameRate = minFramerate;
694
700
  currentBw = Math.max(currentBw, minBitrate);
695
- this.log(`picked start tier ${JSON.stringify(startTier)}`);
701
+ logger.log(`[abr] picked start tier ${JSON.stringify(startTier)}`);
696
702
  } else {
697
703
  currentCodecSet = level?.codecSet;
698
704
  currentVideoRange = level?.videoRange;
@@ -738,23 +744,26 @@ class AbrController extends Logger implements AbrComponentAPI {
738
744
  mediaCapabilities,
739
745
  );
740
746
  levelInfo.supportedPromise.then((decodingInfo) => {
747
+ if (!this.hls) {
748
+ return;
749
+ }
741
750
  levelInfo.supportedResult = decodingInfo;
742
751
  const levels = this.hls.levels;
743
752
  const index = levels.indexOf(levelInfo);
744
753
  if (decodingInfo.error) {
745
- this.warn(
746
- `MediaCapabilities decodingInfo error: "${
754
+ logger.warn(
755
+ `[abr] MediaCapabilities decodingInfo error: "${
747
756
  decodingInfo.error
748
757
  }" for level ${index} ${JSON.stringify(decodingInfo)}`,
749
758
  );
750
759
  } else if (!decodingInfo.supported) {
751
- this.warn(
752
- `Unsupported MediaCapabilities decodingInfo result for level ${index} ${JSON.stringify(
760
+ logger.warn(
761
+ `[abr] Unsupported MediaCapabilities decodingInfo result for level ${index} ${JSON.stringify(
753
762
  decodingInfo,
754
763
  )}`,
755
764
  );
756
765
  if (index > -1 && levels.length > 1) {
757
- this.log(`Removing unsupported level ${index}`);
766
+ logger.log(`[abr] Removing unsupported level ${index}`);
758
767
  this.hls.removeLevel(index);
759
768
  }
760
769
  }
@@ -833,8 +842,8 @@ class AbrController extends Logger implements AbrComponentAPI {
833
842
  (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)
834
843
  ) {
835
844
  if (levelsSkipped.length) {
836
- this.trace(
837
- `Skipped level(s) ${levelsSkipped.join(
845
+ logger.trace(
846
+ `[abr] Skipped level(s) ${levelsSkipped.join(
838
847
  ',',
839
848
  )} of ${maxAutoLevel} max with CODECS and VIDEO-RANGE:"${
840
849
  levels[levelsSkipped[0]].codecs
@@ -843,8 +852,8 @@ class AbrController extends Logger implements AbrComponentAPI {
843
852
  }" ${currentVideoRange}`,
844
853
  );
845
854
  }
846
- this.info(
847
- `switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(
855
+ logger.info(
856
+ `[abr] switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(
848
857
  adjustedbw,
849
858
  )})-bitrate=${Math.round(
850
859
  adjustedbw - bitrate,
@@ -71,27 +71,30 @@ class AudioStreamController
71
71
  hls,
72
72
  fragmentTracker,
73
73
  keyLoader,
74
- 'audio-stream-controller',
74
+ '[audio-stream-controller]',
75
75
  PlaylistLevelType.AUDIO,
76
76
  );
77
- this.registerListeners();
77
+ this._registerListeners();
78
78
  }
79
79
 
80
80
  protected onHandlerDestroying() {
81
- this.unregisterListeners();
81
+ this._unregisterListeners();
82
82
  super.onHandlerDestroying();
83
83
  this.mainDetails = null;
84
84
  this.bufferedTrack = null;
85
85
  this.switchingTrack = null;
86
86
  }
87
87
 
88
- protected registerListeners() {
89
- super.registerListeners();
88
+ private _registerListeners() {
90
89
  const { hls } = this;
90
+ hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
91
+ hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
92
+ hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
91
93
  hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
92
94
  hls.on(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
93
95
  hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
94
96
  hls.on(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
97
+ hls.on(Events.ERROR, this.onError, this);
95
98
  hls.on(Events.BUFFER_RESET, this.onBufferReset, this);
96
99
  hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
97
100
  hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
@@ -100,16 +103,16 @@ class AudioStreamController
100
103
  hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
101
104
  }
102
105
 
103
- protected unregisterListeners() {
106
+ private _unregisterListeners() {
104
107
  const { hls } = this;
105
- if (!hls) {
106
- return;
107
- }
108
- super.unregisterListeners();
108
+ hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
109
+ hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
110
+ hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
109
111
  hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
110
112
  hls.off(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
111
113
  hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
112
114
  hls.off(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
115
+ hls.off(Events.ERROR, this.onError, this);
113
116
  hls.off(Events.BUFFER_RESET, this.onBufferReset, this);
114
117
  hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
115
118
  hls.off(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
@@ -278,14 +281,12 @@ class AudioStreamController
278
281
  const { hls, levels, media, trackId } = this;
279
282
  const config = hls.config;
280
283
 
281
- // 1. if buffering is suspended
282
- // 2. if video not attached AND
284
+ // 1. if video not attached AND
283
285
  // start fragment already requested OR start frag prefetch not enabled
284
- // 3. if tracks or track not loaded and selected
286
+ // 2. if tracks or track not loaded and selected
285
287
  // then exit loop
286
288
  // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
287
289
  if (
288
- !this.buffering ||
289
290
  (!media && (this.startFragRequested || !config.startFragPrefetch)) ||
290
291
  !levels?.[trackId]
291
292
  ) {
@@ -712,7 +713,7 @@ class AudioStreamController
712
713
  this.fragBufferedComplete(frag, part);
713
714
  }
714
715
 
715
- protected onError(event: Events.ERROR, data: ErrorData) {
716
+ private onError(event: Events.ERROR, data: ErrorData) {
716
717
  if (data.fatal) {
717
718
  this.state = State.ERROR;
718
719
  return;
@@ -33,7 +33,7 @@ class AudioTrackController extends BasePlaylistController {
33
33
  private selectDefaultTrack: boolean = true;
34
34
 
35
35
  constructor(hls: Hls) {
36
- super(hls, 'audio-track-controller');
36
+ super(hls, '[audio-track-controller]');
37
37
  this.registerListeners();
38
38
  }
39
39
 
@@ -5,7 +5,7 @@ import { computeReloadInterval, mergeDetails } from '../utils/level-helper';
5
5
  import { ErrorData } from '../types/events';
6
6
  import { getRetryDelay, isTimeoutError } from '../utils/error-helper';
7
7
  import { NetworkErrorAction } from './error-controller';
8
- import { Logger } from '../utils/logger';
8
+ import { logger } from '../utils/logger';
9
9
  import type { LevelDetails } from '../loader/level-details';
10
10
  import type { MediaPlaylist } from '../types/media-playlist';
11
11
  import type {
@@ -14,17 +14,17 @@ import type {
14
14
  TrackLoadedData,
15
15
  } from '../types/events';
16
16
 
17
- export default class BasePlaylistController
18
- extends Logger
19
- implements NetworkComponentAPI
20
- {
17
+ export default class BasePlaylistController implements NetworkComponentAPI {
21
18
  protected hls: Hls;
22
19
  protected timer: number = -1;
23
20
  protected requestScheduled: number = -1;
24
21
  protected canLoad: boolean = false;
22
+ protected log: (msg: any) => void;
23
+ protected warn: (msg: any) => void;
25
24
 
26
25
  constructor(hls: Hls, logPrefix: string) {
27
- super(logPrefix, hls.logger);
26
+ this.log = logger.log.bind(logger, `${logPrefix}:`);
27
+ this.warn = logger.warn.bind(logger, `${logPrefix}:`);
28
28
  this.hls = hls;
29
29
  }
30
30
 
@@ -65,7 +65,7 @@ export default class BasePlaylistController
65
65
  try {
66
66
  uri = new self.URL(attr.URI, previous.url).href;
67
67
  } catch (error) {
68
- this.warn(
68
+ logger.warn(
69
69
  `Could not construct new URL for Rendition Report: ${error}`,
70
70
  );
71
71
  uri = attr.URI || '';
@@ -192,19 +192,7 @@ export default class BasePlaylistController
192
192
  details.targetduration * 1.5,
193
193
  );
194
194
  if (currentGoal > 0) {
195
- if (cdnAge > details.targetduration * 3) {
196
- // Omit segment and part directives when the last response was more than 3 target durations ago,
197
- this.log(
198
- `Playlist last advanced ${lastAdvanced.toFixed(
199
- 2,
200
- )}s ago. Omitting segment and part directives.`,
201
- );
202
- msn = undefined;
203
- part = undefined;
204
- } else if (
205
- previousDetails?.tuneInGoal &&
206
- cdnAge - details.partTarget > previousDetails.tuneInGoal
207
- ) {
195
+ if (previousDetails && currentGoal > previousDetails.tuneInGoal) {
208
196
  // If we attempted to get the next or latest playlist update, but currentGoal increased,
209
197
  // then we either can't catchup, or the "age" header cannot be trusted.
210
198
  this.warn(