hls.js 1.5.14-0.canary.10515 → 1.5.14

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 (107) hide show
  1. package/README.md +3 -4
  2. package/dist/hls-demo.js +38 -41
  3. package/dist/hls-demo.js.map +1 -1
  4. package/dist/hls.js +2903 -4542
  5. package/dist/hls.js.d.ts +112 -186
  6. package/dist/hls.js.map +1 -1
  7. package/dist/hls.light.js +2284 -3295
  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 +1804 -2817
  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 +4652 -6293
  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 +38 -38
  20. package/src/config.ts +2 -5
  21. package/src/controller/abr-controller.ts +25 -39
  22. package/src/controller/audio-stream-controller.ts +136 -156
  23. package/src/controller/audio-track-controller.ts +1 -1
  24. package/src/controller/base-playlist-controller.ts +10 -27
  25. package/src/controller/base-stream-controller.ts +107 -263
  26. package/src/controller/buffer-controller.ts +98 -252
  27. package/src/controller/buffer-operation-queue.ts +19 -16
  28. package/src/controller/cap-level-controller.ts +2 -3
  29. package/src/controller/cmcd-controller.ts +14 -51
  30. package/src/controller/content-steering-controller.ts +15 -29
  31. package/src/controller/eme-controller.ts +23 -10
  32. package/src/controller/error-controller.ts +22 -28
  33. package/src/controller/fps-controller.ts +3 -8
  34. package/src/controller/fragment-finders.ts +16 -44
  35. package/src/controller/fragment-tracker.ts +25 -58
  36. package/src/controller/gap-controller.ts +16 -43
  37. package/src/controller/id3-track-controller.ts +35 -45
  38. package/src/controller/latency-controller.ts +13 -18
  39. package/src/controller/level-controller.ts +19 -37
  40. package/src/controller/stream-controller.ts +83 -100
  41. package/src/controller/subtitle-stream-controller.ts +47 -35
  42. package/src/controller/subtitle-track-controller.ts +3 -5
  43. package/src/controller/timeline-controller.ts +22 -20
  44. package/src/crypt/aes-crypto.ts +2 -21
  45. package/src/crypt/decrypter.ts +16 -32
  46. package/src/crypt/fast-aes-key.ts +5 -28
  47. package/src/demux/audio/aacdemuxer.ts +5 -5
  48. package/src/demux/audio/ac3-demuxer.ts +4 -5
  49. package/src/demux/audio/adts.ts +4 -9
  50. package/src/demux/audio/base-audio-demuxer.ts +14 -16
  51. package/src/demux/audio/mp3demuxer.ts +3 -4
  52. package/src/demux/audio/mpegaudio.ts +1 -1
  53. package/src/demux/id3.ts +411 -0
  54. package/src/demux/inject-worker.ts +4 -38
  55. package/src/demux/mp4demuxer.ts +7 -7
  56. package/src/demux/sample-aes.ts +0 -2
  57. package/src/demux/transmuxer-interface.ts +83 -106
  58. package/src/demux/transmuxer-worker.ts +77 -111
  59. package/src/demux/transmuxer.ts +22 -46
  60. package/src/demux/tsdemuxer.ts +62 -122
  61. package/src/demux/video/avc-video-parser.ts +121 -210
  62. package/src/demux/video/base-video-parser.ts +2 -135
  63. package/src/demux/video/exp-golomb.ts +208 -0
  64. package/src/errors.ts +0 -2
  65. package/src/events.ts +1 -8
  66. package/src/exports-named.ts +1 -1
  67. package/src/hls.ts +48 -97
  68. package/src/loader/date-range.ts +5 -71
  69. package/src/loader/fragment-loader.ts +21 -23
  70. package/src/loader/fragment.ts +4 -8
  71. package/src/loader/key-loader.ts +1 -3
  72. package/src/loader/level-details.ts +6 -6
  73. package/src/loader/level-key.ts +9 -10
  74. package/src/loader/m3u8-parser.ts +144 -138
  75. package/src/loader/playlist-loader.ts +7 -5
  76. package/src/remux/mp4-generator.ts +1 -196
  77. package/src/remux/mp4-remuxer.ts +84 -55
  78. package/src/remux/passthrough-remuxer.ts +8 -23
  79. package/src/task-loop.ts +2 -5
  80. package/src/types/component-api.ts +1 -3
  81. package/src/types/demuxer.ts +0 -3
  82. package/src/types/events.ts +6 -19
  83. package/src/types/fragment-tracker.ts +2 -2
  84. package/src/types/general.ts +6 -0
  85. package/src/types/media-playlist.ts +1 -9
  86. package/src/types/remuxer.ts +1 -1
  87. package/src/utils/attr-list.ts +9 -96
  88. package/src/utils/buffer-helper.ts +31 -12
  89. package/src/utils/cea-608-parser.ts +3 -1
  90. package/src/utils/codecs.ts +5 -34
  91. package/src/utils/discontinuities.ts +47 -21
  92. package/src/utils/fetch-loader.ts +1 -1
  93. package/src/utils/hdr.ts +7 -4
  94. package/src/utils/imsc1-ttml-parser.ts +1 -1
  95. package/src/utils/keysystem-util.ts +6 -1
  96. package/src/utils/level-helper.ts +44 -71
  97. package/src/utils/logger.ts +23 -58
  98. package/src/utils/mp4-tools.ts +3 -5
  99. package/src/utils/rendition-helper.ts +74 -100
  100. package/src/utils/variable-substitution.ts +19 -0
  101. package/src/utils/webvtt-parser.ts +12 -2
  102. package/src/crypt/decrypter-aes-mode.ts +0 -4
  103. package/src/demux/video/hevc-video-parser.ts +0 -749
  104. package/src/utils/encryption-methods-util.ts +0 -21
  105. package/src/utils/hash.ts +0 -10
  106. package/src/utils/utf8-utils.ts +0 -18
  107. package/src/version.ts +0 -1
