hls.js 1.6.0-beta.4.0.canary.11043 → 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.mjs CHANGED
@@ -402,7 +402,7 @@ function enableLogs(debugConfig, context, id) {
402
402
  // Some browsers don't allow to use bind on console object anyway
403
403
  // fallback to default if needed
404
404
  try {
405
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.4.0.canary.11043"}`);
405
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.4.0.canary.11045"}`);
406
406
  } catch (e) {
407
407
  /* log fn threw an exception. All logger methods are no-ops. */
408
408
  return createLogger();
@@ -7955,15 +7955,12 @@ function findPart(partList, sn, partIndex) {
7955
7955
  function reassignFragmentLevelIndexes(levels) {
7956
7956
  levels.forEach((level, index) => {
7957
7957
  var _level$details;
7958
- const fragments = (_level$details = level.details) == null ? void 0 : _level$details.fragments;
7959
- if (fragments) {
7960
- fragments.forEach(fragment => {
7961
- fragment.level = index;
7962
- if (fragment.initSegment) {
7963
- fragment.initSegment.level = index;
7964
- }
7965
- });
7966
- }
7958
+ (_level$details = level.details) == null ? void 0 : _level$details.fragments.forEach(fragment => {
7959
+ fragment.level = index;
7960
+ if (fragment.initSegment) {
7961
+ fragment.initSegment.level = index;
7962
+ }
7963
+ });
7967
7964
  });
7968
7965
  }
7969
7966
 
@@ -8374,6 +8371,7 @@ class BaseStreamController extends TaskLoop {
8374
8371
  this.media = this.mediaBuffer = null;
8375
8372
  this.loopSn = undefined;
8376
8373
  if (transferringMedia) {
8374
+ this.resetLoadingState();
8377
8375
  this.resetTransmuxer();
8378
8376
  return;
8379
8377
  }
@@ -8416,42 +8414,6 @@ class BaseStreamController extends TaskLoop {
8416
8414
  super.onHandlerDestroyed();
8417
8415
  }
8418
8416
  loadFragment(frag, level, targetBufferTime) {
8419
- const config = this.hls.config;
8420
- if (config.interstitialsController && config.enableInterstitialPlayback !== false && frag.type !== PlaylistLevelType.SUBTITLE) {
8421
- // Do not load fragments outside the buffering schedule segment
8422
- const interstitials = this.hls.interstitialsManager;
8423
- const bufferingItem = interstitials == null ? void 0 : interstitials.bufferingItem;
8424
- if (bufferingItem) {
8425
- const bufferingInterstitial = bufferingItem.event;
8426
- if (bufferingInterstitial) {
8427
- // Do not stream fragments while buffering Interstitial Events (except for overlap at the start)
8428
- if (bufferingInterstitial.appendInPlace || Math.abs(frag.start - bufferingItem.start) > 1 || bufferingItem.start === 0) {
8429
- return;
8430
- }
8431
- } else {
8432
- var _level$details;
8433
- // Limit fragment loading to media in schedule item
8434
- if (frag.end <= bufferingItem.start && ((_level$details = level.details) == null ? void 0 : _level$details.live) === false) {
8435
- // fragment ends by schedule item start
8436
- return;
8437
- }
8438
- if (frag.start > bufferingItem.end && bufferingItem.nextEvent) {
8439
- // fragment is past schedule item end
8440
- return;
8441
- }
8442
- }
8443
- }
8444
- // Skip loading of fragments that overlap completely with appendInPlace interstitials
8445
- const playerQueue = interstitials == null ? void 0 : interstitials.playerQueue;
8446
- if (playerQueue) {
8447
- for (let i = playerQueue.length; i--;) {
8448
- const interstitial = playerQueue[i].interstitial;
8449
- if (interstitial.appendInPlace && frag.start >= interstitial.startTime && frag.end <= interstitial.resumeTime) {
8450
- return;
8451
- }
8452
- }
8453
- }
8454
- }
8455
8417
  this.startFragRequested = true;
8456
8418
  this._loadFragForPlayback(frag, level, targetBufferTime);
8457
8419
  }
@@ -8800,9 +8762,9 @@ class BaseStreamController extends TaskLoop {
8800
8762
  }
8801
8763
  doFragPartsLoad(frag, fromPart, level, progressCallback) {
8802
8764
  return new Promise((resolve, reject) => {
8803
- var _level$details2;
8765
+ var _level$details;
8804
8766
  const partsLoaded = [];
8805
- const initialPartList = (_level$details2 = level.details) == null ? void 0 : _level$details2.partList;
8767
+ const initialPartList = (_level$details = level.details) == null ? void 0 : _level$details.partList;
8806
8768
  const loadPart = part => {
8807
8769
  this.fragmentLoader.loadPart(frag, part, progressCallback).then(partLoadedData => {
8808
8770
  partsLoaded[part.index] = partLoadedData;
@@ -9077,6 +9039,7 @@ class BaseStreamController extends TaskLoop {
9077
9039
  const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
9078
9040
  frag = this.getFragmentAtPosition(pos, end, levelDetails);
9079
9041
  }
9042
+ frag = this.filterReplacedPrimary(frag, levelDetails);
9080
9043
  return this.mapToInitFragWhenRequired(frag);
9081
9044
  }
9082
9045
  isLoopLoading(frag, targetBufferTime) {
@@ -9104,6 +9067,48 @@ class BaseStreamController extends TaskLoop {
9104
9067
  this.loopSn = undefined;
9105
9068
  return nextFragment;
9106
9069
  }
9070
+ filterReplacedPrimary(frag, details) {
9071
+ if (!frag) {
9072
+ return frag;
9073
+ }
9074
+ const config = this.hls.config;
9075
+ if (config.interstitialsController && config.enableInterstitialPlayback !== false && frag.type !== PlaylistLevelType.SUBTITLE) {
9076
+ // Do not load fragments outside the buffering schedule segment
9077
+ const interstitials = this.hls.interstitialsManager;
9078
+ const bufferingItem = interstitials == null ? void 0 : interstitials.bufferingItem;
9079
+ if (bufferingItem) {
9080
+ const bufferingInterstitial = bufferingItem.event;
9081
+ if (bufferingInterstitial) {
9082
+ // Do not stream fragments while buffering Interstitial Events (except for overlap at the start)
9083
+ if (bufferingInterstitial.appendInPlace || Math.abs(frag.start - bufferingItem.start) > 1 || bufferingItem.start === 0) {
9084
+ return null;
9085
+ }
9086
+ } else {
9087
+ // Limit fragment loading to media in schedule item
9088
+ if (frag.end <= bufferingItem.start && (details == null ? void 0 : details.live) === false) {
9089
+ // fragment ends by schedule item start
9090
+ // this.fragmentTracker.fragBuffered(frag, true);
9091
+ return null;
9092
+ }
9093
+ if (frag.start > bufferingItem.end && bufferingItem.nextEvent) {
9094
+ // fragment is past schedule item end
9095
+ return null;
9096
+ }
9097
+ }
9098
+ }
9099
+ // Skip loading of fragments that overlap completely with appendInPlace interstitials
9100
+ const playerQueue = interstitials == null ? void 0 : interstitials.playerQueue;
9101
+ if (playerQueue) {
9102
+ for (let i = playerQueue.length; i--;) {
9103
+ const interstitial = playerQueue[i].interstitial;
9104
+ if (interstitial.appendInPlace && frag.start >= interstitial.startTime && frag.end <= interstitial.resumeTime) {
9105
+ return null;
9106
+ }
9107
+ }
9108
+ }
9109
+ }
9110
+ return frag;
9111
+ }
9107
9112
  mapToInitFragWhenRequired(frag) {
9108
9113
  // If an initSegment is present, it must be buffered first
9109
9114
  if (frag != null && frag.initSegment && !(frag != null && frag.initSegment.data) && !this.bitrateTest) {
@@ -9968,7 +9973,7 @@ function requireEventemitter3 () {
9968
9973
  var eventemitter3Exports = requireEventemitter3();
9969
9974
  var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
9970
9975
 
9971
- const version = "1.6.0-beta.4.0.canary.11043";
9976
+ const version = "1.6.0-beta.4.0.canary.11045";
9972
9977
 
9973
9978
  // ensure the worker ends up in the bundle
9974
9979
  // If the worker should not be included this gets aliased to empty.js
@@ -17851,15 +17856,14 @@ class BufferController extends Logger {
17851
17856
  if (!media || !mediaSource) {
17852
17857
  return;
17853
17858
  }
17859
+ // once received, don't listen anymore to sourceopen event
17860
+ mediaSource.removeEventListener('sourceopen', this._onMediaSourceOpen);
17854
17861
  media.removeEventListener('emptied', this._onMediaEmptied);
17855
17862
  this.updateDuration();
17856
17863
  this.hls.trigger(Events.MEDIA_ATTACHED, {
17857
17864
  media,
17858
17865
  mediaSource: mediaSource
17859
17866
  });
17860
-
17861
- // once received, don't listen anymore to sourceopen event
17862
- mediaSource.removeEventListener('sourceopen', this._onMediaSourceOpen);
17863
17867
  if (this.mediaSource !== null) {
17864
17868
  this.checkPendingTracks();
17865
17869
  }
@@ -23036,6 +23040,7 @@ class HlsAssetPlayer {
23036
23040
  this.tracks = null;
23037
23041
  this.hasDetails = false;
23038
23042
  this.mediaAttached = null;
23043
+ this._currentTime = void 0;
23039
23044
  this.checkPlayout = () => {
23040
23045
  const interstitial = this.interstitial;
23041
23046
  const playoutLimit = interstitial.playoutLimit;
@@ -23089,7 +23094,7 @@ class HlsAssetPlayer {
23089
23094
  get bufferedEnd() {
23090
23095
  const media = this.media || this.mediaAttached;
23091
23096
  if (!media) {
23092
- return 0;
23097
+ return this.currentTime;
23093
23098
  }
23094
23099
  const bufferInfo = BufferHelper.bufferInfo(media, media.currentTime, 0.001);
23095
23100
  return this.getAssetTime(bufferInfo.end);
@@ -23097,7 +23102,7 @@ class HlsAssetPlayer {
23097
23102
  get currentTime() {
23098
23103
  const media = this.media || this.mediaAttached;
23099
23104
  if (!media) {
23100
- return 0;
23105
+ return this._currentTime || 0;
23101
23106
  }
23102
23107
  return this.getAssetTime(media.currentTime);
23103
23108
  }
@@ -23142,6 +23147,7 @@ class HlsAssetPlayer {
23142
23147
  removeMediaListeners() {
23143
23148
  const media = this.mediaAttached;
23144
23149
  if (media) {
23150
+ this._currentTime = media.currentTime;
23145
23151
  media.removeEventListener('timeupdate', this.checkPlayout);
23146
23152
  }
23147
23153
  }
@@ -23158,6 +23164,7 @@ class HlsAssetPlayer {
23158
23164
  }
23159
23165
  detachMedia() {
23160
23166
  this.removeMediaListeners();
23167
+ this.mediaAttached = null;
23161
23168
  this.hls.detachMedia();
23162
23169
  }
23163
23170
  resumeBuffering() {
@@ -23179,7 +23186,8 @@ class HlsAssetPlayer {
23179
23186
  this.hls.off(event, listener);
23180
23187
  }
23181
23188
  toString() {
23182
- return `HlsAssetPlayer: ${eventAssetToString(this.assetItem)} ${this.hls.sessionId} ${this.interstitial.appendInPlace ? 'append-in-place' : ''}`;
23189
+ var _this$hls4, _this$interstitial;
23190
+ return `HlsAssetPlayer: ${eventAssetToString(this.assetItem)} ${(_this$hls4 = this.hls) == null ? void 0 : _this$hls4.sessionId} ${(_this$interstitial = this.interstitial) != null && _this$interstitial.appendInPlace ? 'append-in-place' : ''}`;
23183
23191
  }
23184
23192
  }
23185
23193
 
@@ -23336,7 +23344,7 @@ class InterstitialsSchedule extends Logger {
23336
23344
  }
23337
23345
  return null;
23338
23346
  }
23339
- parseInterstitialDateRanges(mediaSelection) {
23347
+ parseInterstitialDateRanges(mediaSelection, enableAppendInPlace) {
23340
23348
  const details = mediaSelection.main.details;
23341
23349
  const {
23342
23350
  dateRanges
@@ -23344,7 +23352,7 @@ class InterstitialsSchedule extends Logger {
23344
23352
  const previousInterstitialEvents = this.events;
23345
23353
  const interstitialEvents = this.parseDateRanges(dateRanges, {
23346
23354
  url: details.url
23347
- });
23355
+ }, enableAppendInPlace);
23348
23356
  const ids = Object.keys(dateRanges);
23349
23357
  const removedInterstitials = previousInterstitialEvents ? previousInterstitialEvents.filter(event => !ids.includes(event.identifier)) : [];
23350
23358
  if (interstitialEvents.length) {
@@ -23400,7 +23408,7 @@ class InterstitialsSchedule extends Logger {
23400
23408
  }
23401
23409
  }
23402
23410
  }
23403
- parseDateRanges(dateRanges, baseData) {
23411
+ parseDateRanges(dateRanges, baseData, enableAppendInPlace) {
23404
23412
  const interstitialEvents = [];
23405
23413
  const ids = Object.keys(dateRanges);
23406
23414
  for (let i = 0; i < ids.length; i++) {
@@ -23415,6 +23423,9 @@ class InterstitialsSchedule extends Logger {
23415
23423
  } else {
23416
23424
  interstitial = new InterstitialEvent(dateRange, baseData);
23417
23425
  this.eventMap[id] = interstitial;
23426
+ if (enableAppendInPlace === false) {
23427
+ interstitial.appendInPlace = enableAppendInPlace;
23428
+ }
23418
23429
  }
23419
23430
  interstitialEvents.push(interstitial);
23420
23431
  }
@@ -23618,13 +23629,11 @@ class InterstitialsSchedule extends Logger {
23618
23629
  interstitial.appendInPlace = false;
23619
23630
  }
23620
23631
  }
23621
- if (!interstitial.appendInPlace) {
23632
+ if (!interstitial.appendInPlace && i + 1 < interstitialEvents.length) {
23622
23633
  // abutting Interstitials must use the same MediaSource strategy, this applies to all whether or not they are back to back:
23623
- for (let j = i - 1; i--;) {
23624
- const timeBetween = interstitialEvents[j + 1].startTime - interstitialEvents[j].resumeTime;
23625
- if (timeBetween < ABUTTING_THRESHOLD_SECONDS) {
23626
- interstitialEvents[j].appendInPlace = false;
23627
- }
23634
+ const timeBetween = interstitialEvents[i + 1].startTime - interstitialEvents[i].resumeTime;
23635
+ if (timeBetween < ABUTTING_THRESHOLD_SECONDS) {
23636
+ interstitialEvents[i + 1].appendInPlace = false;
23628
23637
  }
23629
23638
  }
23630
23639
  // Update cumulativeDuration for next abutting interstitial with the same start date
@@ -23951,9 +23960,6 @@ class InterstitialsController extends Logger {
23951
23960
  const removedIds = removedInterstitials.map(interstitial => interstitial.identifier);
23952
23961
  const interstitialsUpdated = !!(interstitialEvents.length || removedIds.length);
23953
23962
  if (interstitialsUpdated) {
23954
- if (this.hls.config.interstitialAppendInPlace === false) {
23955
- interstitialEvents.forEach(event => event.appendInPlace = false);
23956
- }
23957
23963
  this.log(`INTERSTITIALS_UPDATED (${interstitialEvents.length}): ${interstitialEvents}
23958
23964
  Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
23959
23965
  }
@@ -24083,10 +24089,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
24083
24089
  this.pauseBuffering();
24084
24090
  }
24085
24091
  resumeBuffering() {
24086
- this.playerQueue.forEach(player => player.resumeBuffering());
24092
+ var _this$getBufferingPla;
24093
+ (_this$getBufferingPla = this.getBufferingPlayer()) == null ? void 0 : _this$getBufferingPla.resumeBuffering();
24087
24094
  }
24088
24095
  pauseBuffering() {
24089
- this.playerQueue.forEach(player => player.pauseBuffering());
24096
+ var _this$getBufferingPla2;
24097
+ (_this$getBufferingPla2 = this.getBufferingPlayer()) == null ? void 0 : _this$getBufferingPla2.pauseBuffering();
24090
24098
  }
24091
24099
  destroy() {
24092
24100
  this.unregisterListeners();
@@ -24524,33 +24532,48 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
24524
24532
  }
24525
24533
  transferMediaTo(player, media) {
24526
24534
  var _this$detachedData2, _attachMediaSourceDat;
24535
+ if (player.media === media) {
24536
+ return;
24537
+ }
24527
24538
  let attachMediaSourceData = null;
24528
24539
  const primaryPlayer = this.hls;
24529
24540
  const isAssetPlayer = player !== primaryPlayer;
24530
24541
  const appendInPlace = isAssetPlayer && player.interstitial.appendInPlace;
24531
24542
  const detachedMediaSource = (_this$detachedData2 = this.detachedData) == null ? void 0 : _this$detachedData2.mediaSource;
24532
24543
  let logFromSource;
24533
- if (primaryPlayer.media && appendInPlace) {
24534
- attachMediaSourceData = primaryPlayer.transferMedia();
24535
- this.detachedData = attachMediaSourceData;
24544
+ if (primaryPlayer.media) {
24545
+ if (appendInPlace) {
24546
+ attachMediaSourceData = primaryPlayer.transferMedia();
24547
+ this.detachedData = attachMediaSourceData;
24548
+ }
24536
24549
  logFromSource = `Primary`;
24537
24550
  } else if (detachedMediaSource) {
24538
24551
  const bufferingPlayer = this.getBufferingPlayer();
24539
24552
  if (bufferingPlayer) {
24540
24553
  attachMediaSourceData = bufferingPlayer.transferMedia();
24554
+ logFromSource = `${bufferingPlayer}`;
24555
+ } else {
24556
+ logFromSource = `detached MediaSource`;
24541
24557
  }
24542
- logFromSource = `${bufferingPlayer}`;
24543
24558
  } else {
24544
- logFromSource = `<unknown>`;
24559
+ logFromSource = `detached media`;
24545
24560
  }
24546
- this.log(`transferring to ${isAssetPlayer ? player : 'Primary'}
24547
- MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24548
24561
  if (!attachMediaSourceData) {
24549
24562
  if (detachedMediaSource) {
24550
24563
  attachMediaSourceData = this.detachedData;
24551
24564
  this.log(`using detachedData: MediaSource ${stringify(attachMediaSourceData)}`);
24552
- } else if (!this.detachedData || this.hls.media === media) {
24553
- // Media is attaching when `detachedData` and `hls.media` are populated. Detach to clear the MediaSource.
24565
+ } else if (!this.detachedData || primaryPlayer.media === media) {
24566
+ // Keep interstitial media transition consistent
24567
+ const playerQueue = this.playerQueue;
24568
+ if (playerQueue.length > 1) {
24569
+ playerQueue.forEach(queuedPlayer => {
24570
+ if (isAssetPlayer && queuedPlayer.interstitial.appendInPlace !== appendInPlace) {
24571
+ const interstitial = queuedPlayer.interstitial;
24572
+ this.clearInterstitial(queuedPlayer.interstitial, null);
24573
+ interstitial.appendInPlace = false;
24574
+ }
24575
+ });
24576
+ }
24554
24577
  this.hls.detachMedia();
24555
24578
  this.detachedData = {
24556
24579
  media
@@ -24559,7 +24582,7 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24559
24582
  }
24560
24583
  const transferring = attachMediaSourceData && 'mediaSource' in attachMediaSourceData && ((_attachMediaSourceDat = attachMediaSourceData.mediaSource) == null ? void 0 : _attachMediaSourceDat.readyState) !== 'closed';
24561
24584
  const dataToAttach = transferring && attachMediaSourceData ? attachMediaSourceData : media;
24562
- this.log(`${transferring ? 'transfering MediaSource' : 'attaching media'} to ${isAssetPlayer ? player : 'Primary'}`);
24585
+ this.log(`${transferring ? 'transfering MediaSource' : 'attaching media'} to ${isAssetPlayer ? player : 'Primary'} from ${logFromSource}`);
24563
24586
  if (dataToAttach === attachMediaSourceData) {
24564
24587
  const isAssetAtEndOfSchedule = isAssetPlayer && player.assetId === this.schedule.assetIdAtEnd;
24565
24588
  // Prevent asset players from marking EoS on transferred MediaSource
@@ -24656,6 +24679,7 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24656
24679
  const assetId = playingAsset == null ? void 0 : playingAsset.identifier;
24657
24680
  const player = assetId ? this.getAssetPlayer(assetId) : null;
24658
24681
  if (player && assetId && (!this.eventItemsMatch(currentItem, scheduledItem) || assetListIndex !== undefined && assetId !== ((_interstitial$assetLi = interstitial.assetList) == null ? void 0 : _interstitial$assetLi[assetListIndex].identifier))) {
24682
+ var _this$detachedData3;
24659
24683
  const _assetListIndex = interstitial.findAssetIndex(playingAsset);
24660
24684
  this.log(`INTERSTITIAL_ASSET_ENDED ${_assetListIndex + 1}/${interstitial.assetList.length} ${eventAssetToString(playingAsset)}`);
24661
24685
  this.endedAsset = playingAsset;
@@ -24669,7 +24693,7 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24669
24693
  player
24670
24694
  });
24671
24695
  this.retreiveMediaSource(assetId, scheduledItem);
24672
- if (player.media && !this.detachedData) {
24696
+ if (player.media && !((_this$detachedData3 = this.detachedData) != null && _this$detachedData3.mediaSource)) {
24673
24697
  player.detachMedia();
24674
24698
  }
24675
24699
  }
@@ -24810,13 +24834,13 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24810
24834
  return !!((_this$primaryDetails = this.primaryDetails) != null && _this$primaryDetails.live);
24811
24835
  }
24812
24836
  resumePrimary(scheduledItem, index, fromItem) {
24813
- var _this$detachedData3;
24837
+ var _this$detachedData4;
24814
24838
  this.playingItem = scheduledItem;
24815
24839
  this.playingAsset = this.endedAsset = null;
24816
24840
  this.waitingItem = this.endedItem = null;
24817
24841
  this.bufferedToItem(scheduledItem);
24818
24842
  this.log(`resuming ${segmentToString(scheduledItem)}`);
24819
- if (!((_this$detachedData3 = this.detachedData) != null && _this$detachedData3.mediaSource)) {
24843
+ if (!((_this$detachedData4 = this.detachedData) != null && _this$detachedData4.mediaSource)) {
24820
24844
  let timelinePos = this.timelinePos;
24821
24845
  if (timelinePos < scheduledItem.start || timelinePos >= scheduledItem.end) {
24822
24846
  timelinePos = this.getPrimaryResumption(scheduledItem, index);
@@ -24917,7 +24941,7 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24917
24941
  main
24918
24942
  });
24919
24943
  this.mediaSelection = currentSelection;
24920
- this.schedule.parseInterstitialDateRanges(currentSelection);
24944
+ this.schedule.parseInterstitialDateRanges(currentSelection, this.hls.config.interstitialAppendInPlace);
24921
24945
  if (!this.effectivePlayingItem && this.schedule.items) {
24922
24946
  this.checkStart();
24923
24947
  }
@@ -24999,6 +25023,8 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
24999
25023
  if (!this.playingLastItem && playingItem) {
25000
25024
  const playingIndex = this.findItemIndex(playingItem);
25001
25025
  this.setSchedulePosition(playingIndex + 1);
25026
+ } else {
25027
+ this.shouldPlay = false;
25002
25028
  }
25003
25029
  }
25004
25030
  updateItem(previousItem, time) {
@@ -25167,16 +25193,16 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
25167
25193
  }
25168
25194
  }
25169
25195
  preloadAssets(interstitial, assetListIndex) {
25196
+ const uri = interstitial.assetUrl;
25170
25197
  const assetListLength = interstitial.assetList.length;
25171
25198
  const neverLoaded = assetListLength === 0 && !interstitial.assetListLoader;
25172
25199
  const playOnce = interstitial.cue.once;
25173
25200
  if (neverLoaded) {
25174
- this.log(`Load interstitial asset ${assetListIndex + 1}/${assetListLength} ${interstitial}`);
25201
+ this.log(`Load interstitial asset ${assetListIndex + 1}/${uri ? 1 : assetListLength} ${interstitial}`);
25175
25202
  const timelineStart = interstitial.timelineStart;
25176
25203
  if (interstitial.appendInPlace) {
25177
25204
  this.flushFrontBuffer(timelineStart + 0.25);
25178
25205
  }
25179
- const uri = interstitial.assetUrl;
25180
25206
  if (uri) {
25181
25207
  return this.createAsset(interstitial, 0, 0, timelineStart, interstitial.duration, uri);
25182
25208
  }
@@ -25474,12 +25500,10 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
25474
25500
  }
25475
25501
 
25476
25502
  // detach media and attach to interstitial player if it does not have another element attached
25477
- if (!player.media) {
25478
- this.bufferAssetPlayer(player, media);
25479
- }
25503
+ this.bufferAssetPlayer(player, media);
25480
25504
  }
25481
25505
  bufferAssetPlayer(player, media) {
25482
- var _this$schedule$items4, _this$detachedData4;
25506
+ var _this$schedule$items4, _this$detachedData5;
25483
25507
  const {
25484
25508
  interstitial,
25485
25509
  assetItem,
@@ -25496,8 +25520,13 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
25496
25520
  if (bufferingPlayer === player) {
25497
25521
  return;
25498
25522
  }
25499
- const activeTracks = (bufferingPlayer == null ? void 0 : bufferingPlayer.tracks) || ((_this$detachedData4 = this.detachedData) == null ? void 0 : _this$detachedData4.tracks) || this.requiredTracks;
25500
- if (interstitial.appendInPlace && assetItem !== this.playingAsset) {
25523
+ const appendInPlaceNext = interstitial.appendInPlace;
25524
+ if (appendInPlaceNext && (bufferingPlayer == null ? void 0 : bufferingPlayer.interstitial.appendInPlace) === false) {
25525
+ // Media is detached and not available to append in place
25526
+ return;
25527
+ }
25528
+ const activeTracks = (bufferingPlayer == null ? void 0 : bufferingPlayer.tracks) || ((_this$detachedData5 = this.detachedData) == null ? void 0 : _this$detachedData5.tracks) || this.requiredTracks;
25529
+ if (appendInPlaceNext && assetItem !== this.playingAsset) {
25501
25530
  // Do not buffer another item if tracks are unknown or incompatible
25502
25531
  if (!player.tracks) {
25503
25532
  return;
@@ -25569,7 +25598,6 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
25569
25598
  if (playingItem) {
25570
25599
  this.log(`Fallback to primary from event "${interstitial.identifier}" start: ${flushStart} pos: ${this.timelinePos} playing: ${playingItem ? segmentToString(playingItem) : '<none>'} error: ${interstitial.error}`);
25571
25600
  if (interstitial.appendInPlace) {
25572
- interstitial.appendInPlace = false;
25573
25601
  this.attachPrimary(flushStart, null);
25574
25602
  this.flushFrontBuffer(flushStart);
25575
25603
  }
@@ -25581,6 +25609,8 @@ MediaSource ${stringify(attachMediaSourceData)} from ${logFromSource}`);
25581
25609
  if (!this.itemsMatch(playingItem, newPlayingItem)) {
25582
25610
  const scheduleIndex = this.schedule.findItemIndexAtTime(timelinePos);
25583
25611
  this.setSchedulePosition(scheduleIndex);
25612
+ } else {
25613
+ this.clearInterstitial(interstitial, null);
25584
25614
  }
25585
25615
  } else {
25586
25616
  this.checkStart();
@@ -25985,21 +26015,22 @@ class SubtitleStreamController extends BaseStreamController {
25985
26015
  } else {
25986
26016
  foundFrag = fragments[fragLen - 1];
25987
26017
  }
26018
+ foundFrag = this.filterReplacedPrimary(foundFrag, track.details);
25988
26019
  if (!foundFrag) {
25989
26020
  return;
25990
26021
  }
25991
- foundFrag = this.mapToInitFragWhenRequired(foundFrag);
25992
- if (isMediaFragment(foundFrag)) {
25993
- // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
25994
- const curSNIdx = foundFrag.sn - trackDetails.startSN;
25995
- const prevFrag = fragments[curSNIdx - 1];
25996
- if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
25997
- foundFrag = prevFrag;
25998
- }
26022
+ // Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
26023
+ const curSNIdx = foundFrag.sn - trackDetails.startSN;
26024
+ const prevFrag = fragments[curSNIdx - 1];
26025
+ if (prevFrag && prevFrag.cc === foundFrag.cc && this.fragmentTracker.getState(prevFrag) === FragmentState.NOT_LOADED) {
26026
+ foundFrag = prevFrag;
25999
26027
  }
26000
26028
  if (this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED) {
26001
26029
  // only load if fragment is not loaded
26002
- this.loadFragment(foundFrag, track, targetBufferTime);
26030
+ const fragToLoad = this.mapToInitFragWhenRequired(foundFrag);
26031
+ if (fragToLoad) {
26032
+ this.loadFragment(fragToLoad, track, targetBufferTime);
26033
+ }
26003
26034
  }
26004
26035
  }
26005
26036
  }