hls.js 1.5.10-0.canary.10320 → 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 +61 -47
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +63 -48
- 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 +60 -46
- 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 +58 -45
- 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/src/utils/xhr-loader.ts +5 -5
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.
|
@@ -9003,8 +9015,6 @@ class XhrLoader {
|
|
9003
9015
|
this.config = null;
|
9004
9016
|
this.context = null;
|
9005
9017
|
this.xhrSetup = null;
|
9006
|
-
// @ts-ignore
|
9007
|
-
this.stats = null;
|
9008
9018
|
}
|
9009
9019
|
abortInternal() {
|
9010
9020
|
const loader = this.loader;
|
@@ -9052,13 +9062,14 @@ class XhrLoader {
|
|
9052
9062
|
const xhrSetup = this.xhrSetup;
|
9053
9063
|
if (xhrSetup) {
|
9054
9064
|
Promise.resolve().then(() => {
|
9055
|
-
if (this.stats.aborted) return;
|
9065
|
+
if (this.loader !== xhr || this.stats.aborted) return;
|
9056
9066
|
return xhrSetup(xhr, context.url);
|
9057
9067
|
}).catch(error => {
|
9068
|
+
if (this.loader !== xhr || this.stats.aborted) return;
|
9058
9069
|
xhr.open('GET', context.url, true);
|
9059
9070
|
return xhrSetup(xhr, context.url);
|
9060
9071
|
}).then(() => {
|
9061
|
-
if (this.stats.aborted) return;
|
9072
|
+
if (this.loader !== xhr || this.stats.aborted) return;
|
9062
9073
|
this.openAndSendXhr(xhr, context, config);
|
9063
9074
|
}).catch(error => {
|
9064
9075
|
// IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS
|
@@ -9178,8 +9189,8 @@ class XhrLoader {
|
|
9178
9189
|
}
|
9179
9190
|
}
|
9180
9191
|
loadtimeout() {
|
9181
|
-
|
9182
|
-
const retryConfig =
|
9192
|
+
if (!this.config) return;
|
9193
|
+
const retryConfig = this.config.loadPolicy.timeoutRetry;
|
9183
9194
|
const retryCount = this.stats.retry;
|
9184
9195
|
if (shouldRetry(retryConfig, retryCount, true)) {
|
9185
9196
|
this.retry(retryConfig);
|
@@ -12474,7 +12485,7 @@ class BaseStreamController extends TaskLoop {
|
|
12474
12485
|
if (this.state === State.STOPPED || this.state === State.ERROR) {
|
12475
12486
|
return;
|
12476
12487
|
}
|
12477
|
-
this.warn(reason);
|
12488
|
+
this.warn(`Frag error: ${(reason == null ? void 0 : reason.message) || reason}`);
|
12478
12489
|
this.resetFragmentLoading(frag);
|
12479
12490
|
});
|
12480
12491
|
}
|
@@ -13171,7 +13182,9 @@ class BaseStreamController extends TaskLoop {
|
|
13171
13182
|
const {
|
13172
13183
|
fragmentHint
|
13173
13184
|
} = levelDetails;
|
13174
|
-
const
|
13185
|
+
const {
|
13186
|
+
maxFragLookUpTolerance
|
13187
|
+
} = config;
|
13175
13188
|
const partList = levelDetails.partList;
|
13176
13189
|
const loadingParts = !!(this.loadingParts && partList != null && partList.length && fragmentHint);
|
13177
13190
|
if (loadingParts && fragmentHint && !this.bitrateTest) {
|
@@ -13181,7 +13194,7 @@ class BaseStreamController extends TaskLoop {
|
|
13181
13194
|
}
|
13182
13195
|
let frag;
|
13183
13196
|
if (bufferEnd < end) {
|
13184
|
-
const lookupTolerance = bufferEnd > end -
|
13197
|
+
const lookupTolerance = bufferEnd > end - maxFragLookUpTolerance ? 0 : maxFragLookUpTolerance;
|
13185
13198
|
// Remove the tolerance if it would put the bufferEnd past the actual end of stream
|
13186
13199
|
// Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
|
13187
13200
|
frag = findFragmentByPTS(fragPrevious, fragments, bufferEnd, lookupTolerance);
|
@@ -15450,7 +15463,7 @@ class TSDemuxer {
|
|
15450
15463
|
if (stt) {
|
15451
15464
|
offset += data[offset] + 1;
|
15452
15465
|
}
|
15453
|
-
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes);
|
15466
|
+
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer);
|
15454
15467
|
|
15455
15468
|
// only update track id if track PID found while parsing PMT
|
15456
15469
|
// this is to avoid resetting the PID to -1 in case
|
@@ -15493,14 +15506,7 @@ class TSDemuxer {
|
|
15493
15506
|
}
|
15494
15507
|
}
|
15495
15508
|
if (tsPacketErrors > 0) {
|
15496
|
-
|
15497
|
-
this.observer.emit(Events.ERROR, Events.ERROR, {
|
15498
|
-
type: ErrorTypes.MEDIA_ERROR,
|
15499
|
-
details: ErrorDetails.FRAG_PARSING_ERROR,
|
15500
|
-
fatal: false,
|
15501
|
-
error,
|
15502
|
-
reason: error.message
|
15503
|
-
});
|
15509
|
+
emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`));
|
15504
15510
|
}
|
15505
15511
|
videoTrack.pesData = videoData;
|
15506
15512
|
audioTrack.pesData = audioData;
|
@@ -15658,16 +15664,7 @@ class TSDemuxer {
|
|
15658
15664
|
} else {
|
15659
15665
|
reason = 'No ADTS header found in AAC PES';
|
15660
15666
|
}
|
15661
|
-
|
15662
|
-
logger.warn(`parsing error: ${reason}`);
|
15663
|
-
this.observer.emit(Events.ERROR, Events.ERROR, {
|
15664
|
-
type: ErrorTypes.MEDIA_ERROR,
|
15665
|
-
details: ErrorDetails.FRAG_PARSING_ERROR,
|
15666
|
-
fatal: false,
|
15667
|
-
levelRetry: recoverable,
|
15668
|
-
error,
|
15669
|
-
reason
|
15670
|
-
});
|
15667
|
+
emitParsingError(this.observer, new Error(reason), recoverable);
|
15671
15668
|
if (!recoverable) {
|
15672
15669
|
return;
|
15673
15670
|
}
|
@@ -15753,7 +15750,7 @@ function parsePAT(data, offset) {
|
|
15753
15750
|
// skip the PSI header and parse the first PMT entry
|
15754
15751
|
return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
|
15755
15752
|
}
|
15756
|
-
function parsePMT(data, offset, typeSupported, isSampleAes) {
|
15753
|
+
function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
15757
15754
|
const result = {
|
15758
15755
|
audioPid: -1,
|
15759
15756
|
videoPid: -1,
|
@@ -15861,11 +15858,13 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
15861
15858
|
case 0xc2: // SAMPLE-AES EC3
|
15862
15859
|
/* falls through */
|
15863
15860
|
case 0x87:
|
15864
|
-
|
15861
|
+
emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
|
15862
|
+
return result;
|
15865
15863
|
case 0x24:
|
15866
15864
|
// ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
|
15867
15865
|
{
|
15868
|
-
|
15866
|
+
emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));
|
15867
|
+
return result;
|
15869
15868
|
}
|
15870
15869
|
}
|
15871
15870
|
// move to the next table entry
|
@@ -15874,6 +15873,17 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
15874
15873
|
}
|
15875
15874
|
return result;
|
15876
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
|
+
}
|
15877
15887
|
function logEncryptedSamplesFoundInUnencryptedStream(type) {
|
15878
15888
|
logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
|
15879
15889
|
}
|
@@ -18611,10 +18621,6 @@ class TransmuxerInterface {
|
|
18611
18621
|
this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
|
18612
18622
|
this.observer.on(Events.ERROR, forwardMessage);
|
18613
18623
|
const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
|
18614
|
-
|
18615
|
-
// navigator.vendor is not always available in Web Worker
|
18616
|
-
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
18617
|
-
const vendor = navigator.vendor;
|
18618
18624
|
if (this.useWorker && typeof Worker !== 'undefined') {
|
18619
18625
|
const canCreateWorker = config.workerPath || hasUMDWorker();
|
18620
18626
|
if (canCreateWorker) {
|
@@ -18626,7 +18632,7 @@ class TransmuxerInterface {
|
|
18626
18632
|
logger.log(`injecting Web Worker for "${id}"`);
|
18627
18633
|
this.workerContext = injectWorker();
|
18628
18634
|
}
|
18629
|
-
this.onwmsg =
|
18635
|
+
this.onwmsg = event => this.onWorkerMessage(event);
|
18630
18636
|
const {
|
18631
18637
|
worker
|
18632
18638
|
} = this.workerContext;
|
@@ -18646,7 +18652,7 @@ class TransmuxerInterface {
|
|
18646
18652
|
worker.postMessage({
|
18647
18653
|
cmd: 'init',
|
18648
18654
|
typeSupported: m2tsTypeSupported,
|
18649
|
-
vendor:
|
18655
|
+
vendor: '',
|
18650
18656
|
id: id,
|
18651
18657
|
config: JSON.stringify(config)
|
18652
18658
|
});
|
@@ -18654,12 +18660,12 @@ class TransmuxerInterface {
|
|
18654
18660
|
logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
|
18655
18661
|
this.resetWorker();
|
18656
18662
|
this.error = null;
|
18657
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config,
|
18663
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
18658
18664
|
}
|
18659
18665
|
return;
|
18660
18666
|
}
|
18661
18667
|
}
|
18662
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config,
|
18668
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
18663
18669
|
}
|
18664
18670
|
resetWorker() {
|
18665
18671
|
if (this.workerContext) {
|
@@ -18811,9 +18817,16 @@ class TransmuxerInterface {
|
|
18811
18817
|
});
|
18812
18818
|
this.onFlush(chunkMeta);
|
18813
18819
|
}
|
18814
|
-
onWorkerMessage(
|
18815
|
-
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
|
+
}
|
18816
18826
|
const hls = this.hls;
|
18827
|
+
if (!this.hls) {
|
18828
|
+
return;
|
18829
|
+
}
|
18817
18830
|
switch (data.event) {
|
18818
18831
|
case 'init':
|
18819
18832
|
{
|
@@ -20209,7 +20222,8 @@ class StreamController extends BaseStreamController {
|
|
20209
20222
|
// In the case that AAC and HE-AAC audio codecs are signalled in manifest,
|
20210
20223
|
// force HE-AAC, as it seems that most browsers prefers it.
|
20211
20224
|
// don't force HE-AAC if mono stream, or in Firefox
|
20212
|
-
|
20225
|
+
const audioMetadata = audio.metadata;
|
20226
|
+
if (audioMetadata && 'channelCount' in audioMetadata && (audioMetadata.channelCount || 1) !== 1 && ua.indexOf('firefox') === -1) {
|
20213
20227
|
audioCodec = 'mp4a.40.5';
|
20214
20228
|
}
|
20215
20229
|
}
|
@@ -20372,7 +20386,7 @@ class Hls {
|
|
20372
20386
|
* Get the video-dev/hls.js package version.
|
20373
20387
|
*/
|
20374
20388
|
static get version() {
|
20375
|
-
return "1.5.10-0.canary.
|
20389
|
+
return "1.5.10-0.canary.10326";
|
20376
20390
|
}
|
20377
20391
|
|
20378
20392
|
/**
|