hls.js 1.6.0-beta.4.0.canary.11044 → 1.6.0-beta.4.0.canary.11045

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.js CHANGED
@@ -1073,7 +1073,7 @@
1073
1073
  // Some browsers don't allow to use bind on console object anyway
1074
1074
  // fallback to default if needed
1075
1075
  try {
1076
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.4.0.canary.11044");
1076
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.4.0.canary.11045");
1077
1077
  } catch (e) {
1078
1078
  /* log fn threw an exception. All logger methods are no-ops. */
1079
1079
  return createLogger();
@@ -8716,15 +8716,12 @@
8716
8716
  function reassignFragmentLevelIndexes(levels) {
8717
8717
  levels.forEach(function (level, index) {
8718
8718
  var _level$details;
8719
- var fragments = (_level$details = level.details) == null ? void 0 : _level$details.fragments;
8720
- if (fragments) {
8721
- fragments.forEach(function (fragment) {
8722
- fragment.level = index;
8723
- if (fragment.initSegment) {
8724
- fragment.initSegment.level = index;
8725
- }
8726
- });
8727
- }
8719
+ (_level$details = level.details) == null ? void 0 : _level$details.fragments.forEach(function (fragment) {
8720
+ fragment.level = index;
8721
+ if (fragment.initSegment) {
8722
+ fragment.initSegment.level = index;
8723
+ }
8724
+ });
8728
8725
  });
8729
8726
  }
8730
8727
 
@@ -9116,6 +9113,7 @@
9116
9113
  this.media = this.mediaBuffer = null;
9117
9114
  this.loopSn = undefined;
9118
9115
  if (transferringMedia) {
9116
+ this.resetLoadingState();
9119
9117
  this.resetTransmuxer();
9120
9118
  return;
9121
9119
  }
@@ -9158,42 +9156,6 @@
9158
9156
  _TaskLoop.prototype.onHandlerDestroyed.call(this);
9159
9157
  };
9160
9158
  _proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
9161
- var config = this.hls.config;
9162
- if (config.interstitialsController && config.enableInterstitialPlayback !== false && frag.type !== PlaylistLevelType.SUBTITLE) {
9163
- // Do not load fragments outside the buffering schedule segment
9164
- var interstitials = this.hls.interstitialsManager;
9165
- var bufferingItem = interstitials == null ? void 0 : interstitials.bufferingItem;
9166
- if (bufferingItem) {
9167
- var bufferingInterstitial = bufferingItem.event;
9168
- if (bufferingInterstitial) {
9169
- // Do not stream fragments while buffering Interstitial Events (except for overlap at the start)
9170
- if (bufferingInterstitial.appendInPlace || Math.abs(frag.start - bufferingItem.start) > 1 || bufferingItem.start === 0) {
9171
- return;
9172
- }
9173
- } else {
9174
- var _level$details;
9175
- // Limit fragment loading to media in schedule item
9176
- if (frag.end <= bufferingItem.start && ((_level$details = level.details) == null ? void 0 : _level$details.live) === false) {
9177
- // fragment ends by schedule item start
9178
- return;
9179
- }
9180
- if (frag.start > bufferingItem.end && bufferingItem.nextEvent) {
9181
- // fragment is past schedule item end
9182
- return;
9183
- }
9184
- }
9185
- }
9186
- // Skip loading of fragments that overlap completely with appendInPlace interstitials
9187
- var playerQueue = interstitials == null ? void 0 : interstitials.playerQueue;
9188
- if (playerQueue) {
9189
- for (var i = playerQueue.length; i--;) {
9190
- var interstitial = playerQueue[i].interstitial;
9191
- if (interstitial.appendInPlace && frag.start >= interstitial.startTime && frag.end <= interstitial.resumeTime) {
9192
- return;
9193
- }
9194
- }
9195
- }
9196
- }
9197
9159
  this.startFragRequested = true;
9198
9160
  this._loadFragForPlayback(frag, level, targetBufferTime);
9199
9161
  };
