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/package.json CHANGED
@@ -67,10 +67,10 @@
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.8",
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.19",
73
+ "@microsoft/api-documenter": "7.23.16",
74
74
  "@microsoft/api-extractor": "7.39.1",
75
75
  "@rollup/plugin-alias": "5.1.0",
76
76
  "@rollup/plugin-babel": "6.0.4",
@@ -78,17 +78,17 @@
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",
81
+ "@rollup/plugin-typescript": "11.1.5",
82
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.19.1",
88
- "@typescript-eslint/parser": "6.19.1",
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
93
  "chromedriver": "120.0.1",
94
94
  "doctoc": "2.2.1",
@@ -119,7 +119,7 @@
119
119
  "npm-run-all": "4.1.5",
120
120
  "prettier": "3.1.1",
121
121
  "promise-polyfill": "8.3.0",
122
- "rollup": "4.9.5",
122
+ "rollup": "4.9.4",
123
123
  "rollup-plugin-istanbul": "5.0.0",
124
124
  "sauce-connect-launcher": "1.3.2",
125
125
  "selenium-webdriver": "4.16.0",
@@ -128,7 +128,7 @@
128
128
  "sinon-chai": "3.7.0",
129
129
  "typescript": "5.3.3",
130
130
  "url-toolkit": "2.2.5",
131
- "wrangler": "3.24.0"
131
+ "wrangler": "3.22.4"
132
132
  },