@@ -1,15 +1,15 @@
1
1
  import { Events } from '../events';
2
- import type Hls from '../hls';
2
+ import Hls from '../hls';
3
3
  import { Cmcd } from '@svta/common-media-library/cmcd/Cmcd';
4
4
  import { CmcdObjectType } from '@svta/common-media-library/cmcd/CmcdObjectType';
5
5
  import { CmcdStreamingFormat } from '@svta/common-media-library/cmcd/CmcdStreamingFormat';
6
6
  import { appendCmcdHeaders } from '@svta/common-media-library/cmcd/appendCmcdHeaders';
7
7
  import { appendCmcdQuery } from '@svta/common-media-library/cmcd/appendCmcdQuery';
8
- import type { CmcdEncodeOptions } from '@svta/common-media-library/cmcd/CmcdEncodeOptions';
9
8
  import { uuid } from '@svta/common-media-library/utils/uuid';
10
9
  import { BufferHelper } from '../utils/buffer-helper';
10
+ import { logger } from '../utils/logger';
11
11
  import type { ComponentAPI } from '../types/component-api';
12
- import type { Fragment, Part } from '../loader/fragment';
12
+ import type { Fragment } from '../loader/fragment';
13
13
  import type { BufferCreatedData, MediaAttachedData } from '../types/events';
