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.
- package/dist/hls.js +34 -24
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +10 -10
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +10 -12
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +34 -26
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +2 -2
- package/src/controller/audio-stream-controller.ts +32 -18
- package/src/controller/base-stream-controller.ts +2 -5
- package/src/loader/m3u8-parser.ts +2 -2
- package/src/utils/discontinuities.ts +0 -2
- package/src/utils/level-helper.ts +3 -1
@@ -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 {
|
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
|
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
|
-
|
512
|
-
|
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
|
-
|
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
|
-
|
550
|
-
|
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
|
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
|
-
|
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}
|
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
|
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(
|