hls.js 1.6.0-beta.1.0.canary.10772 → 1.6.0-beta.1.0.canary.10775

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.
@@ -9,7 +9,10 @@ import { ElementaryStreamTypes, isMediaFragment } from '../loader/fragment';
9
9
  import { Level } from '../types/level';
10
10
  import { PlaylistContextType, PlaylistLevelType } from '../types/loader';
11
11
  import { ChunkMetadata } from '../types/transmuxer';
12
- import { alignMediaPlaylistByPDT } from '../utils/discontinuities';
12
+ import {
13
+ alignDiscontinuities,
14
+ alignMediaPlaylistByPDT,
15
+ } from '../utils/discontinuities';
13
16
  import { mediaAttributesIdentical } from '../utils/media-option-attributes';
14
17
  import type { FragmentTracker } from './fragment-tracker';
15
18
  import type Hls from '../hls';
@@ -257,7 +260,7 @@ class AudioStreamController
257
260
  this.nextLoadPosition = this.findSyncFrag(videoAnchor).start;
258
261
  this.clearWaitingFragment();
259
262
  }
260
- } else if (this.state !== State.STOPPED) {
263
+ } else {
261
264
  this.state = State.IDLE;
262
265
  }
263
266
  }
@@ -508,9 +511,10 @@ class AudioStreamController
508
511
 
509
512
  private onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData) {
510
513
  this.mainDetails = data.details;
511
- if (this.cachedTrackLoadedData !== null) {
512
- this.hls.trigger(Events.AUDIO_TRACK_LOADED, this.cachedTrackLoadedData);
514
+ const cachedTrackLoadedData = this.cachedTrackLoadedData;
515
+ if (cachedTrackLoadedData) {
513
516
  this.cachedTrackLoadedData = null;
517
+ this.hls.trigger(Events.AUDIO_TRACK_LOADED, cachedTrackLoadedData);
514
518
  }
515
519
  }
516
520
 
@@ -518,12 +522,19 @@ class AudioStreamController
518
522
  event: Events.AUDIO_TRACK_LOADED,
519
523
  data: TrackLoadedData,
520
524
  ) {
521
- if (this.mainDetails == null) {
525
+ const { levels } = this;
526
+ const { details: newDetails, id: trackId } = data;
527
+ if (
528
+ this.mainDetails == null ||
529
+ this.mainDetails.expired ||
530
+ newDetails.endCC > this.mainDetails.endCC
531
+ ) {
522
532
  this.cachedTrackLoadedData = data;
533
+ if (this.state !== State.STOPPED) {
534
+ this.state = State.WAITING_TRACK;
535
+ }
523
536
  return;
524
537
  }
525
- const { levels } = this;
526
- const { details: newDetails, id: trackId } = data;
527
538
  if (!levels) {
528
539
  this.warn(`Audio tracks were reset while loading level ${trackId}`);
529
540
  return;
@@ -546,22 +557,23 @@ class AudioStreamController
546
557
  if (newDetails.deltaUpdateFailed || !mainDetails) {
547
558
  return;
548
559
  }
549
- if (
550
- !track.details &&
551
- newDetails.hasProgramDateTime &&
552
- mainDetails.hasProgramDateTime
553
- ) {
554
- // Make sure our audio rendition is aligned with the "main" rendition, using
555
- // pdt as our reference times.
556
- alignMediaPlaylistByPDT(newDetails, mainDetails);
557
- sliding = newDetails.fragmentStart;
558
- } else {
560
+
561
+ if (track.details) {
559
562
  sliding = this.alignPlaylists(
560
563
  newDetails,
561
564
  track.details,
562
565
  this.levelLastLoaded?.details,
563
566
  );
564
567
  }
568
+ if (!newDetails.alignedSliding) {
569
+ // Align audio rendition with the "main" playlist on discontinuity change
570
+ // or program-date-time (PDT)
571
+ alignDiscontinuities(newDetails, mainDetails);
572
+ if (!newDetails.alignedSliding) {
573
+ alignMediaPlaylistByPDT(newDetails, mainDetails);
574
+ }
575
+ sliding = newDetails.fragmentStart;
576
+ }
565
577
  }
566
578
  track.details = newDetails;
567
579
  this.levelLastLoaded = track;
@@ -665,7 +677,9 @@ class AudioStreamController
665
677
  complete: false,
666
678
  });
667
679
  cache.push(new Uint8Array(payload));
668
- this.state = State.WAITING_INIT_PTS;
680
+ if (this.state !== State.STOPPED) {
681
+ this.state = State.WAITING_INIT_PTS;
682
+ }
669
683
  }
670
684
  }
671
685
 
@@ -1593,15 +1593,12 @@ export default class BaseStreamController
1593
1593
  const firstLevelLoad = !previousDetails;
1594
1594
  const aligned = details.alignedSliding && Number.isFinite(slidingStart);
1595
1595
  if (firstLevelLoad || (!aligned && !slidingStart)) {
1596
- const { fragPrevious } = this;
1597
- alignStream(fragPrevious, switchDetails, details);
1596
+ alignStream(switchDetails, details);
1598
1597
  const alignedSlidingStart = details.fragmentStart;
1599
1598
  this.log(
1600
1599
  `Live playlist sliding: ${alignedSlidingStart.toFixed(2)} start-sn: ${
1601
1600
  previousDetails ? previousDetails.startSN : 'na'
1602
- }->${details.startSN} prev-sn: ${
1603
- fragPrevious ? fragPrevious.sn : 'na'
1604
- } fragments: ${length}`,
1601
+ }->${details.startSN} fragments: ${length}`,
1605
1602
  );
1606
1603
  return alignedSlidingStart;
1607
1604
  }
@@ -526,7 +526,7 @@ export default class M3U8Parser {
526
526
  }
527
527
 
528
528
  case 'DISCONTINUITY-SEQUENCE':
529
- discontinuityCounter = parseInt(value1);
529
+ level.startCC = discontinuityCounter = parseInt(value1);
530
530
  break;
531
531
  case 'KEY': {
532
532
  const levelKey = parseKey(value1, baseurl, level);
@@ -671,7 +671,7 @@ export default class M3U8Parser {
671
671
  if (!level.live) {
672
672
  lastFragment.endList = true;
673
673
  }
674
- if (firstFragment) {
674
+ if (firstFragment && !level.startCC) {
675
675
  level.startCC = firstFragment.cc;
676
676
  }
677
677
  /**
@@ -57,12 +57,10 @@ export function adjustSlidingStart(sliding: number, details: LevelDetails) {
57
57
  * The PTS of a fragment lets Hls.js know where it fits into a stream - by knowing every PTS, we know which fragment to
58
58
  * download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time
59
59
  * and an extra download.
60
- * @param lastFrag
61
60
  * @param lastLevel
62
61
  * @param details
63
62
  */
64
63
  export function alignStream(
65
- lastFrag: Fragment | null,
66
64
  switchDetails: LevelDetails | undefined,
67
65
  details: LevelDetails,
68
66
  ) {
@@ -229,7 +229,9 @@ export function mergeDetails(
229
229
  newDetails.fragments.shift();
230
230
  }
231
231
  newDetails.startSN = newDetails.fragments[0].sn;
232
- newDetails.startCC = newDetails.fragments[0].cc;
232
+ if (!newDetails.startCC) {
233
+ newDetails.startCC = newDetails.fragments[0].cc;
234
+ }
233
235
  } else {
234
236
  if (newDetails.canSkipDateRanges) {
235
237
  newDetails.dateRanges = mergeDateRanges(