14
14
  import type {
15
15
  FragmentLoaderContext,
@@ -81,7 +81,7 @@ export default class CMCDController implements ComponentAPI {
81
81
  // @ts-ignore
82
82
  this.hls = this.config = this.audioBuffer = this.videoBuffer = null;
83
83
  // @ts-ignore
84
- this.onWaiting = this.onPlaying = this.media = null;
84
+ this.onWaiting = this.onPlaying = null;
85
85
  }
86
86
 
87
87
  private onMediaAttached(
@@ -165,7 +165,7 @@ export default class CMCDController implements ComponentAPI {
165
165
  data.su = this.buffering;
166
166
  }
167
167
 
168
- // TODO: Implement rtp, nrr, dl
168
+ // TODO: Implement rtp, nrr, nor, dl
169
169
 
170
170
  const { includeKeys } = this;
171
171
  if (includeKeys) {
@@ -175,18 +175,14 @@ export default class CMCDController implements ComponentAPI {
175
175
  }, {});
176
176
  }
177
177
 
178
- const options: CmcdEncodeOptions = {
179
- baseUrl: context.url,
180
- };
181
-
182
178
  if (this.useHeaders) {
183
179
  if (!context.headers) {
184
180
  context.headers = {};
185
181
  }
186
182
 
187
- appendCmcdHeaders(context.headers, data, options);
183
+ appendCmcdHeaders(context.headers, data);
188
184
  } else {
189
- context.url = appendCmcdQuery(context.url, data, options);
185
+ context.url = appendCmcdQuery(context.url, data);
190
186
  }
191
187
  }
192
188
 
@@ -200,7 +196,7 @@ export default class CMCDController implements ComponentAPI {
200
196
  su: !this.initialized,
201
197
  });
202
198
  } catch (error) {
203
- this.hls.logger.warn('Could not generate manifest CMCD data.', error);
199
+ logger.warn('Could not generate manifest CMCD data.', error);
204
200
  }
205
201
  };
206
202
 
