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.
@@ -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();
@@ -12684,6 +12684,10 @@ class BaseStreamController extends TaskLoop {
12684
12684
  }
12685
12685
  onHandlerDestroying() {
12686
12686
  this.stopLoad();
12687
+ if (this.transmuxer) {
12688
+ this.transmuxer.destroy();
12689
+ this.transmuxer = null;
12690
+ }
12687
12691
  super.onHandlerDestroying();
12688
12692
  // @ts-ignore
12689
12693
  this.hls = this.onMediaSeeking = this.onMediaEnded = null;
@@ -13807,10 +13811,8 @@ class BaseStreamController extends TaskLoop {
13807
13811
  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)}]`;
13808
13812
  }
13809
13813
  resetTransmuxer() {
13810
- if (this.transmuxer) {
13811
- this.transmuxer.destroy();
13812
- this.transmuxer = null;
13813
- }
13814
+ var _this$transmuxer2;
13815
+ (_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
13814
13816
  }
13815
13817
  recoverWorkerError(data) {
13816
13818
  if (data.event === 'demuxerWorker') {
@@ -13859,29 +13861,66 @@ function changeTypeSupported() {
13859
13861
  return typeof (sourceBuffer == null ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) == null ? void 0 : _sourceBuffer$prototy.changeType) === 'function';
13860
13862
  }
13861
13863
 
13864
+ const version = "1.5.14-0.canary.10432";
13865
+
13862
13866
  // ensure the worker ends up in the bundle
13863
13867
  // If the worker should not be included this gets aliased to empty.js
13868
+ const workerStore = {};
13864
13869
  function hasUMDWorker() {
13865
13870
  return typeof __HLS_WORKER_BUNDLE__ === 'function';
13866
13871
  }
13867
13872
  function injectWorker() {
13873
+ const workerContext = workerStore[version];
13874
+ if (workerContext) {
13875
+ workerContext.clientCount++;
13876
+ return workerContext;
13877
+ }
13868
13878
  const blob = new self.Blob([`var exports={};var module={exports:exports};function define(f){f()};define.amd=true;(${__HLS_WORKER_BUNDLE__.toString()})(true);`], {
13869
13879
  type: 'text/javascript'
13870
13880
  });
13871
13881
  const objectURL = self.URL.createObjectURL(blob);
13872
13882
  const worker = new self.Worker(objectURL);
13873
- return {
13883
+ const result = {
13874
13884
  worker,
13875
- objectURL
13885
+ objectURL,
13886
+ clientCount: 1
13876
13887
  };
13888
+ workerStore[version] = result;
13889
+ return result;
13877
13890
  }
13878
13891
  function loadWorker(path) {
13892
+ const workerContext = workerStore[path];
13893
+ if (workerContext) {
13894
+ workerContext.clientCount++;
13895
+ return workerContext;
13896
+ }
13879
13897
  const scriptURL = new self.URL(path, self.location.href).href;
13880
13898
  const worker = new self.Worker(scriptURL);
13881
- return {
13899
+ const result = {
13882
13900
  worker,
13883
- scriptURL
13901
+ scriptURL,
13902
+ clientCount: 1
13884
13903
  };
13904
+ workerStore[path] = result;
13905
+ return result;
13906
+ }
13907
+ function removeWorkerFromStore(path) {
13908
+ const workerContext = workerStore[path || version];
13909
+ if (workerContext) {
13910
+ const clientCount = workerContext.clientCount--;
13911
+ if (clientCount === 1) {
13912
+ const {
13913
+ worker,
13914
+ objectURL
13915
+ } = workerContext;
13916
+ delete workerStore[path || version];
13917
+ if (objectURL) {
13918
+ // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
13919
+ self.URL.revokeObjectURL(objectURL);
13920
+ }
13921
+ worker.terminate();
13922
+ }
13923
+ }
13885
13924
  }
13886
13925
 
13887
13926
  function dummyTrack(type = '', inputTimeScale = 90000) {
@@ -14558,7 +14597,7 @@ class AACDemuxer extends BaseAudioDemuxer {
14558
14597
  }
14559
14598
 
14560
14599
  // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
14561
- static probe(data) {
14600
+ static probe(data, logger) {
14562
14601
  if (!data) {
14563
14602
  return false;
14564
14603
  }
@@ -15478,7 +15517,8 @@ class SampleAesDecrypter {
15478
15517
 
15479
15518
  const PACKET_LENGTH = 188;
15480
15519
  class TSDemuxer {
15481
- constructor(observer, config, typeSupported) {
15520
+ constructor(observer, config, typeSupported, logger) {
15521
+ this.logger = void 0;
15482
15522
  this.observer = void 0;
15483
15523
  this.config = void 0;
15484
15524
  this.typeSupported = void 0;
@@ -15498,9 +15538,10 @@ class TSDemuxer {
15498
15538
  this.observer = observer;
15499
15539
  this.config = config;
15500
15540
  this.typeSupported = typeSupported;
15541
+ this.logger = logger;
15501
15542
  this.videoParser = null;
15502
15543
  }
15503
- static probe(data) {
15544
+ static probe(data, logger) {
15504
15545
  const syncOffset = TSDemuxer.syncOffset(data);
15505
15546
  if (syncOffset > 0) {
15506
15547
  logger.warn(`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`);
@@ -15662,7 +15703,7 @@ class TSDemuxer {
15662
15703
  switch (pid) {
15663
15704
  case videoPid:
15664
15705
  if (stt) {
15665
- if (videoData && (pes = parsePES(videoData))) {
15706
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
15666
15707
  if (this.videoParser === null) {
15667
15708
  switch (videoTrack.segmentCodec) {
15668
15709
  case 'avc':
@@ -15686,7 +15727,7 @@ class TSDemuxer {
15686
15727
  break;
15687
15728
  case audioPid:
15688
15729
  if (stt) {
15689
- if (audioData && (pes = parsePES(audioData))) {
15730
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
15690
15731
  switch (audioTrack.segmentCodec) {
15691
15732
  case 'aac':
15692
15733
  this.parseAACPES(audioTrack, pes);
@@ -15708,7 +15749,7 @@ class TSDemuxer {
15708
15749
  break;
15709
15750
  case id3Pid:
15710
15751
  if (stt) {
15711
- if (id3Data && (pes = parsePES(id3Data))) {
15752
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
15712
15753
  this.parseID3PES(id3Track, pes);
15713
15754
  }
15714
15755
  id3Data = {
@@ -15726,14 +15767,14 @@ class TSDemuxer {
15726
15767
  offset += data[offset] + 1;
15727
15768
  }
15728
15769
  pmtId = this._pmtId = parsePAT(data, offset);
15729
- // logger.log('PMT PID:' + this._pmtId);
15770
+ // this.logger.log('PMT PID:' + this._pmtId);
15730
15771
  break;
15731
15772
  case pmtId:
15732
15773
  {
15733
15774
  if (stt) {
15734
15775
  offset += data[offset] + 1;
15735
15776
  }
15736
- const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer);
15777
+ const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer, this.logger);
15737
15778
 
15738
15779
  // only update track id if track PID found while parsing PMT
15739
15780
  // this is to avoid resetting the PID to -1 in case
@@ -15756,7 +15797,7 @@ class TSDemuxer {
15756
15797
  id3Track.pid = id3Pid;
15757
15798
  }
15758
15799
  if (unknownPID !== null && !pmtParsed) {
15759
- logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
15800
+ this.logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
15760
15801
  unknownPID = null;
15761
15802
  // we set it to -188, the += 188 in the for loop will reset start to 0
15762
15803
  start = syncOffset - 188;
@@ -15776,7 +15817,7 @@ class TSDemuxer {
15776
15817
  }
15777
15818
  }
15778
15819
  if (tsPacketErrors > 0) {
15779
- emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`));
15820
+ emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`), undefined, this.logger);
15780
15821
  }
15781
15822
  videoTrack.pesData = videoData;
15782
15823
  audioTrack.pesData = audioData;
@@ -15826,7 +15867,7 @@ class TSDemuxer {
15826
15867
  const id3Data = id3Track.pesData;
15827
15868
  // try to parse last PES packets
15828
15869
  let pes;
15829
- if (videoData && (pes = parsePES(videoData))) {
15870
+ if (videoData && (pes = parsePES(videoData, this.logger))) {
15830
15871
  if (this.videoParser === null) {
15831
15872
  switch (videoTrack.segmentCodec) {
15832
15873
  case 'avc':
@@ -15842,7 +15883,7 @@ class TSDemuxer {
15842
15883
  // either avcData null or PES truncated, keep it for next frag parsing
15843
15884
  videoTrack.pesData = videoData;
15844
15885
  }
15845
- if (audioData && (pes = parsePES(audioData))) {
15886
+ if (audioData && (pes = parsePES(audioData, this.logger))) {
15846
15887
  switch (audioTrack.segmentCodec) {
15847
15888
  case 'aac':
15848
15889
  this.parseAACPES(audioTrack, pes);
@@ -15854,13 +15895,13 @@ class TSDemuxer {
15854
15895
  audioTrack.pesData = null;
15855
15896
  } else {
15856
15897
  if (audioData != null && audioData.size) {
15857
- logger.log('last AAC PES packet truncated,might overlap between fragments');
15898
+ this.logger.log('last AAC PES packet truncated,might overlap between fragments');
15858
15899
  }
15859
15900
 
15860
15901
  // either audioData null or PES truncated, keep it for next frag parsing
15861
15902
  audioTrack.pesData = audioData;
15862
15903
  }
15863
- if (id3Data && (pes = parsePES(id3Data))) {
15904
+ if (id3Data && (pes = parsePES(id3Data, this.logger))) {
15864
15905
  this.parseID3PES(id3Track, pes);
15865
15906
  id3Track.pesData = null;
15866
15907
  } else {
@@ -15934,7 +15975,7 @@ class TSDemuxer {
15934
15975
  } else {
15935
15976
  reason = 'No ADTS header found in AAC PES';
15936
15977
  }
15937
- emitParsingError(this.observer, new Error(reason), recoverable);
15978
+ emitParsingError(this.observer, new Error(reason), recoverable, this.logger);
15938
15979
  if (!recoverable) {
15939
15980
  return;
15940
15981
  }
@@ -15949,7 +15990,7 @@ class TSDemuxer {
15949
15990
  const frameDuration = getFrameDuration(track.samplerate);
15950
15991
  pts = aacOverFlow.sample.pts + frameDuration;
15951
15992
  } else {
15952
- logger.warn('[tsdemuxer]: AAC PES unknown PTS');
15993
+ this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');
15953
15994
  return;
15954
15995
  }
15955
15996
 
@@ -15979,7 +16020,7 @@ class TSDemuxer {
15979
16020
  let offset = 0;
15980
16021
  const pts = pes.pts;
15981
16022
  if (pts === undefined) {
15982
- logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
16023
+ this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
15983
16024
  return;
15984
16025
  }
15985
16026
  while (offset < length) {
@@ -16002,7 +16043,7 @@ class TSDemuxer {
16002
16043
  }
16003
16044
  parseID3PES(id3Track, pes) {
16004
16045
  if (pes.pts === undefined) {
16005
- logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
16046
+ this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
16006
16047
  return;
16007
16048
  }
16008
16049
  const id3Sample = _extends({}, pes, {
@@ -16020,7 +16061,7 @@ function parsePAT(data, offset) {
16020
16061
  // skip the PSI header and parse the first PMT entry
16021
16062
  return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
16022
16063
  }
16023
- function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16064
+ function parsePMT(data, offset, typeSupported, isSampleAes, observer, logger) {
16024
16065
  const result = {
16025
16066
  audioPid: -1,
16026
16067
  videoPid: -1,
@@ -16042,7 +16083,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16042
16083
  case 0xcf:
16043
16084
  // SAMPLE-AES AAC
16044
16085
  if (!isSampleAes) {
16045
- logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC');
16086
+ logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', this.logger);
16046
16087
  break;
16047
16088
  }
16048
16089
  /* falls through */
@@ -16064,7 +16105,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16064
16105
  case 0xdb:
16065
16106
  // SAMPLE-AES AVC
16066
16107
  if (!isSampleAes) {
16067
- logEncryptedSamplesFoundInUnencryptedStream('H.264');
16108
+ logEncryptedSamplesFoundInUnencryptedStream('H.264', this.logger);
16068
16109
  break;
16069
16110
  }
16070
16111
  /* falls through */
@@ -16092,7 +16133,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16092
16133
  case 0xc1:
16093
16134
  // SAMPLE-AES AC3
16094
16135
  if (!isSampleAes) {
16095
- logEncryptedSamplesFoundInUnencryptedStream('AC-3');
16136
+ logEncryptedSamplesFoundInUnencryptedStream('AC-3', this.logger);
16096
16137
  break;
16097
16138
  }
16098
16139
  /* falls through */
@@ -16128,12 +16169,12 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16128
16169
  case 0xc2: // SAMPLE-AES EC3
16129
16170
  /* falls through */
16130
16171
  case 0x87:
16131
- emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
16172
+ emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'), undefined, this.logger);
16132
16173
  return result;
16133
16174
  case 0x24:
16134
16175
  // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
16135
16176
  {
16136
- emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));
16177
+ emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'), undefined, this.logger);
16137
16178
  return result;
16138
16179
  }
16139
16180
  }
@@ -16143,7 +16184,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
16143
16184
  }
16144
16185
  return result;
16145
16186
  }
16146
- function emitParsingError(observer, error, levelRetry) {
16187
+ function emitParsingError(observer, error, levelRetry, logger) {
16147
16188
  logger.warn(`parsing error: ${error.message}`);
16148
16189
  observer.emit(Events.ERROR, Events.ERROR, {
16149
16190
  type: ErrorTypes.MEDIA_ERROR,
@@ -16154,10 +16195,10 @@ function emitParsingError(observer, error, levelRetry) {
16154
16195
  reason: error.message
16155
16196
  });
16156
16197
  }
16157
- function logEncryptedSamplesFoundInUnencryptedStream(type) {
16198
+ function logEncryptedSamplesFoundInUnencryptedStream(type, logger) {
16158
16199
  logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
16159
16200
  }
16160
- function parsePES(stream) {
16201
+ function parsePES(stream, logger) {
16161
16202
  let i = 0;
16162
16203
  let frag;
16163
16204
  let pesLen;
@@ -17042,7 +17083,8 @@ const AC3_SAMPLES_PER_FRAME = 1536;
17042
17083
  let chromeVersion = null;
17043
17084
  let safariWebkitVersion = null;
17044
17085
  class MP4Remuxer {
17045
- constructor(observer, config, typeSupported, vendor = '') {
17086
+ constructor(observer, config, typeSupported, logger) {
17087
+ this.logger = void 0;
17046
17088
  this.observer = void 0;
17047
17089
  this.config = void 0;
17048
17090
  this.typeSupported = void 0;
@@ -17058,6 +17100,7 @@ class MP4Remuxer {
17058
17100
  this.observer = observer;
17059
17101
  this.config = config;
17060
17102
  this.typeSupported = typeSupported;
17103
+ this.logger = logger;
17061
17104
  this.ISGenerated = false;
17062
17105
  if (chromeVersion === null) {
17063
17106
  const userAgent = navigator.userAgent || '';
@@ -17074,16 +17117,16 @@ class MP4Remuxer {
17074
17117
  this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;
17075
17118
  }
17076
17119
  resetTimeStamp(defaultTimeStamp) {
17077
- logger.log('[mp4-remuxer]: initPTS & initDTS reset');
17120
+ this.logger.log('[mp4-remuxer]: initPTS & initDTS reset');
17078
17121
  this._initPTS = this._initDTS = defaultTimeStamp;
17079
17122
  }
17080
17123
  resetNextTimestamp() {
17081
- logger.log('[mp4-remuxer]: reset next timestamp');
17124
+ this.logger.log('[mp4-remuxer]: reset next timestamp');
17082
17125
  this.isVideoContiguous = false;
17083
17126
  this.isAudioContiguous = false;
17084
17127
  }
17085
17128
  resetInitSegment() {
17086
- logger.log('[mp4-remuxer]: ISGenerated flag reset');
17129
+ this.logger.log('[mp4-remuxer]: ISGenerated flag reset');
17087
17130
  this.ISGenerated = false;
17088
17131
  this.videoTrackConfig = undefined;
17089
17132
  }
@@ -17102,7 +17145,7 @@ class MP4Remuxer {
17102
17145
  }
17103
17146
  }, videoSamples[0].pts);
17104
17147
  if (rolloverDetected) {
17105
- logger.debug('PTS rollover detected');
17148
+ this.logger.debug('PTS rollover detected');
17106
17149
  }
17107
17150
  return startPTS;
17108
17151
  }
@@ -17146,14 +17189,14 @@ class MP4Remuxer {
17146
17189
  if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {
17147
17190
  independent = true;
17148
17191
  if (firstKeyFrameIndex > 0) {
17149
- logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
17192
+ this.logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
17150
17193
  const startPTS = this.getVideoStartPts(videoTrack.samples);
17151
17194
  videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
17152
17195
  videoTrack.dropped += firstKeyFrameIndex;
17153
17196
  videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / videoTrack.inputTimeScale;
17154
17197
  firstKeyFramePTS = videoTimeOffset;
17155
17198
  } else if (firstKeyFrameIndex === -1) {
17156
- logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
17199
+ this.logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
17157
17200
  independent = false;
17158
17201
  }
17159
17202
  }
@@ -17175,7 +17218,7 @@ class MP4Remuxer {
17175
17218
  if (enoughAudioSamples) {
17176
17219
  // if initSegment was generated without audio samples, regenerate it again
17177
17220
  if (!audioTrack.samplerate) {
17178
- logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
17221
+ this.logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
17179
17222
  initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
17180
17223
  }
17181
17224
  audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === PlaylistLevelType.AUDIO ? videoTimeOffset : undefined);
@@ -17183,7 +17226,7 @@ class MP4Remuxer {
17183
17226
  const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
17184
17227
  // if initSegment was generated without video samples, regenerate it again
17185
17228
  if (!videoTrack.inputTimeScale) {
17186
- logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
17229
+ this.logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
17187
17230
  initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
17188
17231
  }
17189
17232
  video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength);
@@ -17389,9 +17432,9 @@ class MP4Remuxer {
17389
17432
  const foundOverlap = delta < -1;
17390
17433
  if (foundHole || foundOverlap) {
17391
17434
  if (foundHole) {
17392
- logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
17435
+ this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
17393
17436
  } else {
17394
- logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
17437
+ this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
17395
17438
  }
17396
17439
  if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
17397
17440
  firstDTS = nextAvcDts;
@@ -17420,7 +17463,7 @@ class MP4Remuxer {
17420
17463
  }
17421
17464
  }
17422
17465
  }
17423
- logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
17466
+ this.logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
17424
17467
  }
17425
17468
  }
17426
17469
  }
@@ -17520,7 +17563,7 @@ class MP4Remuxer {
17520
17563
  } else {
17521
17564
  stretchedLastFrame = true;
17522
17565
  }
17523
- logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
17566
+ 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.`);
17524
17567
  } else {
17525
17568
  mp4SampleDuration = lastFrameDuration;
17526
17569
  }
