hls.js 1.5.10-0.canary.10321 → 1.5.10-0.canary.10326
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 +56 -41
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +58 -42
- 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 +55 -40
- 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 +53 -39
- 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/base-stream-controller.ts +4 -3
- package/src/controller/fragment-finders.ts +34 -3
- package/src/controller/stream-controller.ts +7 -1
- package/src/demux/transmuxer-interface.ts +26 -16
- package/src/demux/transmuxer-worker.ts +1 -1
- package/src/demux/tsdemuxer.ts +31 -21
package/dist/hls.light.mjs
CHANGED
@@ -501,7 +501,7 @@ function enableLogs(debugConfig, context, id) {
|
|
501
501
|
// Some browsers don't allow to use bind on console object anyway
|
502
502
|
// fallback to default if needed
|
503
503
|
try {
|
504
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.10-0.canary.
|
504
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.10-0.canary.10326"}`);
|
505
505
|
} catch (e) {
|
506
506
|
/* log fn threw an exception. All logger methods are no-ops. */
|
507
507
|
return createLogger();
|
@@ -5262,7 +5262,7 @@ function findFragmentByPDT(fragments, PDTValue, maxFragLookUpTolerance) {
|
|
5262
5262
|
* @param maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous
|
5263
5263
|
* @returns a matching fragment or null
|
5264
5264
|
*/
|
5265
|
-
function findFragmentByPTS(fragPrevious, fragments, bufferEnd = 0, maxFragLookUpTolerance = 0) {
|
5265
|
+
function findFragmentByPTS(fragPrevious, fragments, bufferEnd = 0, maxFragLookUpTolerance = 0, nextFragLookupTolerance = 0.005) {
|
5266
5266
|
let fragNext = null;
|
5267
5267
|
if (fragPrevious) {
|
5268
5268
|
fragNext = fragments[fragPrevious.sn - fragments[0].sn + 1] || null;
|
@@ -5275,7 +5275,7 @@ function findFragmentByPTS(fragPrevious, fragments, bufferEnd = 0, maxFragLookUp
|
|
5275
5275
|
fragNext = fragments[0];
|
5276
5276
|
}
|
5277
5277
|
// Prefer the next fragment if it's within tolerance
|
5278
|
-
if (fragNext && (!fragPrevious || fragPrevious.level === fragNext.level) && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0) {
|
5278
|
+
if (fragNext && ((!fragPrevious || fragPrevious.level === fragNext.level) && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0 || fragmentWithinFastStartSwitch(fragNext, fragPrevious, Math.min(nextFragLookupTolerance, maxFragLookUpTolerance)))) {
|
5279
5279
|
return fragNext;
|
5280
5280
|
}
|
5281
5281
|
// We might be seeking past the tolerance so find the best match
|
@@ -5286,6 +5286,18 @@ function findFragmentByPTS(fragPrevious, fragments, bufferEnd = 0, maxFragLookUp
|
|
5286
5286
|
// If no match was found return the next fragment after fragPrevious, or null
|
5287
5287
|
return fragNext;
|
5288
5288
|
}
|
5289
|
+
function fragmentWithinFastStartSwitch(fragNext, fragPrevious, nextFragLookupTolerance) {
|
5290
|
+
if (fragPrevious && fragPrevious.start === 0 && fragPrevious.level < fragNext.level && (fragPrevious.endPTS || 0) > 0) {
|
5291
|
+
const firstDuration = fragPrevious.tagList.reduce((duration, tag) => {
|
5292
|
+
if (tag[0] === 'INF') {
|
5293
|
+
duration += parseFloat(tag[1]);
|
5294
|
+
}
|
5295
|
+
return duration;
|
5296
|
+
}, nextFragLookupTolerance);
|
5297
|
+
return fragNext.start <= firstDuration;
|
5298
|
+
}
|
5299
|
+
return false;
|
5300
|
+
}
|
5289
5301
|
|
5290
5302
|
/**
|
5291
5303
|
* The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions.
|
@@ -12473,7 +12485,7 @@ class BaseStreamController extends TaskLoop {
|
|
12473
12485
|
if (this.state === State.STOPPED || this.state === State.ERROR) {
|
12474
12486
|
return;
|
12475
12487
|
}
|
12476
|
-
this.warn(reason);
|
12488
|
+
this.warn(`Frag error: ${(reason == null ? void 0 : reason.message) || reason}`);
|
12477
12489
|
this.resetFragmentLoading(frag);
|
12478
12490
|
});
|
12479
12491
|
}
|
@@ -13170,7 +13182,9 @@ class BaseStreamController extends TaskLoop {
|
|
13170
13182
|
const {
|
13171
13183
|
fragmentHint
|
13172
13184
|
} = levelDetails;
|
13173
|
-
const
|
13185
|
+
const {
|
13186
|
+
maxFragLookUpTolerance
|
13187
|
+
} = config;
|
13174
13188
|
const partList = levelDetails.partList;
|
13175
13189
|
const loadingParts = !!(this.loadingParts && partList != null && partList.length && fragmentHint);
|
13176
13190
|
if (loadingParts && fragmentHint && !this.bitrateTest) {
|
@@ -13180,7 +13194,7 @@ class BaseStreamController extends TaskLoop {
|
|
13180
13194
|
}
|
13181
13195
|
let frag;
|
13182
13196
|
if (bufferEnd < end) {
|
13183
|
-
const lookupTolerance = bufferEnd > end -
|
13197
|
+
const lookupTolerance = bufferEnd > end - maxFragLookUpTolerance ? 0 : maxFragLookUpTolerance;
|
13184
13198
|
// Remove the tolerance if it would put the bufferEnd past the actual end of stream
|
13185
13199
|
// Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
|
13186
13200
|
frag = findFragmentByPTS(fragPrevious, fragments, bufferEnd, lookupTolerance);
|
@@ -15449,7 +15463,7 @@ class TSDemuxer {
|
|
15449
15463
|
if (stt) {
|
15450
15464
|
offset += data[offset] + 1;
|
15451
15465
|
}
|
15452
|
-
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes);
|
15466
|
+
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer);
|
15453
15467
|
|
15454
15468
|
// only update track id if track PID found while parsing PMT
|
15455
15469
|
// this is to avoid resetting the PID to -1 in case
|
@@ -15492,14 +15506,7 @@ class TSDemuxer {
|
|
15492
15506
|
}
|
15493
15507
|
}
|
15494
15508
|
if (tsPacketErrors > 0) {
|
15495
|
-
|
15496
|
-
this.observer.emit(Events.ERROR, Events.ERROR, {
|
15497
|
-
type: ErrorTypes.MEDIA_ERROR,
|
15498
|
-
details: ErrorDetails.FRAG_PARSING_ERROR,
|
15499
|
-
fatal: false,
|
15500
|
-
error,
|
15501
|
-
reason: error.message
|
15502
|
-
});
|
15509
|
+
emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`));
|
15503
15510
|
}
|
15504
15511
|
videoTrack.pesData = videoData;
|
15505
15512
|
audioTrack.pesData = audioData;
|
@@ -15657,16 +15664,7 @@ class TSDemuxer {
|
|
15657
15664
|
} else {
|
15658
15665
|
reason = 'No ADTS header found in AAC PES';
|
15659
15666
|
}
|
15660
|
-
|
15661
|
-
logger.warn(`parsing error: ${reason}`);
|
15662
|
-
this.observer.emit(Events.ERROR, Events.ERROR, {
|
15663
|
-
type: ErrorTypes.MEDIA_ERROR,
|
15664
|
-
details: ErrorDetails.FRAG_PARSING_ERROR,
|
15665
|
-
fatal: false,
|
15666
|
-
levelRetry: recoverable,
|
15667
|
-
error,
|
15668
|
-
reason
|
15669
|
-
});
|
15667
|
+
emitParsingError(this.observer, new Error(reason), recoverable);
|
15670
15668
|
if (!recoverable) {
|
15671
15669
|
return;
|
15672
15670
|
}
|
@@ -15752,7 +15750,7 @@ function parsePAT(data, offset) {
|
|
15752
15750
|
// skip the PSI header and parse the first PMT entry
|
15753
15751
|
return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
|
15754
15752
|
}
|
15755
|
-
function parsePMT(data, offset, typeSupported, isSampleAes) {
|
15753
|
+
function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
15756
15754
|
const result = {
|
15757
15755
|
audioPid: -1,
|
15758
15756
|
videoPid: -1,
|
@@ -15860,11 +15858,13 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
15860
15858
|
case 0xc2: // SAMPLE-AES EC3
|
15861
15859
|
/* falls through */
|
15862
15860
|
case 0x87:
|
15863
|
-
|
15861
|
+
emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
|
15862
|
+
return result;
|
15864
15863
|
case 0x24:
|
15865
15864
|
// ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
|
15866
15865
|
{
|
15867
|
-
|
15866
|
+
emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));
|
15867
|
+
return result;
|
15868
15868
|
}
|
15869
15869
|
}
|
15870
15870
|
// move to the next table entry
|
@@ -15873,6 +15873,17 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
15873
15873
|
}
|
15874
15874
|
return result;
|
15875
15875
|
}
|
15876
|
+
function emitParsingError(observer, error, levelRetry) {
|
15877
|
+
logger.warn(`parsing error: ${error.message}`);
|
15878
|
+
observer.emit(Events.ERROR, Events.ERROR, {
|
15879
|
+
type: ErrorTypes.MEDIA_ERROR,
|
15880
|
+
details: ErrorDetails.FRAG_PARSING_ERROR,
|
15881
|
+
fatal: false,
|
15882
|
+
levelRetry,
|
15883
|
+
error,
|
15884
|
+
reason: error.message
|
15885
|
+
});
|
15886
|
+
}
|
15876
15887
|
function logEncryptedSamplesFoundInUnencryptedStream(type) {
|
15877
15888
|
logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
|
15878
15889
|
}
|
@@ -18610,10 +18621,6 @@ class TransmuxerInterface {
|
|
18610
18621
|
this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
|
18611
18622
|
this.observer.on(Events.ERROR, forwardMessage);
|
18612
18623
|
const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
|
18613
|
-
|
18614
|
-
// navigator.vendor is not always available in Web Worker
|
18615
|
-
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
18616
|
-
const vendor = navigator.vendor;
|
18617
18624
|
if (this.useWorker && typeof Worker !== 'undefined') {
|
18618
18625
|
const canCreateWorker = config.workerPath || hasUMDWorker();
|
18619
18626
|
if (canCreateWorker) {
|
@@ -18625,7 +18632,7 @@ class TransmuxerInterface {
|
|
18625
18632
|
logger.log(`injecting Web Worker for "${id}"`);
|
18626
18633
|
this.workerContext = injectWorker();
|
18627
18634
|
}
|
18628
|
-
this.onwmsg =
|
18635
|
+
this.onwmsg = event => this.onWorkerMessage(event);
|
18629
18636
|
const {
|
18630
18637
|
worker
|
18631
18638
|
} = this.workerContext;
|
@@ -18645,7 +18652,7 @@ class TransmuxerInterface {
|
|
18645
18652
|
worker.postMessage({
|
18646
18653
|
cmd: 'init',
|
18647
18654
|
typeSupported: m2tsTypeSupported,
|
18648
|
-
vendor:
|
18655
|
+
vendor: '',
|
18649
18656
|
id: id,
|
18650
18657
|
config: JSON.stringify(config)
|
18651
18658
|
});
|
@@ -18653,12 +18660,12 @@ class TransmuxerInterface {
|
|
18653
18660
|
logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
|
18654
18661
|
this.resetWorker();
|
18655
18662
|
this.error = null;
|
18656
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config,
|
18663
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
18657
18664
|
}
|
18658
18665
|
return;
|
18659
18666
|
}
|
18660
18667
|
}
|
18661
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config,
|
18668
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
18662
18669
|
}
|
18663
18670
|
resetWorker() {
|
18664
18671
|
if (this.workerContext) {
|
@@ -18810,9 +18817,16 @@ class TransmuxerInterface {
|
|
18810
18817
|
});
|
18811
18818
|
this.onFlush(chunkMeta);
|
18812
18819
|
}
|
18813
|
-
onWorkerMessage(
|
18814
|
-
const data =
|
18820
|
+
onWorkerMessage(event) {
|
18821
|
+
const data = event.data;
|
18822
|
+
if (!(data != null && data.event)) {
|
18823
|
+
logger.warn(`worker message received with no ${data ? 'event name' : 'data'}`);
|
18824
|
+
return;
|
18825
|
+
}
|
18815
18826
|
const hls = this.hls;
|
18827
|
+
if (!this.hls) {
|
18828
|
+
return;
|
18829
|
+
}
|
18816
18830
|
switch (data.event) {
|
18817
18831
|
case 'init':
|
18818
18832
|
{
|
@@ -20208,7 +20222,8 @@ class StreamController extends BaseStreamController {
|
|
20208
20222
|
// In the case that AAC and HE-AAC audio codecs are signalled in manifest,
|
20209
20223
|
// force HE-AAC, as it seems that most browsers prefers it.
|
20210
20224
|
// don't force HE-AAC if mono stream, or in Firefox
|
20211
|
-
|
20225
|
+
const audioMetadata = audio.metadata;
|
20226
|
+
if (audioMetadata && 'channelCount' in audioMetadata && (audioMetadata.channelCount || 1) !== 1 && ua.indexOf('firefox') === -1) {
|
20212
20227
|
audioCodec = 'mp4a.40.5';
|
20213
20228
|
}
|
20214
20229
|
}
|
@@ -20371,7 +20386,7 @@ class Hls {
|
|
20371
20386
|
* Get the video-dev/hls.js package version.
|
20372
20387
|
*/
|
20373
20388
|
static get version() {
|
20374
|
-
return "1.5.10-0.canary.
|
20389
|
+
return "1.5.10-0.canary.10326";
|
20375
20390
|
}
|
20376
20391
|
|
20377
20392
|
/**
|