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.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.10766"}`);
|
404
404
|
} catch (e) {
|
405
405
|
/* log fn threw an exception. All logger methods are no-ops. */
|
406
406
|
return createLogger();
|
@@ -2856,6 +2856,10 @@ class BaseSegment {
|
|
2856
2856
|
elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;
|
2857
2857
|
}
|
2858
2858
|
}
|
2859
|
+
function isMediaFragment(frag) {
|
2860
|
+
return frag.sn !== 'initSegment';
|
2861
|
+
}
|
2862
|
+
|
2859
2863
|
/**
|
2860
2864
|
* Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}.
|
2861
2865
|
*/
|
@@ -3009,7 +3013,7 @@ class Fragment extends BaseSegment {
|
|
3009
3013
|
this._programDateTime = value;
|
3010
3014
|
}
|
3011
3015
|
get ref() {
|
3012
|
-
if (this
|
3016
|
+
if (!isMediaFragment(this)) {
|
3013
3017
|
return null;
|
3014
3018
|
}
|
3015
3019
|
if (!this._ref) {
|
@@ -7924,7 +7928,7 @@ class BaseStreamController extends TaskLoop {
|
|
7924
7928
|
fragBufferedComplete(frag, part) {
|
7925
7929
|
const media = this.mediaBuffer ? this.mediaBuffer : this.media;
|
7926
7930
|
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)'})`);
|
7927
|
-
if (frag
|
7931
|
+
if (isMediaFragment(frag)) {
|
7928
7932
|
var _this$levels;
|
7929
7933
|
if (frag.type !== PlaylistLevelType.SUBTITLE) {
|
7930
7934
|
const el = frag.elementaryStreams;
|
@@ -7993,7 +7997,7 @@ class BaseStreamController extends TaskLoop {
|
|
7993
7997
|
this.keyLoader.loadClear(frag, details.encryptedFragments);
|
7994
7998
|
}
|
7995
7999
|
const fragPrevious = this.fragPrevious;
|
7996
|
-
if (frag
|
8000
|
+
if (isMediaFragment(frag) && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
|
7997
8001
|
const shouldLoadParts = this.shouldLoadParts(level.details, frag.end);
|
7998
8002
|
if (shouldLoadParts !== this.loadingParts) {
|
7999
8003
|
this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} loading sn ${fragPrevious == null ? void 0 : fragPrevious.sn}->${frag.sn}`);
|
@@ -8001,7 +8005,7 @@ class BaseStreamController extends TaskLoop {
|
|
8001
8005
|
}
|
8002
8006
|
}
|
8003
8007
|
targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
|
8004
|
-
if (this.loadingParts && frag
|
8008
|
+
if (this.loadingParts && isMediaFragment(frag)) {
|
8005
8009
|
const partList = details.partList;
|
8006
8010
|
if (partList && progressCallback) {
|
8007
8011
|
if (targetBufferTime > frag.end && details.fragmentHint) {
|
@@ -8040,7 +8044,7 @@ class BaseStreamController extends TaskLoop {
|
|
8040
8044
|
}
|
8041
8045
|
}
|
8042
8046
|
}
|
8043
|
-
if (frag
|
8047
|
+
if (isMediaFragment(frag) && this.loadingParts) {
|
8044
8048
|
this.log(`LL-Part loading OFF after next part miss @${targetBufferTime.toFixed(2)}`);
|
8045
8049
|
this.loadingParts = false;
|
8046
8050
|
} else if (!frag.url) {
|
@@ -8599,7 +8603,7 @@ class BaseStreamController extends TaskLoop {
|
|
8599
8603
|
return pos;
|
8600
8604
|
}
|
8601
8605
|
handleFragLoadAborted(frag, part) {
|
8602
|
-
if (this.transmuxer && frag
|
8606
|
+
if (this.transmuxer && isMediaFragment(frag) && frag.stats.aborted) {
|
8603
8607
|
this.warn(`Fragment ${frag.sn}${part ? ' part ' + part.index : ''} of level ${frag.level} was aborted`);
|
8604
8608
|
this.resetFragmentLoading(frag);
|
8605
8609
|
}
|
@@ -8634,10 +8638,18 @@ class BaseStreamController extends TaskLoop {
|
|
8634
8638
|
const errorAction = data.errorAction;
|
8635
8639
|
const {
|
8636
8640
|
action,
|
8641
|
+
flags,
|
8637
8642
|
retryCount = 0,
|
8638
8643
|
retryConfig
|
8639
8644
|
} = errorAction || {};
|
8640
|
-
|
8645
|
+
const couldRetry = !!errorAction && !!retryConfig;
|
8646
|
+
const retry = couldRetry && action === NetworkErrorAction.RetryRequest;
|
8647
|
+
const noAlternate = couldRetry && !errorAction.resolved && flags === ErrorActionFlags.MoveAllAlternatesMatchingHost;
|
8648
|
+
if (!retry && noAlternate && isMediaFragment(frag) && !frag.endList) {
|
8649
|
+
this.resetFragmentErrors(filterType);
|
8650
|
+
this.treatAsGap(frag);
|
8651
|
+
errorAction.resolved = true;
|
8652
|
+
} else if ((retry || noAlternate) && retryCount < retryConfig.maxNumRetry) {
|
8641
8653
|
this.resetStartWhenNotLoaded(this.levelLastLoaded);
|
8642
8654
|
const delay = getRetryDelay(retryConfig, retryCount);
|
8643
8655
|
this.warn(`Fragment ${frag.sn} of ${filterType} ${frag.level} errored with ${data.details}, retrying loading ${retryCount + 1}/${retryConfig.maxNumRetry} in ${delay}ms`);
|
@@ -8655,7 +8667,7 @@ class BaseStreamController extends TaskLoop {
|
|
8655
8667
|
this.warn(`${data.details} reached or exceeded max retry (${retryCount})`);
|
8656
8668
|
return;
|
8657
8669
|
}
|
8658
|
-
} else if (
|
8670
|
+
} else if (action === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
8659
8671
|
this.state = State.WAITING_LEVEL;
|
8660
8672
|
} else {
|
8661
8673
|
this.state = State.ERROR;
|
@@ -8787,10 +8799,7 @@ class BaseStreamController extends TaskLoop {
|
|
8787
8799
|
const error = new Error(`Found no media in fragment ${frag.sn} of level ${frag.level} resetting transmuxer to fallback to playlist timing`);
|
8788
8800
|
if (level.fragmentError === 0) {
|
8789
8801
|
// Mark and track the odd empty segment as a gap to avoid reloading
|
8790
|
-
level
|
8791
|
-
frag.gap = true;
|
8792
|
-
this.fragmentTracker.removeFragment(frag);
|
8793
|
-
this.fragmentTracker.fragBuffered(frag, true);
|
8802
|
+
this.treatAsGap(frag, level);
|
8794
8803
|
}
|
8795
8804
|
this.warn(error.message);
|
8796
8805
|
this.hls.trigger(Events.ERROR, {
|
@@ -8821,6 +8830,14 @@ class BaseStreamController extends TaskLoop {
|
|
8821
8830
|
var _ref, _ref2;
|
8822
8831
|
return `${this.playlistLabel()} ${frag.level} (${part ? 'part' : 'frag'}:[${((_ref = pts && !part ? frag.startPTS : (part || frag).start) != null ? _ref : NaN).toFixed(3)}-${((_ref2 = pts && !part ? frag.endPTS : (part || frag).end) != null ? _ref2 : NaN).toFixed(3)}]${part && frag.type === 'main' ? 'INDEPENDENT=' + (part.independent ? 'YES' : 'NO') : ''}`;
|
8823
8832
|
}
|
8833
|
+
treatAsGap(frag, level) {
|
8834
|
+
if (level) {
|
8835
|
+
level.fragmentError++;
|
8836
|
+
}
|
8837
|
+
frag.gap = true;
|
8838
|
+
this.fragmentTracker.removeFragment(frag);
|
8839
|
+
this.fragmentTracker.fragBuffered(frag, true);
|
8840
|
+
}
|
8824
8841
|
resetTransmuxer() {
|
8825
8842
|
var _this$transmuxer2;
|
8826
8843
|
(_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
|
@@ -18608,7 +18625,7 @@ class LevelController extends BasePlaylistController {
|
|
18608
18625
|
level,
|
18609
18626
|
details
|
18610
18627
|
} = data;
|
18611
|
-
const curLevel =
|
18628
|
+
const curLevel = data.levelInfo;
|
18612
18629
|
if (!curLevel) {
|
18613
18630
|
var _data$deliveryDirecti;
|
18614
18631
|
this.warn(`Invalid level index ${level}`);
|
@@ -18619,7 +18636,7 @@ class LevelController extends BasePlaylistController {
|
|
18619
18636
|
}
|
18620
18637
|
|
18621
18638
|
// only process level loaded events matching with expected level
|
18622
|
-
if (
|
18639
|
+
if (curLevel === this.currentLevel) {
|
18623
18640
|
// reset level load error counter on successful level loaded only if there is no issues with fragments
|
18624
18641
|
if (curLevel.fragmentError === 0) {
|
18625
18642
|
curLevel.loadError = 0;
|
@@ -18657,6 +18674,7 @@ class LevelController extends BasePlaylistController {
|
|
18657
18674
|
this.hls.trigger(Events.LEVEL_LOADING, {
|
18658
18675
|
url,
|
18659
18676
|
level: currentLevelIndex,
|
18677
|
+
levelInfo: currentLevel,
|
18660
18678
|
pathwayId: currentLevel.attrs['PATHWAY-ID'],
|
18661
18679
|
id: 0,
|
18662
18680
|
// Deprecated Level urlId
|
@@ -19081,7 +19099,7 @@ class GapController extends Logger {
|
|
19081
19099
|
}
|
19082
19100
|
}
|
19083
19101
|
|
19084
|
-
const version = "1.6.0-beta.1.0.canary.
|
19102
|
+
const version = "1.6.0-beta.1.0.canary.10766";
|
19085
19103
|
|
19086
19104
|
// ensure the worker ends up in the bundle
|
19087
19105
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -19741,7 +19759,7 @@ class StreamController extends BaseStreamController {
|
|
19741
19759
|
const targetBufferTime = this.backtrackFragment ? this.backtrackFragment.start : bufferInfo.end;
|
19742
19760
|
let frag = this.getNextFragment(targetBufferTime, levelDetails);
|
19743
19761
|
// Avoid backtracking by loading an earlier segment in streams with segments that do not start with a key frame (flagged by `couldBacktrack`)
|
19744
|
-
if (this.couldBacktrack && !this.fragPrevious && frag && frag
|
19762
|
+
if (this.couldBacktrack && !this.fragPrevious && frag && isMediaFragment(frag) && this.fragmentTracker.getState(frag) !== FragmentState.OK) {
|
19745
19763
|
var _this$backtrackFragme;
|
19746
19764
|
const backtrackSn = ((_this$backtrackFragme = this.backtrackFragment) != null ? _this$backtrackFragme : frag).sn;
|
19747
19765
|
const fragIdx = backtrackSn - levelDetails.startSN;
|
@@ -19778,7 +19796,7 @@ class StreamController extends BaseStreamController {
|
|
19778
19796
|
// Check if fragment is not loaded
|
19779
19797
|
const fragState = this.fragmentTracker.getState(frag);
|
19780
19798
|
if (fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
19781
|
-
if (frag
|
19799
|
+
if (!isMediaFragment(frag)) {
|
19782
19800
|
this._loadInitSegment(frag, level);
|
19783
19801
|
} else if (this.bitrateTest) {
|
19784
19802
|
this.log(`Fragment ${frag.sn} of level ${frag.level} is being downloaded to test bitrate and will not be buffered`);
|
@@ -19972,7 +19990,7 @@ class StreamController extends BaseStreamController {
|
|
19972
19990
|
if (!levels || this.state !== State.IDLE) {
|
19973
19991
|
return;
|
19974
19992
|
}
|
19975
|
-
const level =
|
19993
|
+
const level = data.levelInfo;
|
19976
19994
|
if (!level.details || level.details.live && this.levelLastLoaded !== level || this.waitForCdnTuneIn(level.details)) {
|
19977
19995
|
this.state = State.WAITING_LEVEL;
|
19978
19996
|
}
|
@@ -19991,7 +20009,7 @@ class StreamController extends BaseStreamController {
|
|
19991
20009
|
return;
|
19992
20010
|
}
|
19993
20011
|
this.log(`Level ${newLevelId} loaded [${newDetails.startSN},${newDetails.endSN}]${newDetails.lastPartSn ? `[part-${newDetails.lastPartSn}-${newDetails.lastPartIndex}]` : ''}, cc [${newDetails.startCC}, ${newDetails.endCC}] duration:${duration}`);
|
19994
|
-
const curLevel =
|
20012
|
+
const curLevel = data.levelInfo;
|
19995
20013
|
const fragCurrent = this.fragCurrent;
|
19996
20014
|
if (fragCurrent && (this.state === State.FRAG_LOADING || this.state === State.FRAG_LOADING_WAITING_RETRY)) {
|
19997
20015
|
if (fragCurrent.level !== data.level && fragCurrent.loader) {
|
@@ -20204,7 +20222,7 @@ class StreamController extends BaseStreamController {
|
|
20204
20222
|
}
|
20205
20223
|
const stats = part ? part.stats : frag.stats;
|
20206
20224
|
this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first));
|
20207
|
-
if (frag
|
20225
|
+
if (isMediaFragment(frag)) {
|
20208
20226
|
this.fragPrevious = frag;
|
20209
20227
|
}
|
20210
20228
|
this.fragBufferedComplete(frag, part);
|
@@ -21064,6 +21082,7 @@ class PlaylistLoader {
|
|
21064
21082
|
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
21065
21083
|
hls.on(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
|
21066
21084
|
hls.on(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
|
21085
|
+
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
21067
21086
|
}
|
21068
21087
|
unregisterListeners() {
|
21069
21088
|
const {
|
@@ -21073,6 +21092,7 @@ class PlaylistLoader {
|
|
21073
21092
|
hls.off(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
21074
21093
|
hls.off(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
|
21075
21094
|
hls.off(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
|
21095
|
+
hls.off(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
21076
21096
|
}
|
21077
21097
|
|
21078
21098
|
/**
|
@@ -21124,7 +21144,8 @@ class PlaylistLoader {
|
|
21124
21144
|
responseType: 'text',
|
21125
21145
|
type: PlaylistContextType.MANIFEST,
|
21126
21146
|
url,
|
21127
|
-
deliveryDirectives: null
|
21147
|
+
deliveryDirectives: null,
|
21148
|
+
levelOrTrack: null
|
21128
21149
|
});
|
21129
21150
|
}
|
21130
21151
|
onLevelLoading(event, data) {
|
@@ -21133,7 +21154,8 @@ class PlaylistLoader {
|
|
21133
21154
|
level,
|
21134
21155
|
pathwayId,
|
21135
21156
|
url,
|
21136
|
-
deliveryDirectives
|
21157
|
+
deliveryDirectives,
|
21158
|
+
levelInfo
|
21137
21159
|
} = data;
|
21138
21160
|
this.load({
|
21139
21161
|
id,
|
@@ -21142,7 +21164,8 @@ class PlaylistLoader {
|
|
21142
21164
|
responseType: 'text',
|
21143
21165
|
type: PlaylistContextType.LEVEL,
|
21144
21166
|
url,
|
21145
|
-
deliveryDirectives
|
21167
|
+
deliveryDirectives,
|
21168
|
+
levelOrTrack: levelInfo
|
21146
21169
|
});
|
21147
21170
|
}
|
21148
21171
|
onAudioTrackLoading(event, data) {
|
@@ -21150,7 +21173,8 @@ class PlaylistLoader {
|
|
21150
21173
|
id,
|
21151
21174
|
groupId,
|
21152
21175
|
url,
|
21153
|
-
deliveryDirectives
|
21176
|
+
deliveryDirectives,
|
21177
|
+
track
|
21154
21178
|
} = data;
|
21155
21179
|
this.load({
|
21156
21180
|
id,
|
@@ -21159,7 +21183,8 @@ class PlaylistLoader {
|
|
21159
21183
|
responseType: 'text',
|
21160
21184
|
type: PlaylistContextType.AUDIO_TRACK,
|
21161
21185
|
url,
|
21162
|
-
deliveryDirectives
|
21186
|
+
deliveryDirectives,
|
21187
|
+
levelOrTrack: track
|
21163
21188
|
});
|
21164
21189
|
}
|
21165
21190
|
onSubtitleTrackLoading(event, data) {
|
@@ -21167,7 +21192,8 @@ class PlaylistLoader {
|
|
21167
21192
|
id,
|
21168
21193
|
groupId,
|
21169
21194
|
url,
|
21170
|
-
deliveryDirectives
|
21195
|
+
deliveryDirectives,
|
21196
|
+
track
|
21171
21197
|
} = data;
|
21172
21198
|
this.load({
|
21173
21199
|
id,
|
@@ -21176,9 +21202,21 @@ class PlaylistLoader {
|
|
21176
21202
|
responseType: 'text',
|
21177
21203
|
type: PlaylistContextType.SUBTITLE_TRACK,
|
21178
21204
|
url,
|
21179
|
-
deliveryDirectives
|
21205
|
+
deliveryDirectives,
|
21206
|
+
levelOrTrack: track
|
21180
21207
|
});
|
21181
21208
|
}
|
21209
|
+
onLevelsUpdated(event, data) {
|
21210
|
+
// abort and delete loader of removed levels
|
21211
|
+
const loader = this.loaders[PlaylistContextType.LEVEL];
|
21212
|
+
if (loader) {
|
21213
|
+
const context = loader.context;
|
21214
|
+
if (context && !data.levels.some(lvl => lvl === context.levelOrTrack)) {
|
21215
|
+
loader.abort();
|
21216
|
+
delete this.loaders[PlaylistContextType.LEVEL];
|
21217
|
+
}
|
21218
|
+
}
|
21219
|
+
}
|
21182
21220
|
load(context) {
|
21183
21221
|
var _context$deliveryDire;
|
21184
21222
|
const config = this.hls.config;
|
@@ -21189,7 +21227,7 @@ class PlaylistLoader {
|
|
21189
21227
|
let loader = this.getInternalLoader(context);
|
21190
21228
|
if (loader) {
|
21191
21229
|
const loaderContext = loader.context;
|
21192
|
-
if (loaderContext && loaderContext.url === context.url && loaderContext.
|
21230
|
+
if (loaderContext && loaderContext.url === context.url && loaderContext.levelOrTrack === context.levelOrTrack) {
|
21193
21231
|
// same URL can't overlap
|
21194
21232
|
this.hls.logger.trace('[playlist-loader]: playlist request ongoing');
|
21195
21233
|
return;
|
@@ -21511,6 +21549,7 @@ class PlaylistLoader {
|
|
21511
21549
|
case PlaylistContextType.LEVEL:
|
21512
21550
|
hls.trigger(Events.LEVEL_LOADED, {
|
21513
21551
|
details: levelDetails,
|
21552
|
+
levelInfo: context.levelOrTrack || hls.levels[0],
|
21514
21553
|
level: levelIndex || 0,
|
21515
21554
|
id: id || 0,
|
21516
21555
|
stats,
|
@@ -21521,6 +21560,7 @@ class PlaylistLoader {
|
|
21521
21560
|
case PlaylistContextType.AUDIO_TRACK:
|
21522
21561
|
hls.trigger(Events.AUDIO_TRACK_LOADED, {
|
21523
21562
|
details: levelDetails,
|
21563
|
+
track: context.levelOrTrack,
|
21524
21564
|
id: id || 0,
|
21525
21565
|
groupId: groupId || '',
|
21526
21566
|
stats,
|
@@ -21531,6 +21571,7 @@ class PlaylistLoader {
|
|
21531
21571
|
case PlaylistContextType.SUBTITLE_TRACK:
|
21532
21572
|
hls.trigger(Events.SUBTITLE_TRACK_LOADED, {
|
21533
21573
|
details: levelDetails,
|
21574
|
+
track: context.levelOrTrack,
|
21534
21575
|
id: id || 0,
|
21535
21576
|
groupId: groupId || '',
|
21536
21577
|
stats,
|