@@ -17548,7 +17591,7 @@ class MP4Remuxer {
17548
17591
  // Fix for "CNN special report, with CC" in test-streams (Safari browser only)
17549
17592
  // Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
17550
17593
  if (maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta && averageSampleDuration / maxDtsDelta < 0.025 && outputSamples[0].cts === 0) {
17551
- logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
17594
+ this.logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
17552
17595
  let dts = firstDTS;
17553
17596
  for (let i = 0, len = outputSamples.length; i < len; i++) {
17554
17597
  const nextDts = dts + outputSamples[i].duration;
@@ -17673,7 +17716,7 @@ class MP4Remuxer {
17673
17716
  // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
17674
17717
  if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) {
17675
17718
  if (i === 0) {
17676
- logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
17719
+ this.logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
17677
17720
  this.nextAudioPts = nextAudioPts = nextPts = pts;
17678
17721
  }
17679
17722
  } // eslint-disable-line brace-style
@@ -17695,12 +17738,12 @@ class MP4Remuxer {
17695
17738
  if (i === 0) {
17696
17739
  this.nextAudioPts = nextAudioPts = nextPts;
17697
17740
  }
17698
- logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
17741
+ this.logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
17699
17742
  for (let j = 0; j < missing; j++) {
17700
17743
  const newStamp = Math.max(nextPts, 0);
17701
17744
  let fillFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
17702
17745
  if (!fillFrame) {
17703
- logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
17746
+ this.logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
17704
17747
  fillFrame = sample.unit.subarray();
17705
17748
  }
17706
17749
  inputSamples.splice(i, 0, {
@@ -17899,7 +17942,8 @@ class Mp4Sample {
17899
17942
  }
17900
17943
 
17901
17944
  class PassThroughRemuxer {
17902
- constructor() {
17945
+ constructor(observer, config, typeSupported, logger) {
17946
+ this.logger = void 0;
17903
17947
  this.emitInitSegment = false;
17904
17948
  this.audioCodec = void 0;
17905
17949
  this.videoCodec = void 0;
@@ -17907,6 +17951,7 @@ class PassThroughRemuxer {
17907
17951
  this.initPTS = null;
17908
17952
  this.initTracks = void 0;
17909
17953
  this.lastEndTime = null;
17954
+ this.logger = logger;
17910
17955
  }
17911
17956
  destroy() {}
17912
17957
  resetTimeStamp(defaultInitPTS) {
@@ -17964,7 +18009,7 @@ class PassThroughRemuxer {
17964
18009
  id: 'main'
17965
18010
  };
17966
18011
  } else {
17967
- logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
18012
+ this.logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
17968
18013
  }
17969
18014
  this.initTracks = tracks;
17970
18015
  }
@@ -18006,7 +18051,7 @@ class PassThroughRemuxer {
18006
18051
  }
18007
18052
  if (!((_initData2 = initData) != null && _initData2.length)) {
18008
18053
  // We can't remux if the initSegment could not be generated
18009
- logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
18054
+ this.logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
18010
18055
  return result;
18011
18056
  }
18012
18057
  if (this.emitInitSegment) {
@@ -18019,7 +18064,7 @@ class PassThroughRemuxer {
18019
18064
  if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
18020
18065
  initSegment.initPTS = decodeTime - timeOffset;
18021
18066
  if (initPTS && initPTS.timescale === 1) {
18022
- logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
18067
+ this.logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
18023
18068
  }
18024
18069
  this.initPTS = initPTS = {
18025
18070
  baseTime: initSegment.initPTS,
@@ -18032,7 +18077,7 @@ class PassThroughRemuxer {
18032
18077
  if (duration > 0) {
18033
18078
  this.lastEndTime = endTime;
18034
18079
  } else {
18035
- logger.warn('Duration parsed from mp4 should be greater than zero');
18080
+ this.logger.warn('Duration parsed from mp4 should be greater than zero');
18036
18081
  this.resetNextTimestamp();
18037
18082
  }
18038
18083
  const hasAudio = !!initData.audio;
@@ -18090,12 +18135,12 @@ function getParsedTrackCodec(track, type) {
18090
18135
  return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);
18091
18136
  }
18092
18137
  const result = 'mp4a.40.5';
18093
- logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
18138
+ this.logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
18094
18139
  return result;
18095
18140
  }
18096
18141
  // Provide defaults based on codec type
18097
18142
  // This allows for some playback of some fmp4 playlists without CODECS defined in manifest
18098
- logger.warn(`Unhandled video codec "${parsedCodec}"`);
18143
+ this.logger.warn(`Unhandled video codec "${parsedCodec}"`);
18099
18144
  if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
18100
18145
  return 'hvc1.1.6.L120.90';
18101
18146
  }
@@ -18105,16 +18150,12 @@ function getParsedTrackCodec(track, type) {
18105
18150
  return 'avc1.42e01e';
18106
18151
  }
18107
18152
 
18108
- /** returns `undefined` is `self` is missing, e.g. in node */
18109
- const optionalSelf = typeof self !== 'undefined' ? self : undefined;
18110
-
18111
18153
  let now;
18112
18154
  // performance.now() not available on WebWorker, at least on Safari Desktop
18113
18155
  try {
18114
18156
  now = self.performance.now.bind(self.performance);
18115
18157
  } catch (err) {
18116
- logger.debug('Unable to use Performance API on this environment');
18117
- now = optionalSelf == null ? void 0 : optionalSelf.Date.now;
18158
+ now = Date.now;
18118
18159
  }
18119
18160
  const muxConfig = [{
18120
18161
  demux: MP4Demuxer,
@@ -18130,8 +18171,9 @@ const muxConfig = [{
18130
18171
  remux: MP4Remuxer
18131
18172
  }];
18132
18173
  class Transmuxer {
18133
- constructor(observer, typeSupported, config, vendor, id) {
18134
- this.async = false;
18174
+ constructor(observer, typeSupported, config, vendor, id, logger) {
18175
+ this.asyncResult = false;
18176
+ this.logger = void 0;
18135
18177
  this.observer = void 0;
18136
18178
  this.typeSupported = void 0;
18137
18179
  this.config = void 0;
@@ -18149,6 +18191,7 @@ class Transmuxer {
18149
18191
  this.config = config;
18150
18192
  this.vendor = vendor;
18151
18193
  this.id = id;
18194
+ this.logger = logger;
18152
18195
  }
18153
18196
  configure(transmuxConfig) {
18154
18197
  this.transmuxConfig = transmuxConfig;
@@ -18203,6 +18246,7 @@ class Transmuxer {
18203
18246
  }
18204
18247
  uintData = new Uint8Array(decryptedData);
18205
18248
  } else {
18249
+ this.asyncResult = true;
18206
18250
  this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode).then(decryptedData => {
18207
18251
  // Calling push here is important; if flush() is called while this is still resolving, this ensures that
18208
18252
  // the decrypted data has been transmuxed
@@ -18217,7 +18261,7 @@ class Transmuxer {
18217
18261
  if (resetMuxers) {
18218
18262
  const error = this.configureTransmuxer(uintData);
18219
18263
  if (error) {
18220
- logger.warn(`[transmuxer] ${error.message}`);
18264
+ this.logger.warn(`[transmuxer] ${error.message}`);
18221
18265
  this.observer.emit(Events.ERROR, Events.ERROR, {
18222
18266
  type: ErrorTypes.MEDIA_ERROR,
18223
18267
  details: ErrorDetails.FRAG_PARSING_ERROR,
@@ -18239,6 +18283,7 @@ class Transmuxer {
18239
18283
  this.resetContiguity();
18240
18284
  }
18241
18285
  const result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta);
18286
+ this.asyncResult = isPromise(result);
18242
18287
  const currentState = this.currentTransmuxState;
18243
18288
  currentState.contiguous = true;
18244
18289
  currentState.discontinuity = false;
@@ -18257,6 +18302,7 @@ class Transmuxer {
18257
18302
  decryptionPromise
18258
18303
  } = this;
18259
18304
  if (decryptionPromise) {
18305
+ this.asyncResult = true;
18260
18306
  // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
18261
18307
  // only flushing is required for async decryption
18262
18308
  return decryptionPromise.then(() => {
@@ -18284,10 +18330,15 @@ class Transmuxer {
18284
18330
  if (!demuxer || !remuxer) {
18285
18331
  // If probing failed, then Hls.js has been given content its not able to handle
18286
18332
  stats.executeEnd = now();
18287
- return [emptyResult(chunkMeta)];
18333
+ const emptyResults = [emptyResult(chunkMeta)];
18334
+ if (this.asyncResult) {
18335
+ return Promise.resolve(emptyResults);
18336
+ }
18337
+ return emptyResults;
18288
18338
  }
18289
18339
  const demuxResultOrPromise = demuxer.flush(timeOffset);
18290
18340
  if (isPromise(demuxResultOrPromise)) {
18341
+ this.asyncResult = true;
18291
18342
  // Decrypt final SAMPLE-AES samples
18292
18343
  return demuxResultOrPromise.then(demuxResult => {
18293
18344
  this.flushRemux(transmuxResults, demuxResult, chunkMeta);
@@ -18295,6 +18346,9 @@ class Transmuxer {
18295
18346
  });
18296
18347
  }
18297
18348
  this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);
18349
+ if (this.asyncResult) {
18350
+ return Promise.resolve(transmuxResults);
18351
+ }
18298
18352
  return transmuxResults;
18299
18353
  }
18300
18354
  flushRemux(transmuxResults, demuxResult, chunkMeta) {
@@ -18308,7 +18362,7 @@ class Transmuxer {
18308
18362
  accurateTimeOffset,
18309
18363
  timeOffset
18310
18364
  } = this.currentTransmuxState;
18311
- logger.log(`[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''} of level ${chunkMeta.level}`);
18365
+ 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}`);
18312
18366
  const remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
18313
18367
  transmuxResults.push({
18314
18368
  remuxResult,
@@ -18401,7 +18455,7 @@ class Transmuxer {
18401
18455
  let mux;
18402
18456
  for (let i = 0, len = muxConfig.length; i < len; i++) {
18403
18457
  var _muxConfig$i$demux;
18404
- if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data)) {
18458
+ if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data, this.logger)) {
18405
18459
  mux = muxConfig[i];
18406
18460
  break;
18407
18461
  }
@@ -18415,10 +18469,10 @@ class Transmuxer {
18415
18469
  const Remuxer = mux.remux;
18416
18470
  const Demuxer = mux.demux;
18417
18471
  if (!remuxer || !(remuxer instanceof Remuxer)) {
18418
- this.remuxer = new Remuxer(observer, config, typeSupported, vendor);
18472
+ this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);
18419
18473
  }
18420
18474
  if (!demuxer || !(demuxer instanceof Demuxer)) {
18421
- this.demuxer = new Demuxer(observer, config, typeSupported);
18475
+ this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);
18422
18476
  this.probe = Demuxer.probe;
18423
18477
  }
18424
18478
  }
@@ -18823,31 +18877,96 @@ var eventemitter3 = {exports: {}};
18823
18877
  var eventemitter3Exports = eventemitter3.exports;
18824
18878
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
18825
18879
 
18880
+ let transmuxerInstanceCount = 0;
18826
18881
  class TransmuxerInterface {
18827
- constructor(hls, id, onTransmuxComplete, onFlush) {
18882
+ constructor(_hls, id, onTransmuxComplete, onFlush) {
18828
18883
  this.error = null;
18829
18884
  this.hls = void 0;
18830
18885
  this.id = void 0;
18886
+ this.instanceNo = transmuxerInstanceCount++;
18831
18887
  this.observer = void 0;
18832
18888
  this.frag = null;
18833
18889
  this.part = null;
18834
18890
  this.useWorker = void 0;
18835
18891
  this.workerContext = null;
18836
- this.onwmsg = void 0;
18837
18892
  this.transmuxer = null;
18838
18893
  this.onTransmuxComplete = void 0;
18839
18894
  this.onFlush = void 0;
18840
- const config = hls.config;
18841
- this.hls = hls;
18895
+ this.onWorkerMessage = event => {
18896
+ const data = event.data;
18897
+ const hls = this.hls;
18898
+ if (!hls || !(data != null && data.event) || data.instanceNo !== this.instanceNo) {
18899
+ return;
18900
+ }
18901
+ switch (data.event) {
18902
+ case 'init':
18903
+ {
18904
+ var _this$workerContext;
18905
+ const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
18906
+ if (objectURL) {
18907
+ // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
18908
+ self.URL.revokeObjectURL(objectURL);
18909
+ }
18910
+ break;
18911
+ }
18912
+ case 'transmuxComplete':
18913
+ {
18914
+ this.handleTransmuxComplete(data.data);
18915
+ break;
18916
+ }
18917
+ case 'flush':
18918
+ {
18919
+ this.onFlush(data.data);
18920
+ break;
18921
+ }
18922
+
18923
+ // pass logs from the worker thread to the main logger
18924
+ case 'workerLog':
18925
+ {
18926
+ if (hls.logger[data.data.logType]) {
18927
+ hls.logger[data.data.logType](data.data.message);
18928
+ }
18929
+ break;
18930
+ }
18931
+ default:
18932
+ {
18933
+ data.data = data.data || {};
18934
+ data.data.frag = this.frag;
18935
+ data.data.part = this.part;
18936
+ data.data.id = this.id;
18937
+ hls.trigger(data.event, data.data);
18938
+ break;
18939
+ }
18940
+ }
18941
+ };
18942
+ this.onWorkerError = event => {
18943
+ if (!this.hls) {
18944
+ return;
18945
+ }
18946
+ const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
18947
+ this.hls.config.enableWorker = false;
18948
+ this.hls.logger.warn(`Error in "${this.id}" Web Worker, fallback to inline`);
18949
+ this.hls.trigger(Events.ERROR, {
18950
+ type: ErrorTypes.OTHER_ERROR,
18951
+ details: ErrorDetails.INTERNAL_EXCEPTION,
18952
+ fatal: false,
18953
+ event: 'demuxerWorker',
18954
+ error
18955
+ });
18956
+ };
18957
+ const config = _hls.config;
18958
+ this.hls = _hls;
18842
18959
  this.id = id;
18843
18960
  this.useWorker = !!config.enableWorker;
18844
18961
  this.onTransmuxComplete = onTransmuxComplete;
18845
18962
  this.onFlush = onFlush;
18846
18963
  const forwardMessage = (ev, data) => {
18847
18964
  data = data || {};
18848
- data.frag = this.frag;
18849
- data.id = this.id;
18965
+ data.frag = this.frag || undefined;
18850
18966
  if (ev === Events.ERROR) {
18967
+ data = data;
18968
+ data.parent = this.id;
18969
+ data.part = this.part;
18851
18970
  this.error = data.error;
18852
18971
  }
18853
18972
  this.hls.trigger(ev, data);
@@ -18859,6 +18978,7 @@ class TransmuxerInterface {
18859
18978
  this.observer.on(Events.ERROR, forwardMessage);
18860
18979
  const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
18861
18980
  if (this.useWorker && typeof Worker !== 'undefined') {
18981
+ const logger = this.hls.logger;
18862
18982
  const canCreateWorker = config.workerPath || hasUMDWorker();
18863
18983
  if (canCreateWorker) {
18864
18984
  try {
@@ -18869,61 +18989,63 @@ class TransmuxerInterface {
18869
18989
  logger.log(`injecting Web Worker for "${id}"`);
18870
18990
  this.workerContext = injectWorker();
18871
18991
  }
18872
- this.onwmsg = event => this.onWorkerMessage(event);
18873
18992
  const {
18874
18993
  worker
18875
18994
  } = this.workerContext;
18876
- worker.addEventListener('message', this.onwmsg);
18877
- worker.onerror = event => {
18878
- const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
18879
- config.enableWorker = false;
18880
- logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
18881
- this.hls.trigger(Events.ERROR, {
18882
- type: ErrorTypes.OTHER_ERROR,
18883
- details: ErrorDetails.INTERNAL_EXCEPTION,
18884
- fatal: false,
18885
- event: 'demuxerWorker',
18886
- error
18887
- });
18888
- };
18995
+ worker.addEventListener('message', this.onWorkerMessage);
18996
+ worker.addEventListener('error', this.onWorkerError);
18889
18997
  worker.postMessage({
18998
+ instanceNo: this.instanceNo,
18890
18999
  cmd: 'init',
18891
19000
  typeSupported: m2tsTypeSupported,
18892
- vendor: '',
18893
- id: id,
19001
+ id,
18894
19002
  config: JSON.stringify(config)
18895
19003
  });
18896
19004
  } catch (err) {
18897
19005
  logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
18898
- this.resetWorker();
19006
+ this.terminateWorker();
18899
19007
  this.error = null;
18900
- this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
19008
+ this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
18901
19009
  }
18902
19010
  return;
18903
19011
  }
18904
19012
  }
18905
- this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
19013
+ this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
18906
19014
  }
18907
- resetWorker() {
19015
+ reset() {
19016
+ this.frag = null;
19017
+ this.part = null;
19018
+ if (this.workerContext) {
19019
+ const instanceNo = this.instanceNo;
19020
+ this.instanceNo = transmuxerInstanceCount++;
19021
+ const config = this.hls.config;
19022
+ const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
19023
+ this.workerContext.worker.postMessage({
19024
+ instanceNo: this.instanceNo,
19025
+ cmd: 'reset',
19026
+ resetNo: instanceNo,
19027
+ typeSupported: m2tsTypeSupported,
19028
+ id: this.id,
19029
+ config: JSON.stringify(config)
19030
+ });
19031
+ }
19032
+ }
19033
+ terminateWorker() {
18908
19034
  if (this.workerContext) {
18909
19035
  const {
18910
- worker,
18911
- objectURL
19036
+ worker
18912
19037
  } = this.workerContext;
18913
- if (objectURL) {
18914
- // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
18915
- self.URL.revokeObjectURL(objectURL);
18916
- }
18917
- worker.removeEventListener('message', this.onwmsg);
18918
- worker.onerror = null;
18919
- worker.terminate();
18920
19038
  this.workerContext = null;
19039
+ worker.removeEventListener('message', this.onWorkerMessage);
19040
+ worker.removeEventListener('error', this.onWorkerError);
19041
+ removeWorkerFromStore(this.hls.config.workerPath);
18921
19042
  }
18922
19043
  }
18923
19044
  destroy() {
18924
19045
  if (this.workerContext) {
18925
- this.resetWorker();
18926
- this.onwmsg = undefined;
19046
+ this.terminateWorker();
19047
+ // @ts-ignore
19048
+ this.onWorkerMessage = this.onWorkerError = null;
18927
19049
  } else {
18928
19050
  const transmuxer = this.transmuxer;
18929
19051
  if (transmuxer) {
@@ -18936,6 +19058,7 @@ class TransmuxerInterface {
18936
19058
  observer.removeAllListeners();
18937
19059
  }
18938
19060
  this.frag = null;
19061
+ this.part = null;
18939
19062
  // @ts-ignore
18940
19063
  this.observer = null;
18941
19064
  // @ts-ignore
@@ -18945,6 +19068,7 @@ class TransmuxerInterface {
18945
19068
  var _frag$initSegment, _lastFrag$initSegment;
18946
19069
  chunkMeta.transmuxing.start = self.performance.now();
18947
19070
  const {
19071
+ instanceNo,
18948
19072
  transmuxer
18949
19073
  } = this;
18950
19074
  const timeOffset = part ? part.start : frag.start;
@@ -18967,7 +19091,7 @@ class TransmuxerInterface {
18967
19091
  const initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) == null ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) == null ? void 0 : _lastFrag$initSegment.url));
18968
19092
  const state = new TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
18969
19093
  if (!contiguous || discontinuity || initSegmentChange) {
18970
- logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
19094
+ 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}
18971
19095
  discontinuity: ${discontinuity}
18972
19096
  trackSwitch: ${trackSwitch}
18973
19097
  contiguous: ${contiguous}
@@ -18984,6 +19108,7 @@ class TransmuxerInterface {
18984
19108
  if (this.workerContext) {
18985
19109
  // post fragment payload as transferable objects for ArrayBuffer (no copy)
18986
19110
  this.workerContext.worker.postMessage({
19111
+ instanceNo,
18987
19112
  cmd: 'demux',
18988
19113
  data,
18989
19114
  decryptdata,
@@ -18993,14 +19118,12 @@ class TransmuxerInterface {
18993
19118
  } else if (transmuxer) {
18994
19119
  const transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state);
18995
19120
  if (isPromise(transmuxResult)) {
18996
- transmuxer.async = true;
18997
19121
  transmuxResult.then(data => {
18998
19122
  this.handleTransmuxComplete(data);
18999
19123
  }).catch(error => {
19000
19124
  this.transmuxerError(error, chunkMeta, 'transmuxer-interface push error');
19001
19125
  });
19002
19126
  } else {
19003
- transmuxer.async = false;
19004
19127
  this.handleTransmuxComplete(transmuxResult);
19005
19128
  }
19006
19129
  }
@@ -19008,20 +19131,18 @@ class TransmuxerInterface {
19008
19131
  flush(chunkMeta) {
19009
19132
  chunkMeta.transmuxing.start = self.performance.now();
19010
19133
  const {
19134
+ instanceNo,
19011
19135
  transmuxer
19012
19136
  } = this;
19013
19137
  if (this.workerContext) {
19014
19138
  this.workerContext.worker.postMessage({
19139
+ instanceNo,
19015
19140
  cmd: 'flush',
19016
19141
  chunkMeta
19017
19142
  });
19018
19143
  } else if (transmuxer) {
19019
- let transmuxResult = transmuxer.flush(chunkMeta);
19020
- const asyncFlush = isPromise(transmuxResult);
19021
- if (asyncFlush || transmuxer.async) {
19022
- if (!isPromise(transmuxResult)) {
19023
- transmuxResult = Promise.resolve(transmuxResult);
19024
- }
19144
+ const transmuxResult = transmuxer.flush(chunkMeta);
19145
+ if (isPromise(transmuxResult)) {
19025
19146
  transmuxResult.then(data => {
19026
19147
  this.handleFlushResult(data, chunkMeta);
19027
19148
  }).catch(error => {
@@ -19042,6 +19163,7 @@ class TransmuxerInterface {
19042
19163
  details: ErrorDetails.FRAG_PARSING_ERROR,
19043
19164
  chunkMeta,
19044
19165
  frag: this.frag || undefined,
19166
+ part: this.part || undefined,
19045
19167
  fatal: false,
19046
19168
  error,
19047
19169
  err: error,
@@ -19054,60 +19176,14 @@ class TransmuxerInterface {
19054
19176
  });
19055
19177
  this.onFlush(chunkMeta);
19056
19178
  }
19057
- onWorkerMessage(event) {
19058
- const data = event.data;
19059
- if (!(data != null && data.event)) {
19060
- logger.warn(`worker message received with no ${data ? 'event name' : 'data'}`);
19061
- return;
19062
- }
19063
- const hls = this.hls;
19064
- if (!this.hls) {
19065
- return;
19066
- }
19067
- switch (data.event) {
19068
- case 'init':
19069
- {
19070
- var _this$workerContext;
19071
- const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
19072
- if (objectURL) {
19073
- // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
19074
- self.URL.revokeObjectURL(objectURL);
19075
- }
19076
- break;
19077
- }
19078
- case 'transmuxComplete':
19079
- {
19080
- this.handleTransmuxComplete(data.data);
19081
- break;
19082
- }
19083
- case 'flush':
19084
- {
19085
- this.onFlush(data.data);
19086
- break;
19087
- }
19088
-
19089
- // pass logs from the worker thread to the main logger
19090
- case 'workerLog':
19091
- if (logger[data.data.logType]) {
19092
- logger[data.data.logType](data.data.message);
19093
- }
19094
- break;
19095
- default:
19096
- {
19097
- data.data = data.data || {};
19098
- data.data.frag = this.frag;
19099
- data.data.id = this.id;
19100
- hls.trigger(data.event, data.data);
19101
- break;
19102
- }
19103
- }
19104
- }
19105
19179
  configureTransmuxer(config) {
19106
19180
  const {
19181
+ instanceNo,
19107
19182
  transmuxer
19108
19183
  } = this;
19109
19184
  if (this.workerContext) {
19110
19185
  this.workerContext.worker.postMessage({
19186
+ instanceNo,
19111
19187
  cmd: 'configure',
19112
19188
  config
19113
19189
  });
@@ -20636,7 +20712,7 @@ class Hls {
20636
20712
  * Get the video-dev/hls.js package version.
20637
20713
  */
20638
20714
  static get version() {
20639
- return "1.5.14-0.canary.10431";
20715
+ return version;
20640
20716
  }
20641
20717
 
20642
20718
  /**