@@ -209,11 +205,11 @@ export default class CMCDController implements ComponentAPI {
209
205
  */
210
206
  private applyFragmentData = (context: FragmentLoaderContext) => {
211
207
  try {
212
- const { frag, part } = context;
213
- const level = this.hls.levels[frag.level];
214
- const ot = this.getObjectType(frag);
208
+ const fragment = context.frag;
209
+ const level = this.hls.levels[fragment.level];
210
+ const ot = this.getObjectType(fragment);
215
211
  const data: Cmcd = {
216
- d: (part || frag).duration * 1000,
212
+ d: fragment.duration * 1000,
217
213
  ot,
218
214
  };
219
215
 
@@ -227,45 +223,12 @@ export default class CMCDController implements ComponentAPI {
227
223
  data.bl = this.getBufferLength(ot);
228
224
  }
229
225
 
230
- const next = part ? this.getNextPart(part) : this.getNextFrag(frag);
231
-
232
- if (next?.url && next.url !== frag.url) {
233
- data.nor = next.url;
234
- }
235
-
236
226
  this.apply(context, data);
237
227
  } catch (error) {
238
- this.hls.logger.warn('Could not generate segment CMCD data.', error);
228
+ logger.warn('Could not generate segment CMCD data.', error);
239
229
  }
240
230
  };
241
231
 
242
- private getNextFrag(fragment: Fragment): Fragment | undefined {
243
- const levelDetails = this.hls.levels[fragment.level]?.details;
244
- if (levelDetails) {
245
- const index = (fragment.sn as number) - levelDetails.startSN;
246
- return levelDetails.fragments[index + 1];
247
- }
248
-
249
- return undefined;
250
- }
251
-
252
- private getNextPart(part: Part): Part | undefined {
253
- const { index, fragment } = part;
254
- const partList = this.hls.levels[fragment.level]?.details?.partList;
255
-
256
- if (partList) {
257
- const { sn } = fragment;
258
- for (let i = partList.length - 1; i >= 0; i--) {
259
- const p = partList[i];
260
- if (p.index === index && p.fragment.sn === sn) {
261
- return partList[i + 1];
262
- }
263
- }
264
- }
265
-
266
- return undefined;
267
- }
268
-
269
232
  /**
270
233
  * The CMCD object type.
271
234
  */
@@ -324,7 +287,7 @@ export default class CMCDController implements ComponentAPI {
324
287
  * Get the buffer length for a media type in milliseconds
325
288
  */
326
289
  private getBufferLength(type: CmcdObjectType) {
327
- const media = this.media;
290
+ const media = this.hls.media;
328
291
  const buffer =
329
292
  type === CmcdObjectType.AUDIO ? this.audioBuffer : this.videoBuffer;
330
293
 
@@ -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,15 +48,13 @@ 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 = '.';
59
- private _pathwayPriority: string[] | null = null;
57
+ private pathwayPriority: string[] | null = null;
60
58
  private timeToLoad: number = 300;
61
59
  private reloadTimer: number = -1;
62
60
  private updated: number = 0;
@@ -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
 
@@ -92,23 +90,6 @@ export default class ContentSteeringController
92
90
  hls.off(Events.ERROR, this.onError, this);
93
91
  }
94
92
 
95
- pathways() {
96
- return (this.levels || []).reduce((pathways, level) => {
97
- if (pathways.indexOf(level.pathwayId) === -1) {
98
- pathways.push(level.pathwayId);
99
- }
100
- return pathways;
101
- }, [] as string[]);
102
- }
103
-
104
- get pathwayPriority(): string[] | null {
105
- return this._pathwayPriority;
106
- }
107
-
108
- set pathwayPriority(pathwayPriority: string[]) {
109
- this.updatePathwayPriority(pathwayPriority);
110
- }
111
-
112
93
  startLoad() {
113
94
  this.started = true;
114
95
  this.clearTimeout();
@@ -195,7 +176,7 @@ export default class ContentSteeringController
195
176
  errorAction.flags === ErrorActionFlags.MoveAllAlternatesMatchingHost
196
177
  ) {
197
178
  const levels = this.levels;
198
- let pathwayPriority = this._pathwayPriority;
179
+ let pathwayPriority = this.pathwayPriority;
199
180
  let errorPathway = this.pathwayId;
200
181
  if (data.context) {
201
182
  const { groupId, pathwayId, type } = data.context;
@@ -210,14 +191,19 @@ export default class ContentSteeringController
210
191
  }
211
192
  if (!pathwayPriority && levels) {
212
193
  // If PATHWAY-PRIORITY was not provided, list pathways for error handling
213
- pathwayPriority = this.pathways();
194
+ pathwayPriority = levels.reduce((pathways, level) => {
195
+ if (pathways.indexOf(level.pathwayId) === -1) {
196
+ pathways.push(level.pathwayId);
197
+ }
198
+ return pathways;
199
+ }, [] as string[]);
214
200
  }
215
201
  if (pathwayPriority && pathwayPriority.length > 1) {
216
202
  this.updatePathwayPriority(pathwayPriority);
217
203
  errorAction.resolved = this.pathwayId !== errorPathway;
218
204
  }
219
205
  if (!errorAction.resolved) {
220
- this.warn(
206
+ logger.warn(
221
207
  `Could not resolve ${data.details} ("${
222
208
  data.error.message
223
209
  }") with content-steering for Pathway: ${errorPathway} levels: ${
@@ -259,7 +245,7 @@ export default class ContentSteeringController
259
245
  }
260
246
 
261
247
  private updatePathwayPriority(pathwayPriority: string[]) {
262
- this._pathwayPriority = pathwayPriority;
248
+ this.pathwayPriority = pathwayPriority;
263
249
  let levels: Level[] | undefined;
264
250
 
265
251
  // Evaluate if we should remove the pathway from the penalized list
@@ -456,7 +442,7 @@ export default class ContentSteeringController
456
442
  ) => {
457
443
  this.log(`Loaded steering manifest: "${url}"`);
458
444
  const steeringData = response.data as SteeringManifest;
459
- if (steeringData?.VERSION !== 1) {
445
+ if (steeringData.VERSION !== 1) {
460
446
  this.log(`Steering VERSION ${steeringData.VERSION} not supported!`);
461
447
  return;
462
448
  }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { Events } from '../events';
7
7
  import { ErrorTypes, ErrorDetails } from '../errors';
8
- import { Logger } from '../utils/logger';
8
+ import { logger } from '../utils/logger';
9
9
  import {
10
10
  getKeySystemsForConfig,
11
11
  getSupportedMediaKeySystemConfigurations,
@@ -19,7 +19,7 @@ import {
19
19
  KeySystems,
20
20
  requestMediaKeySystemAccess,
21
21
  } from '../utils/mediakeys-helper';
22
- import { strToUtf8array } from '../utils/utf8-utils';
22
+ import { strToUtf8array } from '../utils/keysystem-util';
23
23
  import { base64Decode } from '../utils/numeric-encoding-utils';
24
24
  import { DecryptData, LevelKey } from '../loader/level-key';
25
25
  import Hex from '../utils/hex';
@@ -41,6 +41,9 @@ import type {
41
41
  LoaderConfiguration,
42
42
  LoaderContext,
43
43
  } from '../types/loader';
44
+
45
+ const LOGGER_PREFIX = '[eme]';
46
+
44
47
  interface KeySystemAccessPromises {
45
48
  keySystemAccess: Promise<MediaKeySystemAccess>;
46
49
  mediaKeys?: Promise<MediaKeys>;
@@ -65,7 +68,7 @@ export interface MediaKeySessionContext {
65
68
  * @class
66
69
  * @constructor
67
70
  */
68
- class EMEController extends Logger implements ComponentAPI {
71
+ class EMEController implements ComponentAPI {
69
72
  public static CDMCleanupPromise: Promise<void> | void;
70
73
 
71
74
  private readonly hls: Hls;
@@ -87,9 +90,15 @@ class EMEController extends Logger implements ComponentAPI {
87
90
  private setMediaKeysQueue: Promise<void>[] = EMEController.CDMCleanupPromise
88
91
  ? [EMEController.CDMCleanupPromise]
89
92
  : [];
93
+ private onMediaEncrypted = this._onMediaEncrypted.bind(this);
94
+ private onWaitingForKey = this._onWaitingForKey.bind(this);
95
+
96
+ private debug: (msg: any) => void = logger.debug.bind(logger, LOGGER_PREFIX);
97
+ private log: (msg: any) => void = logger.log.bind(logger, LOGGER_PREFIX);
98
+ private warn: (msg: any) => void = logger.warn.bind(logger, LOGGER_PREFIX);
99
+ private error: (msg: any) => void = logger.error.bind(logger, LOGGER_PREFIX);
90
100
 
91
101
  constructor(hls: Hls) {
92
- super('eme', hls.logger);
93
102
  this.hls = hls;
94
103
  this.config = hls.config;
95
104
  this.registerListeners();
@@ -104,9 +113,13 @@ class EMEController extends Logger implements ComponentAPI {
104
113
  config.licenseXhrSetup = config.licenseResponseCallback = undefined;
105
114
  config.drmSystems = config.drmSystemOptions = {};
106
115
  // @ts-ignore
107
- this.hls = this.config = this.keyIdToKeySessionPromise = null;
116
+ this.hls =
117
+ this.onMediaEncrypted =
118
+ this.onWaitingForKey =
119
+ this.keyIdToKeySessionPromise =
120
+ null as any;
108
121
  // @ts-ignore
109
- this.onMediaEncrypted = this.onWaitingForKey = null;
122
+ this.config = null;
110
123
  }
111
124
 
112
125
  private registerListeners() {
@@ -510,7 +523,7 @@ class EMEController extends Logger implements ComponentAPI {
510
523
  return this.attemptKeySystemAccess(keySystemsToAttempt);
511
524
  }
512
525
 
513
- private onMediaEncrypted = (event: MediaEncryptedEvent) => {
526
+ private _onMediaEncrypted(event: MediaEncryptedEvent) {
514
527
  const { initDataType, initData } = event;
515
528
  this.debug(`"${event.type}" event: init data type: "${initDataType}"`);
516
529
 
@@ -626,11 +639,11 @@ class EMEController extends Logger implements ComponentAPI {
626
639
  );
627
640
  }
628
641
  keySessionContextPromise.catch((error) => this.handleError(error));
629
- };
642
+ }
630
643
 
631
- private onWaitingForKey = (event: Event) => {
644
+ private _onWaitingForKey(event: Event) {
632
645
  this.log(`"${event.type}" event`);
633
- };
646
+ }
634
647
 
635
648
  private attemptSetMediaKeys(
636
649
  keySystem: KeySystems,
@@ -8,12 +8,12 @@ import {
8
8
  } from '../utils/error-helper';
9
9
  import { findFragmentByPTS } from './fragment-finders';
10
10
  import { HdcpLevel, HdcpLevels } from '../types/level';
11
- import { Logger } from '../utils/logger';
11
+ import { logger } from '../utils/logger';
12
12
  import type Hls from '../hls';
13
13
  import type { RetryConfig } from '../config';
14
14
  import type { NetworkComponentAPI } from '../types/component-api';
15
15
  import type { ErrorData } from '../types/events';
16
- import type { Fragment, MediaFragment } from '../loader/fragment';
16
+ import type { Fragment } from '../loader/fragment';
17
17
  import type { LevelDetails } from '../loader/level-details';
18
18
 
19
19
  export const enum NetworkErrorAction {
@@ -50,17 +50,19 @@ type PenalizedRendition = {
50
50
 
51
51
  type PenalizedRenditions = { [key: number]: PenalizedRendition };
52
52
 
53
- export default class ErrorController
54
- extends Logger
55
- implements NetworkComponentAPI
56
- {
53
+ export default class ErrorController implements NetworkComponentAPI {
57
54
  private readonly hls: Hls;
58
55
  private playlistError: number = 0;
59
56
  private penalizedRenditions: PenalizedRenditions = {};
57
+ private log: (msg: any) => void;
58
+ private warn: (msg: any) => void;
59
+ private error: (msg: any) => void;
60
60
 
61
61
  constructor(hls: Hls) {
62
- super('error-controller', hls.logger);
63
62
  this.hls = hls;
63
+ this.log = logger.log.bind(logger, `[info]:`);
64
+ this.warn = logger.warn.bind(logger, `[warning]:`);
65
+ this.error = logger.error.bind(logger, `[error]:`);
64
66
  this.registerListeners();
65
67
  }
66
68
 
@@ -127,7 +129,10 @@ export default class ErrorController
127
129
  case ErrorDetails.FRAG_PARSING_ERROR:
128
130
  // ignore empty segment errors marked as gap
129
131
  if (data.frag?.gap) {
130
- data.errorAction = createDoNothingErrorAction();
132
+ data.errorAction = {
133
+ action: NetworkErrorAction.DoNothing,
134
+ flags: ErrorActionFlags.None,
135
+ };
131
136
  return;
132
137
  }
133
138
  // falls through
@@ -215,13 +220,10 @@ export default class ErrorController
215
220
  case ErrorDetails.BUFFER_ADD_CODEC_ERROR:
216
221
  case ErrorDetails.REMUX_ALLOC_ERROR:
217
222
  case ErrorDetails.BUFFER_APPEND_ERROR:
218
- // Buffer-controller can set errorAction when append errors can be ignored or resolved locally
219
- if (!data.errorAction) {
220
- data.errorAction = this.getLevelSwitchAction(
221
- data,
222
- data.level ?? hls.loadLevel,
223
- );
224
- }
223
+ data.errorAction = this.getLevelSwitchAction(
224
+ data,
225
+ data.level ?? hls.loadLevel,
226
+ );
225
227
  return;
226
228
  case ErrorDetails.INTERNAL_EXCEPTION:
227
229
  case ErrorDetails.BUFFER_APPENDING_ERROR:
@@ -230,7 +232,10 @@ export default class ErrorController
230
232
  case ErrorDetails.BUFFER_STALLED_ERROR:
231
233
  case ErrorDetails.BUFFER_SEEK_OVER_HOLE:
232
234
  case ErrorDetails.BUFFER_NUDGE_ON_STALL:
233
- data.errorAction = createDoNothingErrorAction();
235
+ data.errorAction = {
236
+ action: NetworkErrorAction.DoNothing,
237
+ flags: ErrorActionFlags.None,
238
+ };
234
239
  return;
235
240
  }
236
241
 
@@ -384,7 +389,7 @@ export default class ErrorController
384
389
  const levelDetails = levels[candidate].details;
385
390
  if (levelDetails) {
386
391
  const fragCandidate = findFragmentByPTS(
387
- data.frag as MediaFragment,
392
+ data.frag,
388
393
  levelDetails.fragments,
389
394
  data.frag.start,
390
395
  );
@@ -508,14 +513,3 @@ export default class ErrorController
508
513
  }
509
514
  }
510
515
  }
511
-
512
- export function createDoNothingErrorAction(resolved?: boolean): IErrorAction {
513
- const errorAction: IErrorAction = {
514
- action: NetworkErrorAction.DoNothing,
515
- flags: ErrorActionFlags.None,
516
- };
517
- if (resolved) {
518
- errorAction.resolved = true;
519
- }
520
- return errorAction;
521
- }
@@ -1,4 +1,5 @@
1
1
  import { Events } from '../events';
2
+ import { logger } from '../utils/logger';
2
3
  import type { ComponentAPI } from '../types/component-api';
3
4
  import type Hls from '../hls';
4
5
  import type { MediaAttachingData } from '../types/events';
@@ -27,12 +28,10 @@ class FPSController implements ComponentAPI {
27
28
 
28
29
  protected registerListeners() {
29
30
  this.hls.on(Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
30
- this.hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
31
31
  }
32
32
 
33
33
  protected unregisterListeners() {
34
34
  this.hls.off(Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
35
- this.hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
36
35
  }
37
36
 
38
37
  destroy() {
@@ -66,10 +65,6 @@ class FPSController implements ComponentAPI {
66
65
  }
67
66
  }
68
67
 
69
- private onMediaDetaching() {
70
- this.media = null;
71
- }
72
-
73
68
  checkFPS(
74
69
  video: HTMLVideoElement,
75
70
  decodedFrames: number,
@@ -89,13 +84,13 @@ class FPSController implements ComponentAPI {
89
84
  totalDroppedFrames: droppedFrames,
90
85
  });
91
86
  if (droppedFPS > 0) {
92
- // hls.logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
87
+ // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
93
88
  if (
94
89
  currentDropped >
95
90
  hls.config.fpsDroppedMonitoringThreshold * currentDecoded
96
91
  ) {
97
92
  let currentLevel = hls.currentLevel;
98
- hls.logger.warn(
93
+ logger.warn(
99
94
  'drop FPS ratio greater than max allowed value for currentLevel: ' +
100
95
  currentLevel,
101
96
  );
@@ -1,6 +1,5 @@
1
1
  import BinarySearch from '../utils/binary-search';
2
- import type { Fragment, MediaFragment } from '../loader/fragment';
3
- import type { LevelDetails } from '../loader/level-details';
2
+ import { Fragment } from '../loader/fragment';
4
3
 
5
4
  /**
6
5
  * Returns first fragment whose endPdt value exceeds the given PDT, or null.
@@ -9,10 +8,10 @@ import type { LevelDetails } from '../loader/level-details';
9
8
  * @param maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous
10
9
  */
11
10
  export function findFragmentByPDT(
12
- fragments: MediaFragment[],
11
+ fragments: Array<Fragment>,
13
12
  PDTValue: number | null,
14
13
  maxFragLookUpTolerance: number,
15
- ): MediaFragment | null {
14
+ ): Fragment | null {
16
15
  if (
17
16
  PDTValue === null ||
18
17
  !Array.isArray(fragments) ||
@@ -55,27 +54,23 @@ export function findFragmentByPDT(
55
54
  * @returns a matching fragment or null
56
55
  */
57
56
  export function findFragmentByPTS(
58
- fragPrevious: MediaFragment | null,
59
- fragments: MediaFragment[],
57
+ fragPrevious: Fragment | null,
58
+ fragments: Array<Fragment>,
60
59
  bufferEnd: number = 0,
61
60
  maxFragLookUpTolerance: number = 0,
62
61
  nextFragLookupTolerance: number = 0.005,
63
- ): MediaFragment | null {
64
- let fragNext: MediaFragment | null = null;
62
+ ): Fragment | null {
63
+ let fragNext: Fragment | null = null;
65
64
  if (fragPrevious) {
66
- fragNext = fragments[1 + fragPrevious.sn - fragments[0].sn] || null;
65
+ fragNext =
66
+ fragments[
67
+ (fragPrevious.sn as number) - (fragments[0].sn as number) + 1
68
+ ] || null;
67
69
  // check for buffer-end rounding error
68
- const bufferEdgeError = (fragPrevious.endDTS as number) - bufferEnd;
70
+ const bufferEdgeError = fragPrevious.endDTS - bufferEnd;
69
71
  if (bufferEdgeError > 0 && bufferEdgeError < 0.0000015) {
70
72
  bufferEnd += 0.0000015;
71
73
  }
72
- if (
73
- fragNext &&
74
- fragPrevious.level !== fragNext.level &&
75
- fragNext.end <= fragPrevious.end
76
- ) {
77
- fragNext = fragments[2 + fragPrevious.sn - fragments[0].sn] || null;
78
- }
79
74
  } else if (bufferEnd === 0 && fragments[0].start === 0) {
80
75
  fragNext = fragments[0];
81
76
  }
@@ -140,7 +135,7 @@ function fragmentWithinFastStartSwitch(
140
135
  export function fragmentWithinToleranceTest(
141
136
  bufferEnd = 0,
142
137
  maxFragLookUpTolerance = 0,
143
- candidate: MediaFragment,
138
+ candidate: Fragment,
144
139
  ) {
145
140
  // eagerly accept an accurate match (no tolerance)
146
141
  if (
@@ -194,7 +189,7 @@ export function fragmentWithinToleranceTest(
194
189
  export function pdtWithinToleranceTest(
195
190
  pdtBufferEnd: number,
196
191
  maxFragLookUpTolerance: number,
197
- candidate: MediaFragment,
192
+ candidate: Fragment,
198
193
  ): boolean {
199
194
  const candidateLookupTolerance =
200
195
  Math.min(
@@ -208,9 +203,9 @@ export function pdtWithinToleranceTest(
208
203
  }
209
204
 
210
205
  export function findFragWithCC(
211
- fragments: MediaFragment[],
206
+ fragments: Fragment[],
212
207
  cc: number,
213
- ): MediaFragment | null {
208
+ ): Fragment | null {
214
209
  return BinarySearch.search(fragments, (candidate) => {
215
210
  if (candidate.cc < cc) {
216
211
  return 1;
@@ -221,26 +216,3 @@ export function findFragWithCC(
221
216
  }
222
217
  });
223
218
  }
224
-
225
- export function findNearestWithCC(
226
- details: LevelDetails | undefined,
227
- cc: number,
228
- fragment: MediaFragment,
229
- ): MediaFragment | null {
230
- if (details) {
231
- if (details.startCC <= cc && details.endCC >= cc) {
232
- const start = fragment.start;
233
- const end = fragment.end;
234
- return BinarySearch.search(details.fragments, (candidate) => {
235
- if (candidate.cc < cc || candidate.end <= start) {
236
- return 1;
237
- } else if (candidate.cc > cc || candidate.start >= end) {
238
- return -1;
239
- } else {
240
- return 0;
241
- }
242
- });
243
- }
244
- }
245
- return null;
246
- }