@@ -9552,9 +9514,9 @@
9552
9514
  _proto.doFragPartsLoad = function doFragPartsLoad(frag, fromPart, level, progressCallback) {
9553
9515
  var _this6 = this;
9554
9516
  return new Promise(function (resolve, reject) {
9555
- var _level$details2;
9517
+ var _level$details;
9556
9518
  var partsLoaded = [];
9557
- var initialPartList = (_level$details2 = level.details) == null ? void 0 : _level$details2.partList;
9519
+ var initialPartList = (_level$details = level.details) == null ? void 0 : _level$details.partList;
9558
9520
  var _loadPart = function loadPart(part) {
9559
9521
  _this6.fragmentLoader.loadPart(frag, part, progressCallback).then(function (partLoadedData) {
9560
9522
  partsLoaded[part.index] = partLoadedData;
@@ -9820,6 +9782,7 @@
9820
9782
  var end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
9821
9783
  frag = this.getFragmentAtPosition(pos, end, levelDetails);
9822
9784
  }
9785
+ frag = this.filterReplacedPrimary(frag, levelDetails);
9823
9786
  return this.mapToInitFragWhenRequired(frag);
9824
9787
  };
9825
9788
  _proto.isLoopLoading = function isLoopLoading(frag, targetBufferTime) {
@@ -9847,6 +9810,48 @@
9847
9810
  this.loopSn = undefined;
9848
9811
  return nextFragment;
9849
9812
  };
9813
+ _proto.filterReplacedPrimary = function filterReplacedPrimary(frag, details) {
9814
+ if (!frag) {
9815
+ return frag;
9816
+ }
9817
+ var config = this.hls.config;
9818
+ if (config.interstitialsController && config.enableInterstitialPlayback !== false && frag.type !== PlaylistLevelType.SUBTITLE) {
9819
+ // Do not load fragments outside the buffering schedule segment
9820
+ var interstitials = this.hls.interstitialsManager;
9821
+ var bufferingItem = interstitials == null ? void 0 : interstitials.bufferingItem;
9822
+ if (bufferingItem) {
9823
+ var bufferingInterstitial = bufferingItem.event;
9824
+ if (bufferingInterstitial) {
9825
+ // Do not stream fragments while buffering Interstitial Events (except for overlap at the start)
9826
+ if (bufferingInterstitial.appendInPlace || Math.abs(frag.start - bufferingItem.start) > 1 || bufferingItem.start === 0) {
9827
+ return null;
9828
+ }
9829
+ } else {
9830
+ // Limit fragment loading to media in schedule item
9831
+ if (frag.end <= bufferingItem.start && (details == null ? void 0 : details.live) === false) {
9832
+ // fragment ends by schedule item start
9833
+ // this.fragmentTracker.fragBuffered(frag, true);
9834
+ return null;
9835
+ }
9836
+ if (frag.start > bufferingItem.end && bufferingItem.nextEvent) {
9837
+ // fragment is past schedule item end
9838
+ return null;
9839
+ }
9840
+ }
9841
+ }
9842
+ // Skip loading of fragments that overlap completely with appendInPlace interstitials
9843
+ var playerQueue = interstitials == null ? void 0 : interstitials.playerQueue;
9844
+ if (playerQueue) {
9845
+ for (var i = playerQueue.length; i--;) {
9846
+ var interstitial = playerQueue[i].interstitial;
9847
+ if (interstitial.appendInPlace && frag.start >= interstitial.startTime && frag.end <= interstitial.resumeTime) {
9848
+ return null;
9849
+ }
9850
+ }
9851
+ }
9852
+ }
9853
+ return frag;
9854
+ };
9850
9855
  _proto.mapToInitFragWhenRequired = function mapToInitFragWhenRequired(frag) {
9851
9856
  // If an initSegment is present, it must be buffered first
9852
9857
  if (frag != null && frag.initSegment && !(frag != null && frag.initSegment.data) && !this.bitrateTest) {
@@ -16443,7 +16448,7 @@
16443
16448
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
16444
16449
  }
16445
16450
 
16446
- var version = "1.6.0-beta.4.0.canary.11044";
16451
+ var version = "1.6.0-beta.4.0.canary.11045";
16447
16452
 
16448
16453
  // ensure the worker ends up in the bundle
16449
16454
  // If the worker should not be included this gets aliased to empty.js
@@ -18436,15 +18441,14 @@
18436
18441
  if (!media || !mediaSource) {
18437
18442
  return;
18438
18443
  }
18444
+ // once received, don't listen anymore to sourceopen event
18445
+ mediaSource.removeEventListener('sourceopen', _this2._onMediaSourceOpen);
18439
18446
  media.removeEventListener('emptied', _this2._onMediaEmptied);
18440
18447
  _this2.updateDuration();
18441
18448
  _this2.hls.trigger(Events.MEDIA_ATTACHED, {
18442
18449
  media: media,
18443
18450
  mediaSource: mediaSource
18444
18451
  });
18445
-
18446
- // once received, don't listen anymore to sourceopen event
18447
- mediaSource.removeEventListener('sourceopen', _this2._onMediaSourceOpen);
18448
18452
  if (_this2.mediaSource !== null) {
18449
18453
  _this2.checkPendingTracks();
18450
18454
  }
@@ -23213,6 +23217,7 @@
23213
23217
  this.tracks = null;
23214
23218
  this.hasDetails = false;
23215
23219
  this.mediaAttached = null;
23220
+ this._currentTime = void 0;
23216
23221
  this.checkPlayout = function () {
23217
23222
  var interstitial = _this.interstitial;
23218
23223
  var playoutLimit = interstitial.playoutLimit;
@@ -23257,6 +23262,7 @@
23257
23262
  _proto.removeMediaListeners = function removeMediaListeners() {
23258
23263
  var media = this.mediaAttached;
23259
23264
  if (media) {
23265
+ this._currentTime = media.currentTime;
23260
23266
  media.removeEventListener('timeupdate', this.checkPlayout);
23261
23267
  }
23262
23268
  };
@@ -23273,6 +23279,7 @@
23273
23279
  };
23274
23280
  _proto.detachMedia = function detachMedia() {
23275
23281
  this.removeMediaListeners();
23282
+ this.mediaAttached = null;
23276
23283
  this.hls.detachMedia();
23277
23284
  };
23278
23285
  _proto.resumeBuffering = function resumeBuffering() {
@@ -23294,13 +23301,14 @@
23294
23301
  this.hls.off(event, listener);
23295
23302
  };
23296
23303
  _proto.toString = function toString() {
23297
- return "HlsAssetPlayer: " + eventAssetToString(this.assetItem) + " " + this.hls.sessionId + " " + (this.interstitial.appendInPlace ? 'append-in-place' : '');
23304
+ var _this$hls, _this$interstitial;
23305
+ return "HlsAssetPlayer: " + eventAssetToString(this.assetItem) + " " + ((_this$hls = this.hls) == null ? void 0 : _this$hls.sessionId) + " " + ((_this$interstitial = this.interstitial) != null && _this$interstitial.appendInPlace ? 'append-in-place' : '');
23298
23306
  };
23299
23307
  return _createClass(HlsAssetPlayer, [{
23300
23308
  key: "destroyed",
23301
23309
  get: function get() {
23302
- var _this$hls;
23303
- return !((_this$hls = this.hls) != null && _this$hls.userConfig);
23310
+ var _this$hls2;
23311
+ return !((_this$hls2 = this.hls) != null && _this$hls2.userConfig);
23304
23312
  }
23305
23313
  }, {
23306
23314
  key: "assetId",
@@ -23315,15 +23323,15 @@
23315
23323
  }, {
23316
23324
  key: "media",
23317
23325
  get: function get() {
23318
- var _this$hls2;
23319
- return ((_this$hls2 = this.hls) == null ? void 0 : _this$hls2.media) || null;
23326
+ var _this$hls3;
23327
+ return ((_this$hls3 = this.hls) == null ? void 0 : _this$hls3.media) || null;
23320
23328
  }
23321
23329
  }, {
23322
23330
  key: "bufferedEnd",
23323
23331
  get: function get() {
23324
23332
  var media = this.media || this.mediaAttached;
23325
23333
  if (!media) {
23326
- return 0;
23334
+ return this.currentTime;
23327
23335
  }
23328
23336
  var bufferInfo = BufferHelper.bufferInfo(media, media.currentTime, 0.001);
23329
23337
  return this.getAssetTime(bufferInfo.end);
@@ -23333,7 +23341,7 @@
23333
23341
  get: function get() {
23334
23342
  var media = this.media || this.mediaAttached;
23335
23343
  if (!media) {
23336
- return 0;
23344
+ return this._currentTime || 0;
23337
23345
  }
23338
23346
  return this.getAssetTime(media.currentTime);
23339
23347
  }
@@ -23363,8 +23371,8 @@
23363
23371
  }, {
23364
23372
  key: "timelineOffset",
23365
23373
  get: function get() {
23366
- var _this$hls3;
23367
- return ((_this$hls3 = this.hls) == null ? void 0 : _this$hls3.config.timelineOffset) || 0;
23374
+ var _this$hls4;
23375
+ return ((_this$hls4 = this.hls) == null ? void 0 : _this$hls4.config.timelineOffset) || 0;
23368
23376
  },
23369
23377
  set: function set(value) {
23370
23378
  var timelineOffset = this.timelineOffset;
@@ -23521,14 +23529,14 @@
23521
23529
  }
23522
23530
  return 0;
23523
23531
  };
23524
- _proto.parseInterstitialDateRanges = function parseInterstitialDateRanges(mediaSelection) {
23532
+ _proto.parseInterstitialDateRanges = function parseInterstitialDateRanges(mediaSelection, enableAppendInPlace) {
23525
23533
  var _this2 = this;
23526
23534
  var details = mediaSelection.main.details;
23527
23535
  var dateRanges = details.dateRanges;
23528
23536
  var previousInterstitialEvents = this.events;
23529
23537
  var interstitialEvents = this.parseDateRanges(dateRanges, {
23530
23538
  url: details.url
23531
- });
23539
+ }, enableAppendInPlace);
23532
23540
  var ids = Object.keys(dateRanges);
23533
23541
  var removedInterstitials = previousInterstitialEvents ? previousInterstitialEvents.filter(function (event) {
23534
23542
  return !ids.includes(event.identifier);
@@ -23589,7 +23597,7 @@
23589
23597
  }
23590
23598
  }
23591
23599
  };
23592
- _proto.parseDateRanges = function parseDateRanges(dateRanges, baseData) {
23600
+ _proto.parseDateRanges = function parseDateRanges(dateRanges, baseData, enableAppendInPlace) {
23593
23601
  var interstitialEvents = [];
23594
23602
  var ids = Object.keys(dateRanges);
23595
23603
  for (var i = 0; i < ids.length; i++) {
@@ -23604,6 +23612,9 @@
23604
23612
  } else {
23605
23613
  interstitial = new InterstitialEvent(dateRange, baseData);
23606
23614
  this.eventMap[id] = interstitial;
23615
+ if (enableAppendInPlace === false) {
23616
+ interstitial.appendInPlace = enableAppendInPlace;
23617
+ }
23607
23618
  }
23608
23619
  interstitialEvents.push(interstitial);
23609
23620
  }
@@ -23810,13 +23821,11 @@
23810
23821
  interstitial.appendInPlace = false;
23811
23822
  }
23812
23823
  }
23813
- if (!interstitial.appendInPlace) {
23824
+ if (!interstitial.appendInPlace && i + 1 < interstitialEvents.length) {
23814
23825
  // abutting Interstitials must use the same MediaSource strategy, this applies to all whether or not they are back to back:
23815
- for (var j = i - 1; i--;) {
23816
- var timeBetween = interstitialEvents[j + 1].startTime - interstitialEvents[j].resumeTime;
23817
- if (timeBetween < ABUTTING_THRESHOLD_SECONDS) {
23818
- interstitialEvents[j].appendInPlace = false;
23819
- }
23826
+ var timeBetween = interstitialEvents[i + 1].startTime - interstitialEvents[i].resumeTime;
23827
+ if (timeBetween < ABUTTING_THRESHOLD_SECONDS) {
23828
+ interstitialEvents[i + 1].appendInPlace = false;
23820
23829
  }
23821
23830
  }
23822
23831
  // Update cumulativeDuration for next abutting interstitial with the same start date
@@ -24176,11 +24185,6 @@
24176
24185
  });
24177
24186
  var interstitialsUpdated = !!(interstitialEvents.length || removedIds.length);
24178
24187
  if (interstitialsUpdated) {
24179
- if (_this.hls.config.interstitialAppendInPlace === false) {
24180
- interstitialEvents.forEach(function (event) {
24181
- return event.appendInPlace = false;
24182
- });
24183
- }
24184
24188
  _this.log("INTERSTITIALS_UPDATED (" + interstitialEvents.length + "): " + interstitialEvents + "\nSchedule: " + scheduleItems.map(function (seg) {
24185
24189
  return segmentToString(seg);
24186
24190
  }));
@@ -24314,14 +24318,12 @@
24314
24318
  this.pauseBuffering();
24315
24319
  };
24316
24320
  _proto.resumeBuffering = function resumeBuffering() {
24317
- this.playerQueue.forEach(function (player) {
24318
- return player.resumeBuffering();
24319
- });
24321
+ var _this$getBufferingPla;
24322
+ (_this$getBufferingPla = this.getBufferingPlayer()) == null ? void 0 : _this$getBufferingPla.resumeBuffering();
24320
24323
  };
24321
24324
  _proto.pauseBuffering = function pauseBuffering() {
24322
- this.playerQueue.forEach(function (player) {
24323
- return player.pauseBuffering();
24324
- });
24325
+ var _this$getBufferingPla2;
24326
+ (_this$getBufferingPla2 = this.getBufferingPlayer()) == null ? void 0 : _this$getBufferingPla2.pauseBuffering();
24325
24327
  };
24326
24328
  _proto.destroy = function destroy() {
24327
24329
  this.unregisterListeners();
@@ -24431,33 +24433,51 @@
24431
24433
  }
24432
24434
  };
24433
24435
  _proto.transferMediaTo = function transferMediaTo(player, media) {
24434
- var _this$detachedData, _attachMediaSourceDat;
24436
+ var _this$detachedData,
24437
+ _this2 = this,
24438
+ _attachMediaSourceDat;
24439
+ if (player.media === media) {
24440
+ return;
24441
+ }
24435
24442
  var attachMediaSourceData = null;
24436
24443
  var primaryPlayer = this.hls;
24437
24444
  var isAssetPlayer = player !== primaryPlayer;
24438
24445
  var appendInPlace = isAssetPlayer && player.interstitial.appendInPlace;
24439
24446
  var detachedMediaSource = (_this$detachedData = this.detachedData) == null ? void 0 : _this$detachedData.mediaSource;
24440
24447
  var logFromSource;
24441
- if (primaryPlayer.media && appendInPlace) {
24442
- attachMediaSourceData = primaryPlayer.transferMedia();
24443
- this.detachedData = attachMediaSourceData;
24448
+ if (primaryPlayer.media) {
24449
+ if (appendInPlace) {
24450
+ attachMediaSourceData = primaryPlayer.transferMedia();
24451
+ this.detachedData = attachMediaSourceData;
24452
+ }
24444
24453
  logFromSource = "Primary";
24445
24454
  } else if (detachedMediaSource) {
24446
24455
  var bufferingPlayer = this.getBufferingPlayer();
24447
24456
  if (bufferingPlayer) {
24448
24457
  attachMediaSourceData = bufferingPlayer.transferMedia();
24458
+ logFromSource = "" + bufferingPlayer;
24459
+ } else {
24460
+ logFromSource = "detached MediaSource";
24449
24461
  }
24450
- logFromSource = "" + bufferingPlayer;
24451
24462
  } else {
24452
- logFromSource = "<unknown>";
24463
+ logFromSource = "detached media";
24453
24464
  }
24454
- this.log("transferring to " + (isAssetPlayer ? player : 'Primary') + "\nMediaSource " + stringify(attachMediaSourceData) + " from " + logFromSource);
24455
24465
  if (!attachMediaSourceData) {
24456
24466
  if (detachedMediaSource) {
24457
24467
  attachMediaSourceData = this.detachedData;
24458
24468
  this.log("using detachedData: MediaSource " + stringify(attachMediaSourceData));
24459
- } else if (!this.detachedData || this.hls.media === media) {
24460
- // Media is attaching when `detachedData` and `hls.media` are populated. Detach to clear the MediaSource.
24469
+ } else if (!this.detachedData || primaryPlayer.media === media) {
24470
+ // Keep interstitial media transition consistent
24471
+ var playerQueue = this.playerQueue;
24472
+ if (playerQueue.length > 1) {
24473
+ playerQueue.forEach(function (queuedPlayer) {
24474
+ if (isAssetPlayer && queuedPlayer.interstitial.appendInPlace !== appendInPlace) {
24475
+ var interstitial = queuedPlayer.interstitial;
24476
+ _this2.clearInterstitial(queuedPlayer.interstitial, null);
24477
+ interstitial.appendInPlace = false;
24478
+ }
24479
+ });
24480
+ }
24461
24481
  this.hls.detachMedia();
24462
24482
  this.detachedData = {
24463
24483
  media: media
@@ -24466,7 +24486,7 @@
24466
24486
  }
24467
24487
  var transferring = attachMediaSourceData && 'mediaSource' in attachMediaSourceData && ((_attachMediaSourceDat = attachMediaSourceData.mediaSource) == null ? void 0 : _attachMediaSourceDat.readyState) !== 'closed';
24468
24488
  var dataToAttach = transferring && attachMediaSourceData ? attachMediaSourceData : media;
24469
- this.log((transferring ? 'transfering MediaSource' : 'attaching media') + " to " + (isAssetPlayer ? player : 'Primary'));
24489
+ this.log((transferring ? 'transfering MediaSource' : 'attaching media') + " to " + (isAssetPlayer ? player : 'Primary') + " from " + logFromSource);
24470
24490
  if (dataToAttach === attachMediaSourceData) {
24471
24491
  var isAssetAtEndOfSchedule = isAssetPlayer && player.assetId === this.schedule.assetIdAtEnd;
24472
24492
  // Prevent asset players from marking EoS on transferred MediaSource
@@ -24563,6 +24583,7 @@
24563
24583
  var assetId = playingAsset == null ? void 0 : playingAsset.identifier;
24564
24584
  var player = assetId ? this.getAssetPlayer(assetId) : null;
24565
24585
  if (player && assetId && (!this.eventItemsMatch(currentItem, scheduledItem) || assetListIndex !== undefined && assetId !== ((_interstitial$assetLi = interstitial.assetList) == null ? void 0 : _interstitial$assetLi[assetListIndex].identifier))) {
24586
+ var _this$detachedData2;
24566
24587
  var _assetListIndex = interstitial.findAssetIndex(playingAsset);
24567
24588
  this.log("INTERSTITIAL_ASSET_ENDED " + (_assetListIndex + 1) + "/" + interstitial.assetList.length + " " + eventAssetToString(playingAsset));
24568
24589
  this.endedAsset = playingAsset;
@@ -24576,7 +24597,7 @@
24576
24597
  player: player
24577
24598
  });
24578
24599
  this.retreiveMediaSource(assetId, scheduledItem);
24579
- if (player.media && !this.detachedData) {
24600
+ if (player.media && !((_this$detachedData2 = this.detachedData) != null && _this$detachedData2.mediaSource)) {
24580
24601
  player.detachMedia();
24581
24602
  }
24582
24603
  }
@@ -24606,7 +24627,7 @@
24606
24627
  this.advanceSchedule(index, scheduleItems, assetListIndex, currentItem, playingLastItem);
24607
24628
  };
24608
24629
  _proto.advanceSchedule = function advanceSchedule(index, scheduleItems, assetListIndex, currentItem, playedLastItem) {
24609
- var _this2 = this;
24630
+ var _this3 = this;
24610
24631
  var scheduledItem = index >= 0 ? scheduleItems[index] : null;
24611
24632
  var media = this.primaryMedia;
24612
24633
  // Cleanup out of range Interstitials
@@ -24614,9 +24635,9 @@
24614
24635
  if (playerQueue.length) {
24615
24636
  playerQueue.forEach(function (player) {
24616
24637
  var interstitial = player.interstitial;
24617
- var queuedIndex = _this2.schedule.findEventIndex(interstitial.identifier);
24638
+ var queuedIndex = _this3.schedule.findEventIndex(interstitial.identifier);
24618
24639
  if (queuedIndex < index || queuedIndex > index + 1) {
24619
- _this2.clearInterstitial(interstitial, scheduledItem);
24640
+ _this3.clearInterstitial(interstitial, scheduledItem);
24620
24641
  }
24621
24642
  });
24622
24643
  }
@@ -24707,13 +24728,13 @@
24707
24728
  }
24708
24729
  };
24709
24730
  _proto.resumePrimary = function resumePrimary(scheduledItem, index, fromItem) {
24710
- var _this$detachedData2;
24731
+ var _this$detachedData3;
24711
24732
  this.playingItem = scheduledItem;
24712
24733
  this.playingAsset = this.endedAsset = null;
24713
24734
  this.waitingItem = this.endedItem = null;
24714
24735
  this.bufferedToItem(scheduledItem);
24715
24736
  this.log("resuming " + segmentToString(scheduledItem));
24716
- if (!((_this$detachedData2 = this.detachedData) != null && _this$detachedData2.mediaSource)) {
24737
+ if (!((_this$detachedData3 = this.detachedData) != null && _this$detachedData3.mediaSource)) {
24717
24738
  var timelinePos = this.timelinePos;
24718
24739
  if (timelinePos < scheduledItem.start || timelinePos >= scheduledItem.end) {
24719
24740
  timelinePos = this.getPrimaryResumption(scheduledItem, index);
@@ -24815,7 +24836,7 @@
24815
24836
  main: main
24816
24837
  });
24817
24838
  this.mediaSelection = currentSelection;
24818
- this.schedule.parseInterstitialDateRanges(currentSelection);
24839
+ this.schedule.parseInterstitialDateRanges(currentSelection, this.hls.config.interstitialAppendInPlace);
24819
24840
  if (!this.effectivePlayingItem && this.schedule.items) {
24820
24841
  this.checkStart();
24821
24842
  }
@@ -24901,6 +24922,8 @@
24901
24922
  if (!this.playingLastItem && playingItem) {
24902
24923
  var playingIndex = this.findItemIndex(playingItem);
24903
24924
  this.setSchedulePosition(playingIndex + 1);
24925
+ } else {
24926
+ this.shouldPlay = false;
24904
24927
  }
24905
24928
  };
24906
24929
  _proto.updateItem = function updateItem(previousItem, time) {
@@ -24981,7 +25004,7 @@
24981
25004
  }
24982
25005
  };
24983
25006
  _proto.setBufferingItem = function setBufferingItem(item) {
24984
- var _this3 = this;
25007
+ var _this4 = this;
24985
25008
  var bufferingLast = this.bufferingItem;
24986
25009
  var schedule = this.schedule;
24987
25010
  if (!this.itemsMatch(item, bufferingLast)) {
@@ -25000,7 +25023,7 @@
25000
25023
  if (isInterstitial) {
25001
25024
  // primary fragment loading will exit early in base-stream-controller while `bufferingItem` is set to an Interstitial block
25002
25025
  item.event.assetList.forEach(function (asset) {
25003
- var player = _this3.getAssetPlayer(asset.identifier);
25026
+ var player = _this4.getAssetPlayer(asset.identifier);
25004
25027
  if (player) {
25005
25028
  player.resumeBuffering();
25006
25029
  }
@@ -25074,16 +25097,16 @@
25074
25097
  }
25075
25098
  };
25076
25099
  _proto.preloadAssets = function preloadAssets(interstitial, assetListIndex) {
25100
+ var uri = interstitial.assetUrl;
25077
25101
  var assetListLength = interstitial.assetList.length;
25078
25102
  var neverLoaded = assetListLength === 0 && !interstitial.assetListLoader;
25079
25103
  var playOnce = interstitial.cue.once;
25080
25104
  if (neverLoaded) {
25081
- this.log("Load interstitial asset " + (assetListIndex + 1) + "/" + assetListLength + " " + interstitial);
25105
+ this.log("Load interstitial asset " + (assetListIndex + 1) + "/" + (uri ? 1 : assetListLength) + " " + interstitial);
25082
25106
  var timelineStart = interstitial.timelineStart;
25083
25107
  if (interstitial.appendInPlace) {
25084
25108
  this.flushFrontBuffer(timelineStart + 0.25);
25085
25109
  }
25086
- var uri = interstitial.assetUrl;
25087
25110
  if (uri) {
25088
25111
  return this.createAsset(interstitial, 0, 0, timelineStart, interstitial.duration, uri);
25089
25112
  }
@@ -25112,7 +25135,7 @@
25112
25135
  return null;
25113
25136
  };
25114
25137
  _proto.flushFrontBuffer = function flushFrontBuffer(startOffset) {
25115
- var _this4 = this;
25138
+ var _this5 = this;
25116
25139
  // Force queued flushing of all buffers
25117
25140
  var requiredTracks = this.requiredTracks;
25118
25141
  if (!requiredTracks) {
@@ -25120,7 +25143,7 @@
25120
25143
  }
25121
25144
  var sourceBufferNames = Object.keys(requiredTracks);
25122
25145
  sourceBufferNames.forEach(function (type) {
25123
- _this4.hls.trigger(Events.BUFFER_FLUSHING, {
25146
+ _this5.hls.trigger(Events.BUFFER_FLUSHING, {
25124
25147
  startOffset: startOffset,
25125
25148
  endOffset: Infinity,
25126
25149
  type: type
@@ -25167,7 +25190,7 @@
25167
25190
  return this.createAssetPlayer(interstitial, assetItem, assetListIndex);
25168
25191
  };
25169
25192
  _proto.createAssetPlayer = function createAssetPlayer(interstitial, assetItem, assetListIndex) {
25170
- var _this5 = this;
25193
+ var _this6 = this;
25171
25194
  this.log("create HLSAssetPlayer for " + eventAssetToString(assetItem));
25172
25195
  var primary = this.hls;
25173
25196
  var userConfig = primary.userConfig;
@@ -25234,17 +25257,17 @@
25234
25257
  details: ErrorDetails.INTERSTITIAL_ASSET_ITEM_ERROR,
25235
25258
  error: error
25236
25259
  };
25237
- _this5.handleAssetItemError(errorData, interstitial, _this5.schedule.findEventIndex(interstitial.identifier), assetListIndex, error.message);
25260
+ _this6.handleAssetItemError(errorData, interstitial, _this6.schedule.findEventIndex(interstitial.identifier), assetListIndex, error.message);
25238
25261
  return;
25239
25262
  }
25240
25263
  // Get time at end of last fragment
25241
25264
  var duration = details.edge - details.fragmentStart;
25242
25265
  var currentAssetDuration = assetItem.duration;
25243
25266
  if (currentAssetDuration === null || duration > currentAssetDuration) {
25244
- _this5.log("Interstitial asset \"" + assetId + "\" duration change " + currentAssetDuration + " > " + duration);
25267
+ _this6.log("Interstitial asset \"" + assetId + "\" duration change " + currentAssetDuration + " > " + duration);
25245
25268
  assetItem.duration = duration;
25246
25269
  // Update schedule with new event and asset duration
25247
- _this5.updateSchedule();
25270
+ _this6.updateSchedule();
25248
25271
  }
25249
25272
  };
25250
25273
  player.on(Events.LEVEL_UPDATED, function (event, _ref) {
@@ -25256,39 +25279,39 @@
25256
25279
  return updateAssetPlayerDetails(details);
25257
25280
  });
25258
25281
  var _onBufferCodecs = function onBufferCodecs(event, data) {
25259
- var inQueuPlayer = _this5.getAssetPlayer(assetId);
25282
+ var inQueuPlayer = _this6.getAssetPlayer(assetId);
25260
25283
  if (inQueuPlayer && data.tracks) {
25261
25284
  inQueuPlayer.off(Events.BUFFER_CODECS, _onBufferCodecs);
25262
25285
  inQueuPlayer.tracks = data.tracks;
25263
- var media = _this5.primaryMedia;
25264
- if (_this5.bufferingAsset === inQueuPlayer.assetItem && media && !inQueuPlayer.media) {
25265
- _this5.bufferAssetPlayer(inQueuPlayer, media);
25286
+ var media = _this6.primaryMedia;
25287
+ if (_this6.bufferingAsset === inQueuPlayer.assetItem && media && !inQueuPlayer.media) {
25288
+ _this6.bufferAssetPlayer(inQueuPlayer, media);
25266
25289
  }
25267
25290
  }
25268
25291
  };
25269
25292
  player.on(Events.BUFFER_CODECS, _onBufferCodecs);
25270
25293
  var _bufferedToEnd = function bufferedToEnd(name) {
25271
- var _this5$schedule$items;
25272
- var inQueuPlayer = _this5.getAssetPlayer(assetId);
25273
- _this5.log("buffered to end of asset " + inQueuPlayer);
25294
+ var _this6$schedule$items;
25295
+ var inQueuPlayer = _this6.getAssetPlayer(assetId);
25296
+ _this6.log("buffered to end of asset " + inQueuPlayer);
25274
25297
  if (!inQueuPlayer) {
25275
25298
  return;
25276
25299
  }
25277
25300
  inQueuPlayer.off(Events.BUFFERED_TO_END, _bufferedToEnd);
25278
25301
 
25279
25302
  // Preload at end of asset
25280
- var scheduleIndex = _this5.schedule.findEventIndex(interstitial.identifier);
25303
+ var scheduleIndex = _this6.schedule.findEventIndex(interstitial.identifier);
25281
25304
  var assetListIndex = interstitial.findAssetIndex(assetItem);
25282
25305
  var nextAssetIndex = assetListIndex + 1;
25283
- var item = (_this5$schedule$items = _this5.schedule.items) == null ? void 0 : _this5$schedule$items[scheduleIndex];
25284
- if (_this5.isInterstitial(item)) {
25306
+ var item = (_this6$schedule$items = _this6.schedule.items) == null ? void 0 : _this6$schedule$items[scheduleIndex];
25307
+ if (_this6.isInterstitial(item)) {
25285
25308
  if (assetListIndex !== -1 && !interstitial.isAssetPastPlayoutLimit(nextAssetIndex) && !interstitial.assetList[nextAssetIndex].error) {
25286
- _this5.bufferedToItem(item, assetListIndex + 1);
25309
+ _this6.bufferedToItem(item, assetListIndex + 1);
25287
25310
  } else {
25288
- var _this5$schedule$items2;
25289
- var nextItem = (_this5$schedule$items2 = _this5.schedule.items) == null ? void 0 : _this5$schedule$items2[scheduleIndex + 1];
25311
+ var _this6$schedule$items2;
25312
+ var nextItem = (_this6$schedule$items2 = _this6.schedule.items) == null ? void 0 : _this6$schedule$items2[scheduleIndex + 1];
25290
25313
  if (nextItem) {
25291
- _this5.bufferedToItem(nextItem);
25314
+ _this6.bufferedToItem(nextItem);
25292
25315
  }
25293
25316
  }
25294
25317
  }
@@ -25296,22 +25319,22 @@
25296
25319
  player.on(Events.BUFFERED_TO_END, _bufferedToEnd);
25297
25320
  var endedWithAssetIndex = function endedWithAssetIndex(assetIndex) {
25298
25321
  return function () {
25299
- var inQueuPlayer = _this5.getAssetPlayer(assetId);
25322
+ var inQueuPlayer = _this6.getAssetPlayer(assetId);
25300
25323
  if (!inQueuPlayer) {
25301
25324
  return;
25302
25325
  }
25303
- _this5.shouldPlay = true;
25304
- var scheduleIndex = _this5.schedule.findEventIndex(interstitial.identifier);
25305
- _this5.advanceAfterAssetEnded(interstitial, scheduleIndex, assetIndex);
25326
+ _this6.shouldPlay = true;
25327
+ var scheduleIndex = _this6.schedule.findEventIndex(interstitial.identifier);
25328
+ _this6.advanceAfterAssetEnded(interstitial, scheduleIndex, assetIndex);
25306
25329
  };
25307
25330
  };
25308
25331
  player.once(Events.MEDIA_ENDED, endedWithAssetIndex(assetListIndex));
25309
25332
  player.once(Events.PLAYOUT_LIMIT_REACHED, endedWithAssetIndex(Infinity));
25310
25333
  player.on(Events.ERROR, function (event, data) {
25311
- _this5.handleAssetItemError(data, interstitial, _this5.schedule.findEventIndex(interstitial.identifier), assetListIndex, "Asset player error " + data.error + " " + interstitial);
25334
+ _this6.handleAssetItemError(data, interstitial, _this6.schedule.findEventIndex(interstitial.identifier), assetListIndex, "Asset player error " + data.error + " " + interstitial);
25312
25335
  });
25313
25336
  player.on(Events.DESTROYING, function () {
25314
- var inQueuPlayer = _this5.getAssetPlayer(assetId);
25337
+ var inQueuPlayer = _this6.getAssetPlayer(assetId);
25315
25338
  if (!inQueuPlayer) {
25316
25339
  return;
25317
25340
  }
@@ -25322,7 +25345,7 @@
25322
25345
  details: ErrorDetails.INTERSTITIAL_ASSET_ITEM_ERROR,
25323
25346
  error: error
25324
25347
  };
25325
- _this5.handleAssetItemError(errorData, interstitial, _this5.schedule.findEventIndex(interstitial.identifier), assetListIndex, error.message);
25348
+ _this6.handleAssetItemError(errorData, interstitial, _this6.schedule.findEventIndex(interstitial.identifier), assetListIndex, error.message);
25326
25349
  });
25327
25350
  this.hls.trigger(Events.INTERSTITIAL_ASSET_PLAYER_CREATED, {
25328
25351
  asset: assetItem,
@@ -25333,9 +25356,9 @@
25333
25356
  return player;
25334
25357
  };
25335
25358
  _proto.clearInterstitial = function clearInterstitial(interstitial, toSegment) {
25336
- var _this6 = this;
25359
+ var _this7 = this;
25337
25360
  interstitial.assetList.forEach(function (asset) {
25338
- _this6.clearAssetPlayer(asset.identifier, toSegment);
25361
+ _this7.clearAssetPlayer(asset.identifier, toSegment);
25339
25362
  });
25340
25363
  // Remove asset list and resolved duration
25341
25364
  interstitial.reset();
@@ -25383,12 +25406,10 @@
25383
25406
  }
25384
25407
 
25385
25408
  // detach media and attach to interstitial player if it does not have another element attached
25386
- if (!player.media) {
25387
- this.bufferAssetPlayer(player, media);
25388
- }
25409
+ this.bufferAssetPlayer(player, media);
25389
25410
  };
25390
25411
  _proto.bufferAssetPlayer = function bufferAssetPlayer(player, media) {
25391
- var _this$schedule$items2, _this$detachedData3;
25412
+ var _this$schedule$items2, _this$detachedData4;
25392
25413
  var interstitial = player.interstitial,
25393
25414
  assetItem = player.assetItem,
25394
25415
  assetId = player.assetId;
@@ -25403,8 +25424,13 @@
25403
25424
  if (bufferingPlayer === player) {
25404
25425
  return;
25405
25426
  }
25406
- var activeTracks = (bufferingPlayer == null ? void 0 : bufferingPlayer.tracks) || ((_this$detachedData3 = this.detachedData) == null ? void 0 : _this$detachedData3.tracks) || this.requiredTracks;
25407
- if (interstitial.appendInPlace && assetItem !== this.playingAsset) {
25427
+ var appendInPlaceNext = interstitial.appendInPlace;
25428
+ if (appendInPlaceNext && (bufferingPlayer == null ? void 0 : bufferingPlayer.interstitial.appendInPlace) === false) {
25429
+ // Media is detached and not available to append in place
25430
+ return;
25431
+ }
25432
+ var activeTracks = (bufferingPlayer == null ? void 0 : bufferingPlayer.tracks) || ((_this$detachedData4 = this.detachedData) == null ? void 0 : _this$detachedData4.tracks) || this.requiredTracks;
25433
+ if (appendInPlaceNext && assetItem !== this.playingAsset) {
25408
25434
  // Do not buffer another item if tracks are unknown or incompatible
25409
25435
  if (!player.tracks) {
25410
25436
  return;
@@ -25478,7 +25504,6 @@
25478
25504
  if (playingItem) {
25479
25505
  this.log("Fallback to primary from event \"" + interstitial.identifier + "\" start: " + flushStart + " pos: " + this.timelinePos + " playing: " + (playingItem ? segmentToString(playingItem) : '<none>') + " error: " + interstitial.error);
25480
25506
  if (interstitial.appendInPlace) {
25481
- interstitial.appendInPlace = false;
25482
25507
  this.attachPrimary(flushStart, null);
25483
25508
  this.flushFrontBuffer(flushStart);
25484
25509
  }
@@ -25490,6 +25515,8 @@
25490
25515
  if (!this.itemsMatch(playingItem, newPlayingItem)) {
25491
25516
  var scheduleIndex = this.schedule.findItemIndexAtTime(timelinePos);
25492
25517
  this.setSchedulePosition(scheduleIndex);
25518
+ } else {
25519
+ this.clearInterstitial(interstitial, null);
25493
25520
  }
25494
25521
  } else {
25495
25522
  this.checkStart();
@@ -25499,7 +25526,7 @@
25499
25526
  // Asset List loading
25500
25527
  ;
25501
25528
  _proto.onAssetListLoaded = function onAssetListLoaded(event, data) {
25502
- var _this7 = this,
25529
+ var _this8 = this,
25503
25530
  _this$bufferingItem;
25504
25531
  var interstitial = data.event;
25505
25532
  var interstitialId = interstitial.identifier;
@@ -25512,7 +25539,7 @@
25512
25539
  var sumDuration = 0;
25513
25540
  assets.forEach(function (asset, assetListIndex) {
25514
25541
  var duration = parseFloat(asset.DURATION);
25515
- _this7.createAsset(interstitial, assetListIndex, sumDuration, eventStart + sumDuration, duration, asset.URI);
25542
+ _this8.createAsset(interstitial, assetListIndex, sumDuration, eventStart + sumDuration, duration, asset.URI);
25516
25543
  sumDuration += duration;
25517
25544
  });
25518
25545
  interstitial.duration = sumDuration;
@@ -25900,8 +25927,8 @@
25900
25927
  }, {
25901
25928
  key: "primaryMedia",
25902
25929
  get: function get() {
25903
- var _this$detachedData4;
25904
- return this.media || ((_this$detachedData4 = this.detachedData) == null ? void 0 : _this$detachedData4.media) || null;
25930
+ var _this$detachedData5;
25931
+ return this.media || ((_this$detachedData5 = this.detachedData) == null ? void 0 : _this$detachedData5.media) || null;
25905
25932
  }
25906
25933
  }, {
25907
25934
  key: "playbackDisabled",
@@ -26251,21 +26278,22 @@
26251
26278
  } else {
26252
26279
  foundFrag = fragments[fragLen - 1];
26253
26280
  }
26281
+ foundFrag = this.filterReplacedPrimary(foundFrag, track.details);
26254
26282
  if (!foundFrag) {
26255
26283
  return;
26256
26284
  }
26257
- foundFrag = this.mapToInitFragWhenRequired(foundFrag);
26258
- if (isMediaFragment(foundFrag)) {
26259
- // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
26260
- var curSNIdx = foundFrag.sn - trackDetails.startSN;
26261
- var prevFrag = fragments[curSNIdx - 1];
26262
- if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
26263
- foundFrag = prevFrag;
26264
- }
26285
+ // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
26286
+ var curSNIdx = foundFrag.sn - trackDetails.startSN;
26287
+ var prevFrag = fragments[curSNIdx - 1];
26288
+ if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
26289
+ foundFrag = prevFrag;
26265
26290
  }
26266
26291
  if (this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
26267
26292
  // only load if fragment is not loaded
26268
- this.loadFragment(foundFrag, track, targetBufferTime);
26293
+ var fragToLoad = this.mapToInitFragWhenRequired(foundFrag);
26294
+ if (fragToLoad) {
26295
+ this.loadFragment(fragToLoad, track, targetBufferTime);
26296
+ }
26269
26297
  }
26270
26298
  }
26271
26299
  };