hls.js 1.6.0-beta.2.0.canary.10925 → 1.6.0-beta.2.0.canary.10928

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.
@@ -12,7 +12,7 @@ import type { InFlightData } from './base-stream-controller';
12
12
  import type { InFlightFragments } from '../hls';
13
13
  import type Hls from '../hls';
14
14
  import type { FragmentTracker } from './fragment-tracker';
15
- import type { Fragment } from '../loader/fragment';
15
+ import type { Fragment, MediaFragment } from '../loader/fragment';
16
16
  import type { SourceBufferName } from '../types/buffer';
17
17
  import type {
18
18
  BufferAppendedData,
@@ -503,7 +503,7 @@ export default class GapController extends TaskLoop {
503
503
  * @param partial - The partial fragment found at the current time (where playback is stalling).
504
504
  * @private
505
505
  */
506
- private _trySkipBufferHole(partial: Fragment | null): number {
506
+ private _trySkipBufferHole(partial: MediaFragment | null): number {
507
507
  const { fragmentTracker, media } = this;
508
508
  const config = this.hls?.config;
509
509
  if (!media || !fragmentTracker || !config) {
@@ -515,7 +515,7 @@ export default class GapController extends TaskLoop {
515
515
  const bufferInfo = BufferHelper.bufferInfo(media, currentTime, 0);
516
516
  const startTime =
517
517
  currentTime < bufferInfo.start ? bufferInfo.start : bufferInfo.nextStart;
518
- if (startTime) {
518
+ if (startTime && this.hls) {
519
519
  const bufferStarved = bufferInfo.len <= config.maxBufferHole;
520
520
  const waiting =
521
521
  bufferInfo.len > 0 && bufferInfo.len < 1 && media.readyState < 3;
@@ -541,6 +541,19 @@ export default class GapController extends TaskLoop {
541
541
  PlaylistLevelType.MAIN,
542
542
  );
543
543
  if (startProvisioned) {
544
+ // Do not seek when selected variant playlist is unloaded
545
+ if (!this.hls.loadLevelObj?.details) {
546
+ return 0;
547
+ }
548
+ // Do not seek when required fragments are inflight or appending
549
+ const inFlightDependency = getInFlightDependency(
550
+ this.hls.inFlightFragments,
551
+ startTime,
552
+ );
553
+ if (inFlightDependency) {
554
+ return 0;
555
+ }
556
+ // Do not seek if we can't walk tracked fragments to end of gap
544
557
  let moreToLoad = false;
545
558
  let pos = startProvisioned.end;
546
559
  while (pos < startTime) {
@@ -567,7 +580,7 @@ export default class GapController extends TaskLoop {
567
580
  );
568
581
  this.moved = true;
569
582
  media.currentTime = targetTime;
570
- if (!partial?.gap && this.hls) {
583
+ if (!partial?.gap) {
571
584
  const error = new Error(
572
585
  `fragment loaded with buffer holes, seeking from ${currentTime} to ${targetTime}`,
573
586
  );
@@ -1921,7 +1921,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
1921
1921
  const userConfig = primary.userConfig;
1922
1922
  let videoPreference = userConfig.videoPreference;
1923
1923
  const currentLevel =
1924
- primary.levels[primary.loadLevel] || primary.levels[primary.currentLevel];
1924
+ primary.loadLevelObj || primary.levels[primary.currentLevel];
1925
1925
  if (videoPreference || currentLevel) {
1926
1926
  videoPreference = Object.assign({}, videoPreference);
1927
1927
  if (currentLevel.videoCodec) {
@@ -389,6 +389,10 @@ export default class LevelController extends BasePlaylistController {
389
389
  return this._levels;
390
390
  }
391
391
 
392
+ get loadLevelObj(): Level | null {
393
+ return this.currentLevel;
394
+ }
395
+
392
396
  get level(): number {
393
397
  return this.currentLevelIndex;
394
398
  }
@@ -237,7 +237,7 @@ export default class StreamController
237
237
 
238
238
  protected onTickEnd() {
239
239
  super.onTickEnd();
240
- if (this.media?.readyState) {
240
+ if (this.media?.readyState && this.media.seeking === false) {
241
241
  this.lastCurrentTime = this.media.currentTime;
242
242
  }
243
243
  this.checkFragmentChanged();
package/src/hls.ts CHANGED
@@ -690,10 +690,20 @@ export default class Hls implements HlsEventEmitter {
690
690
  return levels ? levels : [];
691
691
  }
692
692
 
693
+ /**
694
+ * @returns LevelDetails of last loaded level (variant) or `null` prior to loading a media playlist.
695
+ */
693
696
  get latestLevelDetails(): LevelDetails | null {
694
697
  return this.streamController.getLevelDetails() || null;
695
698
  }
696
699
 
700
+ /**
701
+ * @returns Level object of selected level (variant) or `null` prior to selecting a level or once the level is removed.
702
+ */
703
+ get loadLevelObj(): Level | null {
704
+ return this.levelController.loadLevelObj;
705
+ }
706
+
697
707
  /**
698
708
  * Index of quality level (variant) currently played
699
709
  */
@@ -502,5 +502,5 @@ export function useAlternateAudio(
502
502
  audioTrackUrl: string | undefined,
503
503
  hls: Hls,
504
504
  ): boolean {
505
- return !!audioTrackUrl && audioTrackUrl !== hls.levels[hls.loadLevel]?.uri;
505
+ return !!audioTrackUrl && audioTrackUrl !== hls.loadLevelObj?.uri;
506
506
  }