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.
package/dist/hls.mjs CHANGED
@@ -420,7 +420,7 @@ function enableLogs(debugConfig, context, id) {
420
420
  // Some browsers don't allow to use bind on console object anyway
421
421
  // fallback to default if needed
422
422
  try {
423
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.10431"}`);
423
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.10432"}`);
424
424
  } catch (e) {
425
425
  /* log fn threw an exception. All logger methods are no-ops. */
426
426
  return createLogger();
@@ -9838,6 +9838,10 @@ class BaseStreamController extends TaskLoop {
9838
9838
  }
9839
9839
  onHandlerDestroying() {
9840
9840
  this.stopLoad();
9841
+ if (this.transmuxer) {
9842
+ this.transmuxer.destroy();
9843
+ this.transmuxer = null;
9844
+ }
9841
9845
  super.onHandlerDestroying();
9842
9846
  // @ts-ignore
9843
9847
  this.hls = this.onMediaSeeking = this.onMediaEnded = null;
@@ -10961,10 +10965,8 @@ class BaseStreamController extends TaskLoop {
10961
10965
  return `${this.playlistLabel()} ${frag.level} (frag:[${((_ref = pts ? frag.startPTS : frag.start) != null ? _ref : NaN).toFixed(3)}-${((_ref2 = pts ? frag.endPTS : frag.end) != null ? _ref2 : NaN).toFixed(3)}]`;
10962
10966
  }
10963
10967
  resetTransmuxer() {
10964
- if (this.transmuxer) {
10965
- this.transmuxer.destroy();
10966
- this.transmuxer = null;
10967
- }
10968
+ var _this$transmuxer2;
10969
+ (_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
10968
10970
  }
10969
10971
  recoverWorkerError(data) {
10970
10972
  if (data.event === 'demuxerWorker') {
@@ -11027,29 +11029,66 @@ function concatUint8Arrays(chunks, dataLength) {
11027
11029
  return result;
11028
11030
  }
11029
11031
 
11032
+ const version = "1.5.14-0.canary.10432";
11033
+
11030
11034
  // ensure the worker ends up in the bundle
11031
11035
  // If the worker should not be included this gets aliased to empty.js
11036
+ const workerStore = {};
11032
11037
  function hasUMDWorker() {
11033
11038
  return typeof __HLS_WORKER_BUNDLE__ === 'function';
11034
11039
  }
11035
11040
  function injectWorker() {
11041
+ const workerContext = workerStore[version];
11042
+ if (workerContext) {
11043
+ workerContext.clientCount++;
11044
+ return workerContext;
11045
+ }
11036
11046
  const blob = new self.Blob([`var exports={};var module={exports:exports};function define(f){f()};define.amd=true;(${__HLS_WORKER_BUNDLE__.toString()})(true);`], {
11037
11047
  type: 'text/javascript'
11038
11048
  });
11039
11049
  const objectURL = self.URL.createObjectURL(blob);
11040
11050
  const worker = new self.Worker(objectURL);
11041
- return {
11051
+ const result = {
11042
11052
  worker,
11043
- objectURL
11053
+ objectURL,
11054
+ clientCount: 1
11044
11055
  };
11056
+ workerStore[version] = result;
11057
+ return result;
11045
11058
  }
11046
11059
  function loadWorker(path) {
11060
+ const workerContext = workerStore[path];
11061
+ if (workerContext) {
11062
+ workerContext.clientCount++;
11063
+ return workerContext;
11064
+ }
11047
11065
  const scriptURL = new self.URL(path, self.location.href).href;
11048
11066
  const worker = new self.Worker(scriptURL);
11049
- return {
11067
+ const result = {
11050
11068
  worker,
11051
- scriptURL
11069
+ scriptURL,
11070
+ clientCount: 1
11052
11071
  };
11072
+ workerStore[path] = result;
11073
+ return result;
11074
+ }
11075
+ function removeWorkerFromStore(path) {
11076
+ const workerContext = workerStore[path || version];
11077
+ if (workerContext) {
11078
+ const clientCount = workerContext.clientCount--;
11079
+ if (clientCount === 1) {
11080
+ const {
11081
+ worker,
11082
+ objectURL
11083
+ } = workerContext;
11084
+ delete workerStore[path || version];
11085
+ if (objectURL) {
11086
+ // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
11087
+ self.URL.revokeObjectURL(objectURL);
11088
+ }
11089
+ worker.terminate();
11090
+ }
11091
+ }
11053
11092
  }
11054
11093
 
11055
11094
  function dummyTrack(type = '', inputTimeScale = 90000) {
@@ -11726,7 +11765,7 @@ class AACDemuxer extends BaseAudioDemuxer {
11726
11765
  }
11727
11766
 
11728
11767
  // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
11729
- static probe(data) {
11768
+ static probe(data, logger) {
11730
11769
  if (!data) {
11731
11770
  return false;
11732
11771
  }
@@ -13352,7 +13391,8 @@ class SampleAesDecrypter {
13352
13391
 
13353
13392
  const PACKET_LENGTH = 188;
13354
13393
  class TSDemuxer {
13355
- constructor(observer, config, typeSupported) {
13394
+ constructor(observer, config, typeSupported, logger) {
13395
+ this.logger = void 0;
13356
13396
  this.observer = void 0;
13357
13397
  this.config = void 0;
13358
13398
  this.typeSupported = void 0;
@@ -13372,9 +13412,10 @@ class TSDemuxer {
13372
13412
  this.observer = observer;
13373
13413
  this.config = config;
13374
13414
  this.typeSupported = typeSupported;
13415
+ this.logger = logger;
13375
13416
  this.videoParser = null;
13376
13417
  }
13377
- static probe(data) {
13418
+ static probe(data, logger) {
13378
13419
  const syncOffset = TSDemuxer.syncOffset(data);
13379
13420
  if (syncOffset > 0) {
13380
13421
  logger.warn(`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`);
@@ -13536,7 +13577,7 @@ class TSDemuxer {
13536
13577
  switch (pid) {
13537
13578
  case videoPid:
13538
13579
  if (stt) {
13539
- if (videoData && (pes = parsePES(videoData))) {
13580
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
13540
13581
  if (this.videoParser === null) {
13541
13582
  switch (videoTrack.segmentCodec) {
13542
13583
  case 'avc':
@@ -13565,7 +13606,7 @@ class TSDemuxer {
13565
13606
  break;
13566
13607
  case audioPid:
13567
13608
  if (stt) {
13568
- if (audioData && (pes = parsePES(audioData))) {
13609
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
13569
13610
  switch (audioTrack.segmentCodec) {
13570
13611
  case 'aac':
13571
13612
  this.parseAACPES(audioTrack, pes);
@@ -13592,7 +13633,7 @@ class TSDemuxer {
13592
13633
  break;
13593
13634
  case id3Pid:
13594
13635
  if (stt) {
13595
- if (id3Data && (pes = parsePES(id3Data))) {
13636
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
13596
13637
  this.parseID3PES(id3Track, pes);
13597
13638
  }
13598
13639
  id3Data = {
@@ -13610,14 +13651,14 @@ class TSDemuxer {
13610
13651
  offset += data[offset] + 1;
13611
13652
  }
13612
13653
  pmtId = this._pmtId = parsePAT(data, offset);
13613
- // logger.log('PMT PID:' + this._pmtId);
13654
+ // this.logger.log('PMT PID:' + this._pmtId);
13614
13655
  break;
13615
13656
  case pmtId:
13616
13657
  {
13617
13658
  if (stt) {
13618
13659
  offset += data[offset] + 1;
13619
13660
  }
13620
- const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer);
13661
+ const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer, this.logger);
13621
13662
 
13622
13663
  // only update track id if track PID found while parsing PMT
13623
13664
  // this is to avoid resetting the PID to -1 in case
@@ -13640,7 +13681,7 @@ class TSDemuxer {
13640
13681
  id3Track.pid = id3Pid;
13641
13682
  }
13642
13683
  if (unknownPID !== null && !pmtParsed) {
13643
- logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
13684
+ this.logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
13644
13685
  unknownPID = null;
13645
13686
  // we set it to -188, the += 188 in the for loop will reset start to 0
13646
13687
  start = syncOffset - 188;
@@ -13660,7 +13701,7 @@ class TSDemuxer {
13660
13701
  }
13661
13702
  }
13662
13703
  if (tsPacketErrors > 0) {
13663
- emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`));
13704
+ emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`), undefined, this.logger);
13664
13705
  }
13665
13706
  videoTrack.pesData = videoData;
13666
13707
  audioTrack.pesData = audioData;
@@ -13710,7 +13751,7 @@ class TSDemuxer {
13710
13751
  const id3Data = id3Track.pesData;
13711
13752
  // try to parse last PES packets
13712
13753
  let pes;
13713
- if (videoData && (pes = parsePES(videoData))) {
13754
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
13714
13755
  if (this.videoParser === null) {
13715
13756
  switch (videoTrack.segmentCodec) {
13716
13757
  case 'avc':
@@ -13731,7 +13772,7 @@ class TSDemuxer {
13731
13772
  // either avcData null or PES truncated, keep it for next frag parsing
13732
13773
  videoTrack.pesData = videoData;
13733
13774
  }
13734
- if (audioData && (pes = parsePES(audioData))) {
13775
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
13735
13776
  switch (audioTrack.segmentCodec) {
13736
13777
  case 'aac':
13737
13778
  this.parseAACPES(audioTrack, pes);
@@ -13748,13 +13789,13 @@ class TSDemuxer {
13748
13789
  audioTrack.pesData = null;
13749
13790
  } else {
13750
13791
  if (audioData != null && audioData.size) {
13751
- logger.log('last AAC PES packet truncated,might overlap between fragments');
13792
+ this.logger.log('last AAC PES packet truncated,might overlap between fragments');
13752
13793
  }
13753
13794
 
13754
13795
  // either audioData null or PES truncated, keep it for next frag parsing
13755
13796
  audioTrack.pesData = audioData;
13756
13797
  }
13757
- if (id3Data && (pes = parsePES(id3Data))) {
13798
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
13758
13799
  this.parseID3PES(id3Track, pes);
13759
13800
  id3Track.pesData = null;
13760
13801
  } else {
@@ -13828,7 +13869,7 @@ class TSDemuxer {
13828
13869
  } else {
13829
13870
  reason = 'No ADTS header found in AAC PES';
13830
13871
  }
13831
- emitParsingError(this.observer, new Error(reason), recoverable);
13872
+ emitParsingError(this.observer, new Error(reason), recoverable, this.logger);
13832
13873
  if (!recoverable) {
13833
13874
  return;
13834
13875
  }
@@ -13843,7 +13884,7 @@ class TSDemuxer {
13843
13884
  const frameDuration = getFrameDuration(track.samplerate);
13844
13885
  pts = aacOverFlow.sample.pts + frameDuration;
13845
13886
  } else {
13846
- logger.warn('[tsdemuxer]: AAC PES unknown PTS');
13887
+ this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');
13847
13888
  return;
13848
13889
  }
13849
13890
 
@@ -13873,7 +13914,7 @@ class TSDemuxer {
13873
13914
  let offset = 0;
13874
13915
  const pts = pes.pts;
13875
13916
  if (pts === undefined) {
13876
- logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
13917
+ this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
13877
13918
  return;
13878
13919
  }
13879
13920
  while (offset < length) {
@@ -13897,7 +13938,7 @@ class TSDemuxer {
13897
13938
  const data = pes.data;
13898
13939
  const pts = pes.pts;
13899
13940
  if (pts === undefined) {
13900
- logger.warn('[tsdemuxer]: AC3 PES unknown PTS');
13941
+ this.logger.warn('[tsdemuxer]: AC3 PES unknown PTS');
13901
13942
  return;
13902
13943
  }
13903
13944
  const length = data.length;
@@ -13911,7 +13952,7 @@ class TSDemuxer {
13911
13952
  }
13912
13953
  parseID3PES(id3Track, pes) {
13913
13954
  if (pes.pts === undefined) {
13914
- logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
13955
+ this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
13915
13956
  return;
13916
13957
  }
13917
13958
  const id3Sample = _extends({}, pes, {
@@ -13929,7 +13970,7 @@ function parsePAT(data, offset) {
13929
13970
  // skip the PSI header and parse the first PMT entry
13930
13971
  return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
13931
13972
  }
13932
- function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
13973
+ function parsePMT(data, offset, typeSupported, isSampleAes, observer, logger) {
13933
13974
  const result = {
13934
13975
  audioPid: -1,
13935
13976
  videoPid: -1,
@@ -13951,7 +13992,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
13951
13992
  case 0xcf:
13952
13993
  // SAMPLE-AES AAC
13953
13994
  if (!isSampleAes) {
13954
- logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC');
13995
+ logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', this.logger);
13955
13996
  break;
13956
13997
  }
13957
13998
  /* falls through */
@@ -13973,7 +14014,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
13973
14014
  case 0xdb:
13974
14015
  // SAMPLE-AES AVC
13975
14016
  if (!isSampleAes) {
13976
- logEncryptedSamplesFoundInUnencryptedStream('H.264');
14017
+ logEncryptedSamplesFoundInUnencryptedStream('H.264', this.logger);
13977
14018
  break;
13978
14019
  }
13979
14020
  /* falls through */
@@ -14001,7 +14042,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
14001
14042
  case 0xc1:
14002
14043
  // SAMPLE-AES AC3
14003
14044
  if (!isSampleAes) {
14004
- logEncryptedSamplesFoundInUnencryptedStream('AC-3');
14045
+ logEncryptedSamplesFoundInUnencryptedStream('AC-3', this.logger);
14005
14046
  break;
14006
14047
  }
14007
14048
  /* falls through */
@@ -14047,7 +14088,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
14047
14088
  case 0xc2: // SAMPLE-AES EC3
14048
14089
  /* falls through */
14049
14090
  case 0x87:
14050
- emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
14091
+ emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'), undefined, this.logger);
14051
14092
  return result;
14052
14093
  case 0x24:
14053
14094
  // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
@@ -14066,7 +14107,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
14066
14107
  }
14067
14108
  return result;
14068
14109
  }
14069
- function emitParsingError(observer, error, levelRetry) {
14110
+ function emitParsingError(observer, error, levelRetry, logger) {
14070
14111
  logger.warn(`parsing error: ${error.message}`);
14071
14112
  observer.emit(Events.ERROR, Events.ERROR, {
14072
14113
  type: ErrorTypes.MEDIA_ERROR,
@@ -14077,10 +14118,10 @@ function emitParsingError(observer, error, levelRetry) {
14077
14118
  reason: error.message
14078
14119
  });
14079
14120
  }
14080
- function logEncryptedSamplesFoundInUnencryptedStream(type) {
14121
+ function logEncryptedSamplesFoundInUnencryptedStream(type, logger) {
14081
14122
  logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
14082
14123
  }
14083
- function parsePES(stream) {
14124
+ function parsePES(stream, logger) {
14084
14125
  let i = 0;
14085
14126
  let frag;
14086
14127
  let pesLen;
@@ -14971,7 +15012,8 @@ const AC3_SAMPLES_PER_FRAME = 1536;
14971
15012
  let chromeVersion = null;
14972
15013
  let safariWebkitVersion = null;
14973
15014
  class MP4Remuxer {
14974
- constructor(observer, config, typeSupported, vendor = '') {
15015
+ constructor(observer, config, typeSupported, logger) {
15016
+ this.logger = void 0;
14975
15017
  this.observer = void 0;
14976
15018
  this.config = void 0;
14977
15019
  this.typeSupported = void 0;
@@ -14987,6 +15029,7 @@ class MP4Remuxer {
14987
15029
  this.observer = observer;
14988
15030
  this.config = config;
14989
15031
  this.typeSupported = typeSupported;
15032
+ this.logger = logger;
14990
15033
  this.ISGenerated = false;
14991
15034
  if (chromeVersion === null) {
14992
15035
  const userAgent = navigator.userAgent || '';
@@ -15003,16 +15046,16 @@ class MP4Remuxer {
15003
15046
  this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;
15004
15047
  }
15005
15048
  resetTimeStamp(defaultTimeStamp) {
15006
- logger.log('[mp4-remuxer]: initPTS & initDTS reset');
15049
+ this.logger.log('[mp4-remuxer]: initPTS & initDTS reset');
15007
15050
  this._initPTS = this._initDTS = defaultTimeStamp;
15008
15051
  }
15009
15052
  resetNextTimestamp() {
15010
- logger.log('[mp4-remuxer]: reset next timestamp');
15053
+ this.logger.log('[mp4-remuxer]: reset next timestamp');
15011
15054
  this.isVideoContiguous = false;
15012
15055
  this.isAudioContiguous = false;
15013
15056
  }
15014
15057
  resetInitSegment() {
15015
- logger.log('[mp4-remuxer]: ISGenerated flag reset');
15058
+ this.logger.log('[mp4-remuxer]: ISGenerated flag reset');
15016
15059
  this.ISGenerated = false;
15017
15060
  this.videoTrackConfig = undefined;
15018
15061
  }
@@ -15031,7 +15074,7 @@ class MP4Remuxer {
15031
15074
  }
15032
15075
  }, videoSamples[0].pts);
15033
15076
  if (rolloverDetected) {
15034
- logger.debug('PTS rollover detected');
15077
+ this.logger.debug('PTS rollover detected');
15035
15078
  }
15036
15079
  return startPTS;
15037
15080
  }
@@ -15075,14 +15118,14 @@ class MP4Remuxer {
15075
15118
  if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {
15076
15119
  independent = true;
15077
15120
  if (firstKeyFrameIndex > 0) {
15078
- logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
15121
+ this.logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
15079
15122
  const startPTS = this.getVideoStartPts(videoTrack.samples);
15080
15123
  videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
15081
15124
  videoTrack.dropped += firstKeyFrameIndex;
15082
15125
  videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / videoTrack.inputTimeScale;
15083
15126
  firstKeyFramePTS = videoTimeOffset;
15084
15127
  } else if (firstKeyFrameIndex === -1) {
15085
- logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
15128
+ this.logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
15086
15129
  independent = false;
15087
15130
  }
15088
15131
  }
@@ -15104,7 +15147,7 @@ class MP4Remuxer {
15104
15147
  if (enoughAudioSamples) {
15105
15148
  // if initSegment was generated without audio samples, regenerate it again
15106
15149
  if (!audioTrack.samplerate) {
15107
- logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
15150
+ this.logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
15108
15151
  initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
15109
15152
  }
15110
15153
  audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === PlaylistLevelType.AUDIO ? videoTimeOffset : undefined);
@@ -15112,7 +15155,7 @@ class MP4Remuxer {
15112
15155
  const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
15113
15156
  // if initSegment was generated without video samples, regenerate it again
15114
15157
  if (!videoTrack.inputTimeScale) {
15115
- logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
15158
+ this.logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
15116
15159
  initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
15117
15160
  }
15118
15161
  video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength);
@@ -15318,9 +15361,9 @@ class MP4Remuxer {
15318
15361
  const foundOverlap = delta < -1;
15319
15362
  if (foundHole || foundOverlap) {
15320
15363
  if (foundHole) {
15321
- logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
15364
+ this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
15322
15365
  } else {
15323
- logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
15366
+ this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
15324
15367
  }
15325
15368
  if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
15326
15369
  firstDTS = nextAvcDts;
@@ -15349,7 +15392,7 @@ class MP4Remuxer {
15349
15392
  }
15350
15393
  }
15351
15394
  }
15352
- logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
15395
+ this.logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
15353
15396
  }
15354
15397
  }
15355
15398
  }
@@ -15449,7 +15492,7 @@ class MP4Remuxer {
15449
15492
  } else {
15450
15493
  stretchedLastFrame = true;
15451
15494
  }
15452
- logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
15495
+ this.logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
15453
15496
  } else {
15454
15497
  mp4SampleDuration = lastFrameDuration;
15455
15498
  }
@@ -15477,7 +15520,7 @@ class MP4Remuxer {
15477
15520
  // Fix for "CNN special report, with CC" in test-streams (Safari browser only)
15478
15521
  // Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
15479
15522
  if (maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta && averageSampleDuration / maxDtsDelta < 0.025 && outputSamples[0].cts === 0) {
15480
- logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
15523
+ this.logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
15481
15524
  let dts = firstDTS;
15482
15525
  for (let i = 0, len = outputSamples.length; i < len; i++) {
15483
15526
  const nextDts = dts + outputSamples[i].duration;
@@ -15602,7 +15645,7 @@ class MP4Remuxer {
15602
15645
  // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
15603
15646
  if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) {
15604
15647
  if (i === 0) {
15605
- logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
15648
+ this.logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
15606
15649
  this.nextAudioPts = nextAudioPts = nextPts = pts;
15607
15650
  }
15608
15651
  } // eslint-disable-line brace-style
@@ -15624,12 +15667,12 @@ class MP4Remuxer {
15624
15667
  if (i === 0) {
15625
15668
  this.nextAudioPts = nextAudioPts = nextPts;
15626
15669
  }
15627
- logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
15670
+ this.logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
15628
15671
  for (let j = 0; j < missing; j++) {
15629
15672
  const newStamp = Math.max(nextPts, 0);
15630
15673
  let fillFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
15631
15674
  if (!fillFrame) {
15632
- logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
15675
+ this.logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
15633
15676
  fillFrame = sample.unit.subarray();
15634
15677
  }
15635
15678
  inputSamples.splice(i, 0, {
@@ -15828,7 +15871,8 @@ class Mp4Sample {
15828
15871
  }
15829
15872
 
15830
15873
  class PassThroughRemuxer {
15831
- constructor() {
15874
+ constructor(observer, config, typeSupported, logger) {
15875
+ this.logger = void 0;
15832
15876
  this.emitInitSegment = false;
15833
15877
  this.audioCodec = void 0;
15834
15878
  this.videoCodec = void 0;
@@ -15836,6 +15880,7 @@ class PassThroughRemuxer {
15836
15880
  this.initPTS = null;
15837
15881
  this.initTracks = void 0;
15838
15882
  this.lastEndTime = null;
15883
+ this.logger = logger;
15839
15884
  }
15840
15885
  destroy() {}
15841
15886
  resetTimeStamp(defaultInitPTS) {
@@ -15893,7 +15938,7 @@ class PassThroughRemuxer {
15893
15938
  id: 'main'
15894
15939
  };
15895
15940
  } else {
15896
- logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
15941
+ this.logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
15897
15942
  }
15898
15943
  this.initTracks = tracks;
15899
15944
  }
@@ -15935,7 +15980,7 @@ class PassThroughRemuxer {
15935
15980
  }
15936
15981
  if (!((_initData2 = initData) != null && _initData2.length)) {
15937
15982
  // We can't remux if the initSegment could not be generated
15938
- logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
15983
+ this.logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
15939
15984
  return result;
15940
15985
  }
15941
15986
  if (this.emitInitSegment) {
@@ -15948,7 +15993,7 @@ class PassThroughRemuxer {
15948
15993
  if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
15949
15994
  initSegment.initPTS = decodeTime - timeOffset;
15950
15995
  if (initPTS && initPTS.timescale === 1) {
15951
- logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
15996
+ this.logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
15952
15997
  }
15953
15998
  this.initPTS = initPTS = {
15954
15999
  baseTime: initSegment.initPTS,
@@ -15961,7 +16006,7 @@ class PassThroughRemuxer {
15961
16006
  if (duration > 0) {
15962
16007
  this.lastEndTime = endTime;
15963
16008
  } else {
15964
- logger.warn('Duration parsed from mp4 should be greater than zero');
16009
+ this.logger.warn('Duration parsed from mp4 should be greater than zero');
15965
16010
  this.resetNextTimestamp();
15966
16011
  }
15967
16012
  const hasAudio = !!initData.audio;
@@ -16019,12 +16064,12 @@ function getParsedTrackCodec(track, type) {
16019
16064
  return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);
16020
16065
  }
16021
16066
  const result = 'mp4a.40.5';
16022
- logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
16067
+ this.logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
16023
16068
  return result;
16024
16069
  }
16025
16070
  // Provide defaults based on codec type
16026
16071
  // This allows for some playback of some fmp4 playlists without CODECS defined in manifest
16027
- logger.warn(`Unhandled video codec "${parsedCodec}"`);
16072
+ this.logger.warn(`Unhandled video codec "${parsedCodec}"`);
16028
16073
  if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
16029
16074
  return 'hvc1.1.6.L120.90';
16030
16075
  }
@@ -16039,8 +16084,7 @@ let now;
16039
16084
  try {
16040
16085
  now = self.performance.now.bind(self.performance);
16041
16086
  } catch (err) {
16042
- logger.debug('Unable to use Performance API on this environment');
16043
- now = optionalSelf == null ? void 0 : optionalSelf.Date.now;
16087
+ now = Date.now;
16044
16088
  }
16045
16089
  const muxConfig = [{
16046
16090
  demux: MP4Demuxer,
@@ -16062,8 +16106,9 @@ const muxConfig = [{
16062
16106
  });
16063
16107
  }
16064
16108
  class Transmuxer {
16065
- constructor(observer, typeSupported, config, vendor, id) {
16066
- this.async = false;
16109
+ constructor(observer, typeSupported, config, vendor, id, logger) {
16110
+ this.asyncResult = false;
16111
+ this.logger = void 0;
16067
16112
  this.observer = void 0;
16068
16113
  this.typeSupported = void 0;
16069
16114
  this.config = void 0;
@@ -16081,6 +16126,7 @@ class Transmuxer {
16081
16126
  this.config = config;
16082
16127
  this.vendor = vendor;
16083
16128
  this.id = id;
16129
+ this.logger = logger;
16084
16130
  }
16085
16131
  configure(transmuxConfig) {
16086
16132
  this.transmuxConfig = transmuxConfig;
@@ -16135,6 +16181,7 @@ class Transmuxer {
16135
16181
  }
16136
16182
  uintData = new Uint8Array(decryptedData);
16137
16183
  } else {
16184
+ this.asyncResult = true;
16138
16185
  this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode).then(decryptedData => {
16139
16186
  // Calling push here is important; if flush() is called while this is still resolving, this ensures that
16140
16187
  // the decrypted data has been transmuxed
@@ -16149,7 +16196,7 @@ class Transmuxer {
16149
16196
  if (resetMuxers) {
16150
16197
  const error = this.configureTransmuxer(uintData);
16151
16198
  if (error) {
16152
- logger.warn(`[transmuxer] ${error.message}`);
16199
+ this.logger.warn(`[transmuxer] ${error.message}`);
16153
16200
  this.observer.emit(Events.ERROR, Events.ERROR, {
16154
16201
  type: ErrorTypes.MEDIA_ERROR,
16155
16202
  details: ErrorDetails.FRAG_PARSING_ERROR,
@@ -16171,6 +16218,7 @@ class Transmuxer {
16171
16218
  this.resetContiguity();
16172
16219
  }
16173
16220
  const result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta);
16221
+ this.asyncResult = isPromise(result);
16174
16222
  const currentState = this.currentTransmuxState;
16175
16223
  currentState.contiguous = true;
16176
16224
  currentState.discontinuity = false;
@@ -16189,6 +16237,7 @@ class Transmuxer {
16189
16237
  decryptionPromise
16190
16238
  } = this;
16191
16239
  if (decryptionPromise) {
16240
+ this.asyncResult = true;
16192
16241
  // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
16193
16242
  // only flushing is required for async decryption
16194
16243
  return decryptionPromise.then(() => {
@@ -16216,10 +16265,15 @@ class Transmuxer {
16216
16265
  if (!demuxer || !remuxer) {
16217
16266
  // If probing failed, then Hls.js has been given content its not able to handle
16218
16267
  stats.executeEnd = now();
16219
- return [emptyResult(chunkMeta)];
16268
+ const emptyResults = [emptyResult(chunkMeta)];
16269
+ if (this.asyncResult) {
16270
+ return Promise.resolve(emptyResults);
16271
+ }
16272
+ return emptyResults;
16220
16273
  }
16221
16274
  const demuxResultOrPromise = demuxer.flush(timeOffset);
16222
16275
  if (isPromise(demuxResultOrPromise)) {
16276
+ this.asyncResult = true;
16223
16277
  // Decrypt final SAMPLE-AES samples
16224
16278
  return demuxResultOrPromise.then(demuxResult => {
16225
16279
  this.flushRemux(transmuxResults, demuxResult, chunkMeta);
@@ -16227,6 +16281,9 @@ class Transmuxer {
16227
16281
  });
16228
16282
  }
16229
16283
  this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);
16284
+ if (this.asyncResult) {
16285
+ return Promise.resolve(transmuxResults);
16286
+ }
16230
16287
  return transmuxResults;
16231
16288
  }
16232
16289
  flushRemux(transmuxResults, demuxResult, chunkMeta) {
@@ -16240,7 +16297,7 @@ class Transmuxer {
16240
16297
  accurateTimeOffset,
16241
16298
  timeOffset
16242
16299
  } = this.currentTransmuxState;
16243
- logger.log(`[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''} of level ${chunkMeta.level}`);
16300
+ this.logger.log(`[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''} of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`);
16244
16301
  const remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
16245
16302
  transmuxResults.push({
16246
16303
  remuxResult,
@@ -16333,7 +16390,7 @@ class Transmuxer {
16333
16390
  let mux;
16334
16391
  for (let i = 0, len = muxConfig.length; i < len; i++) {
16335
16392
  var _muxConfig$i$demux;
16336
- if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data)) {
16393
+ if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data, this.logger)) {
16337
16394
  mux = muxConfig[i];
16338
16395
  break;
16339
16396
  }
@@ -16347,10 +16404,10 @@ class Transmuxer {
16347
16404
  const Remuxer = mux.remux;
16348
16405
  const Demuxer = mux.demux;
16349
16406
  if (!remuxer || !(remuxer instanceof Remuxer)) {
16350
- this.remuxer = new Remuxer(observer, config, typeSupported, vendor);
16407
+ this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);
16351
16408
  }
16352
16409
  if (!demuxer || !(demuxer instanceof Demuxer)) {
16353
- this.demuxer = new Demuxer(observer, config, typeSupported);
16410
+ this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);
16354
16411
  this.probe = Demuxer.probe;
16355
16412
  }
16356
16413
  }
@@ -16755,31 +16812,96 @@ var eventemitter3 = {exports: {}};
16755
16812
  var eventemitter3Exports = eventemitter3.exports;
16756
16813
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
16757
16814
 
16815
+ let transmuxerInstanceCount = 0;
16758
16816
  class TransmuxerInterface {
16759
- constructor(hls, id, onTransmuxComplete, onFlush) {
16817
+ constructor(_hls, id, onTransmuxComplete, onFlush) {
16760
16818
  this.error = null;
16761
16819
  this.hls = void 0;
16762
16820
  this.id = void 0;
16821
+ this.instanceNo = transmuxerInstanceCount++;
16763
16822
  this.observer = void 0;
16764
16823
  this.frag = null;
16765
16824
  this.part = null;
16766
16825
  this.useWorker = void 0;
16767
16826
  this.workerContext = null;
16768
- this.onwmsg = void 0;
16769
16827
  this.transmuxer = null;
16770
16828
  this.onTransmuxComplete = void 0;
16771
16829
  this.onFlush = void 0;
16772
- const config = hls.config;
16773
- this.hls = hls;
16830
+ this.onWorkerMessage = event => {
16831
+ const data = event.data;
16832
+ const hls = this.hls;
16833
+ if (!hls || !(data != null && data.event) || data.instanceNo !== this.instanceNo) {
16834
+ return;
16835
+ }
16836
+ switch (data.event) {
16837
+ case 'init':
16838
+ {
16839
+ var _this$workerContext;
16840
+ const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
16841
+ if (objectURL) {
16842
+ // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
16843
+ self.URL.revokeObjectURL(objectURL);
16844
+ }
16845
+ break;
16846
+ }
16847
+ case 'transmuxComplete':
16848
+ {
16849
+ this.handleTransmuxComplete(data.data);
16850
+ break;
16851
+ }
16852
+ case 'flush':
16853
+ {
16854
+ this.onFlush(data.data);
16855
+ break;
16856
+ }
16857
+
16858
+ // pass logs from the worker thread to the main logger
16859
+ case 'workerLog':
16860
+ {
16861
+ if (hls.logger[data.data.logType]) {
16862
+ hls.logger[data.data.logType](data.data.message);
16863
+ }
16864
+ break;
16865
+ }
16866
+ default:
16867
+ {
16868
+ data.data = data.data || {};
16869
+ data.data.frag = this.frag;
16870
+ data.data.part = this.part;
16871
+ data.data.id = this.id;
16872
+ hls.trigger(data.event, data.data);
16873
+ break;
16874
+ }
16875
+ }
16876
+ };
16877
+ this.onWorkerError = event => {
16878
+ if (!this.hls) {
16879
+ return;
16880
+ }
16881
+ const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
16882
+ this.hls.config.enableWorker = false;
16883
+ this.hls.logger.warn(`Error in "${this.id}" Web Worker, fallback to inline`);
16884
+ this.hls.trigger(Events.ERROR, {
16885
+ type: ErrorTypes.OTHER_ERROR,
16886
+ details: ErrorDetails.INTERNAL_EXCEPTION,
16887
+ fatal: false,
16888
+ event: 'demuxerWorker',
16889
+ error
16890
+ });
16891
+ };
16892
+ const config = _hls.config;
16893
+ this.hls = _hls;
16774
16894
  this.id = id;
16775
16895
  this.useWorker = !!config.enableWorker;
16776
16896
  this.onTransmuxComplete = onTransmuxComplete;
16777
16897
  this.onFlush = onFlush;
16778
16898
  const forwardMessage = (ev, data) => {
16779
16899
  data = data || {};
16780
- data.frag = this.frag;
16781
- data.id = this.id;
16900
+ data.frag = this.frag || undefined;
16782
16901
  if (ev === Events.ERROR) {
16902
+ data = data;
16903
+ data.parent = this.id;
16904
+ data.part = this.part;
16783
16905
  this.error = data.error;
16784
16906
  }
16785
16907
  this.hls.trigger(ev, data);
@@ -16791,6 +16913,7 @@ class TransmuxerInterface {
16791
16913
  this.observer.on(Events.ERROR, forwardMessage);
16792
16914
  const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
16793
16915
  if (this.useWorker && typeof Worker !== 'undefined') {
16916
+ const logger = this.hls.logger;
16794
16917
  const canCreateWorker = config.workerPath || hasUMDWorker();
16795
16918
  if (canCreateWorker) {
16796
16919
  try {
@@ -16801,61 +16924,63 @@ class TransmuxerInterface {
16801
16924
  logger.log(`injecting Web Worker for "${id}"`);
16802
16925
  this.workerContext = injectWorker();
16803
16926
  }
16804
- this.onwmsg = event => this.onWorkerMessage(event);
16805
16927
  const {
16806
16928
  worker
16807
16929
  } = this.workerContext;
16808
- worker.addEventListener('message', this.onwmsg);
16809
- worker.onerror = event => {
16810
- const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
16811
- config.enableWorker = false;
16812
- logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
16813
- this.hls.trigger(Events.ERROR, {
16814
- type: ErrorTypes.OTHER_ERROR,
16815
- details: ErrorDetails.INTERNAL_EXCEPTION,
16816
- fatal: false,
16817
- event: 'demuxerWorker',
16818
- error
16819
- });
16820
- };
16930
+ worker.addEventListener('message', this.onWorkerMessage);
16931
+ worker.addEventListener('error', this.onWorkerError);
16821
16932
  worker.postMessage({
16933
+ instanceNo: this.instanceNo,
16822
16934
  cmd: 'init',
16823
16935
  typeSupported: m2tsTypeSupported,
16824
- vendor: '',
16825
- id: id,
16936
+ id,
16826
16937
  config: JSON.stringify(config)
16827
16938
  });
16828
16939
  } catch (err) {
16829
16940
  logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
16830
- this.resetWorker();
16941
+ this.terminateWorker();
16831
16942
  this.error = null;
16832
- this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
16943
+ this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
16833
16944
  }
16834
16945
  return;
16835
16946
  }
16836
16947
  }
16837
- this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
16948
+ this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
16838
16949
  }
16839
- resetWorker() {
16950
+ reset() {
16951
+ this.frag = null;
16952
+ this.part = null;
16953
+ if (this.workerContext) {
16954
+ const instanceNo = this.instanceNo;
16955
+ this.instanceNo = transmuxerInstanceCount++;
16956
+ const config = this.hls.config;
16957
+ const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
16958
+ this.workerContext.worker.postMessage({
16959
+ instanceNo: this.instanceNo,
16960
+ cmd: 'reset',
16961
+ resetNo: instanceNo,
16962
+ typeSupported: m2tsTypeSupported,
16963
+ id: this.id,
16964
+ config: JSON.stringify(config)
16965
+ });
16966
+ }
16967
+ }
16968
+ terminateWorker() {
16840
16969
  if (this.workerContext) {
16841
16970
  const {
16842
- worker,
16843
- objectURL
16971
+ worker
16844
16972
  } = this.workerContext;
16845
- if (objectURL) {
16846
- // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
16847
- self.URL.revokeObjectURL(objectURL);
16848
- }
16849
- worker.removeEventListener('message', this.onwmsg);
16850
- worker.onerror = null;
16851
- worker.terminate();
16852
16973
  this.workerContext = null;
16974
+ worker.removeEventListener('message', this.onWorkerMessage);
16975
+ worker.removeEventListener('error', this.onWorkerError);
16976
+ removeWorkerFromStore(this.hls.config.workerPath);
16853
16977
  }
16854
16978
  }
16855
16979
  destroy() {
16856
16980
  if (this.workerContext) {
16857
- this.resetWorker();
16858
- this.onwmsg = undefined;
16981
+ this.terminateWorker();
16982
+ // @ts-ignore
16983
+ this.onWorkerMessage = this.onWorkerError = null;
16859
16984
  } else {
16860
16985
  const transmuxer = this.transmuxer;
16861
16986
  if (transmuxer) {
@@ -16868,6 +16993,7 @@ class TransmuxerInterface {
16868
16993
  observer.removeAllListeners();
16869
16994
  }
16870
16995
  this.frag = null;
16996
+ this.part = null;
16871
16997
  // @ts-ignore
16872
16998
  this.observer = null;
16873
16999
  // @ts-ignore
@@ -16877,6 +17003,7 @@ class TransmuxerInterface {
16877
17003
  var _frag$initSegment, _lastFrag$initSegment;
16878
17004
  chunkMeta.transmuxing.start = self.performance.now();
16879
17005
  const {
17006
+ instanceNo,
16880
17007
  transmuxer
16881
17008
  } = this;
16882
17009
  const timeOffset = part ? part.start : frag.start;
@@ -16899,7 +17026,7 @@ class TransmuxerInterface {
16899
17026
  const initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) == null ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) == null ? void 0 : _lastFrag$initSegment.url));
16900
17027
  const state = new TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
16901
17028
  if (!contiguous || discontinuity || initSegmentChange) {
16902
- logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
17029
+ this.hls.logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
16903
17030
  discontinuity: ${discontinuity}
16904
17031
  trackSwitch: ${trackSwitch}
16905
17032
  contiguous: ${contiguous}
@@ -16916,6 +17043,7 @@ class TransmuxerInterface {
16916
17043
  if (this.workerContext) {
16917
17044
  // post fragment payload as transferable objects for ArrayBuffer (no copy)
16918
17045
  this.workerContext.worker.postMessage({
17046
+ instanceNo,
16919
17047
  cmd: 'demux',
16920
17048
  data,
16921
17049
  decryptdata,
@@ -16925,14 +17053,12 @@ class TransmuxerInterface {
16925
17053
  } else if (transmuxer) {
16926
17054
  const transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state);
16927
17055
  if (isPromise(transmuxResult)) {
16928
- transmuxer.async = true;
16929
17056
  transmuxResult.then(data => {
16930
17057
  this.handleTransmuxComplete(data);
16931
17058
  }).catch(error => {
16932
17059
  this.transmuxerError(error, chunkMeta, 'transmuxer-interface push error');
16933
17060
  });
16934
17061
  } else {
16935
- transmuxer.async = false;
16936
17062
  this.handleTransmuxComplete(transmuxResult);
16937
17063
  }
16938
17064
  }
@@ -16940,20 +17066,18 @@ class TransmuxerInterface {
16940
17066
  flush(chunkMeta) {
16941
17067
  chunkMeta.transmuxing.start = self.performance.now();
16942
17068
  const {
17069
+ instanceNo,
16943
17070
  transmuxer
16944
17071
  } = this;
16945
17072
  if (this.workerContext) {
16946
17073
  this.workerContext.worker.postMessage({
17074
+ instanceNo,
16947
17075
  cmd: 'flush',
16948
17076
  chunkMeta
16949
17077
  });
16950
17078
  } else if (transmuxer) {
16951
- let transmuxResult = transmuxer.flush(chunkMeta);
16952
- const asyncFlush = isPromise(transmuxResult);
16953
- if (asyncFlush || transmuxer.async) {
16954
- if (!isPromise(transmuxResult)) {
16955
- transmuxResult = Promise.resolve(transmuxResult);
16956
- }
17079
+ const transmuxResult = transmuxer.flush(chunkMeta);
17080
+ if (isPromise(transmuxResult)) {
16957
17081
  transmuxResult.then(data => {
16958
17082
  this.handleFlushResult(data, chunkMeta);
16959
17083
  }).catch(error => {
@@ -16974,6 +17098,7 @@ class TransmuxerInterface {
16974
17098
  details: ErrorDetails.FRAG_PARSING_ERROR,
16975
17099
  chunkMeta,
16976
17100
  frag: this.frag || undefined,
17101
+ part: this.part || undefined,
16977
17102
  fatal: false,
16978
17103
  error,
16979
17104
  err: error,
@@ -16986,60 +17111,14 @@ class TransmuxerInterface {
16986
17111
  });
16987
17112
  this.onFlush(chunkMeta);
16988
17113
  }
16989
- onWorkerMessage(event) {
16990
- const data = event.data;
16991
- if (!(data != null && data.event)) {
16992
- logger.warn(`worker message received with no ${data ? 'event name' : 'data'}`);
16993
- return;
16994
- }
16995
- const hls = this.hls;
16996
- if (!this.hls) {
16997
- return;
16998
- }
16999
- switch (data.event) {
17000
- case 'init':
17001
- {
17002
- var _this$workerContext;
17003
- const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
17004
- if (objectURL) {
17005
- // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
17006
- self.URL.revokeObjectURL(objectURL);
17007
- }
17008
- break;
17009
- }
17010
- case 'transmuxComplete':
17011
- {
17012
- this.handleTransmuxComplete(data.data);
17013
- break;
17014
- }
17015
- case 'flush':
17016
- {
17017
- this.onFlush(data.data);
17018
- break;
17019
- }
17020
-
17021
- // pass logs from the worker thread to the main logger
17022
- case 'workerLog':
17023
- if (logger[data.data.logType]) {
17024
- logger[data.data.logType](data.data.message);
17025
- }
17026
- break;
17027
- default:
17028
- {
17029
- data.data = data.data || {};
17030
- data.data.frag = this.frag;
17031
- data.data.id = this.id;
17032
- hls.trigger(data.event, data.data);
17033
- break;
17034
- }
17035
- }
17036
- }
17037
17114
  configureTransmuxer(config) {
17038
17115
  const {
17116
+ instanceNo,
17039
17117
  transmuxer
17040
17118
  } = this;
17041
17119
  if (this.workerContext) {
17042
17120
  this.workerContext.worker.postMessage({
17121
+ instanceNo,
17043
17122
  cmd: 'configure',
17044
17123
  config
17045
17124
  });
@@ -29264,7 +29343,7 @@ class Hls {
29264
29343
  * Get the video-dev/hls.js package version.
29265
29344
  */
29266
29345
  static get version() {
29267
- return "1.5.14-0.canary.10431";
29346
+ return version;
29268
29347
  }
29269
29348
 
29270
29349
  /**