hls.js 1.6.0-beta.1.0.canary.10714 → 1.6.0-beta.1.0.canary.10715
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 +45 -13
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +45 -13
- 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 +48 -13
- 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 +48 -13
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +1 -1
- package/src/controller/abr-controller.ts +64 -11
- package/src/controller/level-controller.ts +7 -3
package/dist/hls.light.mjs
CHANGED
@@ -397,7 +397,7 @@ function enableLogs(debugConfig, context, id) {
|
|
397
397
|
// Some browsers don't allow to use bind on console object anyway
|
398
398
|
// fallback to default if needed
|
399
399
|
try {
|
400
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.
|
400
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10715"}`);
|
401
401
|
} catch (e) {
|
402
402
|
/* log fn threw an exception. All logger methods are no-ops. */
|
403
403
|
return createLogger();
|
@@ -1078,6 +1078,7 @@ class AbrController extends Logger {
|
|
1078
1078
|
quickly enough to prevent underbuffering
|
1079
1079
|
*/
|
1080
1080
|
this._abandonRulesCheck = () => {
|
1081
|
+
var _this$hls$latestLevel;
|
1081
1082
|
const {
|
1082
1083
|
fragCurrent: frag,
|
1083
1084
|
partCurrent: part,
|
@@ -1132,12 +1133,15 @@ class AbrController extends Logger {
|
|
1132
1133
|
}
|
1133
1134
|
const loadRate = loadedFirstByte ? stats.loaded * 1000 / timeStreaming : 0;
|
1134
1135
|
// fragLoadDelay is an estimate of the time (in seconds) it will take to buffer the remainder of the fragment
|
1135
|
-
const
|
1136
|
+
const ttfbSeconds = ttfbEstimate / 1000;
|
1137
|
+
const fragLoadedDelay = loadRate ? (expectedLen - stats.loaded) / loadRate : expectedLen * 8 / bwEstimate + ttfbSeconds;
|
1136
1138
|
// Only downswitch if the time to finish loading the current fragment is greater than the amount of buffer left
|
1137
1139
|
if (fragLoadedDelay <= bufferStarvationDelay) {
|
1138
1140
|
return;
|
1139
1141
|
}
|
1140
1142
|
const bwe = loadRate ? loadRate * 8 : bwEstimate;
|
1143
|
+
const live = ((_this$hls$latestLevel = this.hls.latestLevelDetails) == null ? void 0 : _this$hls$latestLevel.live) === true;
|
1144
|
+
const abrBandWidthUpFactor = this.hls.config.abrBandWidthUpFactor;
|
1141
1145
|
let fragLevelNextLoadedDelay = Number.POSITIVE_INFINITY;
|
1142
1146
|
let nextLoadLevel;
|
1143
1147
|
// Iterate through lower level and try to find the largest one that avoids rebuffering
|
@@ -1145,8 +1149,9 @@ class AbrController extends Logger {
|
|
1145
1149
|
// compute time to load next fragment at lower level
|
1146
1150
|
// 8 = bits per byte (bps/Bps)
|
1147
1151
|
const levelNextBitrate = levels[nextLoadLevel].maxBitrate;
|
1148
|
-
|
1149
|
-
|
1152
|
+
const requiresLevelLoad = !levels[nextLoadLevel].details || live;
|
1153
|
+
fragLevelNextLoadedDelay = this.getTimeToLoadFrag(ttfbSeconds, bwe, duration * levelNextBitrate, requiresLevelLoad);
|
1154
|
+
if (fragLevelNextLoadedDelay < Math.min(bufferStarvationDelay, duration + ttfbSeconds)) {
|
1150
1155
|
break;
|
1151
1156
|
}
|
1152
1157
|
}
|
@@ -1160,7 +1165,6 @@ class AbrController extends Logger {
|
|
1160
1165
|
if (fragLevelNextLoadedDelay > duration * 10) {
|
1161
1166
|
return;
|
1162
1167
|
}
|
1163
|
-
hls.nextLoadLevel = hls.nextAutoLevel = nextLoadLevel;
|
1164
1168
|
if (loadedFirstByte) {
|
1165
1169
|
// If there has been loading progress, sample bandwidth using loading time offset by minimum TTFB time
|
1166
1170
|
this.bwEstimator.sample(timeLoading - Math.min(ttfbEstimate, ttfb), stats.loaded);
|
@@ -1169,11 +1173,15 @@ class AbrController extends Logger {
|
|
1169
1173
|
this.bwEstimator.sampleTTFB(timeLoading);
|
1170
1174
|
}
|
1171
1175
|
const nextLoadLevelBitrate = levels[nextLoadLevel].maxBitrate;
|
1172
|
-
if (this.getBwEstimate() *
|
1176
|
+
if (this.getBwEstimate() * abrBandWidthUpFactor > nextLoadLevelBitrate) {
|
1173
1177
|
this.resetEstimator(nextLoadLevelBitrate);
|
1174
1178
|
}
|
1175
|
-
this.
|
1179
|
+
const bestSwitchLevel = this.findBestLevel(nextLoadLevelBitrate, minAutoLevel, nextLoadLevel, 0, bufferStarvationDelay, 1, 1);
|
1180
|
+
if (bestSwitchLevel > -1) {
|
1181
|
+
nextLoadLevel = bestSwitchLevel;
|
1182
|
+
}
|
1176
1183
|
this.warn(`Fragment ${frag.sn}${part ? ' part ' + part.index : ''} of level ${frag.level} is loading too slowly;
|
1184
|
+
Fragment duration: ${frag.duration.toFixed(3)}
|
1177
1185
|
Time to underbuffer: ${bufferStarvationDelay.toFixed(3)} s
|
1178
1186
|
Estimated load time for current fragment: ${fragLoadedDelay.toFixed(3)} s
|
1179
1187
|
Estimated load time for down switch fragment: ${fragLevelNextLoadedDelay.toFixed(3)} s
|
@@ -1181,6 +1189,28 @@ class AbrController extends Logger {
|
|
1181
1189
|
Current BW estimate: ${isFiniteNumber(bwEstimate) ? bwEstimate | 0 : 'Unknown'} bps
|
1182
1190
|
New BW estimate: ${this.getBwEstimate() | 0} bps
|
1183
1191
|
Switching to level ${nextLoadLevel} @ ${nextLoadLevelBitrate | 0} bps`);
|
1192
|
+
hls.nextLoadLevel = hls.nextAutoLevel = nextLoadLevel;
|
1193
|
+
this.clearTimer();
|
1194
|
+
this.timer = self.setInterval(() => {
|
1195
|
+
// Are nextLoadLevel details available or is stream-controller still in "WAITING_LEVEL" state?
|
1196
|
+
this.clearTimer();
|
1197
|
+
if (this.fragCurrent === frag && this.hls.loadLevel === nextLoadLevel && nextLoadLevel > 0) {
|
1198
|
+
const bufferStarvationDelay = this.getStarvationDelay();
|
1199
|
+
this.warn(`Aborting inflight request ${nextLoadLevel > 0 ? 'and switching down' : ''}
|
1200
|
+
Fragment duration: ${frag.duration.toFixed(3)} s
|
1201
|
+
Time to underbuffer: ${bufferStarvationDelay.toFixed(3)} s`);
|
1202
|
+
frag.abortRequests();
|
1203
|
+
this.fragCurrent = this.partCurrent = null;
|
1204
|
+
if (nextLoadLevel > minAutoLevel) {
|
1205
|
+
let lowestSwitchLevel = this.findBestLevel(this.hls.levels[minAutoLevel].bitrate, minAutoLevel, nextLoadLevel, 0, bufferStarvationDelay, 1, 1);
|
1206
|
+
if (lowestSwitchLevel === -1) {
|
1207
|
+
lowestSwitchLevel = minAutoLevel;
|
1208
|
+
}
|
1209
|
+
this.hls.nextLoadLevel = this.hls.nextAutoLevel = lowestSwitchLevel;
|
1210
|
+
this.resetEstimator(this.hls.levels[lowestSwitchLevel].bitrate);
|
1211
|
+
}
|
1212
|
+
}
|
1213
|
+
}, fragLevelNextLoadedDelay * 1000);
|
1184
1214
|
hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
|
1185
1215
|
frag,
|
1186
1216
|
part,
|
@@ -1541,7 +1571,7 @@ class AbrController extends Logger {
|
|
1541
1571
|
return this.bwEstimator.canEstimate() ? this.bwEstimator.getEstimate() : this.hls.config.abrEwmaDefaultEstimate;
|
1542
1572
|
}
|
1543
1573
|
findBestLevel(currentBw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor) {
|
1544
|
-
var
|
1574
|
+
var _this$hls$latestLevel2;
|
1545
1575
|
const maxFetchDuration = bufferStarvationDelay + maxStarvationDelay;
|
1546
1576
|
const lastLoadedFragLevel = this.lastLoadedFragLevel;
|
1547
1577
|
const selectionBaseLevel = lastLoadedFragLevel === -1 ? this.hls.firstLevel : lastLoadedFragLevel;
|
@@ -1559,7 +1589,7 @@ class AbrController extends Logger {
|
|
1559
1589
|
return 0;
|
1560
1590
|
}
|
1561
1591
|
const level = levels[selectionBaseLevel];
|
1562
|
-
const live = !!(
|
1592
|
+
const live = !!((_this$hls$latestLevel2 = this.hls.latestLevelDetails) != null && _this$hls$latestLevel2.live);
|
1563
1593
|
const firstSelection = loadLevel === -1 || lastLoadedFragLevel === -1;
|
1564
1594
|
let currentCodecSet;
|
1565
1595
|
let currentVideoRange = 'SDR';
|
@@ -18333,8 +18363,10 @@ class LevelController extends BasePlaylistController {
|
|
18333
18363
|
const pathwayId = level.attrs['PATHWAY-ID'];
|
18334
18364
|
this.currentLevelIndex = newLevel;
|
18335
18365
|
this.currentLevel = level;
|
18336
|
-
if (lastLevelIndex === newLevel &&
|
18337
|
-
|
18366
|
+
if (lastLevelIndex === newLevel && lastLevel && lastPathwayId === pathwayId) {
|
18367
|
+
if (level.details || this.requestScheduled !== -1) {
|
18368
|
+
return;
|
18369
|
+
}
|
18338
18370
|
}
|
18339
18371
|
this.log(`Switching to level ${newLevel} (${level.height ? level.height + 'p ' : ''}${level.videoRange ? level.videoRange + ' ' : ''}${level.codecSet ? level.codecSet + ' ' : ''}@${level.bitrate})${pathwayId ? ' with Pathway ' + pathwayId : ''} from level ${lastLevelIndex}${lastPathwayId ? ' with Pathway ' + lastPathwayId : ''}`);
|
18340
18372
|
const levelSwitchingData = {
|
@@ -18428,7 +18460,10 @@ class LevelController extends BasePlaylistController {
|
|
18428
18460
|
return;
|
18429
18461
|
}
|
18430
18462
|
if (data.context.type === PlaylistContextType.LEVEL && data.context.level === this.level) {
|
18431
|
-
this.checkRetry(data);
|
18463
|
+
const retry = this.checkRetry(data);
|
18464
|
+
if (!retry) {
|
18465
|
+
this.requestScheduled = -1;
|
18466
|
+
}
|
18432
18467
|
}
|
18433
18468
|
}
|
18434
18469
|
|
@@ -18927,7 +18962,7 @@ class GapController extends Logger {
|
|
18927
18962
|
}
|
18928
18963
|
}
|
18929
18964
|
|
18930
|
-
const version = "1.6.0-beta.1.0.canary.
|
18965
|
+
const version = "1.6.0-beta.1.0.canary.10715";
|
18931
18966
|
|
18932
18967
|
// ensure the worker ends up in the bundle
|
18933
18968
|
// If the worker should not be included this gets aliased to empty.js
|