hls.js 1.6.0-beta.1.0.canary.10750 → 1.6.0-beta.1.0.canary.10752
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/README.md +6 -11
- package/dist/hls.d.mts +5 -1
- package/dist/hls.d.ts +5 -1
- package/dist/hls.js +74 -24
- package/dist/hls.js.d.ts +5 -1
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +74 -24
- 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 +69 -23
- 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 +69 -23
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +1 -1
- package/src/controller/abr-controller.ts +6 -5
- package/src/controller/base-stream-controller.ts +29 -21
- package/src/controller/stream-controller.ts +5 -4
- package/src/demux/transmuxer-interface.ts +4 -2
- package/src/demux/transmuxer.ts +1 -1
- package/src/loader/fragment-loader.ts +1 -1
- package/src/loader/fragment.ts +33 -0
- package/src/loader/m3u8-parser.ts +10 -0
package/dist/hls.mjs
CHANGED
@@ -400,7 +400,7 @@ function enableLogs(debugConfig, context, id) {
|
|
400
400
|
// Some browsers don't allow to use bind on console object anyway
|
401
401
|
// fallback to default if needed
|
402
402
|
try {
|
403
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.
|
403
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-beta.1.0.canary.10752"}`);
|
404
404
|
} catch (e) {
|
405
405
|
/* log fn threw an exception. All logger methods are no-ops. */
|
406
406
|
return createLogger();
|
@@ -1375,7 +1375,7 @@ class AbrController extends Logger {
|
|
1375
1375
|
const bwEstimate = this.getBwEstimate();
|
1376
1376
|
const levels = hls.levels;
|
1377
1377
|
const level = levels[frag.level];
|
1378
|
-
const expectedLen =
|
1378
|
+
const expectedLen = Math.max(stats.loaded, Math.round(duration * (frag.bitrate || level.averageBitrate) / 8));
|
1379
1379
|
let timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
|
1380
1380
|
if (timeStreaming < 1 && loadedFirstByte) {
|
1381
1381
|
timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
|
@@ -1933,7 +1933,7 @@ class AbrController extends Logger {
|
|
1933
1933
|
}
|
1934
1934
|
|
1935
1935
|
// Use average bitrate when starvation delay (buffer length) is gt or eq two segment durations and rebuffering is not expected (maxStarvationDelay > 0)
|
1936
|
-
const bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ?
|
1936
|
+
const bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ? levelInfo.averageBitrate : levelInfo.maxBitrate;
|
1937
1937
|
const fetchDuration = this.getTimeToLoadFrag(ttfbEstimateSec, adjustedbw, bitrate * avgDuration, levelDetails === undefined);
|
1938
1938
|
const canSwitchWithinTolerance =
|
1939
1939
|
// if adjusted bw is greater than level bitrate AND
|
@@ -3737,6 +3737,8 @@ class Fragment extends BaseSegment {
|
|
3737
3737
|
this._decryptdata = null;
|
3738
3738
|
this._programDateTime = null;
|
3739
3739
|
this._ref = null;
|
3740
|
+
// Approximate bit rate of the fragment expressed in bits per second (bps) as indicated by the last EXT-X-BITRATE (kbps) tag
|
3741
|
+
this._bitrate = void 0;
|
3740
3742
|
this.rawProgramDateTime = null;
|
3741
3743
|
this.tagList = [];
|
3742
3744
|
// EXTINF has to be present for a m3u8 to be considered valid
|
@@ -3791,6 +3793,34 @@ class Fragment extends BaseSegment {
|
|
3791
3793
|
this.urlId = 0;
|
3792
3794
|
this.type = type;
|
3793
3795
|
}
|
3796
|
+
get byteLength() {
|
3797
|
+
if (this.hasStats) {
|
3798
|
+
const total = this.stats.total;
|
3799
|
+
if (total) {
|
3800
|
+
return total;
|
3801
|
+
}
|
3802
|
+
}
|
3803
|
+
if (this.byteRange) {
|
3804
|
+
const start = this.byteRange[0];
|
3805
|
+
const end = this.byteRange[1];
|
3806
|
+
if (isFiniteNumber(start) && isFiniteNumber(end)) {
|
3807
|
+
return end - start;
|
3808
|
+
}
|
3809
|
+
}
|
3810
|
+
return null;
|
3811
|
+
}
|
3812
|
+
get bitrate() {
|
3813
|
+
if (this.byteLength) {
|
3814
|
+
return this.byteLength * 8 / this.duration;
|
3815
|
+
}
|
3816
|
+
if (this._bitrate) {
|
3817
|
+
return this._bitrate;
|
3818
|
+
}
|
3819
|
+
return null;
|
3820
|
+
}
|
3821
|
+
set bitrate(value) {
|
3822
|
+
this._bitrate = value;
|
3823
|
+
}
|
3794
3824
|
get decryptdata() {
|
3795
3825
|
const {
|
3796
3826
|
levelkeys
|
@@ -6918,6 +6948,7 @@ class M3U8Parser {
|
|
6918
6948
|
let currentPart = 0;
|
6919
6949
|
let totalduration = 0;
|
6920
6950
|
let discontinuityCounter = 0;
|
6951
|
+
let currentBitrate = 0;
|
6921
6952
|
let prevFrag = null;
|
6922
6953
|
let frag = new Fragment(type, base);
|
6923
6954
|
let result;
|
@@ -6938,6 +6969,9 @@ class M3U8Parser {
|
|
6938
6969
|
frag.start = totalduration;
|
6939
6970
|
frag.sn = currentSN;
|
6940
6971
|
frag.cc = discontinuityCounter;
|
6972
|
+
if (currentBitrate) {
|
6973
|
+
frag.bitrate = currentBitrate;
|
6974
|
+
}
|
6941
6975
|
frag.level = id;
|
6942
6976
|
if (currentInitSegment) {
|
6943
6977
|
frag.initSegment = currentInitSegment;
|
@@ -7067,6 +7101,12 @@ class M3U8Parser {
|
|
7067
7101
|
break;
|
7068
7102
|
case 'BITRATE':
|
7069
7103
|
frag.tagList.push([tag, value1]);
|
7104
|
+
currentBitrate = parseInt(value1) * 1000;
|
7105
|
+
if (isFiniteNumber(currentBitrate)) {
|
7106
|
+
frag.bitrate = currentBitrate;
|
7107
|
+
} else {
|
7108
|
+
currentBitrate = 0;
|
7109
|
+
}
|
7070
7110
|
break;
|
7071
7111
|
case 'DATERANGE':
|
7072
7112
|
{
|
@@ -8246,22 +8286,24 @@ class BaseStreamController extends TaskLoop {
|
|
8246
8286
|
this.startFragRequested = true;
|
8247
8287
|
this._loadFragForPlayback(frag, level, targetBufferTime);
|
8248
8288
|
}
|
8249
|
-
_loadFragForPlayback(
|
8289
|
+
_loadFragForPlayback(fragment, level, targetBufferTime) {
|
8250
8290
|
const progressCallback = data => {
|
8291
|
+
const frag = data.frag;
|
8251
8292
|
if (this.fragContextChanged(frag)) {
|
8252
|
-
this.warn(
|
8293
|
+
this.warn(`${frag.type} sn: ${frag.sn}${data.part ? ' part: ' + data.part.index : ''} of ${this.fragInfo(frag, false, data.part)}) was dropped during download.`);
|
8253
8294
|
this.fragmentTracker.removeFragment(frag);
|
8254
8295
|
return;
|
8255
8296
|
}
|
8256
8297
|
frag.stats.chunkCount++;
|
8257
8298
|
this._handleFragmentLoadProgress(data);
|
8258
8299
|
};
|
8259
|
-
this._doFragLoad(
|
8300
|
+
this._doFragLoad(fragment, level, targetBufferTime, progressCallback).then(data => {
|
8260
8301
|
if (!data) {
|
8261
8302
|
// if we're here we probably needed to backtrack or are waiting for more parts
|
8262
8303
|
return;
|
8263
8304
|
}
|
8264
8305
|
const state = this.state;
|
8306
|
+
const frag = data.frag;
|
8265
8307
|
if (this.fragContextChanged(frag)) {
|
8266
8308
|
if (state === State.FRAG_LOADING || !this.fragCurrent && state === State.PARSING) {
|
8267
8309
|
this.fragmentTracker.removeFragment(frag);
|
@@ -8281,7 +8323,7 @@ class BaseStreamController extends TaskLoop {
|
|
8281
8323
|
return;
|
8282
8324
|
}
|
8283
8325
|
this.warn(`Frag error: ${(reason == null ? void 0 : reason.message) || reason}`);
|
8284
|
-
this.resetFragmentLoading(
|
8326
|
+
this.resetFragmentLoading(fragment);
|
8285
8327
|
});
|
8286
8328
|
}
|
8287
8329
|
clearTrackerIfNeeded(frag) {
|
@@ -8345,9 +8387,10 @@ class BaseStreamController extends TaskLoop {
|
|
8345
8387
|
};
|
8346
8388
|
this.hls.trigger(Events.BUFFER_FLUSHING, flushScope);
|
8347
8389
|
}
|
8348
|
-
_loadInitSegment(
|
8349
|
-
this._doFragLoad(
|
8350
|
-
|
8390
|
+
_loadInitSegment(fragment, level) {
|
8391
|
+
this._doFragLoad(fragment, level).then(data => {
|
8392
|
+
const frag = data == null ? void 0 : data.frag;
|
8393
|
+
if (!frag || this.fragContextChanged(frag) || !this.levels) {
|
8351
8394
|
throw new Error('init load aborted');
|
8352
8395
|
}
|
8353
8396
|
return data;
|
@@ -8356,6 +8399,7 @@ class BaseStreamController extends TaskLoop {
|
|
8356
8399
|
hls
|
8357
8400
|
} = this;
|
8358
8401
|
const {
|
8402
|
+
frag,
|
8359
8403
|
payload
|
8360
8404
|
} = data;
|
8361
8405
|
const decryptData = frag.decryptdata;
|
@@ -8394,7 +8438,7 @@ class BaseStreamController extends TaskLoop {
|
|
8394
8438
|
return;
|
8395
8439
|
}
|
8396
8440
|
this.warn(reason);
|
8397
|
-
this.resetFragmentLoading(
|
8441
|
+
this.resetFragmentLoading(fragment);
|
8398
8442
|
});
|
8399
8443
|
}
|
8400
8444
|
completeInitSegmentLoad(data) {
|
@@ -8421,7 +8465,7 @@ class BaseStreamController extends TaskLoop {
|
|
8421
8465
|
}
|
8422
8466
|
fragBufferedComplete(frag, part) {
|
8423
8467
|
const media = this.mediaBuffer ? this.mediaBuffer : this.media;
|
8424
|
-
this.log(`Buffered ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag)} > buffer:${media ? TimeRanges.toString(BufferHelper.getBuffered(media)) : '(detached)'})`);
|
8468
|
+
this.log(`Buffered ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag, false, part)} > buffer:${media ? TimeRanges.toString(BufferHelper.getBuffered(media)) : '(detached)'})`);
|
8425
8469
|
if (frag.sn !== 'initSegment') {
|
8426
8470
|
var _this$levels;
|
8427
8471
|
if (frag.type !== PlaylistLevelType.SUBTITLE) {
|
@@ -8508,7 +8552,8 @@ class BaseStreamController extends TaskLoop {
|
|
8508
8552
|
const partIndex = this.getNextPart(partList, frag, targetBufferTime);
|
8509
8553
|
if (partIndex > -1) {
|
8510
8554
|
const part = partList[partIndex];
|
8511
|
-
|
8555
|
+
frag = this.fragCurrent = part.fragment;
|
8556
|
+
this.log(`Loading ${frag.type} sn: ${frag.sn} part: ${part.index} (${partIndex}/${partList.length - 1}) of ${this.fragInfo(frag, false, part)}) cc: ${frag.cc} [${details.startSN}-${details.endSN}], target: ${parseFloat(targetBufferTime.toFixed(3))}`);
|
8512
8557
|
this.nextLoadPosition = part.start + part.duration;
|
8513
8558
|
this.state = State.FRAG_LOADING;
|
8514
8559
|
let _result;
|
@@ -9305,7 +9350,7 @@ class BaseStreamController extends TaskLoop {
|
|
9305
9350
|
// For this error fallthrough. Marking parsed will allow advancing to next fragment.
|
9306
9351
|
}
|
9307
9352
|
this.state = State.PARSED;
|
9308
|
-
this.log(`Parsed ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag)})`);
|
9353
|
+
this.log(`Parsed ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag, false, part)})`);
|
9309
9354
|
this.hls.trigger(Events.FRAG_PARSED, {
|
9310
9355
|
frag,
|
9311
9356
|
part
|
@@ -9314,9 +9359,9 @@ class BaseStreamController extends TaskLoop {
|
|
9314
9359
|
playlistLabel() {
|
9315
9360
|
return this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track';
|
9316
9361
|
}
|
9317
|
-
fragInfo(frag, pts = true) {
|
9362
|
+
fragInfo(frag, pts = true, part) {
|
9318
9363
|
var _ref, _ref2;
|
9319
|
-
return `${this.playlistLabel()} ${frag.level} (frag:[${((_ref = pts ? frag.startPTS : frag.start) != null ? _ref : NaN).toFixed(3)}-${((_ref2 = pts ? frag.endPTS : frag.end) != null ? _ref2 : NaN).toFixed(3)}]`;
|
9364
|
+
return `${this.playlistLabel()} ${frag.level} (${part ? 'part' : 'frag'}:[${((_ref = pts && !part ? frag.startPTS : (part || frag).start) != null ? _ref : NaN).toFixed(3)}-${((_ref2 = pts && !part ? frag.endPTS : (part || frag).end) != null ? _ref2 : NaN).toFixed(3)}]${part && frag.type === 'main' ? 'INDEPENDENT=' + (part.independent ? 'YES' : 'NO') : ''}`;
|
9320
9365
|
}
|
9321
9366
|
resetTransmuxer() {
|
9322
9367
|
var _this$transmuxer2;
|
@@ -9729,7 +9774,7 @@ var eventemitter3 = {exports: {}};
|
|
9729
9774
|
var eventemitter3Exports = eventemitter3.exports;
|
9730
9775
|
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
|
9731
9776
|
|
9732
|
-
const version = "1.6.0-beta.1.0.canary.
|
9777
|
+
const version = "1.6.0-beta.1.0.canary.10752";
|
9733
9778
|
|
9734
9779
|
// ensure the worker ends up in the bundle
|
9735
9780
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -15468,7 +15513,7 @@ class Transmuxer {
|
|
15468
15513
|
accurateTimeOffset,
|
15469
15514
|
timeOffset
|
15470
15515
|
} = this.currentTransmuxState;
|
15471
|
-
this.logger.log(`[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${chunkMeta.part > -1 ? '
|
15516
|
+
this.logger.log(`[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${chunkMeta.part > -1 ? ' part: ' + chunkMeta.part : ''} of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`);
|
15472
15517
|
const remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
|
15473
15518
|
transmuxResults.push({
|
15474
15519
|
remuxResult,
|
@@ -15853,7 +15898,7 @@ class TransmuxerInterface {
|
|
15853
15898
|
const initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) == null ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) == null ? void 0 : _lastFrag$initSegment.url));
|
15854
15899
|
const state = new TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
|
15855
15900
|
if (!contiguous || discontinuity || initSegmentChange) {
|
15856
|
-
this.hls.logger.log(`[transmuxer-interface
|
15901
|
+
this.hls.logger.log(`[transmuxer-interface]: Starting new transmux session for ${frag.type} sn: ${chunkMeta.sn}${chunkMeta.part > -1 ? ' part: ' + chunkMeta.part : ''} ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'}: ${chunkMeta.level} id: ${chunkMeta.id}
|
15857
15902
|
discontinuity: ${discontinuity}
|
15858
15903
|
trackSwitch: ${trackSwitch}
|
15859
15904
|
contiguous: ${contiguous}
|
@@ -31849,13 +31894,14 @@ class StreamController extends BaseStreamController {
|
|
31849
31894
|
}
|
31850
31895
|
return audioCodec;
|
31851
31896
|
}
|
31852
|
-
_loadBitrateTestFrag(
|
31853
|
-
|
31854
|
-
this._doFragLoad(
|
31897
|
+
_loadBitrateTestFrag(fragment, level) {
|
31898
|
+
fragment.bitrateTest = true;
|
31899
|
+
this._doFragLoad(fragment, level).then(data => {
|
31855
31900
|
const {
|
31856
31901
|
hls
|
31857
31902
|
} = this;
|
31858
|
-
|
31903
|
+
const frag = data == null ? void 0 : data.frag;
|
31904
|
+
if (!frag || this.fragContextChanged(frag)) {
|
31859
31905
|
return;
|
31860
31906
|
}
|
31861
31907
|
level.fragmentError = 0;
|