hls.js 1.6.0-beta.1.0.canary.10764 → 1.6.0-beta.1.0.canary.10766
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 +6 -0
- package/dist/hls.d.ts +6 -0
- package/dist/hls.js +89 -39
- package/dist/hls.js.d.ts +6 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +72 -29
- 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 +70 -29
- 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 +87 -39
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +1 -1
- package/src/controller/abr-controller.ts +6 -2
- package/src/controller/audio-stream-controller.ts +7 -7
- package/src/controller/audio-track-controller.ts +1 -0
- package/src/controller/base-stream-controller.ts +35 -20
- package/src/controller/level-controller.ts +3 -2
- package/src/controller/stream-controller.ts +7 -7
- package/src/controller/subtitle-stream-controller.ts +9 -5
- package/src/controller/subtitle-track-controller.ts +1 -0
- package/src/loader/fragment.ts +5 -1
- package/src/loader/playlist-loader.ts +38 -8
- package/src/types/events.ts +4 -0
- package/src/types/loader.ts +4 -1
package/dist/hls.d.mts
CHANGED
@@ -376,6 +376,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
|
|
376
376
|
private updateLevelTiming;
|
377
377
|
private playlistLabel;
|
378
378
|
private fragInfo;
|
379
|
+
private treatAsGap;
|
379
380
|
protected resetTransmuxer(): void;
|
380
381
|
protected recoverWorkerError(data: ErrorData): void;
|
381
382
|
set state(nextState: string);
|
@@ -2606,6 +2607,7 @@ export declare interface LevelLoadedData {
|
|
2606
2607
|
details: LevelDetails;
|
2607
2608
|
id: number;
|
2608
2609
|
level: number;
|
2610
|
+
levelInfo: Level;
|
2609
2611
|
networkDetails: any;
|
2610
2612
|
stats: LoaderStats;
|
2611
2613
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -2614,6 +2616,7 @@ export declare interface LevelLoadedData {
|
|
2614
2616
|
export declare interface LevelLoadingData {
|
2615
2617
|
id: number;
|
2616
2618
|
level: number;
|
2619
|
+
levelInfo: Level;
|
2617
2620
|
pathwayId: string | undefined;
|
2618
2621
|
url: string;
|
2619
2622
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -3152,6 +3155,7 @@ export declare interface PlaylistLoaderContext extends LoaderContext {
|
|
3152
3155
|
pathwayId?: string;
|
3153
3156
|
levelDetails?: LevelDetails;
|
3154
3157
|
deliveryDirectives: HlsUrlParameters | null;
|
3158
|
+
levelOrTrack: Level | MediaPlaylist | null;
|
3155
3159
|
}
|
3156
3160
|
|
3157
3161
|
export declare type RationalTimestamp = {
|
@@ -3654,11 +3658,13 @@ export declare interface TrackLoadedData {
|
|
3654
3658
|
networkDetails: any;
|
3655
3659
|
stats: LoaderStats;
|
3656
3660
|
deliveryDirectives: HlsUrlParameters | null;
|
3661
|
+
track: MediaPlaylist;
|
3657
3662
|
}
|
3658
3663
|
|
3659
3664
|
export declare interface TrackLoadingData {
|
3660
3665
|
id: number;
|
3661
3666
|
groupId: string;
|
3667
|
+
track: MediaPlaylist;
|
3662
3668
|
url: string;
|
3663
3669
|
deliveryDirectives: HlsUrlParameters | null;
|
3664
3670
|
}
|
package/dist/hls.d.ts
CHANGED
@@ -376,6 +376,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
|
|
376
376
|
private updateLevelTiming;
|
377
377
|
private playlistLabel;
|
378
378
|
private fragInfo;
|
379
|
+
private treatAsGap;
|
379
380
|
protected resetTransmuxer(): void;
|
380
381
|
protected recoverWorkerError(data: ErrorData): void;
|
381
382
|
set state(nextState: string);
|
@@ -2606,6 +2607,7 @@ export declare interface LevelLoadedData {
|
|
2606
2607
|
details: LevelDetails;
|
2607
2608
|
id: number;
|
2608
2609
|
level: number;
|
2610
|
+
levelInfo: Level;
|
2609
2611
|
networkDetails: any;
|
2610
2612
|
stats: LoaderStats;
|
2611
2613
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -2614,6 +2616,7 @@ export declare interface LevelLoadedData {
|
|
2614
2616
|
export declare interface LevelLoadingData {
|
2615
2617
|
id: number;
|
2616
2618
|
level: number;
|
2619
|
+
levelInfo: Level;
|
2617
2620
|
pathwayId: string | undefined;
|
2618
2621
|
url: string;
|
2619
2622
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -3152,6 +3155,7 @@ export declare interface PlaylistLoaderContext extends LoaderContext {
|
|
3152
3155
|
pathwayId?: string;
|
3153
3156
|
levelDetails?: LevelDetails;
|
3154
3157
|
deliveryDirectives: HlsUrlParameters | null;
|
3158
|
+
levelOrTrack: Level | MediaPlaylist | null;
|
3155
3159
|
}
|
3156
3160
|
|
3157
3161
|
export declare type RationalTimestamp = {
|
@@ -3654,11 +3658,13 @@ export declare interface TrackLoadedData {
|
|
3654
3658
|
networkDetails: any;
|
3655
3659
|
stats: LoaderStats;
|
3656
3660
|
deliveryDirectives: HlsUrlParameters | null;
|
3661
|
+
track: MediaPlaylist;
|
3657
3662
|
}
|
3658
3663
|
|
3659
3664
|
export declare interface TrackLoadingData {
|
3660
3665
|
id: number;
|
3661
3666
|
groupId: string;
|
3667
|
+
track: MediaPlaylist;
|
3662
3668
|
url: string;
|
3663
3669
|
deliveryDirectives: HlsUrlParameters | null;
|
3664
3670
|
}
|
package/dist/hls.js
CHANGED
@@ -1057,7 +1057,7 @@
|
|
1057
1057
|
// Some browsers don't allow to use bind on console object anyway
|
1058
1058
|
// fallback to default if needed
|
1059
1059
|
try {
|
1060
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.
|
1060
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.10766");
|
1061
1061
|
} catch (e) {
|
1062
1062
|
/* log fn threw an exception. All logger methods are no-ops. */
|
1063
1063
|
return createLogger();
|
@@ -2546,8 +2546,10 @@
|
|
2546
2546
|
return 0; // continue
|
2547
2547
|
}
|
2548
2548
|
if (config.useMediaCapabilities && !levelInfo.supportedResult && !levelInfo.supportedPromise) {
|
2549
|
+
var _levelInfo$videoCodec;
|
2549
2550
|
var mediaCapabilities = navigator.mediaCapabilities;
|
2550
|
-
if (typeof (mediaCapabilities == null ? void 0 : mediaCapabilities.decodingInfo) === 'function' && requiresMediaCapabilitiesDecodingInfo(levelInfo, audioTracksByGroup, currentVideoRange, currentFrameRate, currentBw, audioPreference))
|
2551
|
+
if (typeof (mediaCapabilities == null ? void 0 : mediaCapabilities.decodingInfo) === 'function' && (requiresMediaCapabilitiesDecodingInfo(levelInfo, audioTracksByGroup, currentVideoRange, currentFrameRate, currentBw, audioPreference) || ((_levelInfo$videoCodec = levelInfo.videoCodec) == null ? void 0 : _levelInfo$videoCodec.substring(0, 4)) === 'hvc1') // Force media capabilities check for HEVC to avoid failure on Windows
|
2552
|
+
) {
|
2551
2553
|
levelInfo.supportedPromise = getMediaDecodingInfoPromise(levelInfo, audioTracksByGroup, mediaCapabilities);
|
2552
2554
|
levelInfo.supportedPromise.then(function (decodingInfo) {
|
2553
2555
|
if (!_this3.hls) {
|
@@ -2563,6 +2565,9 @@
|
|
2563
2565
|
if (index > -1 && levels.length > 1) {
|
2564
2566
|
_this3.log("Removing unsupported level " + index);
|
2565
2567
|
_this3.hls.removeLevel(index);
|
2568
|
+
if (_this3.hls.loadLevel === -1) {
|
2569
|
+
_this3.hls.nextLoadLevel = 0;
|
2570
|
+
}
|
2566
2571
|
}
|
2567
2572
|
}
|
2568
2573
|
});
|
@@ -4316,6 +4321,10 @@
|
|
4316
4321
|
}
|
4317
4322
|
}]);
|
4318
4323
|
}();
|
4324
|
+
function isMediaFragment(frag) {
|
4325
|
+
return frag.sn !== 'initSegment';
|
4326
|
+
}
|
4327
|
+
|
4319
4328
|
/**
|
4320
4329
|
* Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}.
|
4321
4330
|
*/
|
@@ -4536,7 +4545,7 @@
|
|
4536
4545
|
}, {
|
4537
4546
|
key: "ref",
|
4538
4547
|
get: function get() {
|
4539
|
-
if (this
|
4548
|
+
if (!isMediaFragment(this)) {
|
4540
4549
|
return null;
|
4541
4550
|
}
|
4542
4551
|
if (!this._ref) {
|
@@ -9191,7 +9200,7 @@
|
|
9191
9200
|
_proto.fragBufferedComplete = function fragBufferedComplete(frag, part) {
|
9192
9201
|
var media = this.mediaBuffer ? this.mediaBuffer : this.media;
|
9193
9202
|
this.log("Buffered " + frag.type + " sn: " + frag.sn + (part ? ' part: ' + part.index : '') + " of " + this.fragInfo(frag, false, part) + " > buffer:" + (media ? TimeRanges.toString(BufferHelper.getBuffered(media)) : '(detached)') + ")");
|
9194
|
-
if (frag
|
9203
|
+
if (isMediaFragment(frag)) {
|
9195
9204
|
var _this$levels;
|
9196
9205
|
if (frag.type !== PlaylistLevelType.SUBTITLE) {
|
9197
9206
|
var el = frag.elementaryStreams;
|
@@ -9265,7 +9274,7 @@
|
|
9265
9274
|
this.keyLoader.loadClear(frag, details.encryptedFragments);
|
9266
9275
|
}
|
9267
9276
|
var fragPrevious = this.fragPrevious;
|
9268
|
-
if (frag
|
9277
|
+
if (isMediaFragment(frag) && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
|
9269
9278
|
var shouldLoadParts = this.shouldLoadParts(level.details, frag.end);
|
9270
9279
|
if (shouldLoadParts !== this.loadingParts) {
|
9271
9280
|
this.log("LL-Part loading " + (shouldLoadParts ? 'ON' : 'OFF') + " loading sn " + (fragPrevious == null ? void 0 : fragPrevious.sn) + "->" + frag.sn);
|
@@ -9273,7 +9282,7 @@
|
|
9273
9282
|
}
|
9274
9283
|
}
|
9275
9284
|
targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
|
9276
|
-
if (this.loadingParts && frag
|
9285
|
+
if (this.loadingParts && isMediaFragment(frag)) {
|
9277
9286
|
var partList = details.partList;
|
9278
9287
|
if (partList && progressCallback) {
|
9279
9288
|
if (targetBufferTime > frag.end && details.fragmentHint) {
|
@@ -9316,7 +9325,7 @@
|
|
9316
9325
|
}
|
9317
9326
|
}
|
9318
9327
|
}
|
9319
|
-
if (frag
|
9328
|
+
if (isMediaFragment(frag) && this.loadingParts) {
|
9320
9329
|
this.log("LL-Part loading OFF after next part miss @" + targetBufferTime.toFixed(2));
|
9321
9330
|
this.loadingParts = false;
|
9322
9331
|
} else if (!frag.url) {
|
@@ -9858,7 +9867,7 @@
|
|
9858
9867
|
return pos;
|
9859
9868
|
};
|
9860
9869
|
_proto.handleFragLoadAborted = function handleFragLoadAborted(frag, part) {
|
9861
|
-
if (this.transmuxer && frag
|
9870
|
+
if (this.transmuxer && isMediaFragment(frag) && frag.stats.aborted) {
|
9862
9871
|
this.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " was aborted");
|
9863
9872
|
this.resetFragmentLoading(frag);
|
9864
9873
|
}
|
@@ -9893,10 +9902,18 @@
|
|
9893
9902
|
var errorAction = data.errorAction;
|
9894
9903
|
var _ref2 = errorAction || {},
|
9895
9904
|
action = _ref2.action,
|
9905
|
+
flags = _ref2.flags,
|
9896
9906
|
_ref2$retryCount = _ref2.retryCount,
|
9897
9907
|
retryCount = _ref2$retryCount === void 0 ? 0 : _ref2$retryCount,
|
9898
9908
|
retryConfig = _ref2.retryConfig;
|
9899
|
-
|
9909
|
+
var couldRetry = !!errorAction && !!retryConfig;
|
9910
|
+
var retry = couldRetry && action === NetworkErrorAction.RetryRequest;
|
9911
|
+
var noAlternate = couldRetry && !errorAction.resolved && flags === ErrorActionFlags.MoveAllAlternatesMatchingHost;
|
9912
|
+
if (!retry && noAlternate && isMediaFragment(frag) && !frag.endList) {
|
9913
|
+
this.resetFragmentErrors(filterType);
|
9914
|
+
this.treatAsGap(frag);
|
9915
|
+
errorAction.resolved = true;
|
9916
|
+
} else if ((retry || noAlternate) && retryCount < retryConfig.maxNumRetry) {
|
9900
9917
|
this.resetStartWhenNotLoaded(this.levelLastLoaded);
|
9901
9918
|
var delay = getRetryDelay(retryConfig, retryCount);
|
9902
9919
|
this.warn("Fragment " + frag.sn + " of " + filterType + " " + frag.level + " errored with " + data.details + ", retrying loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " in " + delay + "ms");
|
@@ -9914,7 +9931,7 @@
|
|
9914
9931
|
this.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
|
9915
9932
|
return;
|
9916
9933
|
}
|
9917
|
-
} else if (
|
9934
|
+
} else if (action === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
9918
9935
|
this.state = State.WAITING_LEVEL;
|
9919
9936
|
} else {
|
9920
9937
|
this.state = State.ERROR;
|
@@ -10050,10 +10067,7 @@
|
|
10050
10067
|
var error = new Error("Found no media in fragment " + frag.sn + " of level " + frag.level + " resetting transmuxer to fallback to playlist timing");
|
10051
10068
|
if (level.fragmentError === 0) {
|
10052
10069
|
// Mark and track the odd empty segment as a gap to avoid reloading
|
10053
|
-
level
|
10054
|
-
frag.gap = true;
|
10055
|
-
this.fragmentTracker.removeFragment(frag);
|
10056
|
-
this.fragmentTracker.fragBuffered(frag, true);
|
10070
|
+
this.treatAsGap(frag, level);
|
10057
10071
|
}
|
10058
10072
|
this.warn(error.message);
|
10059
10073
|
this.hls.trigger(Events.ERROR, {
|
@@ -10087,6 +10101,14 @@
|
|
10087
10101
|
}
|
10088
10102
|
return this.playlistLabel() + " " + frag.level + " (" + (part ? 'part' : 'frag') + ":[" + ((_ref3 = pts && !part ? frag.startPTS : (part || frag).start) != null ? _ref3 : NaN).toFixed(3) + "-" + ((_ref4 = pts && !part ? frag.endPTS : (part || frag).end) != null ? _ref4 : NaN).toFixed(3) + "]" + (part && frag.type === 'main' ? 'INDEPENDENT=' + (part.independent ? 'YES' : 'NO') : '');
|
10089
10103
|
};
|
10104
|
+
_proto.treatAsGap = function treatAsGap(frag, level) {
|
10105
|
+
if (level) {
|
10106
|
+
level.fragmentError++;
|
10107
|
+
}
|
10108
|
+
frag.gap = true;
|
10109
|
+
this.fragmentTracker.removeFragment(frag);
|
10110
|
+
this.fragmentTracker.fragBuffered(frag, true);
|
10111
|
+
};
|
10090
10112
|
_proto.resetTransmuxer = function resetTransmuxer() {
|
10091
10113
|
var _this$transmuxer2;
|
10092
10114
|
(_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
|
@@ -16217,7 +16239,7 @@
|
|
16217
16239
|
return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
|
16218
16240
|
}
|
16219
16241
|
|
16220
|
-
var version = "1.6.0-beta.1.0.canary.
|
16242
|
+
var version = "1.6.0-beta.1.0.canary.10766";
|
16221
16243
|
|
16222
16244
|
// ensure the worker ends up in the bundle
|
16223
16245
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -16910,7 +16932,7 @@
|
|
16910
16932
|
|
16911
16933
|
// Request audio segments up to one fragment ahead of main stream-controller
|
16912
16934
|
var mainFragLoading = (_this$mainFragLoading = this.mainFragLoading) == null ? void 0 : _this$mainFragLoading.frag;
|
16913
|
-
if (this.startFragRequested && mainFragLoading && mainFragLoading
|
16935
|
+
if (this.startFragRequested && mainFragLoading && isMediaFragment(mainFragLoading) && isMediaFragment(frag) && !frag.endList && (!trackDetails.live || !this.loadingParts && targetBufferTime < this.hls.liveSyncPosition)) {
|
16914
16936
|
var mainFrag = mainFragLoading;
|
16915
16937
|
if (frag.start > mainFrag.end) {
|
16916
16938
|
// Get buffered frag at target position from tracker (loaded out of sequence)
|
@@ -17112,7 +17134,7 @@
|
|
17112
17134
|
}
|
17113
17135
|
};
|
17114
17136
|
_proto.onFragLoading = function onFragLoading(event, data) {
|
17115
|
-
if (data.frag.type === PlaylistLevelType.MAIN && data.frag
|
17137
|
+
if (data.frag.type === PlaylistLevelType.MAIN && isMediaFragment(data.frag)) {
|
17116
17138
|
this.mainFragLoading = data;
|
17117
17139
|
if (this.state === State.IDLE) {
|
17118
17140
|
this.tick();
|
@@ -17131,7 +17153,7 @@
|
|
17131
17153
|
this.warn("Fragment " + frag.sn + (part ? ' p: ' + part.index : '') + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state + ", audioSwitch: " + (this.switchingTrack ? this.switchingTrack.name : 'false'));
|
17132
17154
|
return;
|
17133
17155
|
}
|
17134
|
-
if (frag
|
17156
|
+
if (isMediaFragment(frag)) {
|
17135
17157
|
this.fragPrevious = frag;
|
17136
17158
|
var track = this.switchingTrack;
|
17137
17159
|
if (track) {
|
@@ -17329,7 +17351,7 @@
|
|
17329
17351
|
// we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
|
17330
17352
|
if (this.switchingTrack || fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
17331
17353
|
var _track$details2;
|
17332
|
-
if (frag
|
17354
|
+
if (!isMediaFragment(frag)) {
|
17333
17355
|
this._loadInitSegment(frag, track);
|
17334
17356
|
} else if ((_track$details2 = track.details) != null && _track$details2.live && !this.initPTS[frag.cc]) {
|
17335
17357
|
this.log("Waiting for video PTS in continuity counter " + frag.cc + " of live stream before loading audio fragment " + frag.sn + " of level " + this.trackId);
|
@@ -17925,7 +17947,8 @@
|
|
17925
17947
|
url: url,
|
17926
17948
|
id: id,
|
17927
17949
|
groupId: groupId,
|
17928
|
-
deliveryDirectives: hlsUrlParameters || null
|
17950
|
+
deliveryDirectives: hlsUrlParameters || null,
|
17951
|
+
track: audioTrack
|
17929
17952
|
});
|
17930
17953
|
}
|
17931
17954
|
};
|
@@ -25504,7 +25527,7 @@
|
|
25504
25527
|
_proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(event, data) {
|
25505
25528
|
var frag = data.frag,
|
25506
25529
|
success = data.success;
|
25507
|
-
if (frag
|
25530
|
+
if (isMediaFragment(frag)) {
|
25508
25531
|
this.fragPrevious = frag;
|
25509
25532
|
}
|
25510
25533
|
this.state = State.IDLE;
|
@@ -25773,7 +25796,7 @@
|
|
25773
25796
|
return;
|
25774
25797
|
}
|
25775
25798
|
foundFrag = this.mapToInitFragWhenRequired(foundFrag);
|
25776
|
-
if (foundFrag
|
25799
|
+
if (isMediaFragment(foundFrag)) {
|
25777
25800
|
// Load earlier fragment in same discontinuity to make up for misaligned playlists and cues that extend beyond end of segment
|
25778
25801
|
var curSNIdx = foundFrag.sn - trackDetails.startSN;
|
25779
25802
|
var prevFrag = fragments[curSNIdx - 1];
|
@@ -25788,7 +25811,7 @@
|
|
25788
25811
|
}
|
25789
25812
|
};
|
25790
25813
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
25791
|
-
if (frag
|
25814
|
+
if (!isMediaFragment(frag)) {
|
25792
25815
|
this._loadInitSegment(frag, level);
|
25793
25816
|
} else {
|
25794
25817
|
_BaseStreamController.prototype.loadFragment.call(this, frag, level, targetBufferTime);
|
@@ -26290,7 +26313,8 @@
|
|
26290
26313
|
url: url,
|
26291
26314
|
id: id,
|
26292
26315
|
groupId: groupId,
|
26293
|
-
deliveryDirectives: hlsUrlParameters || null
|
26316
|
+
deliveryDirectives: hlsUrlParameters || null,
|
26317
|
+
track: currentTrack
|
26294
26318
|
});
|
26295
26319
|
}
|
26296
26320
|
}
|
@@ -31264,7 +31288,7 @@
|
|
31264
31288
|
var _data$deliveryDirecti2;
|
31265
31289
|
var level = data.level,
|
31266
31290
|
details = data.details;
|
31267
|
-
var curLevel =
|
31291
|
+
var curLevel = data.levelInfo;
|
31268
31292
|
if (!curLevel) {
|
31269
31293
|
var _data$deliveryDirecti;
|
31270
31294
|
this.warn("Invalid level index " + level);
|
@@ -31275,7 +31299,7 @@
|
|
31275
31299
|
}
|
31276
31300
|
|
31277
31301
|
// only process level loaded events matching with expected level
|
31278
|
-
if (
|
31302
|
+
if (curLevel === this.currentLevel) {
|
31279
31303
|
// reset level load error counter on successful level loaded only if there is no issues with fragments
|
31280
31304
|
if (curLevel.fragmentError === 0) {
|
31281
31305
|
curLevel.loadError = 0;
|
@@ -31313,6 +31337,7 @@
|
|
31313
31337
|
this.hls.trigger(Events.LEVEL_LOADING, {
|
31314
31338
|
url: url,
|
31315
31339
|
level: currentLevelIndex,
|
31340
|
+
levelInfo: currentLevel,
|
31316
31341
|
pathwayId: currentLevel.attrs['PATHWAY-ID'],
|
31317
31342
|
id: 0,
|
31318
31343
|
// Deprecated Level urlId
|
@@ -32148,7 +32173,7 @@
|
|
32148
32173
|
var targetBufferTime = this.backtrackFragment ? this.backtrackFragment.start : bufferInfo.end;
|
32149
32174
|
var frag = this.getNextFragment(targetBufferTime, levelDetails);
|
32150
32175
|
// Avoid backtracking by loading an earlier segment in streams with segments that do not start with a key frame (flagged by `couldBacktrack`)
|
32151
|
-
if (this.couldBacktrack && !this.fragPrevious && frag && frag
|
32176
|
+
if (this.couldBacktrack && !this.fragPrevious && frag && isMediaFragment(frag) && this.fragmentTracker.getState(frag) !== FragmentState.OK) {
|
32152
32177
|
var _this$backtrackFragme;
|
32153
32178
|
var backtrackSn = ((_this$backtrackFragme = this.backtrackFragment) != null ? _this$backtrackFragme : frag).sn;
|
32154
32179
|
var fragIdx = backtrackSn - levelDetails.startSN;
|
@@ -32185,7 +32210,7 @@
|
|
32185
32210
|
// Check if fragment is not loaded
|
32186
32211
|
var fragState = this.fragmentTracker.getState(frag);
|
32187
32212
|
if (fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
32188
|
-
if (frag
|
32213
|
+
if (!isMediaFragment(frag)) {
|
32189
32214
|
this._loadInitSegment(frag, level);
|
32190
32215
|
} else if (this.bitrateTest) {
|
32191
32216
|
this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered");
|
@@ -32373,7 +32398,7 @@
|
|
32373
32398
|
if (!levels || this.state !== State.IDLE) {
|
32374
32399
|
return;
|
32375
32400
|
}
|
32376
|
-
var level =
|
32401
|
+
var level = data.levelInfo;
|
32377
32402
|
if (!level.details || level.details.live && this.levelLastLoaded !== level || this.waitForCdnTuneIn(level.details)) {
|
32378
32403
|
this.state = State.WAITING_LEVEL;
|
32379
32404
|
}
|
@@ -32390,7 +32415,7 @@
|
|
32390
32415
|
return;
|
32391
32416
|
}
|
32392
32417
|
this.log("Level " + newLevelId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "]" + (newDetails.lastPartSn ? "[part-" + newDetails.lastPartSn + "-" + newDetails.lastPartIndex + "]" : '') + ", cc [" + newDetails.startCC + ", " + newDetails.endCC + "] duration:" + duration);
|
32393
|
-
var curLevel =
|
32418
|
+
var curLevel = data.levelInfo;
|
32394
32419
|
var fragCurrent = this.fragCurrent;
|
32395
32420
|
if (fragCurrent && (this.state === State.FRAG_LOADING || this.state === State.FRAG_LOADING_WAITING_RETRY)) {
|
32396
32421
|
if (fragCurrent.level !== data.level && fragCurrent.loader) {
|
@@ -32595,7 +32620,7 @@
|
|
32595
32620
|
}
|
32596
32621
|
var stats = part ? part.stats : frag.stats;
|
32597
32622
|
this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first));
|
32598
|
-
if (frag
|
32623
|
+
if (isMediaFragment(frag)) {
|
32599
32624
|
this.fragPrevious = frag;
|
32600
32625
|
}
|
32601
32626
|
this.fragBufferedComplete(frag, part);
|
@@ -33452,6 +33477,7 @@
|
|
33452
33477
|
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
33453
33478
|
hls.on(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
|
33454
33479
|
hls.on(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
|
33480
|
+
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
33455
33481
|
};
|
33456
33482
|
_proto.unregisterListeners = function unregisterListeners() {
|
33457
33483
|
var hls = this.hls;
|
@@ -33459,6 +33485,7 @@
|
|
33459
33485
|
hls.off(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
33460
33486
|
hls.off(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
|
33461
33487
|
hls.off(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
|
33488
|
+
hls.off(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
33462
33489
|
}
|
33463
33490
|
|
33464
33491
|
/**
|
@@ -33508,7 +33535,8 @@
|
|
33508
33535
|
responseType: 'text',
|
33509
33536
|
type: PlaylistContextType.MANIFEST,
|
33510
33537
|
url: url,
|
33511
|
-
deliveryDirectives: null
|
33538
|
+
deliveryDirectives: null,
|
33539
|
+
levelOrTrack: null
|
33512
33540
|
});
|
33513
33541
|
};
|
33514
33542
|
_proto.onLevelLoading = function onLevelLoading(event, data) {
|
@@ -33516,7 +33544,8 @@
|
|
33516
33544
|
level = data.level,
|
33517
33545
|
pathwayId = data.pathwayId,
|
33518
33546
|
url = data.url,
|
33519
|
-
deliveryDirectives = data.deliveryDirectives
|
33547
|
+
deliveryDirectives = data.deliveryDirectives,
|
33548
|
+
levelInfo = data.levelInfo;
|
33520
33549
|
this.load({
|
33521
33550
|
id: id,
|
33522
33551
|
level: level,
|
@@ -33524,14 +33553,16 @@
|
|
33524
33553
|
responseType: 'text',
|
33525
33554
|
type: PlaylistContextType.LEVEL,
|
33526
33555
|
url: url,
|
33527
|
-
deliveryDirectives: deliveryDirectives
|
33556
|
+
deliveryDirectives: deliveryDirectives,
|
33557
|
+
levelOrTrack: levelInfo
|
33528
33558
|
});
|
33529
33559
|
};
|
33530
33560
|
_proto.onAudioTrackLoading = function onAudioTrackLoading(event, data) {
|
33531
33561
|
var id = data.id,
|
33532
33562
|
groupId = data.groupId,
|
33533
33563
|
url = data.url,
|
33534
|
-
deliveryDirectives = data.deliveryDirectives
|
33564
|
+
deliveryDirectives = data.deliveryDirectives,
|
33565
|
+
track = data.track;
|
33535
33566
|
this.load({
|
33536
33567
|
id: id,
|
33537
33568
|
groupId: groupId,
|
@@ -33539,14 +33570,16 @@
|
|
33539
33570
|
responseType: 'text',
|
33540
33571
|
type: PlaylistContextType.AUDIO_TRACK,
|
33541
33572
|
url: url,
|
33542
|
-
deliveryDirectives: deliveryDirectives
|
33573
|
+
deliveryDirectives: deliveryDirectives,
|
33574
|
+
levelOrTrack: track
|
33543
33575
|
});
|
33544
33576
|
};
|
33545
33577
|
_proto.onSubtitleTrackLoading = function onSubtitleTrackLoading(event, data) {
|
33546
33578
|
var id = data.id,
|
33547
33579
|
groupId = data.groupId,
|
33548
33580
|
url = data.url,
|
33549
|
-
deliveryDirectives = data.deliveryDirectives
|
33581
|
+
deliveryDirectives = data.deliveryDirectives,
|
33582
|
+
track = data.track;
|
33550
33583
|
this.load({
|
33551
33584
|
id: id,
|
33552
33585
|
groupId: groupId,
|
@@ -33554,9 +33587,23 @@
|
|
33554
33587
|
responseType: 'text',
|
33555
33588
|
type: PlaylistContextType.SUBTITLE_TRACK,
|
33556
33589
|
url: url,
|
33557
|
-
deliveryDirectives: deliveryDirectives
|
33590
|
+
deliveryDirectives: deliveryDirectives,
|
33591
|
+
levelOrTrack: track
|
33558
33592
|
});
|
33559
33593
|
};
|
33594
|
+
_proto.onLevelsUpdated = function onLevelsUpdated(event, data) {
|
33595
|
+
// abort and delete loader of removed levels
|
33596
|
+
var loader = this.loaders[PlaylistContextType.LEVEL];
|
33597
|
+
if (loader) {
|
33598
|
+
var context = loader.context;
|
33599
|
+
if (context && !data.levels.some(function (lvl) {
|
33600
|
+
return lvl === context.levelOrTrack;
|
33601
|
+
})) {
|
33602
|
+
loader.abort();
|
33603
|
+
delete this.loaders[PlaylistContextType.LEVEL];
|
33604
|
+
}
|
33605
|
+
}
|
33606
|
+
};
|
33560
33607
|
_proto.load = function load(context) {
|
33561
33608
|
var _context$deliveryDire,
|
33562
33609
|
_this = this;
|
@@ -33568,7 +33615,7 @@
|
|
33568
33615
|
var loader = this.getInternalLoader(context);
|
33569
33616
|
if (loader) {
|
33570
33617
|
var loaderContext = loader.context;
|
33571
|
-
if (loaderContext && loaderContext.url === context.url && loaderContext.
|
33618
|
+
if (loaderContext && loaderContext.url === context.url && loaderContext.levelOrTrack === context.levelOrTrack) {
|
33572
33619
|
// same URL can't overlap
|
33573
33620
|
this.hls.logger.trace('[playlist-loader]: playlist request ongoing');
|
33574
33621
|
return;
|
@@ -33889,6 +33936,7 @@
|
|
33889
33936
|
case PlaylistContextType.LEVEL:
|
33890
33937
|
hls.trigger(Events.LEVEL_LOADED, {
|
33891
33938
|
details: levelDetails,
|
33939
|
+
levelInfo: context.levelOrTrack || hls.levels[0],
|
33892
33940
|
level: levelIndex || 0,
|
33893
33941
|
id: id || 0,
|
33894
33942
|
stats: stats,
|
@@ -33899,6 +33947,7 @@
|
|
33899
33947
|
case PlaylistContextType.AUDIO_TRACK:
|
33900
33948
|
hls.trigger(Events.AUDIO_TRACK_LOADED, {
|
33901
33949
|
details: levelDetails,
|
33950
|
+
track: context.levelOrTrack,
|
33902
33951
|
id: id || 0,
|
33903
33952
|
groupId: groupId || '',
|
33904
33953
|
stats: stats,
|
@@ -33909,6 +33958,7 @@
|
|
33909
33958
|
case PlaylistContextType.SUBTITLE_TRACK:
|
33910
33959
|
hls.trigger(Events.SUBTITLE_TRACK_LOADED, {
|
33911
33960
|
details: levelDetails,
|
33961
|
+
track: context.levelOrTrack,
|
33912
33962
|
id: id || 0,
|
33913
33963
|
groupId: groupId || '',
|
33914
33964
|
stats: stats,
|
package/dist/hls.js.d.ts
CHANGED
@@ -376,6 +376,7 @@ export declare class BaseStreamController extends TaskLoop implements NetworkCom
|
|
376
376
|
private updateLevelTiming;
|
377
377
|
private playlistLabel;
|
378
378
|
private fragInfo;
|
379
|
+
private treatAsGap;
|
379
380
|
protected resetTransmuxer(): void;
|
380
381
|
protected recoverWorkerError(data: ErrorData): void;
|
381
382
|
set state(nextState: string);
|
@@ -2606,6 +2607,7 @@ export declare interface LevelLoadedData {
|
|
2606
2607
|
details: LevelDetails;
|
2607
2608
|
id: number;
|
2608
2609
|
level: number;
|
2610
|
+
levelInfo: Level;
|
2609
2611
|
networkDetails: any;
|
2610
2612
|
stats: LoaderStats;
|
2611
2613
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -2614,6 +2616,7 @@ export declare interface LevelLoadedData {
|
|
2614
2616
|
export declare interface LevelLoadingData {
|
2615
2617
|
id: number;
|
2616
2618
|
level: number;
|
2619
|
+
levelInfo: Level;
|
2617
2620
|
pathwayId: string | undefined;
|
2618
2621
|
url: string;
|
2619
2622
|
deliveryDirectives: HlsUrlParameters | null;
|
@@ -3152,6 +3155,7 @@ export declare interface PlaylistLoaderContext extends LoaderContext {
|
|
3152
3155
|
pathwayId?: string;
|
3153
3156
|
levelDetails?: LevelDetails;
|
3154
3157
|
deliveryDirectives: HlsUrlParameters | null;
|
3158
|
+
levelOrTrack: Level | MediaPlaylist | null;
|
3155
3159
|
}
|
3156
3160
|
|
3157
3161
|
export declare type RationalTimestamp = {
|
@@ -3654,11 +3658,13 @@ export declare interface TrackLoadedData {
|
|
3654
3658
|
networkDetails: any;
|
3655
3659
|
stats: LoaderStats;
|
3656
3660
|
deliveryDirectives: HlsUrlParameters | null;
|
3661
|
+
track: MediaPlaylist;
|
3657
3662
|
}
|
3658
3663
|
|
3659
3664
|
export declare interface TrackLoadingData {
|
3660
3665
|
id: number;
|
3661
3666
|
groupId: string;
|
3667
|
+
track: MediaPlaylist;
|
3662
3668
|
url: string;
|
3663
3669
|
deliveryDirectives: HlsUrlParameters | null;
|
3664
3670
|
}
|