hls.js 1.6.0-beta.1.0.canary.10786 → 1.6.0-beta.1.0.canary.10788

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.
@@ -56,8 +56,9 @@ class AudioStreamController
56
56
  extends BaseStreamController
57
57
  implements NetworkComponentAPI
58
58
  {
59
- private videoAnchor: MediaFragment | null = null;
59
+ private mainAnchor: MediaFragment | null = null;
60
60
  private mainFragLoading: FragLoadingData | null = null;
61
+ private audioOnly: boolean = false;
61
62
  private bufferedTrack: MediaPlaylist | null = null;
62
63
  private switchingTrack: MediaPlaylist | null = null;
63
64
  private trackId: number = -1;
@@ -85,9 +86,18 @@ class AudioStreamController
85
86
  protected onHandlerDestroying() {
86
87
  this.unregisterListeners();
87
88
  super.onHandlerDestroying();
88
- this.mainDetails = null;
89
- this.bufferedTrack = null;
90
- this.switchingTrack = null;
89
+ this.resetItem();
90
+ }
91
+
92
+ private resetItem() {
93
+ this.mainDetails =
94
+ this.mainAnchor =
95
+ this.mainFragLoading =
96
+ this.bufferedTrack =
97
+ this.switchingTrack =
98
+ this.waitingData =
99
+ this.cachedTrackLoadedData =
100
+ null;
91
101
  }
92
102
 
93
103
  protected registerListeners() {
@@ -139,7 +149,7 @@ class AudioStreamController
139
149
  this.log(
140
150
  `InitPTS for cc: ${cc} found from main: ${initPTS}/${timescale}`,
141
151
  );
142
- this.videoAnchor = frag;
152
+ this.mainAnchor = frag;
143
153
  // If we are waiting, tick immediately to unblock audio fragment transmuxing
144
154
  if (this.state === State.WAITING_INIT_PTS) {
145
155
  const waitingData = this.waitingData;
@@ -237,7 +247,7 @@ class AudioStreamController
237
247
  const waitingData = this.waitingData;
238
248
  if (waitingData) {
239
249
  const { frag, part, cache, complete } = waitingData;
240
- const videoAnchor = this.videoAnchor;
250
+ const mainAnchor = this.mainAnchor;
241
251
  if (this.initPTS[frag.cc] !== undefined) {
242
252
  this.waitingData = null;
243
253
  this.state = State.FRAG_LOADING;
@@ -252,12 +262,12 @@ class AudioStreamController
252
262
  if (complete) {
253
263
  super._handleFragmentLoadComplete(data);
254
264
  }
255
- } else if (videoAnchor && videoAnchor.cc !== waitingData.frag.cc) {
265
+ } else if (mainAnchor && mainAnchor.cc !== waitingData.frag.cc) {
256
266
  // Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
257
267
  this.log(
258
- `Waiting fragment cc (${frag.cc}) cancelled because video is at cc ${videoAnchor.cc}`,
268
+ `Waiting fragment cc (${frag.cc}) cancelled because video is at cc ${mainAnchor.cc}`,
259
269
  );
260
- this.nextLoadPosition = this.findSyncFrag(videoAnchor).start;
270
+ this.nextLoadPosition = this.findSyncFrag(mainAnchor).start;
261
271
  this.clearWaitingFragment();
262
272
  }
263
273
  } else {
@@ -412,6 +422,7 @@ class AudioStreamController
412
422
  // Request audio segments up to one fragment ahead of main stream-controller
413
423
  const mainFragLoading = this.mainFragLoading?.frag;
414
424
  if (
425
+ !this.audioOnly &&
415
426
  this.startFragRequested &&
416
427
  mainFragLoading &&
417
428
  isMediaFragment(mainFragLoading) &&
@@ -498,14 +509,8 @@ class AudioStreamController
498
509
 
499
510
  protected onManifestLoading() {
500
511
  super.onManifestLoading();
501
- this.bufferFlushed = this.flushing = false;
502
- this.mainDetails =
503
- this.waitingData =
504
- this.videoAnchor =
505
- this.bufferedTrack =
506
- this.cachedTrackLoadedData =
507
- this.switchingTrack =
508
- null;
512
+ this.bufferFlushed = this.flushing = this.audioOnly = false;
513
+ this.resetItem();
509
514
  this.trackId = -1;
510
515
  }
511
516
 
@@ -524,10 +529,11 @@ class AudioStreamController
524
529
  ) {
525
530
  const { levels } = this;
526
531
  const { details: newDetails, id: trackId } = data;
532
+ const mainDetails = this.mainDetails;
527
533
  if (
528
- this.mainDetails == null ||
529
- this.mainDetails.expired ||
530
- newDetails.endCC > this.mainDetails.endCC
534
+ !mainDetails ||
535
+ mainDetails.expired ||
536
+ newDetails.endCC > mainDetails.endCC
531
537
  ) {
532
538
  this.cachedTrackLoadedData = data;
533
539
  if (this.state !== State.STOPPED) {
@@ -553,8 +559,7 @@ class AudioStreamController
553
559
  let sliding = 0;
554
560
  if (newDetails.live || track.details?.live) {
555
561
  this.checkLiveUpdate(newDetails);
556
- const mainDetails = this.mainDetails;
557
- if (newDetails.deltaUpdateFailed || !mainDetails) {
562
+ if (newDetails.deltaUpdateFailed) {
558
563
  return;
559
564
  }
560
565
 
@@ -579,8 +584,8 @@ class AudioStreamController
579
584
  this.levelLastLoaded = track;
580
585
 
581
586
  // compute start position if we are aligned with the main playlist
582
- if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) {
583
- this.setStartPosition(this.mainDetails || newDetails, sliding);
587
+ if (!this.startFragRequested) {
588
+ this.setStartPosition(mainDetails, sliding);
584
589
  }
585
590
 
586
591
  this.hls.trigger(Events.AUDIO_TRACK_UPDATED, {
@@ -709,6 +714,7 @@ class AudioStreamController
709
714
 
710
715
  private onFragLoading(event: Events.FRAG_LOADING, data: FragLoadingData) {
711
716
  if (
717
+ !this.audioOnly &&
712
718
  data.frag.type === PlaylistLevelType.MAIN &&
713
719
  isMediaFragment(data.frag)
714
720
  ) {
@@ -722,6 +728,15 @@ class AudioStreamController
722
728
  private onFragBuffered(event: Events.FRAG_BUFFERED, data: FragBufferedData) {
723
729
  const { frag, part } = data;
724
730
  if (frag.type !== PlaylistLevelType.AUDIO) {
731
+ if (
732
+ !this.audioOnly &&
733
+ frag.type === PlaylistLevelType.MAIN &&
734
+ !frag.elementaryStreams.video &&
735
+ !frag.elementaryStreams.audiovideo
736
+ ) {
737
+ this.audioOnly = true;
738
+ this.mainFragLoading = null;
739
+ }
725
740
  return;
726
741
  }
727
742
  if (this.fragContextChanged(frag)) {
@@ -425,15 +425,14 @@ export function adjustSliding(
425
425
  let sliding = 0;
426
426
  if (advancedOrStable && delta < oldFragments.length) {
427
427
  sliding = oldFragments[delta].start;
428
+ } else if (advancedOrStable && newDetails.startSN === oldDetails.endSN + 1) {
429
+ sliding = oldDetails.fragmentEnd;
428
430
  } else if (advancedOrStable && matchingStableVariantOrRendition) {
429
- // align new start with old end (updated playlist start sequence is past end sequence of last update)
430
- sliding = oldDetails.edge;
431
- } else if (
432
- !newDetails.skippedSegments &&
433
- newDetails.fragments[0].start === 0
434
- ) {
431
+ // align with expected position (updated playlist start sequence is past end sequence of last update)
432
+ sliding = oldDetails.fragmentStart + delta * newDetails.levelTargetDuration;
433
+ } else if (!newDetails.skippedSegments && newDetails.fragmentStart === 0) {
435
434
  // align new start with old (playlist switch has a sequence with no overlap and should not be used for alignment)
436
- sliding = oldDetails.fragments[0].start;
435
+ sliding = oldDetails.fragmentStart;
437
436
  } else {
438
437
  // new details already has a sliding offset or has skipped segments
439
438
  return;