hls.js 1.6.0-beta.1.0.canary.10787 → 1.6.0-beta.1.0.canary.10789
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.d.mts +10 -6
- package/dist/hls.d.ts +10 -6
- package/dist/hls.js +141 -148
- package/dist/hls.js.d.ts +10 -6
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +100 -87
- 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 +97 -84
- 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 +138 -145
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +1 -1
- package/src/controller/audio-track-controller.ts +32 -46
- package/src/controller/base-playlist-controller.ts +97 -77
- package/src/controller/base-stream-controller.ts +1 -1
- package/src/controller/level-controller.ts +31 -46
- package/src/controller/subtitle-track-controller.ts +28 -39
- package/src/loader/level-details.ts +1 -0
- package/src/utils/level-helper.ts +9 -7
package/dist/hls.light.mjs
CHANGED
@@ -400,7 +400,7 @@ function enableLogs(debugConfig, context, id) {
|
|
400
400
|
// Some browsers don't allow to use bind on console object anyway
|
401
401
|
// fallback to default if needed
|
402
402
|
try {
|
403
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.
|
403
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10789"}`);
|
404
404
|
} catch (e) {
|
405
405
|
/* log fn threw an exception. All logger methods are no-ops. */
|
406
406
|
return createLogger();
|
@@ -3140,6 +3140,7 @@ class LevelDetails {
|
|
3140
3140
|
this.dateRanges = void 0;
|
3141
3141
|
this.dateRangeTagCount = 0;
|
3142
3142
|
this.live = true;
|
3143
|
+
this.requestScheduled = -1;
|
3143
3144
|
this.ageHeader = 0;
|
3144
3145
|
this.advancedDateTime = void 0;
|
3145
3146
|
this.updated = true;
|
@@ -5417,6 +5418,9 @@ function mergeDetails(oldDetails, newDetails) {
|
|
5417
5418
|
newDetails.driftEnd = oldDetails.driftEnd;
|
5418
5419
|
newDetails.advancedDateTime = oldDetails.advancedDateTime;
|
5419
5420
|
}
|
5421
|
+
if (newDetails.requestScheduled === -1) {
|
5422
|
+
newDetails.requestScheduled = oldDetails.requestScheduled;
|
5423
|
+
}
|
5420
5424
|
}
|
5421
5425
|
function mergeDateRanges(oldDateRanges, newDetails) {
|
5422
5426
|
const {
|
@@ -5487,12 +5491,14 @@ function adjustSliding(oldDetails, newDetails, matchingStableVariantOrRendition
|
|
5487
5491
|
let sliding = 0;
|
5488
5492
|
if (advancedOrStable && delta < oldFragments.length) {
|
5489
5493
|
sliding = oldFragments[delta].start;
|
5494
|
+
} else if (advancedOrStable && newDetails.startSN === oldDetails.endSN + 1) {
|
5495
|
+
sliding = oldDetails.fragmentEnd;
|
5490
5496
|
} else if (advancedOrStable && matchingStableVariantOrRendition) {
|
5491
|
-
// align
|
5492
|
-
sliding = oldDetails.
|
5493
|
-
} else if (!newDetails.skippedSegments && newDetails.
|
5497
|
+
// align with expected position (updated playlist start sequence is past end sequence of last update)
|
5498
|
+
sliding = oldDetails.fragmentStart + delta * newDetails.levelTargetDuration;
|
5499
|
+
} else if (!newDetails.skippedSegments && newDetails.fragmentStart === 0) {
|
5494
5500
|
// align new start with old (playlist switch has a sequence with no overlap and should not be used for alignment)
|
5495
|
-
sliding = oldDetails.
|
5501
|
+
sliding = oldDetails.fragmentStart;
|
5496
5502
|
} else {
|
5497
5503
|
// new details already has a sliding offset or has skipped segments
|
5498
5504
|
return;
|
@@ -5583,7 +5589,6 @@ class BasePlaylistController extends Logger {
|
|
5583
5589
|
super(logPrefix, hls.logger);
|
5584
5590
|
this.hls = void 0;
|
5585
5591
|
this.timer = -1;
|
5586
|
-
this.requestScheduled = -1;
|
5587
5592
|
this.canLoad = false;
|
5588
5593
|
this.hls = hls;
|
5589
5594
|
}
|
@@ -5600,7 +5605,6 @@ class BasePlaylistController extends Logger {
|
|
5600
5605
|
}
|
5601
5606
|
startLoad() {
|
5602
5607
|
this.canLoad = true;
|
5603
|
-
this.requestScheduled = -1;
|
5604
5608
|
this.loadPlaylist();
|
5605
5609
|
}
|
5606
5610
|
stopLoad() {
|
@@ -5645,16 +5649,25 @@ class BasePlaylistController extends Logger {
|
|
5645
5649
|
}
|
5646
5650
|
}
|
5647
5651
|
loadPlaylist(hlsUrlParameters) {
|
5648
|
-
if (this.requestScheduled === -1) {
|
5649
|
-
this.requestScheduled = self.performance.now();
|
5650
|
-
}
|
5651
5652
|
// Loading is handled by the subclasses
|
5653
|
+
this.clearTimer();
|
5654
|
+
}
|
5655
|
+
loadingPlaylist(playlist, hlsUrlParameters) {
|
5656
|
+
// Loading is handled by the subclasses
|
5657
|
+
this.clearTimer();
|
5652
5658
|
}
|
5653
5659
|
shouldLoadPlaylist(playlist) {
|
5654
5660
|
return this.canLoad && !!playlist && !!playlist.url && (!playlist.details || playlist.details.live);
|
5655
5661
|
}
|
5656
|
-
|
5657
|
-
|
5662
|
+
getUrlWithDirectives(uri, hlsUrlParameters) {
|
5663
|
+
if (hlsUrlParameters) {
|
5664
|
+
try {
|
5665
|
+
return hlsUrlParameters.addDirectives(uri);
|
5666
|
+
} catch (error) {
|
5667
|
+
this.warn(`Could not construct new URL with HLS Delivery Directives: ${error}`);
|
5668
|
+
}
|
5669
|
+
}
|
5670
|
+
return uri;
|
5658
5671
|
}
|
5659
5672
|
playlistLoaded(index, data, previousDetails) {
|
5660
5673
|
const {
|
@@ -5679,10 +5692,9 @@ class BasePlaylistController extends Logger {
|
|
5679
5692
|
|
5680
5693
|
// if current playlist is a live playlist, arm a timer to reload it
|
5681
5694
|
if (details.live || previousDetails != null && previousDetails.live) {
|
5695
|
+
const levelOrTrack = 'levelInfo' in data ? data.levelInfo : data.track;
|
5682
5696
|
details.reloaded(previousDetails);
|
5683
|
-
|
5684
|
-
this.log(`live playlist ${index} ${details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : details.updated ? 'UPDATED' : 'MISSED'}`);
|
5685
|
-
}
|
5697
|
+
this.log(`live playlist ${index} ${details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : details.updated ? 'UPDATED' : 'MISSED'}`);
|
5686
5698
|
// Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
|
5687
5699
|
if (previousDetails && details.fragments.length > 0) {
|
5688
5700
|
mergeDetails(previousDetails, details);
|
@@ -5738,50 +5750,64 @@ class BasePlaylistController extends Logger {
|
|
5738
5750
|
}
|
5739
5751
|
deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
|
5740
5752
|
if (lowLatencyMode || !lastPart) {
|
5741
|
-
this.
|
5753
|
+
this.loadingPlaylist(levelOrTrack, deliveryDirectives);
|
5742
5754
|
return;
|
5743
5755
|
}
|
5744
5756
|
} else if (details.canBlockReload || details.canSkipUntil) {
|
5745
5757
|
deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
|
5746
5758
|
}
|
5759
|
+
if (details.requestScheduled === -1) {
|
5760
|
+
details.requestScheduled = stats.loading.start;
|
5761
|
+
}
|
5762
|
+
if (deliveryDirectives && msn !== undefined && details.canBlockReload) {
|
5763
|
+
details.requestScheduled -= details.partTarget * 1000 || 1000;
|
5764
|
+
}
|
5747
5765
|
const bufferInfo = this.hls.mainForwardBufferInfo;
|
5748
5766
|
const position = bufferInfo ? bufferInfo.end - bufferInfo.len : 0;
|
5749
5767
|
const distanceToLiveEdgeMs = (details.edge - position) * 1000;
|
5750
5768
|
const reloadInterval = computeReloadInterval(details, distanceToLiveEdgeMs);
|
5751
|
-
if (details.
|
5752
|
-
|
5753
|
-
}
|
5754
|
-
|
5755
|
-
|
5756
|
-
|
5757
|
-
this.requestScheduled = now;
|
5758
|
-
} else if (this.requestScheduled - now <= 0) {
|
5759
|
-
this.requestScheduled += reloadInterval;
|
5760
|
-
}
|
5761
|
-
let estimatedTimeUntilUpdate = this.requestScheduled - now;
|
5762
|
-
estimatedTimeUntilUpdate = Math.max(0, estimatedTimeUntilUpdate);
|
5763
|
-
this.log(`reload live playlist ${index} in ${Math.round(estimatedTimeUntilUpdate)} ms`);
|
5764
|
-
// this.log(
|
5765
|
-
// `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
|
5766
|
-
// reload in ${estimatedTimeUntilUpdate / 1000}
|
5767
|
-
// round trip ${(stats.loading.end - stats.loading.start) / 1000}
|
5768
|
-
// diff ${
|
5769
|
-
// (reloadInterval -
|
5770
|
-
// (estimatedTimeUntilUpdate +
|
5771
|
-
// stats.loading.end -
|
5772
|
-
// stats.loading.start)) /
|
5773
|
-
// 1000
|
5774
|
-
// }
|
5775
|
-
// reload interval ${reloadInterval / 1000}
|
5776
|
-
// target duration ${details.targetduration}
|
5777
|
-
// distance to edge ${distanceToLiveEdgeMs / 1000}`
|
5778
|
-
// );
|
5779
|
-
|
5780
|
-
this.timer = self.setTimeout(() => this.loadPlaylist(deliveryDirectives), estimatedTimeUntilUpdate);
|
5769
|
+
if (details.requestScheduled + reloadInterval < now) {
|
5770
|
+
details.requestScheduled = now;
|
5771
|
+
} else {
|
5772
|
+
details.requestScheduled += reloadInterval;
|
5773
|
+
}
|
5774
|
+
this.scheduleLoading(levelOrTrack, deliveryDirectives);
|
5781
5775
|
} else {
|
5782
5776
|
this.clearTimer();
|
5783
5777
|
}
|
5784
5778
|
}
|
5779
|
+
scheduleLoading(levelOrTrack, deliveryDirectives) {
|
5780
|
+
const details = levelOrTrack.details;
|
5781
|
+
if (!details) {
|
5782
|
+
this.loadingPlaylist(levelOrTrack, deliveryDirectives);
|
5783
|
+
return;
|
5784
|
+
}
|
5785
|
+
const now = self.performance.now();
|
5786
|
+
const requestScheduled = details.requestScheduled;
|
5787
|
+
if (now >= requestScheduled) {
|
5788
|
+
this.loadingPlaylist(levelOrTrack, deliveryDirectives);
|
5789
|
+
return;
|
5790
|
+
}
|
5791
|
+
const estimatedTimeUntilUpdate = requestScheduled - now;
|
5792
|
+
this.log(`reload live playlist ${levelOrTrack.name || levelOrTrack.bitrate + 'bps'} in ${Math.round(estimatedTimeUntilUpdate)} ms`);
|
5793
|
+
// this.log(
|
5794
|
+
// `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
|
5795
|
+
// reload in ${estimatedTimeUntilUpdate / 1000}
|
5796
|
+
// round trip ${(stats.loading.end - stats.loading.start) / 1000}
|
5797
|
+
// diff ${
|
5798
|
+
// (reloadInterval -
|
5799
|
+
// (estimatedTimeUntilUpdate +
|
5800
|
+
// stats.loading.end -
|
5801
|
+
// stats.loading.start)) /
|
5802
|
+
// 1000
|
5803
|
+
// }
|
5804
|
+
// reload interval ${reloadInterval / 1000}
|
5805
|
+
// target duration ${details.targetduration}
|
5806
|
+
// distance to edge ${distanceToLiveEdgeMs / 1000}`
|
5807
|
+
// );
|
5808
|
+
|
5809
|
+
this.timer = self.setTimeout(() => this.loadingPlaylist(levelOrTrack, deliveryDirectives), estimatedTimeUntilUpdate);
|
5810
|
+
}
|
5785
5811
|
getDeliveryDirectives(details, previousDeliveryDirectives, msn, part) {
|
5786
5812
|
let skip = getSkipValue(details);
|
5787
5813
|
if (previousDeliveryDirectives != null && previousDeliveryDirectives.skip && details.deltaUpdateFailed) {
|
@@ -5803,7 +5829,6 @@ class BasePlaylistController extends Logger {
|
|
5803
5829
|
const retry = !!errorAction && !!retryConfig && (action === NetworkErrorAction.RetryRequest || !errorAction.resolved && action === NetworkErrorAction.SendAlternateToPenaltyBox);
|
5804
5830
|
if (retry) {
|
5805
5831
|
var _errorEvent$context;
|
5806
|
-
this.requestScheduled = -1;
|
5807
5832
|
if (retryCount >= retryConfig.maxNumRetry) {
|
5808
5833
|
return false;
|
5809
5834
|
}
|
@@ -8606,12 +8631,13 @@ class BaseStreamController extends TaskLoop {
|
|
8606
8631
|
this.nextLoadPosition = startPosition;
|
8607
8632
|
}
|
8608
8633
|
getLoadPosition() {
|
8634
|
+
var _this$hls;
|
8609
8635
|
const {
|
8610
8636
|
media
|
8611
8637
|
} = this;
|
8612
8638
|
// if we have not yet loaded any fragment, start loading from start position
|
8613
8639
|
let pos = 0;
|
8614
|
-
if (this.hls.hasEnoughToStart && media) {
|
8640
|
+
if ((_this$hls = this.hls) != null && _this$hls.hasEnoughToStart && media) {
|
8615
8641
|
pos = media.currentTime;
|
8616
8642
|
} else if (this.nextLoadPosition >= 0) {
|
8617
8643
|
pos = this.nextLoadPosition;
|
@@ -18516,9 +18542,7 @@ class LevelController extends BasePlaylistController {
|
|
18516
18542
|
this.currentLevelIndex = newLevel;
|
18517
18543
|
this.currentLevel = level;
|
18518
18544
|
if (lastLevelIndex === newLevel && lastLevel && lastPathwayId === pathwayId) {
|
18519
|
-
|
18520
|
-
return;
|
18521
|
-
}
|
18545
|
+
return;
|
18522
18546
|
}
|
18523
18547
|
this.log(`Switching to level ${newLevel} (${level.height ? level.height + 'p ' : ''}${level.videoRange ? level.videoRange + ' ' : ''}${level.codecSet ? level.codecSet + ' ' : ''}@${level.bitrate})${pathwayId ? ' with Pathway ' + pathwayId : ''} from level ${lastLevelIndex}${lastPathwayId ? ' with Pathway ' + lastPathwayId : ''}`);
|
18524
18548
|
const levelSwitchingData = {
|
@@ -18612,10 +18636,7 @@ class LevelController extends BasePlaylistController {
|
|
18612
18636
|
return;
|
18613
18637
|
}
|
18614
18638
|
if (data.context.type === PlaylistContextType.LEVEL && data.context.level === this.level) {
|
18615
|
-
|
18616
|
-
if (!retry) {
|
18617
|
-
this.requestScheduled = -1;
|
18618
|
-
}
|
18639
|
+
this.checkRetry(data);
|
18619
18640
|
}
|
18620
18641
|
}
|
18621
18642
|
|
@@ -18670,36 +18691,28 @@ class LevelController extends BasePlaylistController {
|
|
18670
18691
|
}
|
18671
18692
|
loadPlaylist(hlsUrlParameters) {
|
18672
18693
|
super.loadPlaylist();
|
18673
|
-
|
18674
|
-
|
18675
|
-
if (currentLevel && this.shouldLoadPlaylist(currentLevel)) {
|
18676
|
-
let url = currentLevel.uri;
|
18677
|
-
if (hlsUrlParameters) {
|
18678
|
-
try {
|
18679
|
-
url = hlsUrlParameters.addDirectives(url);
|
18680
|
-
} catch (error) {
|
18681
|
-
this.warn(`Could not construct new URL with HLS Delivery Directives: ${error}`);
|
18682
|
-
}
|
18683
|
-
}
|
18684
|
-
const pathwayId = currentLevel.attrs['PATHWAY-ID'];
|
18685
|
-
const details = currentLevel.details;
|
18686
|
-
const age = details == null ? void 0 : details.age;
|
18687
|
-
this.log(`Loading level index ${currentLevelIndex}${(hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : ''}${pathwayId ? ' Pathway ' + pathwayId : ''}${age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : ''} ${url}`);
|
18688
|
-
|
18689
|
-
// console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
|
18690
|
-
// console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
|
18691
|
-
this.clearTimer();
|
18692
|
-
this.hls.trigger(Events.LEVEL_LOADING, {
|
18693
|
-
url,
|
18694
|
-
level: currentLevelIndex,
|
18695
|
-
levelInfo: currentLevel,
|
18696
|
-
pathwayId: currentLevel.attrs['PATHWAY-ID'],
|
18697
|
-
id: 0,
|
18698
|
-
// Deprecated Level urlId
|
18699
|
-
deliveryDirectives: hlsUrlParameters || null
|
18700
|
-
});
|
18694
|
+
if (this.shouldLoadPlaylist(this.currentLevel)) {
|
18695
|
+
this.scheduleLoading(this.currentLevel, hlsUrlParameters);
|
18701
18696
|
}
|
18702
18697
|
}
|
18698
|
+
loadingPlaylist(currentLevel, hlsUrlParameters) {
|
18699
|
+
super.loadingPlaylist(currentLevel, hlsUrlParameters);
|
18700
|
+
const url = this.getUrlWithDirectives(currentLevel.uri, hlsUrlParameters);
|
18701
|
+
const currentLevelIndex = this.currentLevelIndex;
|
18702
|
+
const pathwayId = currentLevel.attrs['PATHWAY-ID'];
|
18703
|
+
const details = currentLevel.details;
|
18704
|
+
const age = details == null ? void 0 : details.age;
|
18705
|
+
this.log(`Loading level index ${currentLevelIndex}${(hlsUrlParameters == null ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : ''}${pathwayId ? ' Pathway ' + pathwayId : ''}${age && details.live ? ' age ' + age.toFixed(1) + (details.type ? ' ' + details.type || '' : '') : ''} ${url}`);
|
18706
|
+
this.hls.trigger(Events.LEVEL_LOADING, {
|
18707
|
+
url,
|
18708
|
+
level: currentLevelIndex,
|
18709
|
+
levelInfo: currentLevel,
|
18710
|
+
pathwayId: currentLevel.attrs['PATHWAY-ID'],
|
18711
|
+
id: 0,
|
18712
|
+
// Deprecated Level urlId
|
18713
|
+
deliveryDirectives: hlsUrlParameters || null
|
18714
|
+
});
|
18715
|
+
}
|
18703
18716
|
get nextLoadLevel() {
|
18704
18717
|
if (this.manualLevelIndex !== -1) {
|
18705
18718
|
return this.manualLevelIndex;
|
@@ -19117,7 +19130,7 @@ class GapController extends Logger {
|
|
19117
19130
|
}
|
19118
19131
|
}
|
19119
19132
|
|
19120
|
-
const version = "1.6.0-beta.1.0.canary.
|
19133
|
+
const version = "1.6.0-beta.1.0.canary.10789";
|
19121
19134
|
|
19122
19135
|
// ensure the worker ends up in the bundle
|
19123
19136
|
// If the worker should not be included this gets aliased to empty.js
|