hls.js 1.6.0-beta.1.0.canary.10765 → 1.6.0-beta.1.0.canary.10767

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
@@ -400,7 +400,7 @@ function enableLogs(debugConfig, context, id) {
400
400
  // Some browsers don't allow to use bind on console object anyway
401
401
  // fallback to default if needed
402
402
  try {
403
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10765"}`);
403
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10767"}`);
404
404
  } catch (e) {
405
405
  /* log fn threw an exception. All logger methods are no-ops. */
406
406
  return createLogger();
@@ -3729,6 +3729,10 @@ class BaseSegment {
3729
3729
  elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;
3730
3730
  }
3731
3731
  }
3732
+ function isMediaFragment(frag) {
3733
+ return frag.sn !== 'initSegment';
3734
+ }
3735
+
3732
3736
  /**
3733
3737
  * Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}.
3734
3738
  */
@@ -3882,7 +3886,7 @@ class Fragment extends BaseSegment {
3882
3886
  this._programDateTime = value;
3883
3887
  }
3884
3888
  get ref() {
3885
- if (this.sn === 'initSegment') {
3889
+ if (!isMediaFragment(this)) {
3886
3890
  return null;
3887
3891
  }
3888
3892
  if (!this._ref) {
@@ -8466,7 +8470,7 @@ class BaseStreamController extends TaskLoop {
8466
8470
  fragBufferedComplete(frag, part) {
8467
8471
  const media = this.mediaBuffer ? this.mediaBuffer : this.media;
8468
8472
  this.log(`Buffered ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag, false, part)} > buffer:${media ? TimeRanges.toString(BufferHelper.getBuffered(media)) : '(detached)'})`);
8469
- if (frag.sn !== 'initSegment') {
8473
+ if (isMediaFragment(frag)) {
8470
8474
  var _this$levels;
8471
8475
  if (frag.type !== PlaylistLevelType.SUBTITLE) {
8472
8476
  const el = frag.elementaryStreams;
@@ -8535,7 +8539,7 @@ class BaseStreamController extends TaskLoop {
8535
8539
  this.keyLoader.loadClear(frag, details.encryptedFragments);
8536
8540
  }
8537
8541
  const fragPrevious = this.fragPrevious;
8538
- if (frag.sn !== 'initSegment' && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
8542
+ if (isMediaFragment(frag) && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
8539
8543
  const shouldLoadParts = this.shouldLoadParts(level.details, frag.end);
8540
8544
  if (shouldLoadParts !== this.loadingParts) {
8541
8545
  this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} loading sn ${fragPrevious == null ? void 0 : fragPrevious.sn}->${frag.sn}`);
@@ -8543,7 +8547,7 @@ class BaseStreamController extends TaskLoop {
8543
8547
  }
8544
8548
  }
8545
8549
  targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
8546
- if (this.loadingParts && frag.sn !== 'initSegment') {
8550
+ if (this.loadingParts && isMediaFragment(frag)) {
8547
8551
  const partList = details.partList;
8548
8552
  if (partList && progressCallback) {
8549
8553
  if (targetBufferTime > frag.end && details.fragmentHint) {
@@ -8582,7 +8586,7 @@ class BaseStreamController extends TaskLoop {
8582
8586
  }
8583
8587
  }
8584
8588
  }
8585
- if (frag.sn !== 'initSegment' && this.loadingParts) {
8589
+ if (isMediaFragment(frag) && this.loadingParts) {
8586
8590
  this.log(`LL-Part loading OFF after next part miss @${targetBufferTime.toFixed(2)}`);
8587
8591
  this.loadingParts = false;
8588
8592
  } else if (!frag.url) {
@@ -9141,7 +9145,7 @@ class BaseStreamController extends TaskLoop {
9141
9145
  return pos;
9142
9146
  }
9143
9147
  handleFragLoadAborted(frag, part) {
9144
- if (this.transmuxer && frag.sn !== 'initSegment' && frag.stats.aborted) {
9148
+ if (this.transmuxer && isMediaFragment(frag) && frag.stats.aborted) {
9145
9149
  this.warn(`Fragment ${frag.sn}${part ? ' part ' + part.index : ''} of level ${frag.level} was aborted`);
9146
9150
  this.resetFragmentLoading(frag);
9147
9151
  }
@@ -9176,10 +9180,18 @@ class BaseStreamController extends TaskLoop {
9176
9180
  const errorAction = data.errorAction;
9177
9181
  const {
9178
9182
  action,
9183
+ flags,
9179
9184
  retryCount = 0,
9180
9185
  retryConfig
9181
9186
  } = errorAction || {};
9182
- if (errorAction && action === NetworkErrorAction.RetryRequest && retryConfig) {
9187
+ const couldRetry = !!errorAction && !!retryConfig;
9188
+ const retry = couldRetry && action === NetworkErrorAction.RetryRequest;
9189
+ const noAlternate = couldRetry && !errorAction.resolved && flags === ErrorActionFlags.MoveAllAlternatesMatchingHost;
9190
+ if (!retry && noAlternate && isMediaFragment(frag) && !frag.endList) {
9191
+ this.resetFragmentErrors(filterType);
9192
+ this.treatAsGap(frag);
9193
+ errorAction.resolved = true;
9194
+ } else if ((retry || noAlternate) && retryCount < retryConfig.maxNumRetry) {
9183
9195
  this.resetStartWhenNotLoaded(this.levelLastLoaded);
9184
9196
  const delay = getRetryDelay(retryConfig, retryCount);
9185
9197
  this.warn(`Fragment ${frag.sn} of ${filterType} ${frag.level} errored with ${data.details}, retrying loading ${retryCount + 1}/${retryConfig.maxNumRetry} in ${delay}ms`);
@@ -9197,7 +9209,7 @@ class BaseStreamController extends TaskLoop {
9197
9209
  this.warn(`${data.details} reached or exceeded max retry (${retryCount})`);
9198
9210
  return;
9199
9211
  }
9200
- } else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
9212
+ } else if (action === NetworkErrorAction.SendAlternateToPenaltyBox) {
9201
9213
  this.state = State.WAITING_LEVEL;
9202
9214
  } else {
9203
9215
  this.state = State.ERROR;
@@ -9329,10 +9341,7 @@ class BaseStreamController extends TaskLoop {
9329
9341
  const error = new Error(`Found no media in fragment ${frag.sn} of level ${frag.level} resetting transmuxer to fallback to playlist timing`);
9330
9342
  if (level.fragmentError === 0) {
9331
9343
  // Mark and track the odd empty segment as a gap to avoid reloading
9332
- level.fragmentError++;
9333
- frag.gap = true;
9334
- this.fragmentTracker.removeFragment(frag);
9335
- this.fragmentTracker.fragBuffered(frag, true);
9344
+ this.treatAsGap(frag, level);
9336
9345
  }
9337
9346
  this.warn(error.message);
9338
9347
  this.hls.trigger(Events.ERROR, {
@@ -9363,6 +9372,14 @@ class BaseStreamController extends TaskLoop {
9363
9372
  var _ref, _ref2;
9364
9373
  return `${this.playlistLabel()} ${frag.level} (${part ? 'part' : 'frag'}:[${((_ref = pts && !part ? frag.startPTS : (part || frag).start) != null ? _ref : NaN).toFixed(3)}-${((_ref2 = pts && !part ? frag.endPTS : (part || frag).end) != null ? _ref2 : NaN).toFixed(3)}]${part && frag.type === 'main' ? 'INDEPENDENT=' + (part.independent ? 'YES' : 'NO') : ''}`;
9365
9374
  }
9375
+ treatAsGap(frag, level) {
9376
+ if (level) {
9377
+ level.fragmentError++;
9378
+ }
9379
+ frag.gap = true;
9380
+ this.fragmentTracker.removeFragment(frag);
9381
+ this.fragmentTracker.fragBuffered(frag, true);
9382
+ }
9366
9383
  resetTransmuxer() {
9367
9384
  var _this$transmuxer2;
9368
9385
  (_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
@@ -9774,7 +9791,7 @@ var eventemitter3 = {exports: {}};
9774
9791
  var eventemitter3Exports = eventemitter3.exports;
9775
9792
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
9776
9793
 
9777
- const version = "1.6.0-beta.1.0.canary.10765";
9794
+ const version = "1.6.0-beta.1.0.canary.10767";
9778
9795
 
9779
9796
  // ensure the worker ends up in the bundle
9780
9797
  // If the worker should not be included this gets aliased to empty.js
@@ -16337,7 +16354,7 @@ class AudioStreamController extends BaseStreamController {
16337
16354
 
16338
16355
  // Request audio segments up to one fragment ahead of main stream-controller
16339
16356
  const mainFragLoading = (_this$mainFragLoading = this.mainFragLoading) == null ? void 0 : _this$mainFragLoading.frag;
16340
- if (this.startFragRequested && mainFragLoading && mainFragLoading.sn !== 'initSegment' && frag.sn !== 'initSegment' && !frag.endList && (!trackDetails.live || !this.loadingParts && targetBufferTime < this.hls.liveSyncPosition)) {
16357
+ if (this.startFragRequested && mainFragLoading && isMediaFragment(mainFragLoading) && isMediaFragment(frag) && !frag.endList && (!trackDetails.live || !this.loadingParts && targetBufferTime < this.hls.liveSyncPosition)) {
16341
16358
  let mainFrag = mainFragLoading;
16342
16359
  if (frag.start > mainFrag.end) {
16343
16360
  // Get buffered frag at target position from tracker (loaded out of sequence)
@@ -16549,7 +16566,7 @@ class AudioStreamController extends BaseStreamController {
16549
16566
  }
16550
16567
  }
16551
16568
  onFragLoading(event, data) {
16552
- if (data.frag.type === PlaylistLevelType.MAIN && data.frag.sn !== 'initSegment') {
16569
+ if (data.frag.type === PlaylistLevelType.MAIN && isMediaFragment(data.frag)) {
16553
16570
  this.mainFragLoading = data;
16554
16571
  if (this.state === State.IDLE) {
16555
16572
  this.tick();
@@ -16570,7 +16587,7 @@ class AudioStreamController extends BaseStreamController {
16570
16587
  this.warn(`Fragment ${frag.sn}${part ? ' p: ' + part.index : ''} of level ${frag.level} finished buffering, but was aborted. state: ${this.state}, audioSwitch: ${this.switchingTrack ? this.switchingTrack.name : 'false'}`);
16571
16588
  return;
16572
16589
  }
16573
- if (frag.sn !== 'initSegment') {
16590
+ if (isMediaFragment(frag)) {
16574
16591
  this.fragPrevious = frag;
16575
16592
  const track = this.switchingTrack;
16576
16593
  if (track) {
@@ -16782,7 +16799,7 @@ class AudioStreamController extends BaseStreamController {
16782
16799
  // we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
16783
16800
  if (this.switchingTrack || fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
16784
16801
  var _track$details2;
16785
- if (frag.sn === 'initSegment') {
16802
+ if (!isMediaFragment(frag)) {
16786
16803
  this._loadInitSegment(frag, track);
16787
16804
  } else if ((_track$details2 = track.details) != null && _track$details2.live && !this.initPTS[frag.cc]) {
16788
16805
  this.log(`Waiting for video PTS in continuity counter ${frag.cc} of live stream before loading audio fragment ${frag.sn} of level ${this.trackId}`);
@@ -25267,7 +25284,7 @@ class SubtitleStreamController extends BaseStreamController {
25267
25284
  frag,
25268
25285
  success
25269
25286
  } = data;
25270
- if (frag.sn !== 'initSegment') {
25287
+ if (isMediaFragment(frag)) {
25271
25288
  this.fragPrevious = frag;
25272
25289
  }
25273
25290
  this.state = State.IDLE;
@@ -25544,7 +25561,7 @@ class SubtitleStreamController extends BaseStreamController {
25544
25561
  return;
25545
25562
  }
25546
25563
  foundFrag = this.mapToInitFragWhenRequired(foundFrag);
25547
- if (foundFrag.sn !== 'initSegment') {
25564
+ if (isMediaFragment(foundFrag)) {
25548
25565
  // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
25549
25566
  const curSNIdx = foundFrag.sn - trackDetails.startSN;
25550
25567
  const prevFrag = fragments[curSNIdx - 1];
@@ -25559,7 +25576,7 @@ class SubtitleStreamController extends BaseStreamController {
25559
25576
  }
25560
25577
  }
25561
25578
  loadFragment(frag, level, targetBufferTime) {
25562
- if (frag.sn === 'initSegment') {
25579
+ if (!isMediaFragment(frag)) {
25563
25580
  this._loadInitSegment(frag, level);
25564
25581
  } else {
25565
25582
  super.loadFragment(frag, level, targetBufferTime);
@@ -31254,7 +31271,7 @@ class StreamController extends BaseStreamController {
31254
31271
  const targetBufferTime = this.backtrackFragment ? this.backtrackFragment.start : bufferInfo.end;
31255
31272
  let frag = this.getNextFragment(targetBufferTime, levelDetails);
31256
31273
  // Avoid backtracking by loading an earlier segment in streams with segments that do not start with a key frame (flagged by `couldBacktrack`)
31257
- if (this.couldBacktrack && !this.fragPrevious && frag && frag.sn !== 'initSegment' && this.fragmentTracker.getState(frag) !== FragmentState.OK) {
31274
+ if (this.couldBacktrack && !this.fragPrevious && frag && isMediaFragment(frag) && this.fragmentTracker.getState(frag) !== FragmentState.OK) {
31258
31275
  var _this$backtrackFragme;
31259
31276
  const backtrackSn = ((_this$backtrackFragme = this.backtrackFragment) != null ? _this$backtrackFragme : frag).sn;
31260
31277
  const fragIdx = backtrackSn - levelDetails.startSN;
@@ -31291,7 +31308,7 @@ class StreamController extends BaseStreamController {
31291
31308
  // Check if fragment is not loaded
31292
31309
  const fragState = this.fragmentTracker.getState(frag);
31293
31310
  if (fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
31294
- if (frag.sn === 'initSegment') {
31311
+ if (!isMediaFragment(frag)) {
31295
31312
  this._loadInitSegment(frag, level);
31296
31313
  } else if (this.bitrateTest) {
31297
31314
  this.log(`Fragment ${frag.sn} of level ${frag.level} is being downloaded to test bitrate and will not be buffered`);
@@ -31717,7 +31734,7 @@ class StreamController extends BaseStreamController {
31717
31734
  }
31718
31735
  const stats = part ? part.stats : frag.stats;
31719
31736
  this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first));
31720
- if (frag.sn !== 'initSegment') {
31737
+ if (isMediaFragment(frag)) {
31721
31738
  this.fragPrevious = frag;
31722
31739
  }
31723
31740
  this.fragBufferedComplete(frag, part);
@@ -33343,6 +33360,10 @@ class Hls {
33343
33360
  return;
33344
33361
  }
33345
33362
  this.logger.log(`attachMedia`);
33363
+ if (this._media) {
33364
+ this.logger.warn(`media must be detached before attaching`);
33365
+ this.detachMedia();
33366
+ }
33346
33367
  const attachMediaSource = 'media' in data;
33347
33368
  const media = attachMediaSource ? data.media : data;
33348
33369
  const attachingData = attachMediaSource ? data : {