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.js
CHANGED
@@ -522,7 +522,7 @@
|
|
522
522
|
// Some browsers don't allow to use bind on console object anyway
|
523
523
|
// fallback to default if needed
|
524
524
|
try {
|
525
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.12-0.canary.
|
525
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.12-0.canary.10367");
|
526
526
|
} catch (e) {
|
527
527
|
/* log fn threw an exception. All logger methods are no-ops. */
|
528
528
|
return createLogger();
|
@@ -4157,10 +4157,9 @@
|
|
4157
4157
|
level = context.level,
|
4158
4158
|
type = context.type;
|
4159
4159
|
var url = getResponseUrl(response, context);
|
4160
|
-
var levelUrlId = 0;
|
4161
4160
|
var levelId = isFiniteNumber(level) ? level : isFiniteNumber(id) ? id : 0;
|
4162
4161
|
var levelType = mapContextToLevelType(context);
|
4163
|
-
var levelDetails = M3U8Parser.parseLevelPlaylist(response.data, url, levelId, levelType,
|
4162
|
+
var levelDetails = M3U8Parser.parseLevelPlaylist(response.data, url, levelId, levelType, 0, this.variableList);
|
4164
4163
|
|
4165
4164
|
// We have done our first request (Manifest-type) and receive
|
4166
4165
|
// not a master playlist but a chunk-list (track/level)
|
@@ -6092,8 +6091,7 @@
|
|
6092
6091
|
}
|
6093
6092
|
return Math.round(reloadInterval);
|
6094
6093
|
}
|
6095
|
-
function getFragmentWithSN(
|
6096
|
-
var details = level == null ? void 0 : level.details;
|
6094
|
+
function getFragmentWithSN(details, sn, fragCurrent) {
|
6097
6095
|
if (!details) {
|
6098
6096
|
return null;
|
6099
6097
|
}
|
@@ -6110,12 +6108,11 @@
|
|
6110
6108
|
}
|
6111
6109
|
return null;
|
6112
6110
|
}
|
6113
|
-
function getPartWith(
|
6114
|
-
|
6115
|
-
if (!(level != null && level.details)) {
|
6111
|
+
function getPartWith(details, sn, partIndex) {
|
6112
|
+
if (!details) {
|
6116
6113
|
return null;
|
6117
6114
|
}
|
6118
|
-
return findPart(
|
6115
|
+
return findPart(details.partList, sn, partIndex);
|
6119
6116
|
}
|
6120
6117
|
function findPart(partList, sn, partIndex) {
|
6121
6118
|
if (partList) {
|
@@ -6266,12 +6263,15 @@
|
|
6266
6263
|
}
|
6267
6264
|
var fragNext = null;
|
6268
6265
|
if (fragPrevious) {
|
6269
|
-
fragNext = fragments[fragPrevious.sn - fragments[0].sn
|
6266
|
+
fragNext = fragments[1 + fragPrevious.sn - fragments[0].sn] || null;
|
6270
6267
|
// check for buffer-end rounding error
|
6271
6268
|
var bufferEdgeError = fragPrevious.endDTS - bufferEnd;
|
6272
6269
|
if (bufferEdgeError > 0 && bufferEdgeError < 0.0000015) {
|
6273
6270
|
bufferEnd += 0.0000015;
|
6274
6271
|
}
|
6272
|
+
if (fragNext && fragPrevious.level !== fragNext.level && fragNext.end <= fragPrevious.end) {
|
6273
|
+
fragNext = fragments[2 + fragPrevious.sn - fragments[0].sn] || null;
|
6274
|
+
}
|
6275
6275
|
} else if (bufferEnd === 0 && fragments[0].start === 0) {
|
6276
6276
|
fragNext = fragments[0];
|
6277
6277
|
}
|
@@ -6368,6 +6368,24 @@
|
|
6368
6368
|
}
|
6369
6369
|
});
|
6370
6370
|
}
|
6371
|
+
function findNearestWithCC(details, cc, fragment) {
|
6372
|
+
if (details) {
|
6373
|
+
if (details.startCC <= cc && details.endCC >= cc) {
|
6374
|
+
var start = fragment.start;
|
6375
|
+
var end = fragment.end;
|
6376
|
+
return BinarySearch.search(details.fragments, function (candidate) {
|
6377
|
+
if (candidate.cc < cc || candidate.end <= start) {
|
6378
|
+
return 1;
|
6379
|
+
} else if (candidate.cc > cc || candidate.start >= end) {
|
6380
|
+
return -1;
|
6381
|
+
} else {
|
6382
|
+
return 0;
|
6383
|
+
}
|
6384
|
+
});
|
6385
|
+
}
|
6386
|
+
}
|
6387
|
+
return null;
|
6388
|
+
}
|
6371
6389
|
|
6372
6390
|
var NetworkErrorAction = {
|
6373
6391
|
DoNothing: 0,
|
@@ -6433,7 +6451,7 @@
|
|
6433
6451
|
this.playlistError = 0;
|
6434
6452
|
};
|
6435
6453
|
_proto.onError = function onError(event, data) {
|
6436
|
-
var _data$frag
|
6454
|
+
var _data$frag;
|
6437
6455
|
if (data.fatal) {
|
6438
6456
|
return;
|
6439
6457
|
}
|
@@ -6449,10 +6467,7 @@
|
|
6449
6467
|
case ErrorDetails.FRAG_PARSING_ERROR:
|
6450
6468
|
// ignore empty segment errors marked as gap
|
6451
6469
|
if ((_data$frag = data.frag) != null && _data$frag.gap) {
|
6452
|
-
data.errorAction =
|
6453
|
-
action: NetworkErrorAction.DoNothing,
|
6454
|
-
flags: ErrorActionFlags.None
|
6455
|
-
};
|
6470
|
+
data.errorAction = createDoNothingErrorAction();
|
6456
6471
|
return;
|
6457
6472
|
}
|
6458
6473
|
// falls through
|
@@ -6519,7 +6534,11 @@
|
|
6519
6534
|
case ErrorDetails.BUFFER_ADD_CODEC_ERROR:
|
6520
6535
|
case ErrorDetails.REMUX_ALLOC_ERROR:
|
6521
6536
|
case ErrorDetails.BUFFER_APPEND_ERROR:
|
6522
|
-
|
6537
|
+
// Buffer-controller can set errorAction when append errors can be ignored or resolved locally
|
6538
|
+
if (!data.errorAction) {
|
6539
|
+
var _data$level;
|
6540
|
+
data.errorAction = this.getLevelSwitchAction(data, (_data$level = data.level) != null ? _data$level : hls.loadLevel);
|
6541
|
+
}
|
6523
6542
|
return;
|
6524
6543
|
case ErrorDetails.INTERNAL_EXCEPTION:
|
6525
6544
|
case ErrorDetails.BUFFER_APPENDING_ERROR:
|
@@ -6528,10 +6547,7 @@
|
|
6528
6547
|
case ErrorDetails.BUFFER_STALLED_ERROR:
|
6529
6548
|
case ErrorDetails.BUFFER_SEEK_OVER_HOLE:
|
6530
6549
|
case ErrorDetails.BUFFER_NUDGE_ON_STALL:
|
6531
|
-
data.errorAction =
|
6532
|
-
action: NetworkErrorAction.DoNothing,
|
6533
|
-
flags: ErrorActionFlags.None
|
6534
|
-
};
|
6550
|
+
data.errorAction = createDoNothingErrorAction();
|
6535
6551
|
return;
|
6536
6552
|
}
|
6537
6553
|
if (data.type === ErrorTypes.KEY_SYSTEM_ERROR) {
|
@@ -6750,6 +6766,13 @@
|
|
6750
6766
|
};
|
6751
6767
|
return ErrorController;
|
6752
6768
|
}(Logger);
|
6769
|
+
function createDoNothingErrorAction(resolved) {
|
6770
|
+
var errorAction = {
|
6771
|
+
action: NetworkErrorAction.DoNothing,
|
6772
|
+
flags: ErrorActionFlags.None
|
6773
|
+
};
|
6774
|
+
return errorAction;
|
6775
|
+
}
|
6753
6776
|
|
6754
6777
|
var BasePlaylistController = /*#__PURE__*/function (_Logger) {
|
6755
6778
|
function BasePlaylistController(hls, logPrefix) {
|
@@ -7360,6 +7383,7 @@
|
|
7360
7383
|
if (!hasCurrentVideoRange) {
|
7361
7384
|
currentVideoRange = undefined;
|
7362
7385
|
}
|
7386
|
+
var hasMultipleSets = codecSets.length > 1;
|
7363
7387
|
var codecSet = codecSets.reduce(function (selected, candidate) {
|
7364
7388
|
// 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
|
7365
7389
|
var candidateTier = codecTiers[candidate];
|
@@ -7369,48 +7393,50 @@
|
|
7369
7393
|
videoRanges = hasCurrentVideoRange ? allowedVideoRanges.filter(function (range) {
|
7370
7394
|
return candidateTier.videoRanges[range] > 0;
|
7371
7395
|
}) : [];
|
7372
|
-
if (
|
7373
|
-
|
7374
|
-
|
7375
|
-
|
7376
|
-
|
7377
|
-
|
7378
|
-
|
7379
|
-
|
7380
|
-
|
7381
|
-
|
7382
|
-
|
7383
|
-
|
7384
|
-
|
7385
|
-
if (!
|
7386
|
-
|
7396
|
+
if (hasMultipleSets) {
|
7397
|
+
if (candidateTier.minBitrate > currentBw) {
|
7398
|
+
logStartCodecCandidateIgnored(candidate, "min bitrate of " + candidateTier.minBitrate + " > current estimate of " + currentBw);
|
7399
|
+
return selected;
|
7400
|
+
}
|
7401
|
+
if (!candidateTier.hasDefaultAudio) {
|
7402
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with default or auto-select sound found");
|
7403
|
+
return selected;
|
7404
|
+
}
|
7405
|
+
if (audioCodecPreference && candidate.indexOf(audioCodecPreference.substring(0, 4)) % 5 !== 0) {
|
7406
|
+
logStartCodecCandidateIgnored(candidate, "audio codec preference \"" + audioCodecPreference + "\" not found");
|
7407
|
+
return selected;
|
7408
|
+
}
|
7409
|
+
if (channelsPreference && !preferStereo) {
|
7410
|
+
if (!candidateTier.channels[channelsPreference]) {
|
7411
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with " + channelsPreference + " channel sound found (channels options: " + Object.keys(candidateTier.channels) + ")");
|
7412
|
+
return selected;
|
7413
|
+
}
|
7414
|
+
} else if ((!audioCodecPreference || preferStereo) && hasStereo && candidateTier.channels['2'] === 0) {
|
7415
|
+
logStartCodecCandidateIgnored(candidate, "no renditions with stereo sound found");
|
7416
|
+
return selected;
|
7417
|
+
}
|
7418
|
+
if (candidateTier.minHeight > maxHeight) {
|
7419
|
+
logStartCodecCandidateIgnored(candidate, "min resolution of " + candidateTier.minHeight + " > maximum of " + maxHeight);
|
7420
|
+
return selected;
|
7421
|
+
}
|
7422
|
+
if (candidateTier.minFramerate > maxFramerate) {
|
7423
|
+
logStartCodecCandidateIgnored(candidate, "min framerate of " + candidateTier.minFramerate + " > maximum of " + maxFramerate);
|
7424
|
+
return selected;
|
7425
|
+
}
|
7426
|
+
if (!videoRanges.some(function (range) {
|
7427
|
+
return candidateTier.videoRanges[range] > 0;
|
7428
|
+
})) {
|
7429
|
+
logStartCodecCandidateIgnored(candidate, "no variants with VIDEO-RANGE of " + JSON.stringify(videoRanges) + " found");
|
7430
|
+
return selected;
|
7431
|
+
}
|
7432
|
+
if (videoCodecPreference && candidate.indexOf(videoCodecPreference.substring(0, 4)) % 5 !== 0) {
|
7433
|
+
logStartCodecCandidateIgnored(candidate, "video codec preference \"" + videoCodecPreference + "\" not found");
|
7434
|
+
return selected;
|
7435
|
+
}
|
7436
|
+
if (candidateTier.maxScore < selectedScore) {
|
7437
|
+
logStartCodecCandidateIgnored(candidate, "max score of " + candidateTier.maxScore + " < selected max of " + selectedScore);
|
7387
7438
|
return selected;
|
7388
7439
|
}
|
7389
|
-
} else if ((!audioCodecPreference || preferStereo) && hasStereo && candidateTier.channels['2'] === 0) {
|
7390
|
-
logStartCodecCandidateIgnored(candidate, "no renditions with stereo sound found");
|
7391
|
-
return selected;
|
7392
|
-
}
|
7393
|
-
if (candidateTier.minHeight > maxHeight) {
|
7394
|
-
logStartCodecCandidateIgnored(candidate, "min resolution of " + candidateTier.minHeight + " > maximum of " + maxHeight);
|
7395
|
-
return selected;
|
7396
|
-
}
|
7397
|
-
if (candidateTier.minFramerate > maxFramerate) {
|
7398
|
-
logStartCodecCandidateIgnored(candidate, "min framerate of " + candidateTier.minFramerate + " > maximum of " + maxFramerate);
|
7399
|
-
return selected;
|
7400
|
-
}
|
7401
|
-
if (!videoRanges.some(function (range) {
|
7402
|
-
return candidateTier.videoRanges[range] > 0;
|
7403
|
-
})) {
|
7404
|
-
logStartCodecCandidateIgnored(candidate, "no variants with VIDEO-RANGE of " + JSON.stringify(videoRanges) + " found");
|
7405
|
-
return selected;
|
7406
|
-
}
|
7407
|
-
if (videoCodecPreference && candidate.indexOf(videoCodecPreference.substring(0, 4)) % 5 !== 0) {
|
7408
|
-
logStartCodecCandidateIgnored(candidate, "video codec preference \"" + videoCodecPreference + "\" not found");
|
7409
|
-
return selected;
|
7410
|
-
}
|
7411
|
-
if (candidateTier.maxScore < selectedScore) {
|
7412
|
-
logStartCodecCandidateIgnored(candidate, "max score of " + candidateTier.maxScore + " < selected max of " + selectedScore);
|
7413
|
-
return selected;
|
7414
7440
|
}
|
7415
7441
|
// Remove candiates with less preferred codecs or more errors
|
7416
7442
|
if (selected && (codecsSetSelectionPreferenceValue(candidate) >= codecsSetSelectionPreferenceValue(selected) || candidateTier.fragmentError > codecTiers[selected].fragmentError)) {
|
@@ -8145,7 +8171,7 @@
|
|
8145
8171
|
if (levelsSkipped.length) {
|
8146
8172
|
_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);
|
8147
8173
|
}
|
8148
|
-
_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:" +
|
8174
|
+
_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);
|
8149
8175
|
}
|
8150
8176
|
if (firstSelection) {
|
8151
8177
|
_this3.firstSelection = i;
|
@@ -8381,12 +8407,14 @@
|
|
8381
8407
|
var _proto = FragmentTracker.prototype;
|
8382
8408
|
_proto._registerListeners = function _registerListeners() {
|
8383
8409
|
var hls = this.hls;
|
8410
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
8384
8411
|
hls.on(Events.BUFFER_APPENDED, this.onBufferAppended, this);
|
8385
8412
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
8386
8413
|
hls.on(Events.FRAG_LOADED, this.onFragLoaded, this);
|
8387
8414
|
};
|
8388
8415
|
_proto._unregisterListeners = function _unregisterListeners() {
|
8389
8416
|
var hls = this.hls;
|
8417
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
8390
8418
|
hls.off(Events.BUFFER_APPENDED, this.onBufferAppended, this);
|
8391
8419
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
8392
8420
|
hls.off(Events.FRAG_LOADED, this.onFragLoaded, this);
|
@@ -8450,7 +8478,7 @@
|
|
8450
8478
|
* The browser will unload parts of the buffer to free up memory for new buffer data
|
8451
8479
|
* 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)
|
8452
8480
|
*/;
|
8453
|
-
_proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType, appendedPart) {
|
8481
|
+
_proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType, appendedPart, removeAppending) {
|
8454
8482
|
var _this = this;
|
8455
8483
|
if (this.timeRanges) {
|
8456
8484
|
this.timeRanges[elementaryStream] = timeRange;
|
@@ -8466,7 +8494,7 @@
|
|
8466
8494
|
if (appendedPartSn >= fragmentEntity.body.sn) {
|
8467
8495
|
return;
|
8468
8496
|
}
|
8469
|
-
if (!fragmentEntity.buffered && !fragmentEntity.loaded) {
|
8497
|
+
if (!fragmentEntity.buffered && (!fragmentEntity.loaded || removeAppending)) {
|
8470
8498
|
if (fragmentEntity.body.type === playlistType) {
|
8471
8499
|
_this.removeFragment(fragmentEntity.body);
|
8472
8500
|
}
|
@@ -8476,6 +8504,10 @@
|
|
8476
8504
|
if (!esData) {
|
8477
8505
|
return;
|
8478
8506
|
}
|
8507
|
+
if (esData.time.length === 0) {
|
8508
|
+
_this.removeFragment(fragmentEntity.body);
|
8509
|
+
return;
|
8510
|
+
}
|
8479
8511
|
esData.time.some(function (time) {
|
8480
8512
|
var isNotBuffered = !_this.isTimeBuffered(time.startPTS, time.endPTS, timeRange);
|
8481
8513
|
if (isNotBuffered) {
|
@@ -8663,6 +8695,9 @@
|
|
8663
8695
|
}
|
8664
8696
|
return false;
|
8665
8697
|
};
|
8698
|
+
_proto.onManifestLoading = function onManifestLoading() {
|
8699
|
+
this.removeAllFragments();
|
8700
|
+
};
|
8666
8701
|
_proto.onFragLoaded = function onFragLoaded(event, data) {
|
8667
8702
|
// don't track initsegment (for which sn is not a number)
|
8668
8703
|
// don't track frags used for bitrateTest, they're irrelevant.
|
@@ -8709,6 +8744,20 @@
|
|
8709
8744
|
var fragKey = getFragmentKey(fragment);
|
8710
8745
|
return !!this.fragments[fragKey];
|
8711
8746
|
};
|
8747
|
+
_proto.hasFragments = function hasFragments(type) {
|
8748
|
+
var fragments = this.fragments;
|
8749
|
+
var keys = Object.keys(fragments);
|
8750
|
+
if (!type) {
|
8751
|
+
return keys.length > 0;
|
8752
|
+
}
|
8753
|
+
for (var i = keys.length; i--;) {
|
8754
|
+
var fragmentEntity = fragments[keys[i]];
|
8755
|
+
if ((fragmentEntity == null ? void 0 : fragmentEntity.body.type) === type) {
|
8756
|
+
return true;
|
8757
|
+
}
|
8758
|
+
}
|
8759
|
+
return false;
|
8760
|
+
};
|
8712
8761
|
_proto.hasParts = function hasParts(type) {
|
8713
8762
|
var _this$activePartLists;
|
8714
8763
|
return !!((_this$activePartLists = this.activePartLists[type]) != null && _this$activePartLists.length);
|
@@ -9135,8 +9184,9 @@
|
|
9135
9184
|
frag.gap = false;
|
9136
9185
|
}
|
9137
9186
|
}
|
9138
|
-
var loader = _this.loader =
|
9187
|
+
var loader = _this.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
|
9139
9188
|
var loaderContext = createLoaderContext(frag);
|
9189
|
+
frag.loader = loader;
|
9140
9190
|
var loadPolicy = getLoaderConfigWithoutReties(config.fragLoadPolicy.default);
|
9141
9191
|
var loaderConfig = {
|
9142
9192
|
loadPolicy: loadPolicy,
|
@@ -9230,8 +9280,9 @@
|
|
9230
9280
|
reject(createGapLoadError(frag, part));
|
9231
9281
|
return;
|
9232
9282
|
}
|
9233
|
-
var loader = _this2.loader =
|
9283
|
+
var loader = _this2.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
|
9234
9284
|
var loaderContext = createLoaderContext(frag, part);
|
9285
|
+
frag.loader = loader;
|
9235
9286
|
// Should we define another load policy for parts?
|
9236
9287
|
var loadPolicy = getLoaderConfigWithoutReties(config.fragLoadPolicy.default);
|
9237
9288
|
var loaderConfig = {
|
@@ -9943,6 +9994,7 @@
|
|
9943
9994
|
_this.initPTS = [];
|
9944
9995
|
_this.buffering = true;
|
9945
9996
|
_this.loadingParts = false;
|
9997
|
+
_this.loopSn = void 0;
|
9946
9998
|
_this.onMediaSeeking = function () {
|
9947
9999
|
var _this2 = _this,
|
9948
10000
|
config = _this2.config,
|
@@ -10041,6 +10093,9 @@
|
|
10041
10093
|
;
|
10042
10094
|
_proto.startLoad = function startLoad(startPosition) {};
|
10043
10095
|
_proto.stopLoad = function stopLoad() {
|
10096
|
+
if (this.state === State.STOPPED) {
|
10097
|
+
return;
|
10098
|
+
}
|
10044
10099
|
this.fragmentLoader.abort();
|
10045
10100
|
this.keyLoader.abort(this.playlistType);
|
10046
10101
|
var frag = this.fragCurrent;
|
@@ -10114,15 +10169,20 @@
|
|
10114
10169
|
this.keyLoader.detach();
|
10115
10170
|
}
|
10116
10171
|
this.media = this.mediaBuffer = null;
|
10117
|
-
this.
|
10172
|
+
this.loopSn = undefined;
|
10173
|
+
this.startFragRequested = this.loadedmetadata = this.loadingParts = false;
|
10118
10174
|
this.fragmentTracker.removeAllFragments();
|
10119
10175
|
this.stopLoad();
|
10120
10176
|
};
|
10121
|
-
_proto.onManifestLoading = function onManifestLoading() {
|
10177
|
+
_proto.onManifestLoading = function onManifestLoading() {
|
10178
|
+
this.initPTS = [];
|
10179
|
+
this.levels = this.levelLastLoaded = this.fragCurrent = null;
|
10180
|
+
this.lastCurrentTime = this.startPosition = 0;
|
10181
|
+
this.startFragRequested = false;
|
10182
|
+
};
|
10122
10183
|
_proto.onError = function onError(event, data) {};
|
10123
10184
|
_proto.onManifestLoaded = function onManifestLoaded(event, data) {
|
10124
10185
|
this.startTimeOffset = data.startTimeOffset;
|
10125
|
-
this.initPTS = [];
|
10126
10186
|
};
|
10127
10187
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
10128
10188
|
this.stopLoad();
|
@@ -10145,6 +10205,7 @@
|
|
10145
10205
|
_TaskLoop.prototype.onHandlerDestroyed.call(this);
|
10146
10206
|
};
|
10147
10207
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
10208
|
+
this.startFragRequested = true;
|
10148
10209
|
this._loadFragForPlayback(frag, level, targetBufferTime);
|
10149
10210
|
};
|
10150
10211
|
_proto._loadFragForPlayback = function _loadFragForPlayback(frag, level, targetBufferTime) {
|
@@ -10373,6 +10434,7 @@
|
|
10373
10434
|
if (targetBufferTime === void 0) {
|
10374
10435
|
targetBufferTime = null;
|
10375
10436
|
}
|
10437
|
+
this.fragCurrent = frag;
|
10376
10438
|
var details = level == null ? void 0 : level.details;
|
10377
10439
|
if (!this.levels || !details) {
|
10378
10440
|
throw new Error("frag load aborted, missing level" + (details ? '' : ' detail') + "s");
|
@@ -10510,7 +10572,7 @@
|
|
10510
10572
|
partsLoaded[part.index] = partLoadedData;
|
10511
10573
|
var loadedPart = partLoadedData.part;
|
10512
10574
|
_this6.hls.trigger(Events.FRAG_LOADED, partLoadedData);
|
10513
|
-
var nextPart = getPartWith(level, frag.sn, part.index + 1) || findPart(initialPartList, frag.sn, part.index + 1);
|
10575
|
+
var nextPart = getPartWith(level.details, frag.sn, part.index + 1) || findPart(initialPartList, frag.sn, part.index + 1);
|
10514
10576
|
if (nextPart) {
|
10515
10577
|
loadPart(nextPart);
|
10516
10578
|
} else {
|
@@ -10599,8 +10661,9 @@
|
|
10599
10661
|
return null;
|
10600
10662
|
}
|
10601
10663
|
var level = levels[levelIndex];
|
10602
|
-
var
|
10603
|
-
var
|
10664
|
+
var levelDetails = level.details;
|
10665
|
+
var part = partIndex > -1 ? getPartWith(levelDetails, sn, partIndex) : null;
|
10666
|
+
var frag = part ? part.fragment : getFragmentWithSN(levelDetails, sn, fragCurrent);
|
10604
10667
|
if (!frag) {
|
10605
10668
|
return null;
|
10606
10669
|
}
|
@@ -10707,7 +10770,11 @@
|
|
10707
10770
|
return false;
|
10708
10771
|
};
|
10709
10772
|
_proto.getAppendedFrag = function getAppendedFrag(position, playlistType) {
|
10710
|
-
var
|
10773
|
+
var _this$fragmentTracker;
|
10774
|
+
if (playlistType === void 0) {
|
10775
|
+
playlistType = PlaylistLevelType.MAIN;
|
10776
|
+
}
|
10777
|
+
var fragOrPart = (_this$fragmentTracker = this.fragmentTracker) == null ? void 0 : _this$fragmentTracker.getAppendedFrag(position, playlistType);
|
10711
10778
|
if (fragOrPart && 'fragment' in fragOrPart) {
|
10712
10779
|
return fragOrPart.fragment;
|
10713
10780
|
}
|
@@ -10760,22 +10827,25 @@
|
|
10760
10827
|
return (trackerState === FragmentState.OK || trackerState === FragmentState.PARTIAL && !!frag.gap) && this.nextLoadPosition > targetBufferTime;
|
10761
10828
|
};
|
10762
10829
|
_proto.getNextFragmentLoopLoading = function getNextFragmentLoopLoading(frag, levelDetails, bufferInfo, playlistType, maxBufLen) {
|
10763
|
-
var
|
10764
|
-
|
10765
|
-
|
10766
|
-
|
10767
|
-
|
10768
|
-
|
10769
|
-
|
10770
|
-
|
10771
|
-
|
10772
|
-
|
10773
|
-
|
10774
|
-
|
10775
|
-
|
10830
|
+
var nextFragment = null;
|
10831
|
+
if (frag.gap) {
|
10832
|
+
nextFragment = this.getNextFragment(this.nextLoadPosition, levelDetails);
|
10833
|
+
if (nextFragment && !nextFragment.gap && bufferInfo.nextStart) {
|
10834
|
+
// Media buffered after GAP tags should not make the next buffer timerange exceed forward buffer length
|
10835
|
+
var nextbufferInfo = this.getFwdBufferInfoAtPos(this.mediaBuffer ? this.mediaBuffer : this.media, bufferInfo.nextStart, playlistType);
|
10836
|
+
if (nextbufferInfo !== null && bufferInfo.len + nextbufferInfo.len >= maxBufLen) {
|
10837
|
+
// Returning here might result in not finding an audio and video candiate to skip to
|
10838
|
+
var sn = nextFragment.sn;
|
10839
|
+
if (this.loopSn !== sn) {
|
10840
|
+
this.log("buffer full after gaps in \"" + playlistType + "\" playlist starting at sn: " + sn);
|
10841
|
+
this.loopSn = sn;
|
10842
|
+
}
|
10843
|
+
return null;
|
10844
|
+
}
|
10776
10845
|
}
|
10777
10846
|
}
|
10778
|
-
|
10847
|
+
this.loopSn = undefined;
|
10848
|
+
return nextFragment;
|
10779
10849
|
};
|
10780
10850
|
_proto.mapToInitFragWhenRequired = function mapToInitFragWhenRequired(frag) {
|
10781
10851
|
// If an initSegment is present, it must be buffered first
|
@@ -10970,7 +11040,7 @@
|
|
10970
11040
|
if (startTimeOffset !== null && isFiniteNumber(startTimeOffset)) {
|
10971
11041
|
startPosition = sliding + startTimeOffset;
|
10972
11042
|
if (startTimeOffset < 0) {
|
10973
|
-
startPosition += details.
|
11043
|
+
startPosition += details.edge;
|
10974
11044
|
}
|
10975
11045
|
startPosition = Math.min(Math.max(sliding, startPosition), sliding + details.totalduration);
|
10976
11046
|
this.log("Start time offset " + startTimeOffset + " found in " + (offsetInMultivariantPlaylist ? 'multivariant' : 'media') + " playlist, adjust startPosition to " + startPosition);
|
@@ -15368,10 +15438,11 @@
|
|
15368
15438
|
if (this.ISGenerated) {
|
15369
15439
|
var _videoTrack$pixelRati, _config$pixelRatio, _videoTrack$pixelRati2, _config$pixelRatio2;
|
15370
15440
|
var config = this.videoTrackConfig;
|
15371
|
-
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]))) {
|
15441
|
+
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) {
|
15372
15442
|
this.resetInitSegment();
|
15373
15443
|
}
|
15374
|
-
}
|
15444
|
+
}
|
15445
|
+
if (!this.ISGenerated) {
|
15375
15446
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
15376
15447
|
}
|
15377
15448
|
var isVideoContiguous = this.isVideoContiguous;
|
@@ -16289,7 +16360,7 @@
|
|
16289
16360
|
if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
|
16290
16361
|
initSegment.initPTS = decodeTime - timeOffset;
|
16291
16362
|
if (initPTS && initPTS.timescale === 1) {
|
16292
|
-
logger.warn("Adjusting initPTS
|
16363
|
+
logger.warn("Adjusting initPTS @" + timeOffset + " from " + initPTS.baseTime / initPTS.timescale + " to " + initSegment.initPTS);
|
16293
16364
|
}
|
16294
16365
|
this.initPTS = initPTS = {
|
16295
16366
|
baseTime: initSegment.initPTS,
|
@@ -17579,9 +17650,8 @@
|
|
17579
17650
|
function AudioStreamController(hls, fragmentTracker, keyLoader) {
|
17580
17651
|
var _this;
|
17581
17652
|
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'audio-stream-controller', PlaylistLevelType.AUDIO) || this;
|
17582
|
-
_this.
|
17583
|
-
_this.
|
17584
|
-
_this.waitingVideoCC = -1;
|
17653
|
+
_this.videoAnchor = null;
|
17654
|
+
_this.mainFragLoading = null;
|
17585
17655
|
_this.bufferedTrack = null;
|
17586
17656
|
_this.switchingTrack = null;
|
17587
17657
|
_this.trackId = -1;
|
@@ -17614,6 +17684,7 @@
|
|
17614
17684
|
hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
|
17615
17685
|
hls.on(Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
|
17616
17686
|
hls.on(Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
|
17687
|
+
hls.on(Events.FRAG_LOADING, this.onFragLoading, this);
|
17617
17688
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
17618
17689
|
};
|
17619
17690
|
_proto.unregisterListeners = function unregisterListeners() {
|
@@ -17631,6 +17702,7 @@
|
|
17631
17702
|
hls.off(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
|
17632
17703
|
hls.off(Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
|
17633
17704
|
hls.off(Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
|
17705
|
+
hls.on(Events.FRAG_LOADING, this.onFragLoading, this);
|
17634
17706
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
17635
17707
|
}
|
17636
17708
|
|
@@ -17643,20 +17715,35 @@
|
|
17643
17715
|
timescale = _ref.timescale;
|
17644
17716
|
// Always update the new INIT PTS
|
17645
17717
|
// Can change due level switch
|
17646
|
-
if (id ===
|
17718
|
+
if (id === PlaylistLevelType.MAIN) {
|
17647
17719
|
var cc = frag.cc;
|
17648
|
-
|
17720
|
+
var inFlightFrag = this.fragCurrent;
|
17721
|
+
this.initPTS[cc] = {
|
17649
17722
|
baseTime: initPTS,
|
17650
17723
|
timescale: timescale
|
17651
17724
|
};
|
17652
17725
|
this.log("InitPTS for cc: " + cc + " found from main: " + initPTS + "/" + timescale);
|
17653
|
-
this.
|
17726
|
+
this.videoAnchor = frag;
|
17654
17727
|
// If we are waiting, tick immediately to unblock audio fragment transmuxing
|
17655
17728
|
if (this.state === State.WAITING_INIT_PTS) {
|
17729
|
+
var waitingData = this.waitingData;
|
17730
|
+
if (!waitingData || waitingData.frag.cc !== cc) {
|
17731
|
+
this.nextLoadPosition = this.findSyncFrag(frag).start;
|
17732
|
+
}
|
17656
17733
|
this.tick();
|
17734
|
+
} else if (!this.loadedmetadata && inFlightFrag && inFlightFrag.cc !== cc) {
|
17735
|
+
this.startFragRequested = false;
|
17736
|
+
this.nextLoadPosition = this.findSyncFrag(frag).start;
|
17737
|
+
inFlightFrag.abortRequests();
|
17738
|
+
this.resetLoadingState();
|
17657
17739
|
}
|
17658
17740
|
}
|
17659
17741
|
};
|
17742
|
+
_proto.findSyncFrag = function findSyncFrag(mainFrag) {
|
17743
|
+
var trackDetails = this.getLevelDetails();
|
17744
|
+
var cc = mainFrag.cc;
|
17745
|
+
return findNearestWithCC(trackDetails, cc, mainFrag) || trackDetails && findFragWithCC(trackDetails.fragments, cc) || mainFrag;
|
17746
|
+
};
|
17660
17747
|
_proto.startLoad = function startLoad(startPosition) {
|
17661
17748
|
if (!this.levels) {
|
17662
17749
|
this.startPosition = startPosition;
|
@@ -17720,9 +17807,9 @@
|
|
17720
17807
|
part = waitingData.part,
|
17721
17808
|
cache = waitingData.cache,
|
17722
17809
|
complete = waitingData.complete;
|
17810
|
+
var videoAnchor = this.videoAnchor;
|
17723
17811
|
if (this.initPTS[frag.cc] !== undefined) {
|
17724
17812
|
this.waitingData = null;
|
17725
|
-
this.waitingVideoCC = -1;
|
17726
17813
|
this.state = State.FRAG_LOADING;
|
17727
17814
|
var payload = cache.flush();
|
17728
17815
|
var data = {
|
@@ -17735,21 +17822,13 @@
|
|
17735
17822
|
if (complete) {
|
17736
17823
|
_BaseStreamController.prototype._handleFragmentLoadComplete.call(this, data);
|
17737
17824
|
}
|
17738
|
-
} else if (
|
17825
|
+
} else if (videoAnchor && videoAnchor.cc !== waitingData.frag.cc) {
|
17739
17826
|
// Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
|
17740
|
-
this.log("Waiting fragment cc (" + frag.cc + ") cancelled because video is at cc " +
|
17827
|
+
this.log("Waiting fragment cc (" + frag.cc + ") cancelled because video is at cc " + videoAnchor.cc);
|
17828
|
+
this.nextLoadPosition = this.findSyncFrag(videoAnchor).start;
|
17741
17829
|
this.clearWaitingFragment();
|
17742
|
-
} else {
|
17743
|
-
// Drop waiting fragment if an earlier fragment is needed
|
17744
|
-
var pos = this.getLoadPosition();
|
17745
|
-
var bufferInfo = BufferHelper.bufferInfo(this.mediaBuffer, pos, this.config.maxBufferHole);
|
17746
|
-
var waitingFragmentAtPosition = fragmentWithinToleranceTest(bufferInfo.end, this.config.maxFragLookUpTolerance, frag);
|
17747
|
-
if (waitingFragmentAtPosition < 0) {
|
17748
|
-
this.log("Waiting fragment cc (" + frag.cc + ") @ " + frag.start + " cancelled because another fragment at " + bufferInfo.end + " is needed");
|
17749
|
-
this.clearWaitingFragment();
|
17750
|
-
}
|
17751
17830
|
}
|
17752
|
-
} else {
|
17831
|
+
} else if (this.state !== State.STOPPED) {
|
17753
17832
|
this.state = State.IDLE;
|
17754
17833
|
}
|
17755
17834
|
}
|
@@ -17759,9 +17838,12 @@
|
|
17759
17838
|
_proto.clearWaitingFragment = function clearWaitingFragment() {
|
17760
17839
|
var waitingData = this.waitingData;
|
17761
17840
|
if (waitingData) {
|
17841
|
+
if (!this.loadedmetadata) {
|
17842
|
+
// Load overlapping fragment on start when discontinuity start times are not aligned
|
17843
|
+
this.startFragRequested = false;
|
17844
|
+
}
|
17762
17845
|
this.fragmentTracker.removeFragment(waitingData.frag);
|
17763
17846
|
this.waitingData = null;
|
17764
|
-
this.waitingVideoCC = -1;
|
17765
17847
|
if (this.state !== State.STOPPED) {
|
17766
17848
|
this.state = State.IDLE;
|
17767
17849
|
}
|
@@ -17823,9 +17905,10 @@
|
|
17823
17905
|
var maxBufLen = hls.maxBufferLength;
|
17824
17906
|
var fragments = trackDetails.fragments;
|
17825
17907
|
var start = fragments[0].start;
|
17826
|
-
var
|
17908
|
+
var loadPosition = this.getLoadPosition();
|
17909
|
+
var targetBufferTime = this.flushing ? loadPosition : bufferInfo.end;
|
17827
17910
|
if (switchingTrack && media) {
|
17828
|
-
var pos =
|
17911
|
+
var pos = loadPosition;
|
17829
17912
|
// STABLE
|
17830
17913
|
if (bufferedTrack && !mediaAttributesIdentical(switchingTrack.attrs, bufferedTrack.attrs)) {
|
17831
17914
|
targetBufferTime = pos;
|
@@ -17845,37 +17928,26 @@
|
|
17845
17928
|
return;
|
17846
17929
|
}
|
17847
17930
|
var frag = this.getNextFragment(targetBufferTime, trackDetails);
|
17848
|
-
var atGap = false;
|
17849
17931
|
// Avoid loop loading by using nextLoadPosition set for backtracking and skipping consecutive GAP tags
|
17850
17932
|
if (frag && this.isLoopLoading(frag, targetBufferTime)) {
|
17851
|
-
atGap = !!frag.gap;
|
17852
17933
|
frag = this.getNextFragmentLoopLoading(frag, trackDetails, bufferInfo, PlaylistLevelType.MAIN, maxBufLen);
|
17853
17934
|
}
|
17854
17935
|
if (!frag) {
|
17855
17936
|
this.bufferFlushed = true;
|
17856
17937
|
return;
|
17857
17938
|
}
|
17858
|
-
if (!trackDetails.live || targetBufferTime < this.hls.liveSyncPosition) {
|
17939
|
+
if (this.startFragRequested && (!trackDetails.live || targetBufferTime < this.hls.liveSyncPosition)) {
|
17859
17940
|
// Request audio segments up to one fragment ahead of main buffer
|
17860
|
-
var
|
17861
|
-
var
|
17862
|
-
|
17863
|
-
|
17864
|
-
|
17865
|
-
if (mainFrag === null) {
|
17866
|
-
return;
|
17867
|
-
}
|
17868
|
-
// Bridge gaps in main buffer (also prevents loop loading at gaps)
|
17869
|
-
atGap || (atGap = !!mainFrag.gap || mainBufferInfo.len === 0);
|
17870
|
-
if (!atGap || bufferInfo.nextStart && bufferInfo.nextStart < mainFrag.end) {
|
17871
|
-
return;
|
17872
|
-
}
|
17941
|
+
var mainFragLoading = this.mainFragLoading;
|
17942
|
+
var mainTargetBufferEnd = mainFragLoading ? (mainFragLoading.part || mainFragLoading.frag).end : null;
|
17943
|
+
var atBufferSyncLimit = mainTargetBufferEnd !== null && frag.start > mainTargetBufferEnd;
|
17944
|
+
if (atBufferSyncLimit && !frag.endList) {
|
17945
|
+
return;
|
17873
17946
|
}
|
17874
17947
|
}
|
17875
17948
|
this.loadFragment(frag, levelInfo, targetBufferTime);
|
17876
17949
|
};
|
17877
17950
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
17878
|
-
this.videoBuffer = null;
|
17879
17951
|
this.bufferFlushed = this.flushing = false;
|
17880
17952
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
17881
17953
|
};
|
@@ -17918,12 +17990,10 @@
|
|
17918
17990
|
}
|
17919
17991
|
};
|
17920
17992
|
_proto.onManifestLoading = function onManifestLoading() {
|
17921
|
-
|
17922
|
-
this.startPosition = this.lastCurrentTime = 0;
|
17993
|
+
_BaseStreamController.prototype.onManifestLoading.call(this);
|
17923
17994
|
this.bufferFlushed = this.flushing = false;
|
17924
|
-
this.
|
17925
|
-
this.
|
17926
|
-
this.trackId = this.videoTrackCC = this.waitingVideoCC = -1;
|
17995
|
+
this.mainDetails = this.waitingData = this.videoAnchor = this.bufferedTrack = this.cachedTrackLoadedData = this.switchingTrack = null;
|
17996
|
+
this.trackId = -1;
|
17927
17997
|
};
|
17928
17998
|
_proto.onLevelLoaded = function onLevelLoaded(event, data) {
|
17929
17999
|
this.mainDetails = data.details;
|
@@ -18030,7 +18100,6 @@
|
|
18030
18100
|
},
|
18031
18101
|
cache = _this$waitingData.cache;
|
18032
18102
|
cache.push(new Uint8Array(payload));
|
18033
|
-
this.waitingVideoCC = this.videoTrackCC;
|
18034
18103
|
this.state = State.WAITING_INIT_PTS;
|
18035
18104
|
}
|
18036
18105
|
};
|
@@ -18044,7 +18113,7 @@
|
|
18044
18113
|
_proto.onBufferReset = function onBufferReset( /* event: Events.BUFFER_RESET */
|
18045
18114
|
) {
|
18046
18115
|
// reset reference to sourcebuffers
|
18047
|
-
this.mediaBuffer =
|
18116
|
+
this.mediaBuffer = null;
|
18048
18117
|
this.loadedmetadata = false;
|
18049
18118
|
};
|
18050
18119
|
_proto.onBufferCreated = function onBufferCreated(event, data) {
|
@@ -18052,8 +18121,13 @@
|
|
18052
18121
|
if (audioTrack) {
|
18053
18122
|
this.mediaBuffer = audioTrack.buffer || null;
|
18054
18123
|
}
|
18055
|
-
|
18056
|
-
|
18124
|
+
};
|
18125
|
+
_proto.onFragLoading = function onFragLoading(event, data) {
|
18126
|
+
if (data.frag.type === PlaylistLevelType.MAIN && data.frag.sn !== 'initSegment') {
|
18127
|
+
this.mainFragLoading = data;
|
18128
|
+
if (this.state === State.IDLE) {
|
18129
|
+
this.tick();
|
18130
|
+
}
|
18057
18131
|
}
|
18058
18132
|
};
|
18059
18133
|
_proto.onFragBuffered = function onFragBuffered(event, data) {
|
@@ -18061,12 +18135,9 @@
|
|
18061
18135
|
part = data.part;
|
18062
18136
|
if (frag.type !== PlaylistLevelType.AUDIO) {
|
18063
18137
|
if (!this.loadedmetadata && frag.type === PlaylistLevelType.MAIN) {
|
18064
|
-
var
|
18065
|
-
if (
|
18066
|
-
|
18067
|
-
if (bufferedTimeRanges.length) {
|
18068
|
-
this.loadedmetadata = true;
|
18069
|
-
}
|
18138
|
+
var bufferedState = this.fragmentTracker.getState(frag);
|
18139
|
+
if (bufferedState === FragmentState.OK || bufferedState === FragmentState.PARTIAL) {
|
18140
|
+
this.loadedmetadata = true;
|
18070
18141
|
}
|
18071
18142
|
}
|
18072
18143
|
return;
|
@@ -18233,12 +18304,15 @@
|
|
18233
18304
|
if (tracks.video) {
|
18234
18305
|
delete tracks.video;
|
18235
18306
|
}
|
18307
|
+
if (tracks.audiovideo) {
|
18308
|
+
delete tracks.audiovideo;
|
18309
|
+
}
|
18236
18310
|
|
18237
18311
|
// include levelCodec in audio and video tracks
|
18238
|
-
|
18239
|
-
if (!track) {
|
18312
|
+
if (!tracks.audio) {
|
18240
18313
|
return;
|
18241
18314
|
}
|
18315
|
+
var track = tracks.audio;
|
18242
18316
|
track.id = 'audio';
|
18243
18317
|
var variantAudioCodecs = currentLevel.audioCodec;
|
18244
18318
|
this.log("Init audio buffer, container:" + track.container + ", codecs[level/parsed]=[" + variantAudioCodecs + "/" + track.codec + "]");
|
@@ -18265,7 +18339,6 @@
|
|
18265
18339
|
_proto.loadFragment = function loadFragment(frag, track, targetBufferTime) {
|
18266
18340
|
// only load if fragment is not loaded or if in audio switch
|
18267
18341
|
var fragState = this.fragmentTracker.getState(frag);
|
18268
|
-
this.fragCurrent = frag;
|
18269
18342
|
|
18270
18343
|
// we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
|
18271
18344
|
if (this.switchingTrack || fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
@@ -18280,7 +18353,6 @@
|
|
18280
18353
|
alignMediaPlaylistByPDT(track.details, mainDetails);
|
18281
18354
|
}
|
18282
18355
|
} else {
|
18283
|
-
this.startFragRequested = true;
|
18284
18356
|
_BaseStreamController.prototype.loadFragment.call(this, frag, track, targetBufferTime);
|
18285
18357
|
}
|
18286
18358
|
} else {
|
@@ -18683,8 +18755,8 @@
|
|
18683
18755
|
this.tick();
|
18684
18756
|
};
|
18685
18757
|
_proto.onManifestLoading = function onManifestLoading() {
|
18758
|
+
_BaseStreamController.prototype.onManifestLoading.call(this);
|
18686
18759
|
this.mainDetails = null;
|
18687
|
-
this.fragmentTracker.removeAllFragments();
|
18688
18760
|
};
|
18689
18761
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
18690
18762
|
this.tracksBuffered = [];
|
@@ -18696,7 +18768,9 @@
|
|
18696
18768
|
_proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(event, data) {
|
18697
18769
|
var frag = data.frag,
|
18698
18770
|
success = data.success;
|
18699
|
-
|
18771
|
+
if (frag.sn !== 'initSegment') {
|
18772
|
+
this.fragPrevious = frag;
|
18773
|
+
}
|
18700
18774
|
this.state = State.IDLE;
|
18701
18775
|
if (!success) {
|
18702
18776
|
return;
|
@@ -18981,11 +19055,9 @@
|
|
18981
19055
|
}
|
18982
19056
|
};
|
18983
19057
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
18984
|
-
this.fragCurrent = frag;
|
18985
19058
|
if (frag.sn === 'initSegment') {
|
18986
19059
|
this._loadInitSegment(frag, level);
|
18987
19060
|
} else {
|
18988
|
-
this.startFragRequested = true;
|
18989
19061
|
_BaseStreamController.prototype.loadFragment.call(this, frag, level, targetBufferTime);
|
18990
19062
|
}
|
18991
19063
|
};
|
@@ -19670,6 +19742,7 @@
|
|
19670
19742
|
hls.on(Events.LEVEL_UPDATED, this.onLevelUpdated, this);
|
19671
19743
|
hls.on(Events.FRAG_PARSED, this.onFragParsed, this);
|
19672
19744
|
hls.on(Events.FRAG_CHANGED, this.onFragChanged, this);
|
19745
|
+
hls.on(Events.ERROR, this.onError, this);
|
19673
19746
|
};
|
19674
19747
|
_proto.unregisterListeners = function unregisterListeners() {
|
19675
19748
|
var hls = this.hls;
|
@@ -19685,6 +19758,7 @@
|
|
19685
19758
|
hls.off(Events.LEVEL_UPDATED, this.onLevelUpdated, this);
|
19686
19759
|
hls.off(Events.FRAG_PARSED, this.onFragParsed, this);
|
19687
19760
|
hls.off(Events.FRAG_CHANGED, this.onFragChanged, this);
|
19761
|
+
hls.off(Events.ERROR, this.onError, this);
|
19688
19762
|
};
|
19689
19763
|
_proto._initSourceBuffer = function _initSourceBuffer() {
|
19690
19764
|
this.sourceBuffer = {};
|
@@ -19694,11 +19768,7 @@
|
|
19694
19768
|
video: [],
|
19695
19769
|
audiovideo: []
|
19696
19770
|
};
|
19697
|
-
this.
|
19698
|
-
audio: 0,
|
19699
|
-
video: 0,
|
19700
|
-
audiovideo: 0
|
19701
|
-
};
|
19771
|
+
this.resetAppendErrors();
|
19702
19772
|
this.lastMpegAudioChunk = null;
|
19703
19773
|
this.blockedAudioAppend = null;
|
19704
19774
|
this.lastVideoAppendEnd = 0;
|
@@ -20228,6 +20298,22 @@
|
|
20228
20298
|
this.updateMediaSource(durationAndRange);
|
20229
20299
|
}
|
20230
20300
|
};
|
20301
|
+
_proto.onError = function onError(event, data) {
|
20302
|
+
if (data.details === ErrorDetails.BUFFER_APPEND_ERROR && data.frag) {
|
20303
|
+
var _data$errorAction;
|
20304
|
+
var nextAutoLevel = (_data$errorAction = data.errorAction) == null ? void 0 : _data$errorAction.nextAutoLevel;
|
20305
|
+
if (isFiniteNumber(nextAutoLevel) && nextAutoLevel !== data.frag.level) {
|
20306
|
+
this.resetAppendErrors();
|
20307
|
+
}
|
20308
|
+
}
|
20309
|
+
};
|
20310
|
+
_proto.resetAppendErrors = function resetAppendErrors() {
|
20311
|
+
this.appendErrors = {
|
20312
|
+
audio: 0,
|
20313
|
+
video: 0,
|
20314
|
+
audiovideo: 0
|
20315
|
+
};
|
20316
|
+
};
|
20231
20317
|
_proto.trimBuffers = function trimBuffers() {
|
20232
20318
|
var hls = this.hls,
|
20233
20319
|
details = this.details,
|
@@ -23120,7 +23206,7 @@
|
|
23120
23206
|
initPTS = _ref.initPTS,
|
23121
23207
|
timescale = _ref.timescale;
|
23122
23208
|
var unparsedVttFrags = this.unparsedVttFrags;
|
23123
|
-
if (id ===
|
23209
|
+
if (id === PlaylistLevelType.MAIN) {
|
23124
23210
|
this.initPTS[frag.cc] = {
|
23125
23211
|
baseTime: initPTS,
|
23126
23212
|
timescale: timescale
|
@@ -28940,7 +29026,6 @@
|
|
28940
29026
|
_proto.loadFragment = function loadFragment(frag, level, targetBufferTime) {
|
28941
29027
|
// Check if fragment is not loaded
|
28942
29028
|
var fragState = this.fragmentTracker.getState(frag);
|
28943
|
-
this.fragCurrent = frag;
|
28944
29029
|
if (fragState === FragmentState.NOT_LOADED || fragState === FragmentState.PARTIAL) {
|
28945
29030
|
if (frag.sn === 'initSegment') {
|
28946
29031
|
this._loadInitSegment(frag, level);
|
@@ -28948,7 +29033,6 @@
|
|
28948
29033
|
this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered");
|
28949
29034
|
this._loadBitrateTestFrag(frag, level);
|
28950
29035
|
} else {
|
28951
|
-
this.startFragRequested = true;
|
28952
29036
|
_BaseStreamController.prototype.loadFragment.call(this, frag, level, targetBufferTime);
|
28953
29037
|
}
|
28954
29038
|
} else {
|
@@ -29078,14 +29162,14 @@
|
|
29078
29162
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
29079
29163
|
};
|
29080
29164
|
_proto.onManifestLoading = function onManifestLoading() {
|
29165
|
+
_BaseStreamController.prototype.onManifestLoading.call(this);
|
29081
29166
|
// reset buffer on manifest loading
|
29082
29167
|
this.log('Trigger BUFFER_RESET');
|
29083
29168
|
this.hls.trigger(Events.BUFFER_RESET, undefined);
|
29084
|
-
this.fragmentTracker.removeAllFragments();
|
29085
29169
|
this.couldBacktrack = false;
|
29086
|
-
this.
|
29087
|
-
this.
|
29088
|
-
this.altAudio = this.audioOnly =
|
29170
|
+
this.fragLastKbps = 0;
|
29171
|
+
this.fragPlaying = this.backtrackFragment = null;
|
29172
|
+
this.altAudio = this.audioOnly = false;
|
29089
29173
|
};
|
29090
29174
|
_proto.onManifestParsed = function onManifestParsed(event, data) {
|
29091
29175
|
// detect if we have different kind of audio codecs used amongst playlists
|
@@ -29370,7 +29454,7 @@
|
|
29370
29454
|
// in that case, reset startFragRequested flag
|
29371
29455
|
if (!this.loadedmetadata) {
|
29372
29456
|
this.startFragRequested = false;
|
29373
|
-
this.nextLoadPosition = this.
|
29457
|
+
this.nextLoadPosition = this.lastCurrentTime;
|
29374
29458
|
}
|
29375
29459
|
this.tickImmediate();
|
29376
29460
|
};
|
@@ -29454,7 +29538,7 @@
|
|
29454
29538
|
};
|
29455
29539
|
_proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) {
|
29456
29540
|
var _id3$samples;
|
29457
|
-
var id =
|
29541
|
+
var id = this.playlistType;
|
29458
29542
|
var hls = this.hls;
|
29459
29543
|
var remuxResult = transmuxResult.remuxResult,
|
29460
29544
|
chunkMeta = transmuxResult.chunkMeta;
|
@@ -29644,31 +29728,38 @@
|
|
29644
29728
|
audio.levelCodec = audioCodec;
|
29645
29729
|
audio.id = 'main';
|
29646
29730
|
this.log("Init audio buffer, container:" + audio.container + ", codecs[selected/level/parsed]=[" + (audioCodec || '') + "/" + (currentLevel.audioCodec || '') + "/" + audio.codec + "]");
|
29731
|
+
delete tracks.audiovideo;
|
29647
29732
|
}
|
29648
29733
|
if (video) {
|
29649
29734
|
video.levelCodec = currentLevel.videoCodec;
|
29650
29735
|
video.id = 'main';
|
29651
29736
|
this.log("Init video buffer, container:" + video.container + ", codecs[level/parsed]=[" + (currentLevel.videoCodec || '') + "/" + video.codec + "]");
|
29737
|
+
delete tracks.audiovideo;
|
29652
29738
|
}
|
29653
29739
|
if (audiovideo) {
|
29654
29740
|
this.log("Init audiovideo buffer, container:" + audiovideo.container + ", codecs[level/parsed]=[" + currentLevel.codecs + "/" + audiovideo.codec + "]");
|
29741
|
+
delete tracks.video;
|
29742
|
+
delete tracks.audio;
|
29743
|
+
}
|
29744
|
+
var trackTypes = Object.keys(tracks);
|
29745
|
+
if (trackTypes.length) {
|
29746
|
+
this.hls.trigger(Events.BUFFER_CODECS, tracks);
|
29747
|
+
// loop through tracks that are going to be provided to bufferController
|
29748
|
+
trackTypes.forEach(function (trackName) {
|
29749
|
+
var track = tracks[trackName];
|
29750
|
+
var initSegment = track.initSegment;
|
29751
|
+
if (initSegment != null && initSegment.byteLength) {
|
29752
|
+
_this3.hls.trigger(Events.BUFFER_APPENDING, {
|
29753
|
+
type: trackName,
|
29754
|
+
data: initSegment,
|
29755
|
+
frag: frag,
|
29756
|
+
part: null,
|
29757
|
+
chunkMeta: chunkMeta,
|
29758
|
+
parent: frag.type
|
29759
|
+
});
|
29760
|
+
}
|
29761
|
+
});
|
29655
29762
|
}
|
29656
|
-
this.hls.trigger(Events.BUFFER_CODECS, tracks);
|
29657
|
-
// loop through tracks that are going to be provided to bufferController
|
29658
|
-
Object.keys(tracks).forEach(function (trackName) {
|
29659
|
-
var track = tracks[trackName];
|
29660
|
-
var initSegment = track.initSegment;
|
29661
|
-
if (initSegment != null && initSegment.byteLength) {
|
29662
|
-
_this3.hls.trigger(Events.BUFFER_APPENDING, {
|
29663
|
-
type: trackName,
|
29664
|
-
data: initSegment,
|
29665
|
-
frag: frag,
|
29666
|
-
part: null,
|
29667
|
-
chunkMeta: chunkMeta,
|
29668
|
-
parent: frag.type
|
29669
|
-
});
|
29670
|
-
}
|
29671
|
-
});
|
29672
29763
|
// trigger handler right now
|
29673
29764
|
this.tickImmediate();
|
29674
29765
|
};
|
@@ -29749,22 +29840,30 @@
|
|
29749
29840
|
}, {
|
29750
29841
|
key: "currentFrag",
|
29751
29842
|
get: function get() {
|
29752
|
-
var
|
29753
|
-
if (
|
29754
|
-
return this.fragPlaying
|
29843
|
+
var _this$media2;
|
29844
|
+
if (this.fragPlaying) {
|
29845
|
+
return this.fragPlaying;
|
29846
|
+
}
|
29847
|
+
var currentTime = ((_this$media2 = this.media) == null ? void 0 : _this$media2.currentTime) || this.lastCurrentTime;
|
29848
|
+
if (isFiniteNumber(currentTime)) {
|
29849
|
+
return this.getAppendedFrag(currentTime);
|
29755
29850
|
}
|
29756
29851
|
return null;
|
29757
29852
|
}
|
29758
29853
|
}, {
|
29759
29854
|
key: "currentProgramDateTime",
|
29760
29855
|
get: function get() {
|
29761
|
-
var
|
29762
|
-
|
29763
|
-
|
29764
|
-
var
|
29765
|
-
|
29766
|
-
|
29767
|
-
|
29856
|
+
var _this$media3;
|
29857
|
+
var currentTime = ((_this$media3 = this.media) == null ? void 0 : _this$media3.currentTime) || this.lastCurrentTime;
|
29858
|
+
if (isFiniteNumber(currentTime)) {
|
29859
|
+
var details = this.getLevelDetails();
|
29860
|
+
var frag = this.currentFrag || (details ? findFragmentByPTS(null, details.fragments, currentTime) : null);
|
29861
|
+
if (frag) {
|
29862
|
+
var programDateTime = frag.programDateTime;
|
29863
|
+
if (programDateTime !== null) {
|
29864
|
+
var epocMs = programDateTime + (currentTime - frag.start) * 1000;
|
29865
|
+
return new Date(epocMs);
|
29866
|
+
}
|
29768
29867
|
}
|
29769
29868
|
}
|
29770
29869
|
return null;
|
@@ -29882,7 +29981,7 @@
|
|
29882
29981
|
if (AudioStreamControllerClass) {
|
29883
29982
|
networkControllers.push(new AudioStreamControllerClass(this, fragmentTracker, keyLoader));
|
29884
29983
|
}
|
29885
|
-
// subtitleTrackController
|
29984
|
+
// Instantiate subtitleTrackController before SubtitleStreamController to receive level events first
|
29886
29985
|
this.subtitleTrackController = this.createController(config.subtitleTrackController, networkControllers);
|
29887
29986
|
var SubtitleStreamControllerClass = config.subtitleStreamController;
|
29888
29987
|
if (SubtitleStreamControllerClass) {
|
@@ -30678,7 +30777,7 @@
|
|
30678
30777
|
* Get the video-dev/hls.js package version.
|
30679
30778
|
*/
|
30680
30779
|
function get() {
|
30681
|
-
return "1.5.12-0.canary.
|
30780
|
+
return "1.5.12-0.canary.10367";
|
30682
30781
|
}
|
30683
30782
|
}, {
|
30684
30783
|
key: "Events",
|