hls.js 1.5.5-0.canary.9984 → 1.5.5-0.canary.9986
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 +75 -8
- package/dist/hls.js.d.ts +2 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +75 -8
- 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 +75 -8
- 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 +75 -8
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +1 -1
- package/src/controller/base-playlist-controller.ts +13 -1
- package/src/controller/base-stream-controller.ts +93 -4
- package/src/controller/level-controller.ts +7 -1
package/dist/hls.light.mjs
CHANGED
@@ -512,7 +512,7 @@ function enableLogs(debugConfig, context, id) {
|
|
512
512
|
// Some browsers don't allow to use bind on console object anyway
|
513
513
|
// fallback to default if needed
|
514
514
|
try {
|
515
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.5-0.canary.
|
515
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.5-0.canary.9986"}`);
|
516
516
|
} catch (e) {
|
517
517
|
/* log fn threw an exception. All logger methods are no-ops. */
|
518
518
|
return createLogger();
|
@@ -5713,7 +5713,12 @@ class BasePlaylistController extends Logger {
|
|
5713
5713
|
const cdnAge = lastAdvanced + details.ageHeader;
|
5714
5714
|
let currentGoal = Math.min(cdnAge - details.partTarget, details.targetduration * 1.5);
|
5715
5715
|
if (currentGoal > 0) {
|
5716
|
-
if (
|
5716
|
+
if (cdnAge > details.targetduration * 3) {
|
5717
|
+
// Omit segment and part directives when the last response was more than 3 target durations ago,
|
5718
|
+
this.log(`Playlist last advanced ${lastAdvanced.toFixed(2)}s ago. Omitting segment and part directives.`);
|
5719
|
+
msn = undefined;
|
5720
|
+
part = undefined;
|
5721
|
+
} else if (previousDetails != null && previousDetails.tuneInGoal && cdnAge - details.partTarget > previousDetails.tuneInGoal) {
|
5717
5722
|
// If we attempted to get the next or latest playlist update, but currentGoal increased,
|
5718
5723
|
// then we either can't catchup, or the "age" header cannot be trusted.
|
5719
5724
|
this.warn(`CDN Tune-in goal increased from: ${previousDetails.tuneInGoal} to: ${currentGoal} with playlist age: ${details.age}`);
|
@@ -10059,7 +10064,12 @@ class LevelController extends BasePlaylistController {
|
|
10059
10064
|
if (curLevel.fragmentError === 0) {
|
10060
10065
|
curLevel.loadError = 0;
|
10061
10066
|
}
|
10062
|
-
|
10067
|
+
// Ignore matching details populated by loading a Media Playlist directly
|
10068
|
+
let previousDetails = curLevel.details;
|
10069
|
+
if (previousDetails === data.details && previousDetails.advanced) {
|
10070
|
+
previousDetails = undefined;
|
10071
|
+
}
|
10072
|
+
this.playlistLoaded(level, data, previousDetails);
|
10063
10073
|
} else if ((_data$deliveryDirecti2 = data.deliveryDirectives) != null && _data$deliveryDirecti2.skip) {
|
10064
10074
|
// received a delta playlist update that cannot be merged
|
10065
10075
|
details.deltaUpdateFailed = true;
|
@@ -11956,6 +11966,7 @@ class BaseStreamController extends TaskLoop {
|
|
11956
11966
|
this.decrypter = void 0;
|
11957
11967
|
this.initPTS = [];
|
11958
11968
|
this.buffering = true;
|
11969
|
+
this.loadingParts = false;
|
11959
11970
|
this.onMediaSeeking = () => {
|
11960
11971
|
const {
|
11961
11972
|
config,
|
@@ -11992,6 +12003,14 @@ class BaseStreamController extends TaskLoop {
|
|
11992
12003
|
// Remove gap fragments
|
11993
12004
|
this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
|
11994
12005
|
this.lastCurrentTime = currentTime;
|
12006
|
+
if (!this.loadingParts) {
|
12007
|
+
const bufferEnd = Math.max(bufferInfo.end, currentTime);
|
12008
|
+
const shouldLoadParts = this.shouldLoadParts(this.getLevelDetails(), bufferEnd);
|
12009
|
+
if (shouldLoadParts) {
|
12010
|
+
this.log(`LL-Part loading ON after seeking to ${currentTime.toFixed(2)} with buffer @${bufferEnd.toFixed(2)}`);
|
12011
|
+
this.loadingParts = shouldLoadParts;
|
12012
|
+
}
|
12013
|
+
}
|
11995
12014
|
}
|
11996
12015
|
|
11997
12016
|
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
@@ -12402,8 +12421,16 @@ class BaseStreamController extends TaskLoop {
|
|
12402
12421
|
} else if (!frag.encrypted && details.encryptedFragments.length) {
|
12403
12422
|
this.keyLoader.loadClear(frag, details.encryptedFragments);
|
12404
12423
|
}
|
12424
|
+
const fragPrevious = this.fragPrevious;
|
12425
|
+
if (frag.sn !== 'initSegment' && (!fragPrevious || frag.sn !== fragPrevious.sn)) {
|
12426
|
+
const shouldLoadParts = this.shouldLoadParts(level.details, frag.end);
|
12427
|
+
if (shouldLoadParts !== this.loadingParts) {
|
12428
|
+
this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} loading sn ${fragPrevious == null ? void 0 : fragPrevious.sn}->${frag.sn}`);
|
12429
|
+
this.loadingParts = shouldLoadParts;
|
12430
|
+
}
|
12431
|
+
}
|
12405
12432
|
targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
|
12406
|
-
if (this.
|
12433
|
+
if (this.loadingParts && frag.sn !== 'initSegment') {
|
12407
12434
|
const partList = details.partList;
|
12408
12435
|
if (partList && progressCallback) {
|
12409
12436
|
if (targetBufferTime > frag.end && details.fragmentHint) {
|
@@ -12441,6 +12468,13 @@ class BaseStreamController extends TaskLoop {
|
|
12441
12468
|
}
|
12442
12469
|
}
|
12443
12470
|
}
|
12471
|
+
if (frag.sn !== 'initSegment' && this.loadingParts) {
|
12472
|
+
this.log(`LL-Part loading OFF after next part miss @${targetBufferTime.toFixed(2)}`);
|
12473
|
+
this.loadingParts = false;
|
12474
|
+
} else if (!frag.url) {
|
12475
|
+
// Selected fragment hint for part but not loading parts
|
12476
|
+
return Promise.resolve(null);
|
12477
|
+
}
|
12444
12478
|
this.log(`Loading fragment ${frag.sn} cc: ${frag.cc} ${details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : ''}${this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track'}: ${frag.level}, target: ${parseFloat(targetBufferTime.toFixed(3))}`);
|
12445
12479
|
// Don't update nextLoadPosition for fragments which are not buffered
|
12446
12480
|
if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
|
@@ -12539,8 +12573,36 @@ class BaseStreamController extends TaskLoop {
|
|
12539
12573
|
if (part) {
|
12540
12574
|
part.stats.parsing.end = now;
|
12541
12575
|
}
|
12576
|
+
// See if part loading should be disabled/enabled based on buffer and playback position.
|
12577
|
+
if (frag.sn !== 'initSegment') {
|
12578
|
+
const levelDetails = this.getLevelDetails();
|
12579
|
+
const loadingPartsAtEdge = levelDetails && frag.sn > levelDetails.endSN;
|
12580
|
+
const shouldLoadParts = loadingPartsAtEdge || this.shouldLoadParts(levelDetails, frag.end);
|
12581
|
+
if (shouldLoadParts !== this.loadingParts) {
|
12582
|
+
this.log(`LL-Part loading ${shouldLoadParts ? 'ON' : 'OFF'} after parsing segment ending @${frag.end.toFixed(2)}`);
|
12583
|
+
this.loadingParts = shouldLoadParts;
|
12584
|
+
}
|
12585
|
+
}
|
12542
12586
|
this.updateLevelTiming(frag, part, level, chunkMeta.partial);
|
12543
12587
|
}
|
12588
|
+
shouldLoadParts(details, bufferEnd) {
|
12589
|
+
if (this.config.lowLatencyMode) {
|
12590
|
+
if (!details) {
|
12591
|
+
return this.loadingParts;
|
12592
|
+
}
|
12593
|
+
if (details != null && details.partList) {
|
12594
|
+
var _details$fragmentHint;
|
12595
|
+
// Buffer must be ahead of first part + duration of parts after last segment
|
12596
|
+
// and playback must be at or past segment adjacent to part list
|
12597
|
+
const firstPart = details.partList[0];
|
12598
|
+
const safePartStart = firstPart.end + (((_details$fragmentHint = details.fragmentHint) == null ? void 0 : _details$fragmentHint.duration) || 0);
|
12599
|
+
if (bufferEnd >= safePartStart && this.lastCurrentTime > firstPart.start - firstPart.fragment.duration) {
|
12600
|
+
return true;
|
12601
|
+
}
|
12602
|
+
}
|
12603
|
+
}
|
12604
|
+
return false;
|
12605
|
+
}
|
12544
12606
|
getCurrentContext(chunkMeta) {
|
12545
12607
|
const {
|
12546
12608
|
levels,
|
@@ -12689,7 +12751,8 @@ class BaseStreamController extends TaskLoop {
|
|
12689
12751
|
config
|
12690
12752
|
} = this;
|
12691
12753
|
const start = fragments[0].start;
|
12692
|
-
|
12754
|
+
const canLoadParts = config.lowLatencyMode && !!levelDetails.partList;
|
12755
|
+
let frag = null;
|
12693
12756
|
if (levelDetails.live) {
|
12694
12757
|
const initialLiveManifestSize = config.initialLiveManifestSize;
|
12695
12758
|
if (fragLen < initialLiveManifestSize) {
|
@@ -12701,6 +12764,10 @@ class BaseStreamController extends TaskLoop {
|
|
12701
12764
|
// Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that
|
12702
12765
|
// we get the fragment matching that start time
|
12703
12766
|
if (!levelDetails.PTSKnown && !this.startFragRequested && this.startPosition === -1 || pos < start) {
|
12767
|
+
if (canLoadParts && !this.loadingParts) {
|
12768
|
+
this.log(`LL-Part loading ON for initial live fragment`);
|
12769
|
+
this.loadingParts = true;
|
12770
|
+
}
|
12704
12771
|
frag = this.getInitialLiveFragment(levelDetails, fragments);
|
12705
12772
|
this.startPosition = this.nextLoadPosition = frag ? this.hls.liveSyncPosition || frag.start : pos;
|
12706
12773
|
}
|
@@ -12711,7 +12778,7 @@ class BaseStreamController extends TaskLoop {
|
|
12711
12778
|
|
12712
12779
|
// If we haven't run into any special cases already, just load the fragment most closely matching the requested position
|
12713
12780
|
if (!frag) {
|
12714
|
-
const end =
|
12781
|
+
const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
|
12715
12782
|
frag = this.getFragmentAtPosition(pos, end, levelDetails);
|
12716
12783
|
}
|
12717
12784
|
return this.mapToInitFragWhenRequired(frag);
|
@@ -12833,7 +12900,7 @@ class BaseStreamController extends TaskLoop {
|
|
12833
12900
|
} = levelDetails;
|
12834
12901
|
const tolerance = config.maxFragLookUpTolerance;
|
12835
12902
|
const partList = levelDetails.partList;
|
12836
|
-
const loadingParts = !!(
|
12903
|
+
const loadingParts = !!(this.loadingParts && partList != null && partList.length && fragmentHint);
|
12837
12904
|
if (loadingParts && fragmentHint && !this.bitrateTest) {
|
12838
12905
|
// Include incomplete fragment with parts at end
|
12839
12906
|
fragments = fragments.concat(fragmentHint);
|
@@ -19924,7 +19991,7 @@ class Hls {
|
|
19924
19991
|
* Get the video-dev/hls.js package version.
|
19925
19992
|
*/
|
19926
19993
|
static get version() {
|
19927
|
-
return "1.5.5-0.canary.
|
19994
|
+
return "1.5.5-0.canary.9986";
|
19928
19995
|
}
|
19929
19996
|
|
19930
19997
|
/**
|