133
- "version": "1.5.2-0.canary.9924"
133
+ "version": "1.5.2"
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;
@@ -287,7 +286,7 @@ class AbrController extends Logger implements AbrComponentAPI {
287
286
  const level = levels[frag.level];
288
287
  const expectedLen =
289
288
  stats.total ||
290
- Math.max(stats.loaded, Math.round((duration * level.maxBitrate) / 8));
289
+ Math.max(stats.loaded, Math.round((duration * level.averageBitrate) / 8));
291
290
  let timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
292
291
  if (timeStreaming < 1 && loadedFirstByte) {
293
292
  timeStreaming = Math.min(timeLoading, (stats.loaded * 8) / bwEstimate);
@@ -347,7 +346,7 @@ class AbrController extends Logger implements AbrComponentAPI {
347
346
  // If there has been no loading progress, sample TTFB
348
347
  this.bwEstimator.sampleTTFB(timeLoading);
349
348
  }
350
- const nextLoadLevelBitrate = levels[nextLoadLevel].bitrate;
349
+ const nextLoadLevelBitrate = levels[nextLoadLevel].maxBitrate;
351
350
  if (
352
351
  this.getBwEstimate() * this.hls.config.abrBandWidthUpFactor >
353
352
  nextLoadLevelBitrate
@@ -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
  }
@@ -592,8 +591,8 @@ class AbrController extends Logger implements AbrComponentAPI {
592
591
  ? Math.min(currentFragDuration, config.maxLoadingDelay)
593
592
  : config.maxLoadingDelay;
594
593
  maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
595
- this.info(
596
- `bitrate test took ${Math.round(
594
+ logger.info(
595
+ `[abr] bitrate test took ${Math.round(
597
596
  1000 * bitrateTestDelay,
598
597
  )}ms, set first fragment max fetchDuration to ${Math.round(
599
598
  1000 * maxStarvationDelay,
@@ -612,8 +611,8 @@ class AbrController extends Logger implements AbrComponentAPI {
612
611
  bwFactor,
613
612
  bwUpFactor,
614
613
  );
615
- this.info(
616
- `${
614
+ logger.info(
615
+ `[abr] ${
617
616
  bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'
618
617
  }, optimal quality level ${bestLevel}`,
619
618
  );
@@ -692,7 +691,7 @@ class AbrController extends Logger implements AbrComponentAPI {
692
691
  : videoRanges[0];
693
692
  currentFrameRate = minFramerate;
694
693
  currentBw = Math.max(currentBw, minBitrate);
695
- this.log(`picked start tier ${JSON.stringify(startTier)}`);
694
+ logger.log(`[abr] picked start tier ${JSON.stringify(startTier)}`);
696
695
  } else {
697
696
  currentCodecSet = level?.codecSet;
698
697
  currentVideoRange = level?.videoRange;
@@ -742,19 +741,19 @@ class AbrController extends Logger implements AbrComponentAPI {
742
741
  const levels = this.hls.levels;
743
742
  const index = levels.indexOf(levelInfo);
744
743
  if (decodingInfo.error) {
745
- this.warn(
746
- `MediaCapabilities decodingInfo error: "${
744
+ logger.warn(
745
+ `[abr] MediaCapabilities decodingInfo error: "${
747
746
  decodingInfo.error
748
747
  }" for level ${index} ${JSON.stringify(decodingInfo)}`,
749
748
  );
750
749
  } else if (!decodingInfo.supported) {
751
- this.warn(
752
- `Unsupported MediaCapabilities decodingInfo result for level ${index} ${JSON.stringify(
750
+ logger.warn(
751
+ `[abr] Unsupported MediaCapabilities decodingInfo result for level ${index} ${JSON.stringify(
753
752
  decodingInfo,
754
753
  )}`,
755
754
  );
756
755
  if (index > -1 && levels.length > 1) {
757
- this.log(`Removing unsupported level ${index}`);
756
+ logger.log(`[abr] Removing unsupported level ${index}`);
758
757
  this.hls.removeLevel(index);
759
758
  }
760
759
  }
@@ -832,8 +831,8 @@ class AbrController extends Logger implements AbrComponentAPI {
832
831
  (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)
833
832
  ) {
834
833
  if (levelsSkipped.length) {
835
- this.trace(
836
- `Skipped level(s) ${levelsSkipped.join(
834
+ logger.trace(
835
+ `[abr] Skipped level(s) ${levelsSkipped.join(
837
836
  ',',
838
837
  )} of ${maxAutoLevel} max with CODECS and VIDEO-RANGE:"${
839
838
  levels[levelsSkipped[0]].codecs
@@ -842,8 +841,8 @@ class AbrController extends Logger implements AbrComponentAPI {
842
841
  }" ${currentVideoRange}`,
843
842
  );
844
843
  }
845
- this.info(
846
- `switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(
844
+ logger.info(
845
+ `[abr] switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(
847
846
  adjustedbw,
848
847
  )})-bitrate=${Math.round(
849
848
  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);
@@ -710,7 +713,7 @@ class AudioStreamController
710
713
  this.fragBufferedComplete(frag, part);
711
714
  }
712
715
 
713
- protected onError(event: Events.ERROR, data: ErrorData) {
716
+ private onError(event: Events.ERROR, data: ErrorData) {
714
717
  if (data.fatal) {
715
718
  this.state = State.ERROR;
716
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 || '';
@@ -1,15 +1,12 @@
1
1
  import TaskLoop from '../task-loop';
2
2
  import { FragmentState } from './fragment-tracker';
3
3
  import { Bufferable, BufferHelper, BufferInfo } from '../utils/buffer-helper';
4
+ import { logger } from '../utils/logger';
4
5
  import { Events } from '../events';
5
6
  import { ErrorDetails, ErrorTypes } from '../errors';
6
7
  import { ChunkMetadata } from '../types/transmuxer';
7
8
  import { appendUint8Array } from '../utils/mp4-tools';
8
9
  import { alignStream } from '../utils/discontinuities';
9
- import {
10
- isFullSegmentEncryption,
11
- getAesModeFromFullSegmentMethod,
12
- } from '../utils/encryption-methods-util';
13
10
  import {
14
11
  findFragmentByPDT,
15
12
  findFragmentByPTS,
@@ -100,6 +97,12 @@ export default class BaseStreamController
100
97
  protected startFragRequested: boolean = false;
101
98
  protected decrypter: Decrypter;
102
99
  protected initPTS: RationalTimestamp[] = [];
100
+ protected onvseeking: EventListener | null = null;
101
+ protected onvended: EventListener | null = null;
102
+
103
+ private readonly logPrefix: string = '';
104
+ protected log: (msg: any) => void;
105
+ protected warn: (msg: any) => void;
103
106
 
104
107
  constructor(
105
108
  hls: Hls,
@@ -108,32 +111,18 @@ export default class BaseStreamController
108
111
  logPrefix: string,
109
112
  playlistType: PlaylistLevelType,
110
113
  ) {
111
- super(logPrefix, hls.logger);
114
+ super();
112
115
  this.playlistType = playlistType;
116
+ this.logPrefix = logPrefix;
117
+ this.log = logger.log.bind(logger, `${logPrefix}:`);
118
+ this.warn = logger.warn.bind(logger, `${logPrefix}:`);
113
119
  this.hls = hls;
114
120
  this.fragmentLoader = new FragmentLoader(hls.config);
115
121
  this.keyLoader = keyLoader;
116
122
  this.fragmentTracker = fragmentTracker;
117
123
  this.config = hls.config;
118
124
  this.decrypter = new Decrypter(hls.config);
119
- }
120
-
121
- protected registerListeners() {
122
- const { hls } = this;
123
- hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
124
- hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
125
- hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
126
125
  hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
127
- hls.on(Events.ERROR, this.onError, this);
128
- }
129
-
130
- protected unregisterListeners() {
131
- const { hls } = this;
132
- hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
133
- hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
134
- hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
135
- hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
136
- hls.off(Events.ERROR, this.onError, this);
137
126
  }
138
127
 
139
128
  protected doTick() {
@@ -208,8 +197,10 @@ export default class BaseStreamController
208
197
  data: MediaAttachedData,
209
198
  ) {
210
199
  const media = (this.media = this.mediaBuffer = data.media);
211
- media.addEventListener('seeking', this.onMediaSeeking);
212
- media.addEventListener('ended', this.onMediaEnded);
200
+ this.onvseeking = this.onMediaSeeking.bind(this) as EventListener;
201
+ this.onvended = this.onMediaEnded.bind(this) as EventListener;
202
+ media.addEventListener('seeking', this.onvseeking);
203
+ media.addEventListener('ended', this.onvended);
213
204
  const config = this.config;
214
205
  if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
215
206
  this.startLoad(config.startPosition);
@@ -224,9 +215,10 @@ export default class BaseStreamController
224
215
  }
225
216
 
226
217
  // remove video listeners
227
- if (media) {
228
- media.removeEventListener('seeking', this.onMediaSeeking);
229
- media.removeEventListener('ended', this.onMediaEnded);
218
+ if (media && this.onvseeking && this.onvended) {
219
+ media.removeEventListener('seeking', this.onvseeking);
220
+ media.removeEventListener('ended', this.onvended);
221
+ this.onvseeking = this.onvended = null;
230
222
  }
231
223
  if (this.keyLoader) {
232
224
  this.keyLoader.detach();
@@ -237,11 +229,7 @@ export default class BaseStreamController
237
229
  this.stopLoad();
238
230
  }
239
231
 
240
- protected onManifestLoading() {}
241
-
242
- protected onError(event: Events.ERROR, data: ErrorData) {}
243
-
244
- protected onMediaSeeking = () => {
232
+ protected onMediaSeeking() {
245
233
  const { config, fragCurrent, media, mediaBuffer, state } = this;
246
234
  const currentTime: number = media ? media.currentTime : 0;
247
235
  const bufferInfo = BufferHelper.bufferInfo(
@@ -304,12 +292,12 @@ export default class BaseStreamController
304
292
 
305
293
  // Async tick to speed up processing
306
294
  this.tickImmediate();
307
- };
295
+ }
308
296
 
309
- protected onMediaEnded = () => {
297
+ protected onMediaEnded() {
310
298
  // reset startPosition and lastCurrentTime to restart playback @ stream beginning
311
299
  this.startPosition = this.lastCurrentTime = 0;
312
- };
300
+ }
313
301
 
314
302
  protected onManifestLoaded(
315
303
  event: Events.MANIFEST_LOADED,
@@ -324,7 +312,7 @@ export default class BaseStreamController
324
312
  this.stopLoad();
325
313
  super.onHandlerDestroying();
326
314
  // @ts-ignore
327
- this.hls = this.onMediaSeeking = this.onMediaEnded = null;
315
+ this.hls = null;
328
316
  }
329
317
 
330
318
  protected onHandlerDestroyed() {
@@ -498,7 +486,7 @@ export default class BaseStreamController
498
486
  payload.byteLength > 0 &&
499
487
  decryptData?.key &&
500
488
  decryptData.iv &&
501
- isFullSegmentEncryption(decryptData.method)
489
+ decryptData.method === 'AES-128'
502
490
  ) {
503
491
  const startTime = self.performance.now();
504
492
  // decrypt init segment data
@@ -507,7 +495,6 @@ export default class BaseStreamController
507
495
  new Uint8Array(payload),
508
496
  decryptData.key.buffer,
509
497
  decryptData.iv.buffer,
510
- getAesModeFromFullSegmentMethod(decryptData.method),
511
498
  )
512
499
  .catch((err) => {
513
500
  hls.trigger(Events.ERROR, {
@@ -662,7 +649,7 @@ export default class BaseStreamController
662
649
  if (frag.encrypted && !frag.decryptdata?.key) {
663
650
  this.log(
664
651
  `Loading key for ${frag.sn} of [${details.startSN}-${details.endSN}], ${
665
- this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track'
652
+ this.logPrefix === '[stream-controller]' ? 'level' : 'track'
666
653
  } ${frag.level}`,
667
654
  );
668
655
  this.state = State.KEY_LOADING;
@@ -702,7 +689,7 @@ export default class BaseStreamController
702
689
  } of playlist [${details.startSN}-${
703
690
  details.endSN
704
691
  }] parts [0-${partIndex}-${partList.length - 1}] ${
705
- this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track'
692
+ this.logPrefix === '[stream-controller]' ? 'level' : 'track'
706
693
  }: ${frag.level}, target: ${parseFloat(
707
694
  targetBufferTime.toFixed(3),
708
695
  )}`,
@@ -761,7 +748,7 @@ export default class BaseStreamController
761
748
  this.log(
762
749
  `Loading fragment ${frag.sn} cc: ${frag.cc} ${
763
750
  details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : ''
764
- }${this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track'}: ${
751
+ }${this.logPrefix === '[stream-controller]' ? 'level' : 'track'}: ${
765
752
  frag.level
766
753
  }, target: ${parseFloat(targetBufferTime.toFixed(3))}`,
767
754
  );
@@ -1563,7 +1550,7 @@ export default class BaseStreamController
1563
1550
  errorAction.resolved = true;
1564
1551
  }
1565
1552
  } else {
1566
- this.warn(
1553
+ logger.warn(
1567
1554
  `${data.details} reached or exceeded max retry (${retryCount})`,
1568
1555
  );
1569
1556
  return;
@@ -1,5 +1,5 @@
1
1
  import { Events } from '../events';
2
- import { Logger } from '../utils/logger';
2
+ import { logger } from '../utils/logger';
3
3
  import { ErrorDetails, ErrorTypes } from '../errors';
4
4
  import { BufferHelper } from '../utils/buffer-helper';
5
5
  import {
@@ -42,7 +42,7 @@ interface BufferedChangeEvent extends Event {
42
42
  readonly removedRanges?: TimeRanges;
43
43
  }
44
44
 
45
- export default class BufferController extends Logger implements ComponentAPI {
45
+ export default class BufferController implements ComponentAPI {
46
46
  // The level details used to determine duration, target-duration and live
47
47
  private details: LevelDetails | null = null;
48
48
  // cache the self generated object url to detect hijack of video tag
@@ -82,10 +82,17 @@ export default class BufferController extends Logger implements ComponentAPI {
82
82
  public pendingTracks: TrackSet = {};
83
83
  public sourceBuffer!: SourceBuffers;
84
84
 
85
+ protected log: (msg: any) => void;
86
+ protected warn: (msg: any, obj?: any) => void;
87
+ protected error: (msg: any, obj?: any) => void;
88
+
85
89
  constructor(hls: Hls) {
86
- super('buffer-controller', hls.logger);
87
90
  this.hls = hls;
91
+ const logPrefix = '[buffer-controller]';
88
92
  this.appendSource = hls.config.preferManagedMediaSource;
93
+ this.log = logger.log.bind(logger, logPrefix);
94
+ this.warn = logger.warn.bind(logger, logPrefix);
95
+ this.error = logger.error.bind(logger, logPrefix);
89
96
  this._initSourceBuffer();
90
97
  this.registerListeners();
91
98
  }
@@ -103,12 +110,6 @@ export default class BufferController extends Logger implements ComponentAPI {
103
110
  this.lastMpegAudioChunk = null;
104
111
  // @ts-ignore
105
112
  this.hls = null;
106
- // @ts-ignore
107
- this._onMediaSourceOpen = this._onMediaSourceClose = null;
108
- // @ts-ignore
109
- this._onMediaSourceEnded = null;
110
- // @ts-ignore
111
- this._onStartStreaming = this._onEndStreaming = null;
112
113
  }
113
114
 
114
115
  protected registerListeners() {
@@ -1003,7 +1004,7 @@ export default class BufferController extends Logger implements ComponentAPI {
1003
1004
  private _onMediaEmptied = () => {
1004
1005
  const { mediaSrc, _objectUrl } = this;
1005
1006
  if (mediaSrc !== _objectUrl) {
1006
- this.error(
1007
+ logger.error(
1007
1008
  `Media element src was set while attaching MediaSource (${_objectUrl} > ${mediaSrc})`,
1008
1009
  );
1009
1010
  }
@@ -12,6 +12,7 @@ import type {
12
12
  LevelsUpdatedData,
13
13
  } from '../types/events';
14
14
  import StreamController from './stream-controller';
15
+ import { logger } from '../utils/logger';
15
16
  import type { ComponentAPI } from '../types/component-api';
16
17
  import type Hls from '../hls';
17
18
 
@@ -151,7 +152,7 @@ class CapLevelController implements ComponentAPI {
151
152
  const hls = this.hls;
152
153
  const maxLevel = this.getMaxLevel(levels.length - 1);
153
154
  if (maxLevel !== this.autoLevelCapping) {
154
- hls.logger.log(
155
+ logger.log(
155
156
  `Setting autoLevelCapping to ${maxLevel}: ${levels[maxLevel].height}p@${levels[maxLevel].bitrate} for media ${this.mediaWidth}x${this.mediaHeight}`,
156
157
  );
157
158
  }
@@ -3,7 +3,7 @@ import { Level } from '../types/level';
3
3
  import { reassignFragmentLevelIndexes } from '../utils/level-helper';
4
4
  import { AttrList } from '../utils/attr-list';
5
5
  import { ErrorActionFlags, NetworkErrorAction } from './error-controller';
6
- import { Logger } from '../utils/logger';
6
+ import { logger } from '../utils/logger';
7
7
  import {
8
8
  PlaylistContextType,
9
9
  type Loader,
@@ -48,11 +48,9 @@ export type UriReplacement = {
48
48
 
49
49
  const PATHWAY_PENALTY_DURATION_MS = 300000;
50
50
 
51
- export default class ContentSteeringController
52
- extends Logger
53
- implements NetworkComponentAPI
54
- {
51
+ export default class ContentSteeringController implements NetworkComponentAPI {
55
52
  private readonly hls: Hls;
53
+ private log: (msg: any) => void;
56
54
  private loader: Loader<LoaderContext> | null = null;
57
55
  private uri: string | null = null;
58
56
  private pathwayId: string = '.';
@@ -68,8 +66,8 @@ export default class ContentSteeringController
68
66
  private penalizedPathways: { [pathwayId: string]: number } = {};
69
67
 
70
68
  constructor(hls: Hls) {
71
- super('content-steering', hls.logger);
72
69
  this.hls = hls;
70
+ this.log = logger.log.bind(logger, `[content-steering]:`);
73
71
  this.registerListeners();
74
72
  }
75
73
 
@@ -205,7 +203,7 @@ export default class ContentSteeringController
205
203
  errorAction.resolved = this.pathwayId !== errorPathway;
206
204
  }
207
205
  if (!errorAction.resolved) {
208
- this.warn(
206
+ logger.warn(
209
207
  `Could not resolve ${data.details} ("${
210
208
  data.error.message
211
209
  }") with content-steering for Pathway: ${errorPathway} levels: ${
@@ -444,7 +442,7 @@ export default class ContentSteeringController
444
442
  ) => {
445
443
  this.log(`Loaded steering manifest: "${url}"`);
446
444
  const steeringData = response.data as SteeringManifest;
447
- if (steeringData?.VERSION !== 1) {
445
+ if (steeringData.VERSION !== 1) {
448
446
  this.log(`Steering VERSION ${steeringData.VERSION} not supported!`);
449
447
  return;
450
448
  }