hls.js 1.5.14-0.canary.10431 → 1.5.14-0.canary.10432

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.
@@ -6,114 +6,121 @@ import { ErrorDetails, ErrorTypes } from '../errors';
6
6
  import type { RemuxedTrack, RemuxerResult } from '../types/remuxer';
7
7
  import type { TransmuxerResult, ChunkMetadata } from '../types/transmuxer';
8
8
 
9
+ const transmuxers: (Transmuxer | undefined)[] = [];
10
+
9
11
  if (typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) {
10
- startWorker(self);
12
+ startWorker();
11
13
  }
12
14
 
13
- function startWorker(self) {
14
- const observer = new EventEmitter();
15
- const forwardMessage = (ev, data) => {
16
- self.postMessage({ event: ev, data: data });
17
- };
18
-
19
- // forward events to main thread
20
- observer.on(Events.FRAG_DECRYPTED, forwardMessage);
21
- observer.on(Events.ERROR, forwardMessage);
22
-
23
- // forward logger events to main thread
24
- const forwardWorkerLogs = (logger: ILogger) => {
25
- for (const logFn in logger) {
26
- const func: ILogFunction = (message?) => {
27
- forwardMessage('workerLog', {
28
- logType: logFn,
29
- message,
30
- });
31
- };
32
-
33
- logger[logFn] = func;
34
- }
35
- };
36
-
15
+ function startWorker() {
37
16
  self.addEventListener('message', (ev) => {
38
17
  const data = ev.data;
39
- switch (data.cmd) {
40
- case 'init': {
41
- const config = JSON.parse(data.config);
42
- self.transmuxer = new Transmuxer(
43
- observer,
44
- data.typeSupported,
45
- config,
46
- '',
47
- data.id,
48
- );
49
- const logger = enableLogs(config.debug, data.id);
50
- forwardWorkerLogs(logger);
51
- forwardMessage('init', null);
52
- break;
18
+ const instanceNo = data.instanceNo;
19
+ if (instanceNo === undefined) {
20
+ return;
21
+ }
22
+ const transmuxer = transmuxers[instanceNo];
23
+ if (data.cmd === 'reset') {
24
+ delete transmuxers[data.resetNo];
25
+ if (transmuxer) {
26
+ transmuxer.destroy();
53
27
  }
28
+ data.cmd = 'init';
29
+ }
30
+ if (data.cmd === 'init') {
31
+ const config = JSON.parse(data.config);
32
+ const observer = new EventEmitter();
33
+ observer.on(Events.FRAG_DECRYPTED, forwardMessage);
34
+ observer.on(Events.ERROR, forwardMessage);
35
+ const logger = enableLogs(config.debug, data.id);
36
+ forwardWorkerLogs(logger, instanceNo);
37
+ transmuxers[instanceNo] = new Transmuxer(
38
+ observer,
39
+ data.typeSupported,
40
+ config,
41
+ '',
42
+ data.id,
43
+ logger,
44
+ );
45
+ forwardMessage('init', null, instanceNo);
46
+ return;
47
+ }
48
+ if (!transmuxer) {
49
+ return;
50
+ }
51
+ switch (data.cmd) {
54
52
  case 'configure': {
55
- self.transmuxer.configure(data.config);
53
+ transmuxer.configure(data.config);
56
54
  break;
57
55
  }
58
56
  case 'demux': {
59
57
  const transmuxResult: TransmuxerResult | Promise<TransmuxerResult> =
60
- self.transmuxer.push(
58
+ transmuxer.push(
61
59
  data.data,
62
60
  data.decryptdata,
63
61
  data.chunkMeta,
64
62
  data.state,
65
63
  );
66
64
  if (isPromise(transmuxResult)) {
67
- self.transmuxer.async = true;
68
65
  transmuxResult
69
66
  .then((data) => {
70
- emitTransmuxComplete(self, data);
67
+ emitTransmuxComplete(self, data, instanceNo);
71
68
  })
72
69
  .catch((error) => {
73
- forwardMessage(Events.ERROR, {
74
- type: ErrorTypes.MEDIA_ERROR,
75
- details: ErrorDetails.FRAG_PARSING_ERROR,
76
- chunkMeta: data.chunkMeta,
77
- fatal: false,
78
- error,
79
- err: error,
80
- reason: `transmuxer-worker push error`,
81
- });
70
+ forwardMessage(
71
+ Events.ERROR,
72
+ {
73
+ instanceNo,
74
+ type: ErrorTypes.MEDIA_ERROR,
75
+ details: ErrorDetails.FRAG_PARSING_ERROR,
76
+ chunkMeta: data.chunkMeta,
77
+ fatal: false,
78
+ error,
79
+ err: error,
80
+ reason: `transmuxer-worker push error`,
81
+ },
82
+ instanceNo,
83
+ );
82
84
  });
83
85
  } else {
84
- self.transmuxer.async = false;
85
- emitTransmuxComplete(self, transmuxResult);
86
+ emitTransmuxComplete(self, transmuxResult, instanceNo);
86
87
  }
87
88
  break;
88
89
  }
89
90
  case 'flush': {
90
- const id = data.chunkMeta;
91
- let transmuxResult = self.transmuxer.flush(id);
92
- const asyncFlush = isPromise(transmuxResult);
93
- if (asyncFlush || self.transmuxer.async) {
94
- if (!isPromise(transmuxResult)) {
95
- transmuxResult = Promise.resolve(transmuxResult);
96
- }
91
+ const chunkMeta = data.chunkMeta as ChunkMetadata;
92
+ const transmuxResult = transmuxer.flush(chunkMeta);
93
+ if (isPromise(transmuxResult)) {
97
94
  transmuxResult
98
95
  .then((results: Array<TransmuxerResult>) => {
99
- handleFlushResult(self, results as Array<TransmuxerResult>, id);
96
+ handleFlushResult(
97
+ self,
98
+ results as Array<TransmuxerResult>,
99
+ chunkMeta,
100
+ instanceNo,
101
+ );
100
102
  })
101
103
  .catch((error) => {
102
- forwardMessage(Events.ERROR, {
103
- type: ErrorTypes.MEDIA_ERROR,
104
- details: ErrorDetails.FRAG_PARSING_ERROR,
105
- chunkMeta: data.chunkMeta,
106
- fatal: false,
107
- error,
108
- err: error,
109
- reason: `transmuxer-worker flush error`,
110
- });
104
+ forwardMessage(
105
+ Events.ERROR,
106
+ {
107
+ type: ErrorTypes.MEDIA_ERROR,
108
+ details: ErrorDetails.FRAG_PARSING_ERROR,
109
+ chunkMeta: data.chunkMeta,
110
+ fatal: false,
111
+ error,
112
+ err: error,
113
+ reason: `transmuxer-worker flush error`,
114
+ },
115
+ instanceNo,
116
+ );
111
117
  });
112
118
  } else {
113
119
  handleFlushResult(
114
120
  self,
115
121
  transmuxResult as Array<TransmuxerResult>,
116
- id,
122
+ chunkMeta,
123
+ instanceNo,
117
124
  );
118
125
  }
119
126
  break;
@@ -127,6 +134,7 @@ function startWorker(self) {
127
134
  function emitTransmuxComplete(
128
135
  self: any,
129
136
  transmuxResult: TransmuxerResult,
137
+ instanceNo: number,
130
138
  ): boolean {
131
139
  if (isEmptyResult(transmuxResult.remuxResult)) {
132
140
  return false;
@@ -140,7 +148,7 @@ function emitTransmuxComplete(
140
148
  addToTransferable(transferable, video);
141
149
  }
142
150
  self.postMessage(
143
- { event: 'transmuxComplete', data: transmuxResult },
151
+ { event: 'transmuxComplete', data: transmuxResult, instanceNo },
144
152
  transferable,
145
153
  );
146
154
  return true;
@@ -164,16 +172,42 @@ function handleFlushResult(
164
172
  self: any,
165
173
  results: Array<TransmuxerResult>,
166
174
  chunkMeta: ChunkMetadata,
175
+ instanceNo: number,
167
176
  ) {
168
177
  const parsed = results.reduce(
169
- (parsed, result) => emitTransmuxComplete(self, result) || parsed,
178
+ (parsed, result) =>
179
+ emitTransmuxComplete(self, result, instanceNo) || parsed,
170
180
  false,
171
181
  );
172
182
  if (!parsed) {
173
183
  // Emit at least one "transmuxComplete" message even if media is not found to update stream-controller state to PARSING
174
- self.postMessage({ event: 'transmuxComplete', data: results[0] });
184
+ self.postMessage({
185
+ event: 'transmuxComplete',
186
+ data: results[0],
187
+ instanceNo,
188
+ });
189
+ }
190
+ self.postMessage({ event: 'flush', data: chunkMeta, instanceNo });
191
+ }
192
+
193
+ function forwardMessage(event, data, instanceNo) {
194
+ self.postMessage({ event, data, instanceNo });
195
+ }
196
+
197
+ function forwardWorkerLogs(logger: ILogger, instanceNo: number) {
198
+ for (const logFn in logger) {
199
+ const func: ILogFunction = (message?) => {
200
+ forwardMessage(
201
+ 'workerLog',
202
+ {
203
+ logType: logFn,
204
+ message,
205
+ },
206
+ instanceNo,
207
+ );
208
+ };
209
+ logger[logFn] = func;
175
210
  }
176
- self.postMessage({ event: 'flush', data: chunkMeta });
177
211
  }
178
212
 
179
213
  function isEmptyResult(remuxResult: RemuxerResult) {
@@ -9,7 +9,7 @@ import MP3Demuxer from './audio/mp3demuxer';
9
9
  import { AC3Demuxer } from './audio/ac3-demuxer';
10
10
  import MP4Remuxer from '../remux/mp4-remuxer';
11
11
  import PassThroughRemuxer from '../remux/passthrough-remuxer';
12
- import { logger } from '../utils/logger';
12
+ import { PlaylistLevelType } from '../types/loader';
13
13
  import {
14
14
  isFullSegmentEncryption,
15
15
  getAesModeFromFullSegmentMethod,
@@ -19,18 +19,16 @@ import type { Remuxer } from '../types/remuxer';
19
19
  import type { TransmuxerResult, ChunkMetadata } from '../types/transmuxer';
20
20
  import type { HlsConfig } from '../config';
21
21
  import type { DecryptData } from '../loader/level-key';
22
- import type { PlaylistLevelType } from '../types/loader';
23
22
  import type { TypeSupported } from '../utils/codecs';
23
+ import type { ILogger } from '../utils/logger';
24
24
  import type { RationalTimestamp } from '../utils/timescale-conversion';
25
- import { optionalSelf } from '../utils/global';
26
25
 
27
- let now;
26
+ let now: () => number;
28
27
  // performance.now() not available on WebWorker, at least on Safari Desktop
29
28
  try {
30
29
  now = self.performance.now.bind(self.performance);
31
30
  } catch (err) {
32
- logger.debug('Unable to use Performance API on this environment');
33
- now = optionalSelf?.Date.now;
31
+ now = Date.now;
34
32
  }
35
33
 
36
34
  type MuxConfig =
@@ -52,7 +50,8 @@ if (__USE_M2TS_ADVANCED_CODECS__) {
52
50
  }
53
51
 
54
52
  export default class Transmuxer {
55
- public async: boolean = false;
53
+ private asyncResult: boolean = false;
54
+ private logger: ILogger;
56
55
  private observer: HlsEventEmitter;
57
56
  private typeSupported: TypeSupported;
58
57
  private config: HlsConfig;
@@ -72,12 +71,14 @@ export default class Transmuxer {
72
71
  config: HlsConfig,
73
72
  vendor: string,
74
73
  id: PlaylistLevelType,
74
+ logger: ILogger,
75
75
  ) {
76
76
  this.observer = observer;
77
77
  this.typeSupported = typeSupported;
78
78
  this.config = config;
79
79
  this.vendor = vendor;
80
80
  this.id = id;
81
+ this.logger = logger;
81
82
  }
82
83
 
83
84
  configure(transmuxConfig: TransmuxConfig) {
@@ -144,6 +145,7 @@ export default class Transmuxer {
144
145
  }
145
146
  uintData = new Uint8Array(decryptedData);
146
147
  } else {
148
+ this.asyncResult = true;
147
149
  this.decryptionPromise = decrypter
148
150
  .webCryptoDecrypt(
149
151
  uintData,
@@ -162,7 +164,7 @@ export default class Transmuxer {
162
164
  this.decryptionPromise = null;
163
165
  return result;
164
166
  });
165
- return this.decryptionPromise!;
167
+ return this.decryptionPromise;
166
168
  }
167
169
  }
168
170
 
@@ -170,7 +172,7 @@ export default class Transmuxer {
170
172
  if (resetMuxers) {
171
173
  const error = this.configureTransmuxer(uintData);
172
174
  if (error) {
173
- logger.warn(`[transmuxer] ${error.message}`);
175
+ this.logger.warn(`[transmuxer] ${error.message}`);
174
176
  this.observer.emit(Events.ERROR, Events.ERROR, {
175
177
  type: ErrorTypes.MEDIA_ERROR,
176
178
  details: ErrorDetails.FRAG_PARSING_ERROR,
@@ -208,6 +210,8 @@ export default class Transmuxer {
208
210
  accurateTimeOffset,
209
211
  chunkMeta,
210
212
  );
213
+ this.asyncResult = isPromise(result);
214
+
211
215
  const currentState = this.currentTransmuxState;
212
216
 
213
217
  currentState.contiguous = true;
@@ -228,6 +232,7 @@ export default class Transmuxer {
228
232
  const { decrypter, currentTransmuxState, decryptionPromise } = this;
229
233
 
230
234
  if (decryptionPromise) {
235
+ this.asyncResult = true;
231
236
  // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
232
237
  // only flushing is required for async decryption
233
238
  return decryptionPromise.then(() => {
@@ -254,11 +259,16 @@ export default class Transmuxer {
254
259
  if (!demuxer || !remuxer) {
255
260
  // If probing failed, then Hls.js has been given content its not able to handle
256
261
  stats.executeEnd = now();
257
- return [emptyResult(chunkMeta)];
262
+ const emptyResults = [emptyResult(chunkMeta)];
263
+ if (this.asyncResult) {
264
+ return Promise.resolve(emptyResults);
265
+ }
266
+ return emptyResults;
258
267
  }
259
268
 
260
269
  const demuxResultOrPromise = demuxer.flush(timeOffset);
261
270
  if (isPromise(demuxResultOrPromise)) {
271
+ this.asyncResult = true;
262
272
  // Decrypt final SAMPLE-AES samples
263
273
  return demuxResultOrPromise.then((demuxResult) => {
264
274
  this.flushRemux(transmuxResults, demuxResult, chunkMeta);
@@ -267,6 +277,9 @@ export default class Transmuxer {
267
277
  }
268
278
 
269
279
  this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);
280
+ if (this.asyncResult) {
281
+ return Promise.resolve(transmuxResults);
282
+ }
270
283
  return transmuxResults;
271
284
  }
272
285
 
@@ -277,10 +290,10 @@ export default class Transmuxer {
277
290
  ) {
278
291
  const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;
279
292
  const { accurateTimeOffset, timeOffset } = this.currentTransmuxState;
280
- logger.log(
281
- `[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${
293
+ this.logger.log(
294
+ `[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${
282
295
  chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''
283
- } of level ${chunkMeta.level}`,
296
+ } of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`,
284
297
  );
285
298
  const remuxResult = this.remuxer!.remux(
286
299
  audioTrack,
@@ -438,7 +451,7 @@ export default class Transmuxer {
438
451
  // probe for content type
439
452
  let mux;
440
453
  for (let i = 0, len = muxConfig.length; i < len; i++) {
441
- if (muxConfig[i].demux?.probe(data)) {
454
+ if (muxConfig[i].demux?.probe(data, this.logger)) {
442
455
  mux = muxConfig[i];
443
456
  break;
444
457
  }
@@ -452,10 +465,10 @@ export default class Transmuxer {
452
465
  const Remuxer: MuxConfig['remux'] = mux.remux;
453
466
  const Demuxer: MuxConfig['demux'] = mux.demux;
454
467
  if (!remuxer || !(remuxer instanceof Remuxer)) {
455
- this.remuxer = new Remuxer(observer, config, typeSupported, vendor);
468
+ this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);
456
469
  }
457
470
  if (!demuxer || !(demuxer instanceof Demuxer)) {
458
- this.demuxer = new Demuxer(observer, config, typeSupported);
471
+ this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);
459
472
  this.probe = Demuxer.probe;
460
473
  }
461
474
  }
@@ -18,11 +18,11 @@ import HevcVideoParser from './video/hevc-video-parser';
18
18
  import SampleAesDecrypter from './sample-aes';
19
19
  import { Events } from '../events';
20
20
  import { appendUint8Array, RemuxerTrackIdConfig } from '../utils/mp4-tools';
21
- import { logger } from '../utils/logger';
22
21
  import { ErrorTypes, ErrorDetails } from '../errors';
23
22
  import type { HlsConfig } from '../config';
24
23
  import type { HlsEventEmitter } from '../events';
25
24
  import type { TypeSupported } from '../utils/codecs';
25
+ import type { ILogger } from '../utils/logger';
26
26
  import {
27
27
  MetadataSchema,
28
28
  type DemuxedVideoTrack,
@@ -54,9 +54,10 @@ export type ParsedVideoSample = ParsedTimestamp &
54
54
  const PACKET_LENGTH = 188;
55
55
 
56
56
  class TSDemuxer implements Demuxer {
57
+ private readonly logger: ILogger;
57
58
  private readonly observer: HlsEventEmitter;
58
59
  private readonly config: HlsConfig;
59
- private typeSupported: TypeSupported;
60
+ private readonly typeSupported: TypeSupported;
60
61
 
61
62
  private sampleAes: SampleAesDecrypter | null = null;
62
63
  private pmtParsed: boolean = false;
@@ -77,14 +78,16 @@ class TSDemuxer implements Demuxer {
77
78
  observer: HlsEventEmitter,
78
79
  config: HlsConfig,
79
80
  typeSupported: TypeSupported,
81
+ logger: ILogger,
80
82
  ) {
81
83
  this.observer = observer;
82
84
  this.config = config;
83
85
  this.typeSupported = typeSupported;
86
+ this.logger = logger;
84
87
  this.videoParser = null;
85
88
  }
86
89
 
87
- static probe(data: Uint8Array) {
90
+ static probe(data: Uint8Array, logger: ILogger) {
88
91
  const syncOffset = TSDemuxer.syncOffset(data);
89
92
  if (syncOffset > 0) {
90
93
  logger.warn(
@@ -288,7 +291,7 @@ class TSDemuxer implements Demuxer {
288
291
  switch (pid) {
289
292
  case videoPid:
290
293
  if (stt) {
291
- if (videoData && (pes = parsePES(videoData))) {
294
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
292
295
  if (this.videoParser === null) {
293
296
  switch (videoTrack.segmentCodec) {
294
297
  case 'avc':
@@ -321,7 +324,7 @@ class TSDemuxer implements Demuxer {
321
324
  break;
322
325
  case audioPid:
323
326
  if (stt) {
324
- if (audioData && (pes = parsePES(audioData))) {
327
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
325
328
  switch (audioTrack.segmentCodec) {
326
329
  case 'aac':
327
330
  this.parseAACPES(audioTrack, pes);
@@ -345,7 +348,7 @@ class TSDemuxer implements Demuxer {
345
348
  break;
346
349
  case id3Pid:
347
350
  if (stt) {
348
- if (id3Data && (pes = parsePES(id3Data))) {
351
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
349
352
  this.parseID3PES(id3Track, pes);
350
353
  }
351
354
 
@@ -362,7 +365,7 @@ class TSDemuxer implements Demuxer {
362
365
  }
363
366
 
364
367
  pmtId = this._pmtId = parsePAT(data, offset);
365
- // logger.log('PMT PID:' + this._pmtId);
368
+ // this.logger.log('PMT PID:' + this._pmtId);
366
369
  break;
367
370
  case pmtId: {
368
371
  if (stt) {
@@ -375,6 +378,7 @@ class TSDemuxer implements Demuxer {
375
378
  this.typeSupported,
376
379
  isSampleAes,
377
380
  this.observer,
381
+ this.logger,
378
382
  );
379
383
 
380
384
  // only update track id if track PID found while parsing PMT
@@ -400,7 +404,7 @@ class TSDemuxer implements Demuxer {
400
404
  }
401
405
 
402
406
  if (unknownPID !== null && !pmtParsed) {
403
- logger.warn(
407
+ this.logger.warn(
404
408
  `MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`,
405
409
  );
406
410
  unknownPID = null;
@@ -428,6 +432,8 @@ class TSDemuxer implements Demuxer {
428
432
  new Error(
429
433
  `Found ${tsPacketErrors} TS packet/s that do not start with 0x47`,
430
434
  ),
435
+ undefined,
436
+ this.logger,
431
437
  );
432
438
  }
433
439
 
@@ -477,7 +483,7 @@ class TSDemuxer implements Demuxer {
477
483
  const id3Data = id3Track.pesData;
478
484
  // try to parse last PES packets
479
485
  let pes: PES | null;
480
- if (videoData && (pes = parsePES(videoData))) {
486
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
481
487
  if (this.videoParser === null) {
482
488
  switch (videoTrack.segmentCodec) {
483
489
  case 'avc':
@@ -505,7 +511,7 @@ class TSDemuxer implements Demuxer {
505
511
  videoTrack.pesData = videoData;
506
512
  }
507
513
 
508
- if (audioData && (pes = parsePES(audioData))) {
514
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
509
515
  switch (audioTrack.segmentCodec) {
510
516
  case 'aac':
511
517
  this.parseAACPES(audioTrack, pes);
@@ -522,7 +528,7 @@ class TSDemuxer implements Demuxer {
522
528
  audioTrack.pesData = null;
523
529
  } else {
524
530
  if (audioData?.size) {
525
- logger.log(
531
+ this.logger.log(
526
532
  'last AAC PES packet truncated,might overlap between fragments',
527
533
  );
528
534
  }
@@ -531,7 +537,7 @@ class TSDemuxer implements Demuxer {
531
537
  audioTrack.pesData = audioData;
532
538
  }
533
539
 
534
- if (id3Data && (pes = parsePES(id3Data))) {
540
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
535
541
  this.parseID3PES(id3Track, pes);
536
542
  id3Track.pesData = null;
537
543
  } else {
@@ -625,7 +631,12 @@ class TSDemuxer implements Demuxer {
625
631
  } else {
626
632
  reason = 'No ADTS header found in AAC PES';
627
633
  }
628
- emitParsingError(this.observer, new Error(reason), recoverable);
634
+ emitParsingError(
635
+ this.observer,
636
+ new Error(reason),
637
+ recoverable,
638
+ this.logger,
639
+ );
629
640
  if (!recoverable) {
630
641
  return;
631
642
  }
@@ -648,7 +659,7 @@ class TSDemuxer implements Demuxer {
648
659
  const frameDuration = ADTS.getFrameDuration(track.samplerate as number);
649
660
  pts = aacOverFlow.sample.pts + frameDuration;
650
661
  } else {
651
- logger.warn('[tsdemuxer]: AAC PES unknown PTS');
662
+ this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');
652
663
  return;
653
664
  }
654
665
 
@@ -679,7 +690,7 @@ class TSDemuxer implements Demuxer {
679
690
  let offset = 0;
680
691
  const pts = pes.pts;
681
692
  if (pts === undefined) {
682
- logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
693
+ this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
683
694
  return;
684
695
  }
685
696
 
@@ -711,7 +722,7 @@ class TSDemuxer implements Demuxer {
711
722
  const data = pes.data;
712
723
  const pts = pes.pts;
713
724
  if (pts === undefined) {
714
- logger.warn('[tsdemuxer]: AC3 PES unknown PTS');
725
+ this.logger.warn('[tsdemuxer]: AC3 PES unknown PTS');
715
726
  return;
716
727
  }
717
728
  const length = data.length;
@@ -730,7 +741,7 @@ class TSDemuxer implements Demuxer {
730
741
 
731
742
  private parseID3PES(id3Track: DemuxedMetadataTrack, pes: PES) {
732
743
  if (pes.pts === undefined) {
733
- logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
744
+ this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
734
745
  return;
735
746
  }
736
747
  const id3Sample = Object.assign({}, pes as Required<PES>, {
@@ -757,6 +768,7 @@ function parsePMT(
757
768
  typeSupported: TypeSupported,
758
769
  isSampleAes: boolean,
759
770
  observer: HlsEventEmitter,
771
+ logger: ILogger,
760
772
  ) {
761
773
  const result = {
762
774
  audioPid: -1,
@@ -779,7 +791,7 @@ function parsePMT(
779
791
  switch (data[offset]) {
780
792
  case 0xcf: // SAMPLE-AES AAC
781
793
  if (!isSampleAes) {
782
- logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC');
794
+ logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', this.logger);
783
795
  break;
784
796
  }
785
797
  /* falls through */
@@ -802,7 +814,7 @@ function parsePMT(
802
814
 
803
815
  case 0xdb: // SAMPLE-AES AVC
804
816
  if (!isSampleAes) {
805
- logEncryptedSamplesFoundInUnencryptedStream('H.264');
817
+ logEncryptedSamplesFoundInUnencryptedStream('H.264', this.logger);
806
818
  break;
807
819
  }
808
820
  /* falls through */
@@ -830,7 +842,7 @@ function parsePMT(
830
842
 
831
843
  case 0xc1: // SAMPLE-AES AC3
832
844
  if (!isSampleAes) {
833
- logEncryptedSamplesFoundInUnencryptedStream('AC-3');
845
+ logEncryptedSamplesFoundInUnencryptedStream('AC-3', this.logger);
834
846
  break;
835
847
  }
836
848
  /* falls through */
@@ -886,7 +898,12 @@ function parsePMT(
886
898
  case 0xc2: // SAMPLE-AES EC3
887
899
  /* falls through */
888
900
  case 0x87:
889
- emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
901
+ emitParsingError(
902
+ observer,
903
+ new Error('Unsupported EC-3 in M2TS found'),
904
+ undefined,
905
+ this.logger,
906
+ );
890
907
  return result;
891
908
 
892
909
  case 0x24: // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
@@ -900,6 +917,8 @@ function parsePMT(
900
917
  emitParsingError(
901
918
  observer,
902
919
  new Error('Unsupported HEVC in M2TS found'),
920
+ undefined,
921
+ this.logger,
903
922
  );
904
923
  return result;
905
924
  }
@@ -919,7 +938,8 @@ function parsePMT(
919
938
  function emitParsingError(
920
939
  observer: HlsEventEmitter,
921
940
  error: Error,
922
- levelRetry?: boolean,
941
+ levelRetry: boolean | undefined,
942
+ logger: ILogger,
923
943
  ) {
924
944
  logger.warn(`parsing error: ${error.message}`);
925
945
  observer.emit(Events.ERROR, Events.ERROR, {
@@ -932,11 +952,14 @@ function emitParsingError(
932
952
  });
933
953
  }
934
954
 
935
- function logEncryptedSamplesFoundInUnencryptedStream(type: string) {
955
+ function logEncryptedSamplesFoundInUnencryptedStream(
956
+ type: string,
957
+ logger: ILogger,
958
+ ) {
936
959
  logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
937
960
  }
938
961
 
939
- function parsePES(stream: ElementaryStreamData): PES | null {
962
+ function parsePES(stream: ElementaryStreamData, logger: ILogger): PES | null {
940
963
  let i = 0;
941
964
  let frag: Uint8Array;
942
965
  let pesLen: number;