hls.js 1.5.12-0.canary.10366 → 1.5.12-0.canary.10367
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 +293 -194
- package/dist/hls.js.d.ts +14 -8
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +211 -131
- 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 +208 -129
- 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 +290 -192
- 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 +1 -1
- package/src/controller/audio-stream-controller.ts +86 -84
- package/src/controller/base-stream-controller.ts +50 -41
- package/src/controller/buffer-controller.ts +20 -5
- package/src/controller/error-controller.ts +22 -14
- package/src/controller/fragment-finders.ts +33 -3
- package/src/controller/fragment-tracker.ts +30 -1
- package/src/controller/stream-controller.ts +54 -47
- package/src/controller/subtitle-stream-controller.ts +4 -4
- package/src/controller/timeline-controller.ts +1 -1
- package/src/hls.ts +1 -1
- package/src/loader/fragment-loader.ts +14 -19
- package/src/loader/fragment.ts +2 -2
- package/src/loader/level-details.ts +1 -2
- package/src/loader/playlist-loader.ts +1 -2
- package/src/remux/mp4-remuxer.ts +12 -8
- package/src/remux/passthrough-remuxer.ts +1 -1
- package/src/types/events.ts +13 -1
- package/src/utils/level-helper.ts +4 -5
- package/src/utils/rendition-helper.ts +84 -79
package/dist/hls.light.js
CHANGED
@@ -493,7 +493,7 @@
|
|
493
493
|
// Some browsers don't allow to use bind on console object anyway
|
494
494
|
// fallback to default if needed
|
495
495
|
try {
|
496
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.12-0.canary.
|
496
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.12-0.canary.10367");
|
497
497
|
} catch (e) {
|
498
498
|
/* log fn threw an exception. All logger methods are no-ops. */
|
499
499
|
return createLogger();
|
@@ -3713,10 +3713,9 @@
|
|
3713
3713
|
level = context.level,
|
3714
3714
|
type = context.type;
|
3715
3715
|
var url = getResponseUrl(response, context);
|
3716
|
-
var levelUrlId = 0;
|
3717
3716
|
var levelId = isFiniteNumber(level) ? level : isFiniteNumber(id) ? id : 0;
|
3718
3717
|
var levelType = mapContextToLevelType(context);
|
3719
|
-
var levelDetails = M3U8Parser.parseLevelPlaylist(response.data, url, levelId, levelType,
|
3718
|
+
var levelDetails = M3U8Parser.parseLevelPlaylist(response.data, url, levelId, levelType, 0, this.variableList);
|
3720
3719
|
|
3721
3720
|
// We have done our first request (Manifest-type) and receive
|
3722
3721
|
// not a master playlist but a chunk-list (track/level)
|
@@ -5504,8 +5503,7 @@
|
|
5504
5503
|
}
|
5505
5504
|
return Math.round(reloadInterval);
|
5506
5505
|
}
|
5507
|
-
function getFragmentWithSN(
|
5508
|
-
var details = level == null ? void 0 : level.details;
|
5506
|
+
function getFragmentWithSN(details, sn, fragCurrent) {
|
5509
5507
|
if (!details) {
|
5510
5508
|
return null;
|
5511
5509
|
}
|
@@ -5522,12 +5520,11 @@
|
|
5522
5520
|
}
|
5523
5521
|
return null;
|
5524
5522
|
}
|
5525
|
-
function getPartWith(
|
5526
|
-
|
5527
|
-
if (!(level != null && level.details)) {
|
5523
|
+
function getPartWith(details, sn, partIndex) {
|
5524
|
+
if (!details) {
|
5528
5525
|
return null;
|
5529
5526
|
}
|
5530
|
-
return findPart(
|
5527
|
+
return findPart(details.partList, sn, partIndex);
|
5531
5528
|
}
|
5532
5529
|
function findPart(partList, sn, partIndex) {
|
5533
5530
|
if (partList) {
|
@@ -5678,12 +5675,15 @@
|
|
5678
5675
|
}
|
5679
5676
|
var fragNext = null;
|
5680
5677
|
if (fragPrevious) {
|
5681
|
-
fragNext = fragments[fragPrevious.sn - fragments[0].sn
|
5678
|
+
fragNext = fragments[1 + fragPrevious.sn - fragments[0].sn] || null;
|
5682
5679
|
// check for buffer-end rounding error
|
5683
5680
|
var bufferEdgeError = fragPrevious.endDTS - bufferEnd;
|
5684
5681
|
if (bufferEdgeError > 0 && bufferEdgeError < 0.0000015) {
|
5685
5682
|
bufferEnd += 0.0000015;
|
5686
5683
|
}
|
5684
|
+
if (fragNext && fragPrevious.level !== fragNext.level && fragNext.end <= fragPrevious.end) {
|
5685
|
+
fragNext = fragments[2 + fragPrevious.sn - fragments[0].sn] || null;
|
5686
|
+
}
|
5687
5687
|
} else if (bufferEnd === 0 && fragments[0].start === 0) {
|
5688
5688
|
fragNext = fragments[0];
|
5689
5689
|
}
|
@@ -5845,7 +5845,7 @@
|
|
5845
5845
|
this.playlistError = 0;
|
5846
5846
|
};
|
5847
5847
|
_proto.onError = function onError(event, data) {
|
5848
|
-
var _data$frag
|
5848
|
+
var _data$frag;
|
5849
5849
|
if (data.fatal) {
|
5850
5850
|
return;
|
5851
5851
|
}
|
@@ -5861,10 +5861,7 @@
|
|
5861
5861
|
case ErrorDetails.FRAG_PARSING_ERROR:
|
5862
5862
|
// ignore empty segment errors marked as gap
|
5863
5863
|
if ((_data$frag = data.frag) != null && _data$frag.gap) {
|
5864
|
-
data.errorAction =
|
5865
|
-
action: NetworkErrorAction.DoNothing,
|
5866
|
-
flags: ErrorActionFlags.None
|
5867
|
-
};
|
5864
|
+
data.errorAction = createDoNothingErrorAction();
|
5868
5865
|
return;
|
5869
5866
|
}
|
5870
5867
|
// falls through
|
@@ -5931,7 +5928,11 @@
|
|
5931
5928
|
case ErrorDetails.BUFFER_ADD_CODEC_ERROR:
|
5932
5929
|
case ErrorDetails.REMUX_ALLOC_ERROR:
|
5933
5930
|
case ErrorDetails.BUFFER_APPEND_ERROR:
|
5934
|
-
|
5931
|
+
// Buffer-controller can set errorAction when append errors can be ignored or resolved locally
|
5932
|
+
if (!data.errorAction) {
|
5933
|
+
var _data$level;
|
5934
|
+
data.errorAction = this.getLevelSwitchAction(data, (_data$level = data.level) != null ? _data$level : hls.loadLevel);
|
5935
|
+
}
|
5935
5936
|
return;
|
5936
5937
|
case ErrorDetails.INTERNAL_EXCEPTION:
|
5937
5938
|
case ErrorDetails.BUFFER_APPENDING_ERROR:
|
@@ -5940,10 +5941,7 @@
|
|
5940
5941
|
case ErrorDetails.BUFFER_STALLED_ERROR:
|
5941
5942
|
case ErrorDetails.BUFFER_SEEK_OVER_HOLE:
|
5942
5943
|
case ErrorDetails.BUFFER_NUDGE_ON_STALL:
|
5943
|
-
data.errorAction =
|
5944
|
-
action: NetworkErrorAction.DoNothing,
|
5945
|
-
flags: ErrorActionFlags.None
|
5946
|
-
};
|
5944
|
+
data.errorAction = createDoNothingErrorAction();
|
5947
5945
|
return;
|
5948
5946
|
}
|
5949
5947
|
if (data.type === ErrorTypes.KEY_SYSTEM_ERROR) {
|
@@ -6162,6 +6160,13 @@
|
|
6162
6160
|
};
|
6163
6161
|
return ErrorController;
|
6164
6162
|
}(Logger);
|
6163
|
+
function createDoNothingErrorAction(resolved) {
|
6164
|
+
var errorAction = {
|
6165
|
+
action: NetworkErrorAction.DoNothing,
|
6166
|
+
flags: ErrorActionFlags.None
|
6167
|
+
};
|
6168
|
+
return errorAction;
|
6169
|
+
}
|
6165
6170
|
|
6166
6171
|
var BasePlaylistController = /*#__PURE__*/function (_Logger) {
|
6167
6172
|
function BasePlaylistController(hls, logPrefix) {
|
@@ -6637,6 +6642,7 @@
|
|
6637
6642
|
if (!hasCurrentVideoRange) {
|
6638
6643
|
currentVideoRange = undefined;
|
6639
6644
|
}
|
6645
|
+
var hasMultipleSets = codecSets.length > 1;
|
6640
6646
|
var codecSet = codecSets.reduce(function (selected, candidate) {
|
6641
6647
|
// Remove candiates which do not meet bitrate, default audio, stereo or channels preference, 1080p or lower, 30fps or lower, or SDR/HDR selection if present
|
6642
6648
|
var candidateTier = codecTiers[candidate];
|
@@ -6646,48 +6652,50 @@
|
|
6646
6652
|
videoRanges = hasCurrentVideoRange ? allowedVideoRanges.filter(function (range) {
|
6647
6653
|
return candidateTier.videoRanges[range] > 0;
|
6648
6654
|
}) : [];
|
6649
|
-
if (
|
6650
|
-
|
6651
|
-
|
6652
|
-
|
6653
|
-
|
6654
|
-
|
6655
|
-
|
6656
|
-
|
6657
|
-
|
6658
|
-
|
6659
|
-
|
6660
|
-
|
6661
|
-
|
6662
|
-
if (!
|
6663
|
-
|
6655
|
+
if (hasMultipleSets) {
|
6656
|
+
if (candidateTier.minBitrate > currentBw) {
|
6657
|
+
logStartCodecCandidateIgnored(candidate, "min bitrate of " + candidateTier.minBitrate + " > current estimate of " + currentBw);
|
6658
|
+
return selected;
|
6659
|
+
}
|
6660
|
+
if (!candidateTier.hasDefaultAudio) {
|
6661
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with default or auto-select sound found");
|
6662
|
+
return selected;
|
6663
|
+
}
|
6664
|
+
if (audioCodecPreference && candidate.indexOf(audioCodecPreference.substring(0, 4)) % 5 !== 0) {
|
6665
|
+
logStartCodecCandidateIgnored(candidate, "audio codec preference \"" + audioCodecPreference + "\" not found");
|
6666
|
+
return selected;
|
6667
|
+
}
|
6668
|
+
if (channelsPreference && !preferStereo) {
|
6669
|
+
if (!candidateTier.channels[channelsPreference]) {
|
6670
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with " + channelsPreference + " channel sound found (channels options: " + Object.keys(candidateTier.channels) + ")");
|
6671
|
+
return selected;
|
6672
|
+
}
|
6673
|
+
} else if ((!audioCodecPreference || preferStereo) && hasStereo && candidateTier.channels['2'] === 0) {
|
6674
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with stereo sound found");
|
6675
|
+
return selected;
|
6676
|
+
}
|
6677
|
+
if (candidateTier.minHeight > maxHeight) {
|
6678
|
+
logStartCodecCandidateIgnored(candidate, "min resolution of " + candidateTier.minHeight + " > maximum of " + maxHeight);
|
6679
|
+
return selected;
|
6680
|
+
}
|
6681
|
+
if (candidateTier.minFramerate > maxFramerate) {
|
6682
|
+
logStartCodecCandidateIgnored(candidate, "min framerate of " + candidateTier.minFramerate + " > maximum of " + maxFramerate);
|
6683
|
+
return selected;
|
6684
|
+
}
|
6685
|
+
if (!videoRanges.some(function (range) {
|
6686
|
+
return candidateTier.videoRanges[range] > 0;
|
6687
|
+
})) {
|
6688
|
+
logStartCodecCandidateIgnored(candidate, "no variants with VIDEO-RANGE of " + JSON.stringify(videoRanges) + " found");
|
6689
|
+
return selected;
|
6690
|
+
}
|
6691
|
+
if (videoCodecPreference && candidate.indexOf(videoCodecPreference.substring(0, 4)) % 5 !== 0) {
|
6692
|
+
logStartCodecCandidateIgnored(candidate, "video codec preference \"" + videoCodecPreference + "\" not found");
|
6693
|
+
return selected;
|
6694
|
+
}
|
6695
|
+
if (candidateTier.maxScore < selectedScore) {
|
6696
|
+
logStartCodecCandidateIgnored(candidate, "max score of " + candidateTier.maxScore + " < selected max of " + selectedScore);
|
6664
6697
|
return selected;
|
6665
6698
|
}
|
6666
|
-
} else if ((!audioCodecPreference || preferStereo) && hasStereo && candidateTier.channels['2'] === 0) {
|
6667
|
-
logStartCodecCandidateIgnored(candidate, "no renditions with stereo sound found");
|
6668
|
-
return selected;
|
6669
|
-
}
|
6670
|
-
if (candidateTier.minHeight > maxHeight) {
|
6671
|
-
logStartCodecCandidateIgnored(candidate, "min resolution of " + candidateTier.minHeight + " > maximum of " + maxHeight);
|
6672
|
-
return selected;
|
6673
|
-
}
|
6674
|
-
if (candidateTier.minFramerate > maxFramerate) {
|
6675
|
-
logStartCodecCandidateIgnored(candidate, "min framerate of " + candidateTier.minFramerate + " > maximum of " + maxFramerate);
|
6676
|
-
return selected;
|
6677
|
-
}
|
6678
|
-
if (!videoRanges.some(function (range) {
|
6679
|
-
return candidateTier.videoRanges[range] > 0;
|
6680
|
-
})) {
|
6681
|
-
logStartCodecCandidateIgnored(candidate, "no variants with VIDEO-RANGE of " + JSON.stringify(videoRanges) + " found");
|
6682
|
-
return selected;
|
6683
|
-
}
|
6684
|
-
if (videoCodecPreference && candidate.indexOf(videoCodecPreference.substring(0, 4)) % 5 !== 0) {
|
6685
|
-
logStartCodecCandidateIgnored(candidate, "video codec preference \"" + videoCodecPreference + "\" not found");
|
6686
|
-
return selected;
|
6687
|
-
}
|
6688
|
-
if (candidateTier.maxScore < selectedScore) {
|
6689
|
-
logStartCodecCandidateIgnored(candidate, "max score of " + candidateTier.maxScore + " < selected max of " + selectedScore);
|
6690
|
-
return selected;
|
6691
6699
|
}
|
6692
6700
|
// Remove candiates with less preferred codecs or more errors
|
6693
6701
|
if (selected && (codecsSetSelectionPreferenceValue(candidate) >= codecsSetSelectionPreferenceValue(selected) || candidateTier.fragmentError > codecTiers[selected].fragmentError)) {
|
@@ -7288,7 +7296,7 @@
|
|
7288
7296
|
if (levelsSkipped.length) {
|
7289
7297
|
_this3.trace("Skipped level(s) " + levelsSkipped.join(',') + " of " + maxAutoLevel + " max with CODECS and VIDEO-RANGE:\"" + levels[levelsSkipped[0]].codecs + "\" " + levels[levelsSkipped[0]].videoRange + "; not compatible with \"" + level.codecs + "\" " + currentVideoRange);
|
7290
7298
|
}
|
7291
|
-
_this3.info("switch candidate:" + selectionBaseLevel + "->" + i + " adjustedbw(" + Math.round(adjustedbw) + ")-bitrate=" + Math.round(adjustedbw - bitrate) + " ttfb:" + ttfbEstimateSec.toFixed(1) + " avgDuration:" + avgDuration.toFixed(1) + " maxFetchDuration:" + maxFetchDuration.toFixed(1) + " fetchDuration:" + fetchDuration.toFixed(1) + " firstSelection:" + firstSelection + " codecSet:" +
|
7299
|
+
_this3.info("switch candidate:" + selectionBaseLevel + "->" + i + " adjustedbw(" + Math.round(adjustedbw) + ")-bitrate=" + Math.round(adjustedbw - bitrate) + " ttfb:" + ttfbEstimateSec.toFixed(1) + " avgDuration:" + avgDuration.toFixed(1) + " maxFetchDuration:" + maxFetchDuration.toFixed(1) + " fetchDuration:" + fetchDuration.toFixed(1) + " firstSelection:" + firstSelection + " codecSet:" + levelInfo.codecSet + " videoRange:" + levelInfo.videoRange + " hls.loadLevel:" + loadLevel);
|
7292
7300
|
}
|
7293
7301
|
if (firstSelection) {
|
7294
7302
|
_this3.firstSelection = i;
|
@@ -7704,6 +7712,7 @@
|
|
7704
7712
|
hls.on(Events.LEVEL_UPDATED, this.onLevelUpdated, this);
|
7705
7713
|
hls.on(Events.FRAG_PARSED, this.onFragParsed, this);
|
7706
7714
|
hls.on(Events.FRAG_CHANGED, this.onFragChanged, this);
|
7715
|
+
hls.on(Events.ERROR, this.onError, this);
|
7707
7716
|
};
|
7708
7717
|
_proto.unregisterListeners = function unregisterListeners() {
|
7709
7718
|
var hls = this.hls;
|
@@ -7719,6 +7728,7 @@
|
|
7719
7728
|
hls.off(Events.LEVEL_UPDATED, this.onLevelUpdated, this);
|
7720
7729
|
hls.off(Events.FRAG_PARSED, this.onFragParsed, this);
|
7721
7730
|
hls.off(Events.FRAG_CHANGED, this.onFragChanged, this);
|
7731
|
+
hls.off(Events.ERROR, this.onError, this);
|
7722
7732
|
};
|
7723
7733
|
_proto._initSourceBuffer = function _initSourceBuffer() {
|
7724
7734
|
this.sourceBuffer = {};
|
@@ -7728,11 +7738,7 @@
|
|
7728
7738
|
video: [],
|
7729
7739
|
audiovideo: []
|
7730
7740
|
};
|
7731
|
-
this.
|
7732
|
-
audio: 0,
|
7733
|
-
video: 0,
|
7734
|
-
audiovideo: 0
|
7735
|
-
};
|
7741
|
+
this.resetAppendErrors();
|
7736
7742
|
this.lastMpegAudioChunk = null;
|
7737
7743
|
this.blockedAudioAppend = null;
|
7738
7744
|
this.lastVideoAppendEnd = 0;
|
@@ -8262,6 +8268,22 @@
|
|
8262
8268
|
this.updateMediaSource(durationAndRange);
|
8263
8269
|
}
|
8264
8270
|
};
|
8271
|
+
_proto.onError = function onError(event, data) {
|
8272
|
+
if (data.details === ErrorDetails.BUFFER_APPEND_ERROR && data.frag) {
|
8273
|
+
var _data$errorAction;
|
8274
|
+
var nextAutoLevel = (_data$errorAction = data.errorAction) == null ? void 0 : _data$errorAction.nextAutoLevel;
|
8275
|
+
if (isFiniteNumber(nextAutoLevel) && nextAutoLevel !== data.frag.level) {
|
8276
|
+
this.resetAppendErrors();
|
8277
|
+
}
|
8278
|
+
}
|
8279
|
+
};
|
8280
|
+
_proto.resetAppendErrors = function resetAppendErrors() {
|
8281
|
+
this.appendErrors = {
|
8282
|
+
audio: 0,
|
8283
|
+
video: 0,
|
8284
|
+
audiovideo: 0
|
8285
|
+
};
|
8286
|
+
};
|
8265
8287
|
_proto.trimBuffers = function trimBuffers() {
|
8266
8288
|
var hls = this.hls,
|
8267
8289
|
details = this.details,
|
@@ -10963,12 +10985,14 @@
|
|
10963
10985
|
var _proto = FragmentTracker.prototype;
|
10964
10986
|
_proto._registerListeners = function _registerListeners() {
|
10965
10987
|
var hls = this.hls;
|
10988
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
10966
10989
|
hls.on(Events.BUFFER_APPENDED, this.onBufferAppended, this);
|
10967
10990
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
10968
10991
|
hls.on(Events.FRAG_LOADED, this.onFragLoaded, this);
|
10969
10992
|
};
|
10970
10993
|
_proto._unregisterListeners = function _unregisterListeners() {
|
10971
10994
|
var hls = this.hls;
|
10995
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
10972
10996
|
hls.off(Events.BUFFER_APPENDED, this.onBufferAppended, this);
|
10973
10997
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
10974
10998
|
hls.off(Events.FRAG_LOADED, this.onFragLoaded, this);
|
@@ -11032,7 +11056,7 @@
|
|
11032
11056
|
* The browser will unload parts of the buffer to free up memory for new buffer data
|
11033
11057
|
* Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable)
|
11034
11058
|
*/;
|
11035
|
-
_proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType, appendedPart) {
|
11059
|
+
_proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType, appendedPart, removeAppending) {
|
11036
11060
|
var _this = this;
|
11037
11061
|
if (this.timeRanges) {
|
11038
11062
|
this.timeRanges[elementaryStream] = timeRange;
|
@@ -11048,7 +11072,7 @@
|
|
11048
11072
|
if (appendedPartSn >= fragmentEntity.body.sn) {
|
11049
11073
|
return;
|
11050
11074
|
}
|
11051
|
-
if (!fragmentEntity.buffered && !fragmentEntity.loaded) {
|
11075
|
+
if (!fragmentEntity.buffered && (!fragmentEntity.loaded || removeAppending)) {
|
11052
11076
|
if (fragmentEntity.body.type === playlistType) {
|
11053
11077
|
_this.removeFragment(fragmentEntity.body);
|
11054
11078
|
}
|
@@ -11058,6 +11082,10 @@
|
|
11058
11082
|
if (!esData) {
|
11059
11083
|
return;
|
11060
11084
|
}
|
11085
|
+
if (esData.time.length === 0) {
|
11086
|
+
_this.removeFragment(fragmentEntity.body);
|
11087
|
+
return;
|
11088
|
+
}
|
11061
11089
|
esData.time.some(function (time) {
|
11062
11090
|
var isNotBuffered = !_this.isTimeBuffered(time.startPTS, time.endPTS, timeRange);
|
11063
11091
|
if (isNotBuffered) {
|
@@ -11245,6 +11273,9 @@
|
|
11245
11273
|
}
|
11246
11274
|
return false;
|
11247
11275
|
};
|
11276
|
+
_proto.onManifestLoading = function onManifestLoading() {
|
11277
|
+
this.removeAllFragments();
|
11278
|
+
};
|
11248
11279
|
_proto.onFragLoaded = function onFragLoaded(event, data) {
|
11249
11280
|
// don't track initsegment (for which sn is not a number)
|
11250
11281
|
// don't track frags used for bitrateTest, they're irrelevant.
|
@@ -11291,6 +11322,20 @@
|
|
11291
11322
|
var fragKey = getFragmentKey(fragment);
|
11292
11323
|
return !!this.fragments[fragKey];
|
11293
11324
|
};
|
11325
|
+
_proto.hasFragments = function hasFragments(type) {
|
11326
|
+
var fragments = this.fragments;
|
11327
|
+
var keys = Object.keys(fragments);
|
11328
|
+
if (!type) {
|
11329
|
+
return keys.length > 0;
|
11330
|
+
}
|
11331
|
+
for (var i = keys.length; i--;) {
|
11332
|
+
var fragmentEntity = fragments[keys[i]];
|
11333
|
+
if ((fragmentEntity == null ? void 0 : fragmentEntity.body.type) === type) {
|
11334
|
+
return true;
|
11335
|
+
}
|
11336
|
+
}
|
11337
|
+
return false;
|
11338
|
+
};
|
11294
11339
|
_proto.hasParts = function hasParts(type) {
|
11295
11340
|
var _this$activePartLists;
|
11296
11341
|
return !!((_this$activePartLists = this.activePartLists[type]) != null && _this$activePartLists.length);
|
@@ -11399,8 +11444,9 @@
|
|
11399
11444
|
frag.gap = false;
|
11400
11445
|
}
|
11401
11446
|
}
|
11402
|
-
var loader = _this.loader =
|
11447
|
+
var loader = _this.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
|
11403
11448
|
var loaderContext = createLoaderContext(frag);
|
11449
|
+
frag.loader = loader;
|
11404
11450
|
var loadPolicy = getLoaderConfigWithoutReties(config.fragLoadPolicy.default);
|
11405
11451
|
var loaderConfig = {
|
11406
11452
|
loadPolicy: loadPolicy,
|
@@ -11494,8 +11540,9 @@
|
|
11494
11540
|
reject(createGapLoadError(frag, part));
|
11495
11541
|
return;
|
11496
11542
|
}
|
11497
|
-
var loader = _this2.loader =
|
11543
|
+
var loader = _this2.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
|
11498
11544
|
var loaderContext = createLoaderContext(frag, part);
|
11545
|
+
frag.loader = loader;
|
11499
11546
|
// Should we define another load policy for parts?
|
11500
11547
|
var loadPolicy = getLoaderConfigWithoutReties(config.fragLoadPolicy.default);
|
11501
11548
|
var loaderConfig = {
|
@@ -12767,6 +12814,7 @@
|
|
12767
12814
|
_this.initPTS = [];
|
12768
12815
|
_this.buffering = true;
|
12769
12816
|
_this.loadingParts = false;
|
12817
|
+
_this.loopSn = void 0;
|
12770
12818
|
_this.onMediaSeeking = function () {
|
12771
12819
|
var _this2 = _this,
|
12772
12820
|
config = _this2.config,
|
@@ -12865,6 +12913,9 @@
|
|
12865
12913
|
;
|
12866
12914
|
_proto.startLoad = function startLoad(startPosition) {};
|
12867
12915
|
_proto.stopLoad = function stopLoad() {
|
12916
|
+
if (this.state === State.STOPPED) {
|
12917
|
+
return;
|
12918
|
+
}
|
12868
12919
|
this.fragmentLoader.abort();
|
12869
12920
|
this.keyLoader.abort(this.playlistType);
|
12870
12921
|
var frag = this.fragCurrent;
|
@@ -12938,15 +12989,20 @@
|
|
12938
12989
|
this.keyLoader.detach();
|
12939
12990
|
}
|
12940
12991
|
this.media = this.mediaBuffer = null;
|
12941
|
-
this.
|
12992
|
+
this.loopSn = undefined;
|
12993
|
+
this.startFragRequested = this.loadedmetadata = this.loadingParts = false;
|
12942
12994
|
this.fragmentTracker.removeAllFragments();
|
12943
12995
|
this.stopLoad();
|
12944
12996
|
};
|
12945
|
-
_proto.onManifestLoading = function onManifestLoading() {
|
12997
|
+
_proto.onManifestLoading = function onManifestLoading() {
|
12998
|
+
this.initPTS = [];
|
12999
|
+
this.levels = this.levelLastLoaded = this.fragCurrent = null;
|
13000
|
+
this.lastCurrentTime = this.startPosition = 0;
|
13001
|
+
this.startFragRequested = false;
|
13002
|
+
};
|
12946
13003
|
_proto.onError = function onError(event, data) {};
|
12947
13004
|
_proto.onManifestLoaded = function onManifestLoaded(event, data) {
|
12948
13005
|
this.startTimeOffset = data.startTimeOffset;
|
12949
|
-
this.initPTS = [];
|
12950
13006
|
};
|
12951
13007
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
12952
13008
|
this.stopLoad();
|
@@ -12969,6 +13025,7 @@
|
|
12969
13025
|
_TaskLoop.prototype.onHandlerDestroyed.call(this);
|
12970
13026
|
};
|
12971
13027
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
13028
|
+
this.startFragRequested = true;
|
12972
13029
|
this._loadFragForPlayback(frag, level, targetBufferTime);
|
12973
13030
|
};
|
12974
13031
|
_proto._loadFragForPlayback = function _loadFragForPlayback(frag, level, targetBufferTime) {
|
@@ -13197,6 +13254,7 @@
|
|
13197
13254
|
if (targetBufferTime === void 0) {
|
13198
13255
|
targetBufferTime = null;
|
13199
13256
|
}
|
13257
|
+
this.fragCurrent = frag;
|
13200
13258
|
var details = level == null ? void 0 : level.details;
|
13201
13259
|
if (!this.levels || !details) {
|
13202
13260
|
throw new Error("frag load aborted, missing level" + (details ? '' : ' detail') + "s");
|
@@ -13334,7 +13392,7 @@
|
|
13334
13392
|
partsLoaded[part.index] = partLoadedData;
|
13335
13393
|
var loadedPart = partLoadedData.part;
|
13336
13394
|
_this6.hls.trigger(Events.FRAG_LOADED, partLoadedData);
|
13337
|
-
var nextPart = getPartWith(level, frag.sn, part.index + 1) || findPart(initialPartList, frag.sn, part.index + 1);
|
13395
|
+
var nextPart = getPartWith(level.details, frag.sn, part.index + 1) || findPart(initialPartList, frag.sn, part.index + 1);
|
13338
13396
|
if (nextPart) {
|
13339
13397
|
loadPart(nextPart);
|
13340
13398
|
} else {
|
@@ -13423,8 +13481,9 @@
|
|
13423
13481
|
return null;
|
13424
13482
|
}
|
13425
13483
|
var level = levels[levelIndex];
|
13426
|
-
var
|
13427
|
-
var
|
13484
|
+
var levelDetails = level.details;
|
13485
|
+
var part = partIndex > -1 ? getPartWith(levelDetails, sn, partIndex) : null;
|
13486
|
+
var frag = part ? part.fragment : getFragmentWithSN(levelDetails, sn, fragCurrent);
|
13428
13487
|
if (!frag) {
|
13429
13488
|
return null;
|
13430
13489
|
}
|
@@ -13531,7 +13590,11 @@
|
|
13531
13590
|
return false;
|
13532
13591
|
};
|
13533
13592
|
_proto.getAppendedFrag = function getAppendedFrag(position, playlistType) {
|
13534
|
-
var
|
13593
|
+
var _this$fragmentTracker;
|
13594
|
+
if (playlistType === void 0) {
|
13595
|
+
playlistType = PlaylistLevelType.MAIN;
|
13596
|
+
}
|
13597
|
+
var fragOrPart = (_this$fragmentTracker = this.fragmentTracker) == null ? void 0 : _this$fragmentTracker.getAppendedFrag(position, playlistType);
|
13535
13598
|
if (fragOrPart && 'fragment' in fragOrPart) {
|
13536
13599
|
return fragOrPart.fragment;
|
13537
13600
|
}
|
@@ -13584,22 +13647,25 @@
|
|
13584
13647
|
return (trackerState === FragmentState.OK || trackerState === FragmentState.PARTIAL && !!frag.gap) && this.nextLoadPosition > targetBufferTime;
|
13585
13648
|
};
|
13586
13649
|
_proto.getNextFragmentLoopLoading = function getNextFragmentLoopLoading(frag, levelDetails, bufferInfo, playlistType, maxBufLen) {
|
13587
|
-
var
|
13588
|
-
|
13589
|
-
|
13590
|
-
|
13591
|
-
|
13592
|
-
|
13593
|
-
|
13594
|
-
|
13595
|
-
|
13596
|
-
|
13597
|
-
|
13598
|
-
|
13599
|
-
|
13650
|
+
var nextFragment = null;
|
13651
|
+
if (frag.gap) {
|
13652
|
+
nextFragment = this.getNextFragment(this.nextLoadPosition, levelDetails);
|
13653
|
+
if (nextFragment && !nextFragment.gap && bufferInfo.nextStart) {
|
13654
|
+
// Media buffered after GAP tags should not make the next buffer timerange exceed forward buffer length
|
13655
|
+
var nextbufferInfo = this.getFwdBufferInfoAtPos(this.mediaBuffer ? this.mediaBuffer : this.media, bufferInfo.nextStart, playlistType);
|
13656
|
+
if (nextbufferInfo !== null && bufferInfo.len + nextbufferInfo.len >= maxBufLen) {
|
13657
|
+
// Returning here might result in not finding an audio and video candiate to skip to
|
13658
|
+
var sn = nextFragment.sn;
|
13659
|
+
if (this.loopSn !== sn) {
|
13660
|
+
this.log("buffer full after gaps in \"" + playlistType + "\" playlist starting at sn: " + sn);
|
13661
|
+
this.loopSn = sn;
|
13662
|
+
}
|
13663
|
+
return null;
|
13664
|
+
}
|
13600
13665
|
}
|
13601
13666
|
}
|
13602
|
-
|
13667
|
+
this.loopSn = undefined;
|
13668
|
+
return nextFragment;
|
13603
13669
|
};
|
13604
13670
|
_proto.mapToInitFragWhenRequired = function mapToInitFragWhenRequired(frag) {
|
13605
13671
|
// If an initSegment is present, it must be buffered first
|
@@ -13794,7 +13860,7 @@
|
|
13794
13860
|
if (startTimeOffset !== null && isFiniteNumber(startTimeOffset)) {
|
13795
13861
|
startPosition = sliding + startTimeOffset;
|
13796
13862
|
if (startTimeOffset < 0) {
|
13797
|
-
startPosition += details.
|
13863
|
+
startPosition += details.edge;
|
13798
13864
|
}
|
13799
13865
|
startPosition = Math.min(Math.max(sliding, startPosition), sliding + details.totalduration);
|
13800
13866
|
this.log("Start time offset " + startTimeOffset + " found in " + (offsetInMultivariantPlaylist ? 'multivariant' : 'media') + " playlist, adjust startPosition to " + startPosition);
|
@@ -17395,10 +17461,11 @@
|
|
17395
17461
|
if (this.ISGenerated) {
|
17396
17462
|
var _videoTrack$pixelRati, _config$pixelRatio, _videoTrack$pixelRati2, _config$pixelRatio2;
|
17397
17463
|
var config = this.videoTrackConfig;
|
17398
|
-
if (config && (videoTrack.width !== config.width || videoTrack.height !== config.height || ((_videoTrack$pixelRati = videoTrack.pixelRatio) == null ? void 0 : _videoTrack$pixelRati[0]) !== ((_config$pixelRatio = config.pixelRatio) == null ? void 0 : _config$pixelRatio[0]) || ((_videoTrack$pixelRati2 = videoTrack.pixelRatio) == null ? void 0 : _videoTrack$pixelRati2[1]) !== ((_config$pixelRatio2 = config.pixelRatio) == null ? void 0 : _config$pixelRatio2[1]))) {
|
17464
|
+
if (config && (videoTrack.width !== config.width || videoTrack.height !== config.height || ((_videoTrack$pixelRati = videoTrack.pixelRatio) == null ? void 0 : _videoTrack$pixelRati[0]) !== ((_config$pixelRatio = config.pixelRatio) == null ? void 0 : _config$pixelRatio[0]) || ((_videoTrack$pixelRati2 = videoTrack.pixelRatio) == null ? void 0 : _videoTrack$pixelRati2[1]) !== ((_config$pixelRatio2 = config.pixelRatio) == null ? void 0 : _config$pixelRatio2[1])) || !config && enoughVideoSamples || this.nextAudioPts === null && enoughAudioSamples) {
|
17399
17465
|
this.resetInitSegment();
|
17400
17466
|
}
|
17401
|
-
}
|
17467
|
+
}
|
17468
|
+
if (!this.ISGenerated) {
|
17402
17469
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
17403
17470
|
}
|
17404
17471
|
var isVideoContiguous = this.isVideoContiguous;
|
@@ -18316,7 +18383,7 @@
|
|
18316
18383
|
if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
|
18317
18384
|
initSegment.initPTS = decodeTime - timeOffset;
|
18318
18385
|
if (initPTS && initPTS.timescale === 1) {
|
18319
|
-
logger.warn("Adjusting initPTS
|
18386
|
+
logger.warn("Adjusting initPTS @" + timeOffset + " from " + initPTS.baseTime / initPTS.timescale + " to " + initSegment.initPTS);
|
18320
18387
|
}
|
18321
18388
|
this.initPTS = initPTS = {
|
18322
18389
|
baseTime: initSegment.initPTS,
|
@@ -20171,7 +20238,6 @@
|
|
20171
20238
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
20172
20239
|
// Check if fragment is not loaded
|
20173
20240
|
var fragState = this.fragmentTracker.getState(frag);
|
20174
|
-
this.fragCurrent = frag;
|
20175
20241
|
if (fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
20176
20242
|
if (frag.sn === 'initSegment') {
|
20177
20243
|
this._loadInitSegment(frag, level);
|
@@ -20179,7 +20245,6 @@
|
|
20179
20245
|
this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered");
|
20180
20246
|
this._loadBitrateTestFrag(frag, level);
|
20181
20247
|
} else {
|
20182
|
-
this.startFragRequested = true;
|
20183
20248
|
_BaseStreamController.prototype.loadFragment.call(this, frag, level, targetBufferTime);
|
20184
20249
|
}
|
20185
20250
|
} else {
|
@@ -20309,14 +20374,14 @@
|
|
20309
20374
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
20310
20375
|
};
|
20311
20376
|
_proto.onManifestLoading = function onManifestLoading() {
|
20377
|
+
_BaseStreamController.prototype.onManifestLoading.call(this);
|
20312
20378
|
// reset buffer on manifest loading
|
20313
20379
|
this.log('Trigger BUFFER_RESET');
|
20314
20380
|
this.hls.trigger(Events.BUFFER_RESET, undefined);
|
20315
|
-
this.fragmentTracker.removeAllFragments();
|
20316
20381
|
this.couldBacktrack = false;
|
20317
|
-
this.
|
20318
|
-
this.
|
20319
|
-
this.altAudio = this.audioOnly =
|
20382
|
+
this.fragLastKbps = 0;
|
20383
|
+
this.fragPlaying = this.backtrackFragment = null;
|
20384
|
+
this.altAudio = this.audioOnly = false;
|
20320
20385
|
};
|
20321
20386
|
_proto.onManifestParsed = function onManifestParsed(event, data) {
|
20322
20387
|
// detect if we have different kind of audio codecs used amongst playlists
|
@@ -20601,7 +20666,7 @@
|
|
20601
20666
|
// in that case, reset startFragRequested flag
|
20602
20667
|
if (!this.loadedmetadata) {
|
20603
20668
|
this.startFragRequested = false;
|
20604
|
-
this.nextLoadPosition = this.
|
20669
|
+
this.nextLoadPosition = this.lastCurrentTime;
|
20605
20670
|
}
|
20606
20671
|
this.tickImmediate();
|
20607
20672
|
};
|
@@ -20685,7 +20750,7 @@
|
|
20685
20750
|
};
|
20686
20751
|
_proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) {
|
20687
20752
|
var _id3$samples;
|
20688
|
-
var id =
|
20753
|
+
var id = this.playlistType;
|
20689
20754
|
var hls = this.hls;
|
20690
20755
|
var remuxResult = transmuxResult.remuxResult,
|
20691
20756
|
chunkMeta = transmuxResult.chunkMeta;
|
@@ -20875,31 +20940,38 @@
|
|
20875
20940
|
audio.levelCodec = audioCodec;
|
20876
20941
|
audio.id = 'main';
|
20877
20942
|
this.log("Init audio buffer, container:" + audio.container + ", codecs[selected/level/parsed]=[" + (audioCodec || '') + "/" + (currentLevel.audioCodec || '') + "/" + audio.codec + "]");
|
20943
|
+
delete tracks.audiovideo;
|
20878
20944
|
}
|
20879
20945
|
if (video) {
|
20880
20946
|
video.levelCodec = currentLevel.videoCodec;
|
20881
20947
|
video.id = 'main';
|
20882
20948
|
this.log("Init video buffer, container:" + video.container + ", codecs[level/parsed]=[" + (currentLevel.videoCodec || '') + "/" + video.codec + "]");
|
20949
|
+
delete tracks.audiovideo;
|
20883
20950
|
}
|
20884
20951
|
if (audiovideo) {
|
20885
20952
|
this.log("Init audiovideo buffer, container:" + audiovideo.container + ", codecs[level/parsed]=[" + currentLevel.codecs + "/" + audiovideo.codec + "]");
|
20953
|
+
delete tracks.video;
|
20954
|
+
delete tracks.audio;
|
20955
|
+
}
|
20956
|
+
var trackTypes = Object.keys(tracks);
|
20957
|
+
if (trackTypes.length) {
|
20958
|
+
this.hls.trigger(Events.BUFFER_CODECS, tracks);
|
20959
|
+
// loop through tracks that are going to be provided to bufferController
|
20960
|
+
trackTypes.forEach(function (trackName) {
|
20961
|
+
var track = tracks[trackName];
|
20962
|
+
var initSegment = track.initSegment;
|
20963
|
+
if (initSegment != null && initSegment.byteLength) {
|
20964
|
+
_this3.hls.trigger(Events.BUFFER_APPENDING, {
|
20965
|
+
type: trackName,
|
20966
|
+
data: initSegment,
|
20967
|
+
frag: frag,
|
20968
|
+
part: null,
|
20969
|
+
chunkMeta: chunkMeta,
|
20970
|
+
parent: frag.type
|
20971
|
+
});
|
20972
|
+
}
|
20973
|
+
});
|
20886
20974
|
}
|
20887
|
-
this.hls.trigger(Events.BUFFER_CODECS, tracks);
|
20888
|
-
// loop through tracks that are going to be provided to bufferController
|
20889
|
-
Object.keys(tracks).forEach(function (trackName) {
|
20890
|
-
var track = tracks[trackName];
|
20891
|
-
var initSegment = track.initSegment;
|
20892
|
-
if (initSegment != null && initSegment.byteLength) {
|
20893
|
-
_this3.hls.trigger(Events.BUFFER_APPENDING, {
|
20894
|
-
type: trackName,
|
20895
|
-
data: initSegment,
|
20896
|
-
frag: frag,
|
20897
|
-
part: null,
|
20898
|
-
chunkMeta: chunkMeta,
|
20899
|
-
parent: frag.type
|
20900
|
-
});
|
20901
|
-
}
|
20902
|
-
});
|
20903
20975
|
// trigger handler right now
|
20904
20976
|
this.tickImmediate();
|
20905
20977
|
};
|
@@ -20980,22 +21052,30 @@
|
|
20980
21052
|
}, {
|
20981
21053
|
key: "currentFrag",
|
20982
21054
|
get: function get() {
|
20983
|
-
var
|
20984
|
-
if (
|
20985
|
-
return this.fragPlaying
|
21055
|
+
var _this$media2;
|
21056
|
+
if (this.fragPlaying) {
|
21057
|
+
return this.fragPlaying;
|
21058
|
+
}
|
21059
|
+
var currentTime = ((_this$media2 = this.media) == null ? void 0 : _this$media2.currentTime) || this.lastCurrentTime;
|
21060
|
+
if (isFiniteNumber(currentTime)) {
|
21061
|
+
return this.getAppendedFrag(currentTime);
|
20986
21062
|
}
|
20987
21063
|
return null;
|
20988
21064
|
}
|
20989
21065
|
}, {
|
20990
21066
|
key: "currentProgramDateTime",
|
20991
21067
|
get: function get() {
|
20992
|
-
var
|
20993
|
-
|
20994
|
-
|
20995
|
-
var
|
20996
|
-
|
20997
|
-
|
20998
|
-
|
21068
|
+
var _this$media3;
|
21069
|
+
var currentTime = ((_this$media3 = this.media) == null ? void 0 : _this$media3.currentTime) || this.lastCurrentTime;
|
21070
|
+
if (isFiniteNumber(currentTime)) {
|
21071
|
+
var details = this.getLevelDetails();
|
21072
|
+
var frag = this.currentFrag || (details ? findFragmentByPTS(null, details.fragments, currentTime) : null);
|
21073
|
+
if (frag) {
|
21074
|
+
var programDateTime = frag.programDateTime;
|
21075
|
+
if (programDateTime !== null) {
|
21076
|
+
var epocMs = programDateTime + (currentTime - frag.start) * 1000;
|
21077
|
+
return new Date(epocMs);
|
21078
|
+
}
|
20999
21079
|
}
|
21000
21080
|
}
|
21001
21081
|
return null;
|
@@ -21113,7 +21193,7 @@
|
|
21113
21193
|
if (AudioStreamControllerClass) {
|
21114
21194
|
networkControllers.push(new AudioStreamControllerClass(this, fragmentTracker, keyLoader));
|
21115
21195
|
}
|
21116
|
-
// subtitleTrackController
|
21196
|
+
// Instantiate subtitleTrackController before SubtitleStreamController to receive level events first
|
21117
21197
|
this.subtitleTrackController = this.createController(config.subtitleTrackController, networkControllers);
|
21118
21198
|
var SubtitleStreamControllerClass = config.subtitleStreamController;
|
21119
21199
|
if (SubtitleStreamControllerClass) {
|
@@ -21909,7 +21989,7 @@
|
|
21909
21989
|
* Get the video-dev/hls.js package version.
|
21910
21990
|
*/
|
21911
21991
|
function get() {
|
21912
|
-
return "1.5.12-0.canary.
|
21992
|
+
return "1.5.12-0.canary.10367";
|
21913
21993
|
}
|
21914
21994
|
}, {
|
21915
21995
|
key: "Events",
|