hls.js 1.5.14-0.canary.10429 → 1.5.14-0.canary.10432
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 +351 -268
- package/dist/hls.js.d.ts +6 -2
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +351 -271
- 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 +276 -204
- 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 +276 -201
- 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 +28 -20
- package/src/demux/audio/aacdemuxer.ts +3 -3
- package/src/demux/audio/ac3-demuxer.ts +1 -1
- package/src/demux/inject-worker.ts +38 -4
- package/src/demux/transmuxer-interface.ts +98 -67
- package/src/demux/transmuxer-worker.ts +110 -76
- package/src/demux/transmuxer.ts +29 -16
- package/src/demux/tsdemuxer.ts +47 -24
- package/src/hls.ts +2 -1
- package/src/remux/mp4-remuxer.ts +24 -23
- package/src/remux/passthrough-remuxer.ts +22 -7
- package/src/utils/discontinuities.ts +21 -47
- package/src/version.ts +1 -0
package/dist/hls.light.mjs
CHANGED
@@ -420,7 +420,7 @@ function enableLogs(debugConfig, context, id) {
|
|
420
420
|
// Some browsers don't allow to use bind on console object anyway
|
421
421
|
// fallback to default if needed
|
422
422
|
try {
|
423
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.
|
423
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.10432"}`);
|
424
424
|
} catch (e) {
|
425
425
|
/* log fn threw an exception. All logger methods are no-ops. */
|
426
426
|
return createLogger();
|
@@ -11836,30 +11836,14 @@ function findFirstFragWithCC(fragments, cc) {
|
|
11836
11836
|
}
|
11837
11837
|
return null;
|
11838
11838
|
}
|
11839
|
-
function shouldAlignOnDiscontinuities(
|
11840
|
-
if (
|
11841
|
-
if (details.
|
11839
|
+
function shouldAlignOnDiscontinuities(refDetails, details) {
|
11840
|
+
if (refDetails) {
|
11841
|
+
if (details.startCC < refDetails.endCC && details.endCC > refDetails.startCC) {
|
11842
11842
|
return true;
|
11843
11843
|
}
|
11844
11844
|
}
|
11845
11845
|
return false;
|
11846
11846
|
}
|
11847
|
-
|
11848
|
-
// Find the first frag in the previous level which matches the CC of the first frag of the new level
|
11849
|
-
function findDiscontinuousReferenceFrag(prevDetails, curDetails) {
|
11850
|
-
const prevFrags = prevDetails.fragments;
|
11851
|
-
const curFrags = curDetails.fragments;
|
11852
|
-
if (!curFrags.length || !prevFrags.length) {
|
11853
|
-
logger.log('No fragments to align');
|
11854
|
-
return;
|
11855
|
-
}
|
11856
|
-
const prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc);
|
11857
|
-
if (!prevStartFrag || prevStartFrag && !prevStartFrag.startPTS) {
|
11858
|
-
logger.log('No frag in previous level to align on');
|
11859
|
-
return;
|
11860
|
-
}
|
11861
|
-
return prevStartFrag;
|
11862
|
-
}
|
11863
11847
|
function adjustFragmentStart(frag, sliding) {
|
11864
11848
|
if (frag) {
|
11865
11849
|
const start = frag.start + sliding;
|
@@ -11894,7 +11878,7 @@ function alignStream(lastFrag, switchDetails, details) {
|
|
11894
11878
|
if (!switchDetails) {
|
11895
11879
|
return;
|
11896
11880
|
}
|
11897
|
-
alignDiscontinuities(
|
11881
|
+
alignDiscontinuities(details, switchDetails);
|
11898
11882
|
if (!details.alignedSliding && switchDetails) {
|
11899
11883
|
// If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level.
|
11900
11884
|
// Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same
|
@@ -11910,20 +11894,24 @@ function alignStream(lastFrag, switchDetails, details) {
|
|
11910
11894
|
}
|
11911
11895
|
|
11912
11896
|
/**
|
11913
|
-
*
|
11914
|
-
* discontinuity sequence.
|
11915
|
-
* @param lastFrag - The last Fragment which shares the same discontinuity sequence
|
11897
|
+
* Ajust the start of fragments in `details` by the difference in time between fragments of the latest
|
11898
|
+
* shared discontinuity sequence change.
|
11916
11899
|
* @param lastLevel - The details of the last loaded level
|
11917
11900
|
* @param details - The details of the new level
|
11918
11901
|
*/
|
11919
|
-
function alignDiscontinuities(
|
11920
|
-
if (shouldAlignOnDiscontinuities(
|
11921
|
-
|
11922
|
-
if (referenceFrag && isFiniteNumber(referenceFrag.start)) {
|
11923
|
-
logger.log(`Adjusting PTS using last level due to CC increase within current level ${details.url}`);
|
11924
|
-
adjustSlidingStart(referenceFrag.start, details);
|
11925
|
-
}
|
11902
|
+
function alignDiscontinuities(details, refDetails) {
|
11903
|
+
if (!shouldAlignOnDiscontinuities(refDetails, details)) {
|
11904
|
+
return;
|
11926
11905
|
}
|
11906
|
+
const targetCC = Math.min(refDetails.endCC, details.endCC);
|
11907
|
+
const refFrag = findFirstFragWithCC(refDetails.fragments, targetCC);
|
11908
|
+
const frag = findFirstFragWithCC(details.fragments, targetCC);
|
11909
|
+
if (!refFrag || !frag) {
|
11910
|
+
return;
|
11911
|
+
}
|
11912
|
+
logger.log(`Aligning playlist at start of dicontinuity sequence ${targetCC}`);
|
11913
|
+
const delta = refFrag.start - frag.start;
|
11914
|
+
adjustSlidingStart(delta, details);
|
11927
11915
|
}
|
11928
11916
|
|
11929
11917
|
/**
|
@@ -12696,6 +12684,10 @@ class BaseStreamController extends TaskLoop {
|
|
12696
12684
|
}
|
12697
12685
|
onHandlerDestroying() {
|
12698
12686
|
this.stopLoad();
|
12687
|
+
if (this.transmuxer) {
|
12688
|
+
this.transmuxer.destroy();
|
12689
|
+
this.transmuxer = null;
|
12690
|
+
}
|
12699
12691
|
super.onHandlerDestroying();
|
12700
12692
|
// @ts-ignore
|
12701
12693
|
this.hls = this.onMediaSeeking = this.onMediaEnded = null;
|
@@ -12742,7 +12734,7 @@ class BaseStreamController extends TaskLoop {
|
|
12742
12734
|
return;
|
12743
12735
|
}
|
12744
12736
|
if ('payload' in data) {
|
12745
|
-
this.log(`Loaded
|
12737
|
+
this.log(`Loaded ${frag.type} sn: ${frag.sn} of ${this.playlistLabel()} ${frag.level}`);
|
12746
12738
|
this.hls.trigger(Events.FRAG_LOADED, data);
|
12747
12739
|
}
|
12748
12740
|
|
@@ -12892,9 +12884,9 @@ class BaseStreamController extends TaskLoop {
|
|
12892
12884
|
return !frag || !fragCurrent || frag.sn !== fragCurrent.sn || frag.level !== fragCurrent.level;
|
12893
12885
|
}
|
12894
12886
|
fragBufferedComplete(frag, part) {
|
12895
|
-
var
|
12887
|
+
var _this$fragCurrent, _this$fragPrevious;
|
12896
12888
|
const media = this.mediaBuffer ? this.mediaBuffer : this.media;
|
12897
|
-
this.log(`Buffered ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.
|
12889
|
+
this.log(`Buffered ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag)} > buffer:${media ? TimeRanges.toString(BufferHelper.getBuffered(media)) : '(detached)'})`);
|
12898
12890
|
if (frag.sn !== 'initSegment') {
|
12899
12891
|
var _this$levels;
|
12900
12892
|
if (frag.type !== PlaylistLevelType.SUBTITLE) {
|
@@ -12951,7 +12943,7 @@ class BaseStreamController extends TaskLoop {
|
|
12951
12943
|
}
|
12952
12944
|
let keyLoadingPromise = null;
|
12953
12945
|
if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
|
12954
|
-
this.log(`Loading key for ${frag.sn} of [${details.startSN}-${details.endSN}], ${this.
|
12946
|
+
this.log(`Loading key for ${frag.sn} of [${details.startSN}-${details.endSN}], ${this.playlistLabel()} ${frag.level}`);
|
12955
12947
|
this.state = State.KEY_LOADING;
|
12956
12948
|
this.fragCurrent = frag;
|
12957
12949
|
keyLoadingPromise = this.keyLoader.load(frag).then(keyLoadedData => {
|
@@ -12990,7 +12982,7 @@ class BaseStreamController extends TaskLoop {
|
|
12990
12982
|
const partIndex = this.getNextPart(partList, frag, targetBufferTime);
|
12991
12983
|
if (partIndex > -1) {
|
12992
12984
|
const part = partList[partIndex];
|
12993
|
-
this.log(`Loading part sn: ${frag.sn} p: ${part.index} cc: ${frag.cc} of playlist [${details.startSN}-${details.endSN}] parts [0-${partIndex}-${partList.length - 1}] ${this.
|
12985
|
+
this.log(`Loading part sn: ${frag.sn} p: ${part.index} cc: ${frag.cc} of playlist [${details.startSN}-${details.endSN}] parts [0-${partIndex}-${partList.length - 1}] ${this.playlistLabel()}: ${frag.level}, target: ${parseFloat(targetBufferTime.toFixed(3))}`);
|
12994
12986
|
this.nextLoadPosition = part.start + part.duration;
|
12995
12987
|
this.state = State.FRAG_LOADING;
|
12996
12988
|
let _result;
|
@@ -13026,7 +13018,7 @@ class BaseStreamController extends TaskLoop {
|
|
13026
13018
|
// Selected fragment hint for part but not loading parts
|
13027
13019
|
return Promise.resolve(null);
|
13028
13020
|
}
|
13029
|
-
this.log(`Loading
|
13021
|
+
this.log(`Loading ${frag.type} sn: ${frag.sn} of ${this.fragInfo(frag, false)}) cc: ${frag.cc} ${details ? '[' + details.startSN + '-' + details.endSN + ']' : ''}, target: ${parseFloat(targetBufferTime.toFixed(3))}`);
|
13030
13022
|
// Don't update nextLoadPosition for fragments which are not buffered
|
13031
13023
|
if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
|
13032
13024
|
this.nextLoadPosition = frag.start + frag.duration;
|
@@ -13805,16 +13797,22 @@ class BaseStreamController extends TaskLoop {
|
|
13805
13797
|
// For this error fallthrough. Marking parsed will allow advancing to next fragment.
|
13806
13798
|
}
|
13807
13799
|
this.state = State.PARSED;
|
13800
|
+
this.log(`Parsed ${frag.type} sn: ${frag.sn}${part ? ' part: ' + part.index : ''} of ${this.fragInfo(frag)})`);
|
13808
13801
|
this.hls.trigger(Events.FRAG_PARSED, {
|
13809
13802
|
frag,
|
13810
13803
|
part
|
13811
13804
|
});
|
13812
13805
|
}
|
13806
|
+
playlistLabel() {
|
13807
|
+
return this.playlistType === PlaylistLevelType.MAIN ? 'level' : 'track';
|
13808
|
+
}
|
13809
|
+
fragInfo(frag, pts = true) {
|
13810
|
+
var _ref, _ref2;
|
13811
|
+
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)}]`;
|
13812
|
+
}
|
13813
13813
|
resetTransmuxer() {
|
13814
|
-
|
13815
|
-
|
13816
|
-
this.transmuxer = null;
|
13817
|
-
}
|
13814
|
+
var _this$transmuxer2;
|
13815
|
+
(_this$transmuxer2 = this.transmuxer) == null ? void 0 : _this$transmuxer2.reset();
|
13818
13816
|
}
|
13819
13817
|
recoverWorkerError(data) {
|
13820
13818
|
if (data.event === 'demuxerWorker') {
|
@@ -13863,29 +13861,66 @@ function changeTypeSupported() {
|
|
13863
13861
|
return typeof (sourceBuffer == null ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) == null ? void 0 : _sourceBuffer$prototy.changeType) === 'function';
|
13864
13862
|
}
|
13865
13863
|
|
13864
|
+
const version = "1.5.14-0.canary.10432";
|
13865
|
+
|
13866
13866
|
// ensure the worker ends up in the bundle
|
13867
13867
|
// If the worker should not be included this gets aliased to empty.js
|
13868
|
+
const workerStore = {};
|
13868
13869
|
function hasUMDWorker() {
|
13869
13870
|
return typeof __HLS_WORKER_BUNDLE__ === 'function';
|
13870
13871
|
}
|
13871
13872
|
function injectWorker() {
|
13873
|
+
const workerContext = workerStore[version];
|
13874
|
+
if (workerContext) {
|
13875
|
+
workerContext.clientCount++;
|
13876
|
+
return workerContext;
|
13877
|
+
}
|
13872
13878
|
const blob = new self.Blob([`var exports={};var module={exports:exports};function define(f){f()};define.amd=true;(${__HLS_WORKER_BUNDLE__.toString()})(true);`], {
|
13873
13879
|
type: 'text/javascript'
|
13874
13880
|
});
|
13875
13881
|
const objectURL = self.URL.createObjectURL(blob);
|
13876
13882
|
const worker = new self.Worker(objectURL);
|
13877
|
-
|
13883
|
+
const result = {
|
13878
13884
|
worker,
|
13879
|
-
objectURL
|
13885
|
+
objectURL,
|
13886
|
+
clientCount: 1
|
13880
13887
|
};
|
13888
|
+
workerStore[version] = result;
|
13889
|
+
return result;
|
13881
13890
|
}
|
13882
13891
|
function loadWorker(path) {
|
13892
|
+
const workerContext = workerStore[path];
|
13893
|
+
if (workerContext) {
|
13894
|
+
workerContext.clientCount++;
|
13895
|
+
return workerContext;
|
13896
|
+
}
|
13883
13897
|
const scriptURL = new self.URL(path, self.location.href).href;
|
13884
13898
|
const worker = new self.Worker(scriptURL);
|
13885
|
-
|
13899
|
+
const result = {
|
13886
13900
|
worker,
|
13887
|
-
scriptURL
|
13901
|
+
scriptURL,
|
13902
|
+
clientCount: 1
|
13888
13903
|
};
|
13904
|
+
workerStore[path] = result;
|
13905
|
+
return result;
|
13906
|
+
}
|
13907
|
+
function removeWorkerFromStore(path) {
|
13908
|
+
const workerContext = workerStore[path || version];
|
13909
|
+
if (workerContext) {
|
13910
|
+
const clientCount = workerContext.clientCount--;
|
13911
|
+
if (clientCount === 1) {
|
13912
|
+
const {
|
13913
|
+
worker,
|
13914
|
+
objectURL
|
13915
|
+
} = workerContext;
|
13916
|
+
delete workerStore[path || version];
|
13917
|
+
if (objectURL) {
|
13918
|
+
// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
13919
|
+
self.URL.revokeObjectURL(objectURL);
|
13920
|
+
}
|
13921
|
+
worker.terminate();
|
13922
|
+
}
|
13923
|
+
}
|
13889
13924
|
}
|
13890
13925
|
|
13891
13926
|
function dummyTrack(type = '', inputTimeScale = 90000) {
|
@@ -14562,7 +14597,7 @@ class AACDemuxer extends BaseAudioDemuxer {
|
|
14562
14597
|
}
|
14563
14598
|
|
14564
14599
|
// Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
|
14565
|
-
static probe(data) {
|
14600
|
+
static probe(data, logger) {
|
14566
14601
|
if (!data) {
|
14567
14602
|
return false;
|
14568
14603
|
}
|
@@ -15482,7 +15517,8 @@ class SampleAesDecrypter {
|
|
15482
15517
|
|
15483
15518
|
const PACKET_LENGTH = 188;
|
15484
15519
|
class TSDemuxer {
|
15485
|
-
constructor(observer, config, typeSupported) {
|
15520
|
+
constructor(observer, config, typeSupported, logger) {
|
15521
|
+
this.logger = void 0;
|
15486
15522
|
this.observer = void 0;
|
15487
15523
|
this.config = void 0;
|
15488
15524
|
this.typeSupported = void 0;
|
@@ -15502,9 +15538,10 @@ class TSDemuxer {
|
|
15502
15538
|
this.observer = observer;
|
15503
15539
|
this.config = config;
|
15504
15540
|
this.typeSupported = typeSupported;
|
15541
|
+
this.logger = logger;
|
15505
15542
|
this.videoParser = null;
|
15506
15543
|
}
|
15507
|
-
static probe(data) {
|
15544
|
+
static probe(data, logger) {
|
15508
15545
|
const syncOffset = TSDemuxer.syncOffset(data);
|
15509
15546
|
if (syncOffset > 0) {
|
15510
15547
|
logger.warn(`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`);
|
@@ -15666,7 +15703,7 @@ class TSDemuxer {
|
|
15666
15703
|
switch (pid) {
|
15667
15704
|
case videoPid:
|
15668
15705
|
if (stt) {
|
15669
|
-
if (videoData && (pes = parsePES(videoData))) {
|
15706
|
+
if (videoData && (pes = parsePES(videoData, this.logger))) {
|
15670
15707
|
if (this.videoParser === null) {
|
15671
15708
|
switch (videoTrack.segmentCodec) {
|
15672
15709
|
case 'avc':
|
@@ -15690,7 +15727,7 @@ class TSDemuxer {
|
|
15690
15727
|
break;
|
15691
15728
|
case audioPid:
|
15692
15729
|
if (stt) {
|
15693
|
-
if (audioData && (pes = parsePES(audioData))) {
|
15730
|
+
if (audioData && (pes = parsePES(audioData, this.logger))) {
|
15694
15731
|
switch (audioTrack.segmentCodec) {
|
15695
15732
|
case 'aac':
|
15696
15733
|
this.parseAACPES(audioTrack, pes);
|
@@ -15712,7 +15749,7 @@ class TSDemuxer {
|
|
15712
15749
|
break;
|
15713
15750
|
case id3Pid:
|
15714
15751
|
if (stt) {
|
15715
|
-
if (id3Data && (pes = parsePES(id3Data))) {
|
15752
|
+
if (id3Data && (pes = parsePES(id3Data, this.logger))) {
|
15716
15753
|
this.parseID3PES(id3Track, pes);
|
15717
15754
|
}
|
15718
15755
|
id3Data = {
|
@@ -15730,14 +15767,14 @@ class TSDemuxer {
|
|
15730
15767
|
offset += data[offset] + 1;
|
15731
15768
|
}
|
15732
15769
|
pmtId = this._pmtId = parsePAT(data, offset);
|
15733
|
-
// logger.log('PMT PID:' + this._pmtId);
|
15770
|
+
// this.logger.log('PMT PID:' + this._pmtId);
|
15734
15771
|
break;
|
15735
15772
|
case pmtId:
|
15736
15773
|
{
|
15737
15774
|
if (stt) {
|
15738
15775
|
offset += data[offset] + 1;
|
15739
15776
|
}
|
15740
|
-
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer);
|
15777
|
+
const parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes, this.observer, this.logger);
|
15741
15778
|
|
15742
15779
|
// only update track id if track PID found while parsing PMT
|
15743
15780
|
// this is to avoid resetting the PID to -1 in case
|
@@ -15760,7 +15797,7 @@ class TSDemuxer {
|
|
15760
15797
|
id3Track.pid = id3Pid;
|
15761
15798
|
}
|
15762
15799
|
if (unknownPID !== null && !pmtParsed) {
|
15763
|
-
logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
|
15800
|
+
this.logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
|
15764
15801
|
unknownPID = null;
|
15765
15802
|
// we set it to -188, the += 188 in the for loop will reset start to 0
|
15766
15803
|
start = syncOffset - 188;
|
@@ -15780,7 +15817,7 @@ class TSDemuxer {
|
|
15780
15817
|
}
|
15781
15818
|
}
|
15782
15819
|
if (tsPacketErrors > 0) {
|
15783
|
-
emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`));
|
15820
|
+
emitParsingError(this.observer, new Error(`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`), undefined, this.logger);
|
15784
15821
|
}
|
15785
15822
|
videoTrack.pesData = videoData;
|
15786
15823
|
audioTrack.pesData = audioData;
|
@@ -15830,7 +15867,7 @@ class TSDemuxer {
|
|
15830
15867
|
const id3Data = id3Track.pesData;
|
15831
15868
|
// try to parse last PES packets
|
15832
15869
|
let pes;
|
15833
|
-
if (videoData && (pes = parsePES(videoData))) {
|
15870
|
+
if (videoData && (pes = parsePES(videoData, this.logger))) {
|
15834
15871
|
if (this.videoParser === null) {
|
15835
15872
|
switch (videoTrack.segmentCodec) {
|
15836
15873
|
case 'avc':
|
@@ -15846,7 +15883,7 @@ class TSDemuxer {
|
|
15846
15883
|
// either avcData null or PES truncated, keep it for next frag parsing
|
15847
15884
|
videoTrack.pesData = videoData;
|
15848
15885
|
}
|
15849
|
-
if (audioData && (pes = parsePES(audioData))) {
|
15886
|
+
if (audioData && (pes = parsePES(audioData, this.logger))) {
|
15850
15887
|
switch (audioTrack.segmentCodec) {
|
15851
15888
|
case 'aac':
|
15852
15889
|
this.parseAACPES(audioTrack, pes);
|
@@ -15858,13 +15895,13 @@ class TSDemuxer {
|
|
15858
15895
|
audioTrack.pesData = null;
|
15859
15896
|
} else {
|
15860
15897
|
if (audioData != null && audioData.size) {
|
15861
|
-
logger.log('last AAC PES packet truncated,might overlap between fragments');
|
15898
|
+
this.logger.log('last AAC PES packet truncated,might overlap between fragments');
|
15862
15899
|
}
|
15863
15900
|
|
15864
15901
|
// either audioData null or PES truncated, keep it for next frag parsing
|
15865
15902
|
audioTrack.pesData = audioData;
|
15866
15903
|
}
|
15867
|
-
if (id3Data && (pes = parsePES(id3Data))) {
|
15904
|
+
if (id3Data && (pes = parsePES(id3Data, this.logger))) {
|
15868
15905
|
this.parseID3PES(id3Track, pes);
|
15869
15906
|
id3Track.pesData = null;
|
15870
15907
|
} else {
|
@@ -15938,7 +15975,7 @@ class TSDemuxer {
|
|
15938
15975
|
} else {
|
15939
15976
|
reason = 'No ADTS header found in AAC PES';
|
15940
15977
|
}
|
15941
|
-
emitParsingError(this.observer, new Error(reason), recoverable);
|
15978
|
+
emitParsingError(this.observer, new Error(reason), recoverable, this.logger);
|
15942
15979
|
if (!recoverable) {
|
15943
15980
|
return;
|
15944
15981
|
}
|
@@ -15953,7 +15990,7 @@ class TSDemuxer {
|
|
15953
15990
|
const frameDuration = getFrameDuration(track.samplerate);
|
15954
15991
|
pts = aacOverFlow.sample.pts + frameDuration;
|
15955
15992
|
} else {
|
15956
|
-
logger.warn('[tsdemuxer]: AAC PES unknown PTS');
|
15993
|
+
this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');
|
15957
15994
|
return;
|
15958
15995
|
}
|
15959
15996
|
|
@@ -15983,7 +16020,7 @@ class TSDemuxer {
|
|
15983
16020
|
let offset = 0;
|
15984
16021
|
const pts = pes.pts;
|
15985
16022
|
if (pts === undefined) {
|
15986
|
-
logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
|
16023
|
+
this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
|
15987
16024
|
return;
|
15988
16025
|
}
|
15989
16026
|
while (offset < length) {
|
@@ -16006,7 +16043,7 @@ class TSDemuxer {
|
|
16006
16043
|
}
|
16007
16044
|
parseID3PES(id3Track, pes) {
|
16008
16045
|
if (pes.pts === undefined) {
|
16009
|
-
logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
|
16046
|
+
this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
|
16010
16047
|
return;
|
16011
16048
|
}
|
16012
16049
|
const id3Sample = _extends({}, pes, {
|
@@ -16024,7 +16061,7 @@ function parsePAT(data, offset) {
|
|
16024
16061
|
// skip the PSI header and parse the first PMT entry
|
16025
16062
|
return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
|
16026
16063
|
}
|
16027
|
-
function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
16064
|
+
function parsePMT(data, offset, typeSupported, isSampleAes, observer, logger) {
|
16028
16065
|
const result = {
|
16029
16066
|
audioPid: -1,
|
16030
16067
|
videoPid: -1,
|
@@ -16046,7 +16083,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
16046
16083
|
case 0xcf:
|
16047
16084
|
// SAMPLE-AES AAC
|
16048
16085
|
if (!isSampleAes) {
|
16049
|
-
logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC');
|
16086
|
+
logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', this.logger);
|
16050
16087
|
break;
|
16051
16088
|
}
|
16052
16089
|
/* falls through */
|
@@ -16068,7 +16105,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
16068
16105
|
case 0xdb:
|
16069
16106
|
// SAMPLE-AES AVC
|
16070
16107
|
if (!isSampleAes) {
|
16071
|
-
logEncryptedSamplesFoundInUnencryptedStream('H.264');
|
16108
|
+
logEncryptedSamplesFoundInUnencryptedStream('H.264', this.logger);
|
16072
16109
|
break;
|
16073
16110
|
}
|
16074
16111
|
/* falls through */
|
@@ -16096,7 +16133,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
16096
16133
|
case 0xc1:
|
16097
16134
|
// SAMPLE-AES AC3
|
16098
16135
|
if (!isSampleAes) {
|
16099
|
-
logEncryptedSamplesFoundInUnencryptedStream('AC-3');
|
16136
|
+
logEncryptedSamplesFoundInUnencryptedStream('AC-3', this.logger);
|
16100
16137
|
break;
|
16101
16138
|
}
|
16102
16139
|
/* falls through */
|
@@ -16132,12 +16169,12 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
16132
16169
|
case 0xc2: // SAMPLE-AES EC3
|
16133
16170
|
/* falls through */
|
16134
16171
|
case 0x87:
|
16135
|
-
emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
|
16172
|
+
emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'), undefined, this.logger);
|
16136
16173
|
return result;
|
16137
16174
|
case 0x24:
|
16138
16175
|
// ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
|
16139
16176
|
{
|
16140
|
-
emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));
|
16177
|
+
emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'), undefined, this.logger);
|
16141
16178
|
return result;
|
16142
16179
|
}
|
16143
16180
|
}
|
@@ -16147,7 +16184,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
16147
16184
|
}
|
16148
16185
|
return result;
|
16149
16186
|
}
|
16150
|
-
function emitParsingError(observer, error, levelRetry) {
|
16187
|
+
function emitParsingError(observer, error, levelRetry, logger) {
|
16151
16188
|
logger.warn(`parsing error: ${error.message}`);
|
16152
16189
|
observer.emit(Events.ERROR, Events.ERROR, {
|
16153
16190
|
type: ErrorTypes.MEDIA_ERROR,
|
@@ -16158,10 +16195,10 @@ function emitParsingError(observer, error, levelRetry) {
|
|
16158
16195
|
reason: error.message
|
16159
16196
|
});
|
16160
16197
|
}
|
16161
|
-
function logEncryptedSamplesFoundInUnencryptedStream(type) {
|
16198
|
+
function logEncryptedSamplesFoundInUnencryptedStream(type, logger) {
|
16162
16199
|
logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
|
16163
16200
|
}
|
16164
|
-
function parsePES(stream) {
|
16201
|
+
function parsePES(stream, logger) {
|
16165
16202
|
let i = 0;
|
16166
16203
|
let frag;
|
16167
16204
|
let pesLen;
|
@@ -17046,7 +17083,8 @@ const AC3_SAMPLES_PER_FRAME = 1536;
|
|
17046
17083
|
let chromeVersion = null;
|
17047
17084
|
let safariWebkitVersion = null;
|
17048
17085
|
class MP4Remuxer {
|
17049
|
-
constructor(observer, config, typeSupported,
|
17086
|
+
constructor(observer, config, typeSupported, logger) {
|
17087
|
+
this.logger = void 0;
|
17050
17088
|
this.observer = void 0;
|
17051
17089
|
this.config = void 0;
|
17052
17090
|
this.typeSupported = void 0;
|
@@ -17062,6 +17100,7 @@ class MP4Remuxer {
|
|
17062
17100
|
this.observer = observer;
|
17063
17101
|
this.config = config;
|
17064
17102
|
this.typeSupported = typeSupported;
|
17103
|
+
this.logger = logger;
|
17065
17104
|
this.ISGenerated = false;
|
17066
17105
|
if (chromeVersion === null) {
|
17067
17106
|
const userAgent = navigator.userAgent || '';
|
@@ -17078,16 +17117,16 @@ class MP4Remuxer {
|
|
17078
17117
|
this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;
|
17079
17118
|
}
|
17080
17119
|
resetTimeStamp(defaultTimeStamp) {
|
17081
|
-
logger.log('[mp4-remuxer]: initPTS & initDTS reset');
|
17120
|
+
this.logger.log('[mp4-remuxer]: initPTS & initDTS reset');
|
17082
17121
|
this._initPTS = this._initDTS = defaultTimeStamp;
|
17083
17122
|
}
|
17084
17123
|
resetNextTimestamp() {
|
17085
|
-
logger.log('[mp4-remuxer]: reset next timestamp');
|
17124
|
+
this.logger.log('[mp4-remuxer]: reset next timestamp');
|
17086
17125
|
this.isVideoContiguous = false;
|
17087
17126
|
this.isAudioContiguous = false;
|
17088
17127
|
}
|
17089
17128
|
resetInitSegment() {
|
17090
|
-
logger.log('[mp4-remuxer]: ISGenerated flag reset');
|
17129
|
+
this.logger.log('[mp4-remuxer]: ISGenerated flag reset');
|
17091
17130
|
this.ISGenerated = false;
|
17092
17131
|
this.videoTrackConfig = undefined;
|
17093
17132
|
}
|
@@ -17106,7 +17145,7 @@ class MP4Remuxer {
|
|
17106
17145
|
}
|
17107
17146
|
}, videoSamples[0].pts);
|
17108
17147
|
if (rolloverDetected) {
|
17109
|
-
logger.debug('PTS rollover detected');
|
17148
|
+
this.logger.debug('PTS rollover detected');
|
17110
17149
|
}
|
17111
17150
|
return startPTS;
|
17112
17151
|
}
|
@@ -17150,14 +17189,14 @@ class MP4Remuxer {
|
|
17150
17189
|
if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {
|
17151
17190
|
independent = true;
|
17152
17191
|
if (firstKeyFrameIndex > 0) {
|
17153
|
-
logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
|
17192
|
+
this.logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
|
17154
17193
|
const startPTS = this.getVideoStartPts(videoTrack.samples);
|
17155
17194
|
videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
|
17156
17195
|
videoTrack.dropped += firstKeyFrameIndex;
|
17157
17196
|
videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / videoTrack.inputTimeScale;
|
17158
17197
|
firstKeyFramePTS = videoTimeOffset;
|
17159
17198
|
} else if (firstKeyFrameIndex === -1) {
|
17160
|
-
logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
|
17199
|
+
this.logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
|
17161
17200
|
independent = false;
|
17162
17201
|
}
|
17163
17202
|
}
|
@@ -17179,7 +17218,7 @@ class MP4Remuxer {
|
|
17179
17218
|
if (enoughAudioSamples) {
|
17180
17219
|
// if initSegment was generated without audio samples, regenerate it again
|
17181
17220
|
if (!audioTrack.samplerate) {
|
17182
|
-
logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
|
17221
|
+
this.logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
|
17183
17222
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
17184
17223
|
}
|
17185
17224
|
audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === PlaylistLevelType.AUDIO ? videoTimeOffset : undefined);
|
@@ -17187,7 +17226,7 @@ class MP4Remuxer {
|
|
17187
17226
|
const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
|
17188
17227
|
// if initSegment was generated without video samples, regenerate it again
|
17189
17228
|
if (!videoTrack.inputTimeScale) {
|
17190
|
-
logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
|
17229
|
+
this.logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
|
17191
17230
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
17192
17231
|
}
|
17193
17232
|
video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength);
|
@@ -17393,9 +17432,9 @@ class MP4Remuxer {
|
|
17393
17432
|
const foundOverlap = delta < -1;
|
17394
17433
|
if (foundHole || foundOverlap) {
|
17395
17434
|
if (foundHole) {
|
17396
|
-
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
|
17435
|
+
this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
|
17397
17436
|
} else {
|
17398
|
-
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
|
17437
|
+
this.logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
|
17399
17438
|
}
|
17400
17439
|
if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
|
17401
17440
|
firstDTS = nextAvcDts;
|
@@ -17424,7 +17463,7 @@ class MP4Remuxer {
|
|
17424
17463
|
}
|
17425
17464
|
}
|
17426
17465
|
}
|
17427
|
-
logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
|
17466
|
+
this.logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
|
17428
17467
|
}
|
17429
17468
|
}
|
17430
17469
|
}
|
@@ -17524,7 +17563,7 @@ class MP4Remuxer {
|
|
17524
17563
|
} else {
|
17525
17564
|
stretchedLastFrame = true;
|
17526
17565
|
}
|
17527
|
-
logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
|
17566
|
+
this.logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
|
17528
17567
|
} else {
|
17529
17568
|
mp4SampleDuration = lastFrameDuration;
|
17530
17569
|
}
|
@@ -17552,7 +17591,7 @@ class MP4Remuxer {
|
|
17552
17591
|
// Fix for "CNN special report, with CC" in test-streams (Safari browser only)
|
17553
17592
|
// Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
|
17554
17593
|
if (maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta && averageSampleDuration / maxDtsDelta < 0.025 && outputSamples[0].cts === 0) {
|
17555
|
-
logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
|
17594
|
+
this.logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
|
17556
17595
|
let dts = firstDTS;
|
17557
17596
|
for (let i = 0, len = outputSamples.length; i < len; i++) {
|
17558
17597
|
const nextDts = dts + outputSamples[i].duration;
|
@@ -17677,7 +17716,7 @@ class MP4Remuxer {
|
|
17677
17716
|
// When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
|
17678
17717
|
if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) {
|
17679
17718
|
if (i === 0) {
|
17680
|
-
logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
|
17719
|
+
this.logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
|
17681
17720
|
this.nextAudioPts = nextAudioPts = nextPts = pts;
|
17682
17721
|
}
|
17683
17722
|
} // eslint-disable-line brace-style
|
@@ -17699,12 +17738,12 @@ class MP4Remuxer {
|
|
17699
17738
|
if (i === 0) {
|
17700
17739
|
this.nextAudioPts = nextAudioPts = nextPts;
|
17701
17740
|
}
|
17702
|
-
logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
|
17741
|
+
this.logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
|
17703
17742
|
for (let j = 0; j < missing; j++) {
|
17704
17743
|
const newStamp = Math.max(nextPts, 0);
|
17705
17744
|
let fillFrame = AAC.getSilentFrame(track.parsedCodec || track.manifestCodec || track.codec, track.channelCount);
|
17706
17745
|
if (!fillFrame) {
|
17707
|
-
logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
17746
|
+
this.logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
17708
17747
|
fillFrame = sample.unit.subarray();
|
17709
17748
|
}
|
17710
17749
|
inputSamples.splice(i, 0, {
|
@@ -17903,7 +17942,8 @@ class Mp4Sample {
|
|
17903
17942
|
}
|
17904
17943
|
|
17905
17944
|
class PassThroughRemuxer {
|
17906
|
-
constructor() {
|
17945
|
+
constructor(observer, config, typeSupported, logger) {
|
17946
|
+
this.logger = void 0;
|
17907
17947
|
this.emitInitSegment = false;
|
17908
17948
|
this.audioCodec = void 0;
|
17909
17949
|
this.videoCodec = void 0;
|
@@ -17911,6 +17951,7 @@ class PassThroughRemuxer {
|
|
17911
17951
|
this.initPTS = null;
|
17912
17952
|
this.initTracks = void 0;
|
17913
17953
|
this.lastEndTime = null;
|
17954
|
+
this.logger = logger;
|
17914
17955
|
}
|
17915
17956
|
destroy() {}
|
17916
17957
|
resetTimeStamp(defaultInitPTS) {
|
@@ -17968,7 +18009,7 @@ class PassThroughRemuxer {
|
|
17968
18009
|
id: 'main'
|
17969
18010
|
};
|
17970
18011
|
} else {
|
17971
|
-
logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
|
18012
|
+
this.logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
|
17972
18013
|
}
|
17973
18014
|
this.initTracks = tracks;
|
17974
18015
|
}
|
@@ -18010,7 +18051,7 @@ class PassThroughRemuxer {
|
|
18010
18051
|
}
|
18011
18052
|
if (!((_initData2 = initData) != null && _initData2.length)) {
|
18012
18053
|
// We can't remux if the initSegment could not be generated
|
18013
|
-
logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
|
18054
|
+
this.logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
|
18014
18055
|
return result;
|
18015
18056
|
}
|
18016
18057
|
if (this.emitInitSegment) {
|
@@ -18023,7 +18064,7 @@ class PassThroughRemuxer {
|
|
18023
18064
|
if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
|
18024
18065
|
initSegment.initPTS = decodeTime - timeOffset;
|
18025
18066
|
if (initPTS && initPTS.timescale === 1) {
|
18026
|
-
logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
|
18067
|
+
this.logger.warn(`Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`);
|
18027
18068
|
}
|
18028
18069
|
this.initPTS = initPTS = {
|
18029
18070
|
baseTime: initSegment.initPTS,
|
@@ -18036,7 +18077,7 @@ class PassThroughRemuxer {
|
|
18036
18077
|
if (duration > 0) {
|
18037
18078
|
this.lastEndTime = endTime;
|
18038
18079
|
} else {
|
18039
|
-
logger.warn('Duration parsed from mp4 should be greater than zero');
|
18080
|
+
this.logger.warn('Duration parsed from mp4 should be greater than zero');
|
18040
18081
|
this.resetNextTimestamp();
|
18041
18082
|
}
|
18042
18083
|
const hasAudio = !!initData.audio;
|
@@ -18094,12 +18135,12 @@ function getParsedTrackCodec(track, type) {
|
|
18094
18135
|
return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);
|
18095
18136
|
}
|
18096
18137
|
const result = 'mp4a.40.5';
|
18097
|
-
logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
|
18138
|
+
this.logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
|
18098
18139
|
return result;
|
18099
18140
|
}
|
18100
18141
|
// Provide defaults based on codec type
|
18101
18142
|
// This allows for some playback of some fmp4 playlists without CODECS defined in manifest
|
18102
|
-
logger.warn(`Unhandled video codec "${parsedCodec}"`);
|
18143
|
+
this.logger.warn(`Unhandled video codec "${parsedCodec}"`);
|
18103
18144
|
if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
|
18104
18145
|
return 'hvc1.1.6.L120.90';
|
18105
18146
|
}
|
@@ -18109,16 +18150,12 @@ function getParsedTrackCodec(track, type) {
|
|
18109
18150
|
return 'avc1.42e01e';
|
18110
18151
|
}
|
18111
18152
|
|
18112
|
-
/** returns `undefined` is `self` is missing, e.g. in node */
|
18113
|
-
const optionalSelf = typeof self !== 'undefined' ? self : undefined;
|
18114
|
-
|
18115
18153
|
let now;
|
18116
18154
|
// performance.now() not available on WebWorker, at least on Safari Desktop
|
18117
18155
|
try {
|
18118
18156
|
now = self.performance.now.bind(self.performance);
|
18119
18157
|
} catch (err) {
|
18120
|
-
|
18121
|
-
now = optionalSelf == null ? void 0 : optionalSelf.Date.now;
|
18158
|
+
now = Date.now;
|
18122
18159
|
}
|
18123
18160
|
const muxConfig = [{
|
18124
18161
|
demux: MP4Demuxer,
|
@@ -18134,8 +18171,9 @@ const muxConfig = [{
|
|
18134
18171
|
remux: MP4Remuxer
|
18135
18172
|
}];
|
18136
18173
|
class Transmuxer {
|
18137
|
-
constructor(observer, typeSupported, config, vendor, id) {
|
18138
|
-
this.
|
18174
|
+
constructor(observer, typeSupported, config, vendor, id, logger) {
|
18175
|
+
this.asyncResult = false;
|
18176
|
+
this.logger = void 0;
|
18139
18177
|
this.observer = void 0;
|
18140
18178
|
this.typeSupported = void 0;
|
18141
18179
|
this.config = void 0;
|
@@ -18153,6 +18191,7 @@ class Transmuxer {
|
|
18153
18191
|
this.config = config;
|
18154
18192
|
this.vendor = vendor;
|
18155
18193
|
this.id = id;
|
18194
|
+
this.logger = logger;
|
18156
18195
|
}
|
18157
18196
|
configure(transmuxConfig) {
|
18158
18197
|
this.transmuxConfig = transmuxConfig;
|
@@ -18207,6 +18246,7 @@ class Transmuxer {
|
|
18207
18246
|
}
|
18208
18247
|
uintData = new Uint8Array(decryptedData);
|
18209
18248
|
} else {
|
18249
|
+
this.asyncResult = true;
|
18210
18250
|
this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer, aesMode).then(decryptedData => {
|
18211
18251
|
// Calling push here is important; if flush() is called while this is still resolving, this ensures that
|
18212
18252
|
// the decrypted data has been transmuxed
|
@@ -18221,7 +18261,7 @@ class Transmuxer {
|
|
18221
18261
|
if (resetMuxers) {
|
18222
18262
|
const error = this.configureTransmuxer(uintData);
|
18223
18263
|
if (error) {
|
18224
|
-
logger.warn(`[transmuxer] ${error.message}`);
|
18264
|
+
this.logger.warn(`[transmuxer] ${error.message}`);
|
18225
18265
|
this.observer.emit(Events.ERROR, Events.ERROR, {
|
18226
18266
|
type: ErrorTypes.MEDIA_ERROR,
|
18227
18267
|
details: ErrorDetails.FRAG_PARSING_ERROR,
|
@@ -18243,6 +18283,7 @@ class Transmuxer {
|
|
18243
18283
|
this.resetContiguity();
|
18244
18284
|
}
|
18245
18285
|
const result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta);
|
18286
|
+
this.asyncResult = isPromise(result);
|
18246
18287
|
const currentState = this.currentTransmuxState;
|
18247
18288
|
currentState.contiguous = true;
|
18248
18289
|
currentState.discontinuity = false;
|
@@ -18261,6 +18302,7 @@ class Transmuxer {
|
|
18261
18302
|
decryptionPromise
|
18262
18303
|
} = this;
|
18263
18304
|
if (decryptionPromise) {
|
18305
|
+
this.asyncResult = true;
|
18264
18306
|
// Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
|
18265
18307
|
// only flushing is required for async decryption
|
18266
18308
|
return decryptionPromise.then(() => {
|
@@ -18288,10 +18330,15 @@ class Transmuxer {
|
|
18288
18330
|
if (!demuxer || !remuxer) {
|
18289
18331
|
// If probing failed, then Hls.js has been given content its not able to handle
|
18290
18332
|
stats.executeEnd = now();
|
18291
|
-
|
18333
|
+
const emptyResults = [emptyResult(chunkMeta)];
|
18334
|
+
if (this.asyncResult) {
|
18335
|
+
return Promise.resolve(emptyResults);
|
18336
|
+
}
|
18337
|
+
return emptyResults;
|
18292
18338
|
}
|
18293
18339
|
const demuxResultOrPromise = demuxer.flush(timeOffset);
|
18294
18340
|
if (isPromise(demuxResultOrPromise)) {
|
18341
|
+
this.asyncResult = true;
|
18295
18342
|
// Decrypt final SAMPLE-AES samples
|
18296
18343
|
return demuxResultOrPromise.then(demuxResult => {
|
18297
18344
|
this.flushRemux(transmuxResults, demuxResult, chunkMeta);
|
@@ -18299,6 +18346,9 @@ class Transmuxer {
|
|
18299
18346
|
});
|
18300
18347
|
}
|
18301
18348
|
this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);
|
18349
|
+
if (this.asyncResult) {
|
18350
|
+
return Promise.resolve(transmuxResults);
|
18351
|
+
}
|
18302
18352
|
return transmuxResults;
|
18303
18353
|
}
|
18304
18354
|
flushRemux(transmuxResults, demuxResult, chunkMeta) {
|
@@ -18312,7 +18362,7 @@ class Transmuxer {
|
|
18312
18362
|
accurateTimeOffset,
|
18313
18363
|
timeOffset
|
18314
18364
|
} = this.currentTransmuxState;
|
18315
|
-
logger.log(`[transmuxer.ts]: Flushed
|
18365
|
+
this.logger.log(`[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''} of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`);
|
18316
18366
|
const remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
|
18317
18367
|
transmuxResults.push({
|
18318
18368
|
remuxResult,
|
@@ -18405,7 +18455,7 @@ class Transmuxer {
|
|
18405
18455
|
let mux;
|
18406
18456
|
for (let i = 0, len = muxConfig.length; i < len; i++) {
|
18407
18457
|
var _muxConfig$i$demux;
|
18408
|
-
if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data)) {
|
18458
|
+
if ((_muxConfig$i$demux = muxConfig[i].demux) != null && _muxConfig$i$demux.probe(data, this.logger)) {
|
18409
18459
|
mux = muxConfig[i];
|
18410
18460
|
break;
|
18411
18461
|
}
|
@@ -18419,10 +18469,10 @@ class Transmuxer {
|
|
18419
18469
|
const Remuxer = mux.remux;
|
18420
18470
|
const Demuxer = mux.demux;
|
18421
18471
|
if (!remuxer || !(remuxer instanceof Remuxer)) {
|
18422
|
-
this.remuxer = new Remuxer(observer, config, typeSupported,
|
18472
|
+
this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);
|
18423
18473
|
}
|
18424
18474
|
if (!demuxer || !(demuxer instanceof Demuxer)) {
|
18425
|
-
this.demuxer = new Demuxer(observer, config, typeSupported);
|
18475
|
+
this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);
|
18426
18476
|
this.probe = Demuxer.probe;
|
18427
18477
|
}
|
18428
18478
|
}
|
@@ -18827,31 +18877,96 @@ var eventemitter3 = {exports: {}};
|
|
18827
18877
|
var eventemitter3Exports = eventemitter3.exports;
|
18828
18878
|
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
|
18829
18879
|
|
18880
|
+
let transmuxerInstanceCount = 0;
|
18830
18881
|
class TransmuxerInterface {
|
18831
|
-
constructor(
|
18882
|
+
constructor(_hls, id, onTransmuxComplete, onFlush) {
|
18832
18883
|
this.error = null;
|
18833
18884
|
this.hls = void 0;
|
18834
18885
|
this.id = void 0;
|
18886
|
+
this.instanceNo = transmuxerInstanceCount++;
|
18835
18887
|
this.observer = void 0;
|
18836
18888
|
this.frag = null;
|
18837
18889
|
this.part = null;
|
18838
18890
|
this.useWorker = void 0;
|
18839
18891
|
this.workerContext = null;
|
18840
|
-
this.onwmsg = void 0;
|
18841
18892
|
this.transmuxer = null;
|
18842
18893
|
this.onTransmuxComplete = void 0;
|
18843
18894
|
this.onFlush = void 0;
|
18844
|
-
|
18845
|
-
|
18895
|
+
this.onWorkerMessage = event => {
|
18896
|
+
const data = event.data;
|
18897
|
+
const hls = this.hls;
|
18898
|
+
if (!hls || !(data != null && data.event) || data.instanceNo !== this.instanceNo) {
|
18899
|
+
return;
|
18900
|
+
}
|
18901
|
+
switch (data.event) {
|
18902
|
+
case 'init':
|
18903
|
+
{
|
18904
|
+
var _this$workerContext;
|
18905
|
+
const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
|
18906
|
+
if (objectURL) {
|
18907
|
+
// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
18908
|
+
self.URL.revokeObjectURL(objectURL);
|
18909
|
+
}
|
18910
|
+
break;
|
18911
|
+
}
|
18912
|
+
case 'transmuxComplete':
|
18913
|
+
{
|
18914
|
+
this.handleTransmuxComplete(data.data);
|
18915
|
+
break;
|
18916
|
+
}
|
18917
|
+
case 'flush':
|
18918
|
+
{
|
18919
|
+
this.onFlush(data.data);
|
18920
|
+
break;
|
18921
|
+
}
|
18922
|
+
|
18923
|
+
// pass logs from the worker thread to the main logger
|
18924
|
+
case 'workerLog':
|
18925
|
+
{
|
18926
|
+
if (hls.logger[data.data.logType]) {
|
18927
|
+
hls.logger[data.data.logType](data.data.message);
|
18928
|
+
}
|
18929
|
+
break;
|
18930
|
+
}
|
18931
|
+
default:
|
18932
|
+
{
|
18933
|
+
data.data = data.data || {};
|
18934
|
+
data.data.frag = this.frag;
|
18935
|
+
data.data.part = this.part;
|
18936
|
+
data.data.id = this.id;
|
18937
|
+
hls.trigger(data.event, data.data);
|
18938
|
+
break;
|
18939
|
+
}
|
18940
|
+
}
|
18941
|
+
};
|
18942
|
+
this.onWorkerError = event => {
|
18943
|
+
if (!this.hls) {
|
18944
|
+
return;
|
18945
|
+
}
|
18946
|
+
const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
|
18947
|
+
this.hls.config.enableWorker = false;
|
18948
|
+
this.hls.logger.warn(`Error in "${this.id}" Web Worker, fallback to inline`);
|
18949
|
+
this.hls.trigger(Events.ERROR, {
|
18950
|
+
type: ErrorTypes.OTHER_ERROR,
|
18951
|
+
details: ErrorDetails.INTERNAL_EXCEPTION,
|
18952
|
+
fatal: false,
|
18953
|
+
event: 'demuxerWorker',
|
18954
|
+
error
|
18955
|
+
});
|
18956
|
+
};
|
18957
|
+
const config = _hls.config;
|
18958
|
+
this.hls = _hls;
|
18846
18959
|
this.id = id;
|
18847
18960
|
this.useWorker = !!config.enableWorker;
|
18848
18961
|
this.onTransmuxComplete = onTransmuxComplete;
|
18849
18962
|
this.onFlush = onFlush;
|
18850
18963
|
const forwardMessage = (ev, data) => {
|
18851
18964
|
data = data || {};
|
18852
|
-
data.frag = this.frag;
|
18853
|
-
data.id = this.id;
|
18965
|
+
data.frag = this.frag || undefined;
|
18854
18966
|
if (ev === Events.ERROR) {
|
18967
|
+
data = data;
|
18968
|
+
data.parent = this.id;
|
18969
|
+
data.part = this.part;
|
18855
18970
|
this.error = data.error;
|
18856
18971
|
}
|
18857
18972
|
this.hls.trigger(ev, data);
|
@@ -18863,6 +18978,7 @@ class TransmuxerInterface {
|
|
18863
18978
|
this.observer.on(Events.ERROR, forwardMessage);
|
18864
18979
|
const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
|
18865
18980
|
if (this.useWorker && typeof Worker !== 'undefined') {
|
18981
|
+
const logger = this.hls.logger;
|
18866
18982
|
const canCreateWorker = config.workerPath || hasUMDWorker();
|
18867
18983
|
if (canCreateWorker) {
|
18868
18984
|
try {
|
@@ -18873,61 +18989,63 @@ class TransmuxerInterface {
|
|
18873
18989
|
logger.log(`injecting Web Worker for "${id}"`);
|
18874
18990
|
this.workerContext = injectWorker();
|
18875
18991
|
}
|
18876
|
-
this.onwmsg = event => this.onWorkerMessage(event);
|
18877
18992
|
const {
|
18878
18993
|
worker
|
18879
18994
|
} = this.workerContext;
|
18880
|
-
worker.addEventListener('message', this.
|
18881
|
-
worker.
|
18882
|
-
const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
|
18883
|
-
config.enableWorker = false;
|
18884
|
-
logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
|
18885
|
-
this.hls.trigger(Events.ERROR, {
|
18886
|
-
type: ErrorTypes.OTHER_ERROR,
|
18887
|
-
details: ErrorDetails.INTERNAL_EXCEPTION,
|
18888
|
-
fatal: false,
|
18889
|
-
event: 'demuxerWorker',
|
18890
|
-
error
|
18891
|
-
});
|
18892
|
-
};
|
18995
|
+
worker.addEventListener('message', this.onWorkerMessage);
|
18996
|
+
worker.addEventListener('error', this.onWorkerError);
|
18893
18997
|
worker.postMessage({
|
18998
|
+
instanceNo: this.instanceNo,
|
18894
18999
|
cmd: 'init',
|
18895
19000
|
typeSupported: m2tsTypeSupported,
|
18896
|
-
|
18897
|
-
id: id,
|
19001
|
+
id,
|
18898
19002
|
config: JSON.stringify(config)
|
18899
19003
|
});
|
18900
19004
|
} catch (err) {
|
18901
19005
|
logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
|
18902
|
-
this.
|
19006
|
+
this.terminateWorker();
|
18903
19007
|
this.error = null;
|
18904
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
19008
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
|
18905
19009
|
}
|
18906
19010
|
return;
|
18907
19011
|
}
|
18908
19012
|
}
|
18909
|
-
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
19013
|
+
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id, _hls.logger);
|
18910
19014
|
}
|
18911
|
-
|
19015
|
+
reset() {
|
19016
|
+
this.frag = null;
|
19017
|
+
this.part = null;
|
19018
|
+
if (this.workerContext) {
|
19019
|
+
const instanceNo = this.instanceNo;
|
19020
|
+
this.instanceNo = transmuxerInstanceCount++;
|
19021
|
+
const config = this.hls.config;
|
19022
|
+
const m2tsTypeSupported = getM2TSSupportedAudioTypes(config.preferManagedMediaSource);
|
19023
|
+
this.workerContext.worker.postMessage({
|
19024
|
+
instanceNo: this.instanceNo,
|
19025
|
+
cmd: 'reset',
|
19026
|
+
resetNo: instanceNo,
|
19027
|
+
typeSupported: m2tsTypeSupported,
|
19028
|
+
id: this.id,
|
19029
|
+
config: JSON.stringify(config)
|
19030
|
+
});
|
19031
|
+
}
|
19032
|
+
}
|
19033
|
+
terminateWorker() {
|
18912
19034
|
if (this.workerContext) {
|
18913
19035
|
const {
|
18914
|
-
worker
|
18915
|
-
objectURL
|
19036
|
+
worker
|
18916
19037
|
} = this.workerContext;
|
18917
|
-
if (objectURL) {
|
18918
|
-
// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
18919
|
-
self.URL.revokeObjectURL(objectURL);
|
18920
|
-
}
|
18921
|
-
worker.removeEventListener('message', this.onwmsg);
|
18922
|
-
worker.onerror = null;
|
18923
|
-
worker.terminate();
|
18924
19038
|
this.workerContext = null;
|
19039
|
+
worker.removeEventListener('message', this.onWorkerMessage);
|
19040
|
+
worker.removeEventListener('error', this.onWorkerError);
|
19041
|
+
removeWorkerFromStore(this.hls.config.workerPath);
|
18925
19042
|
}
|
18926
19043
|
}
|
18927
19044
|
destroy() {
|
18928
19045
|
if (this.workerContext) {
|
18929
|
-
this.
|
18930
|
-
|
19046
|
+
this.terminateWorker();
|
19047
|
+
// @ts-ignore
|
19048
|
+
this.onWorkerMessage = this.onWorkerError = null;
|
18931
19049
|
} else {
|
18932
19050
|
const transmuxer = this.transmuxer;
|
18933
19051
|
if (transmuxer) {
|
@@ -18940,6 +19058,7 @@ class TransmuxerInterface {
|
|
18940
19058
|
observer.removeAllListeners();
|
18941
19059
|
}
|
18942
19060
|
this.frag = null;
|
19061
|
+
this.part = null;
|
18943
19062
|
// @ts-ignore
|
18944
19063
|
this.observer = null;
|
18945
19064
|
// @ts-ignore
|
@@ -18949,6 +19068,7 @@ class TransmuxerInterface {
|
|
18949
19068
|
var _frag$initSegment, _lastFrag$initSegment;
|
18950
19069
|
chunkMeta.transmuxing.start = self.performance.now();
|
18951
19070
|
const {
|
19071
|
+
instanceNo,
|
18952
19072
|
transmuxer
|
18953
19073
|
} = this;
|
18954
19074
|
const timeOffset = part ? part.start : frag.start;
|
@@ -18971,7 +19091,7 @@ class TransmuxerInterface {
|
|
18971
19091
|
const initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) == null ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) == null ? void 0 : _lastFrag$initSegment.url));
|
18972
19092
|
const state = new TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
|
18973
19093
|
if (!contiguous || discontinuity || initSegmentChange) {
|
18974
|
-
logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
|
19094
|
+
this.hls.logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
|
18975
19095
|
discontinuity: ${discontinuity}
|
18976
19096
|
trackSwitch: ${trackSwitch}
|
18977
19097
|
contiguous: ${contiguous}
|
@@ -18988,6 +19108,7 @@ class TransmuxerInterface {
|
|
18988
19108
|
if (this.workerContext) {
|
18989
19109
|
// post fragment payload as transferable objects for ArrayBuffer (no copy)
|
18990
19110
|
this.workerContext.worker.postMessage({
|
19111
|
+
instanceNo,
|
18991
19112
|
cmd: 'demux',
|
18992
19113
|
data,
|
18993
19114
|
decryptdata,
|
@@ -18997,14 +19118,12 @@ class TransmuxerInterface {
|
|
18997
19118
|
} else if (transmuxer) {
|
18998
19119
|
const transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state);
|
18999
19120
|
if (isPromise(transmuxResult)) {
|
19000
|
-
transmuxer.async = true;
|
19001
19121
|
transmuxResult.then(data => {
|
19002
19122
|
this.handleTransmuxComplete(data);
|
19003
19123
|
}).catch(error => {
|
19004
19124
|
this.transmuxerError(error, chunkMeta, 'transmuxer-interface push error');
|
19005
19125
|
});
|
19006
19126
|
} else {
|
19007
|
-
transmuxer.async = false;
|
19008
19127
|
this.handleTransmuxComplete(transmuxResult);
|
19009
19128
|
}
|
19010
19129
|
}
|
@@ -19012,20 +19131,18 @@ class TransmuxerInterface {
|
|
19012
19131
|
flush(chunkMeta) {
|
19013
19132
|
chunkMeta.transmuxing.start = self.performance.now();
|
19014
19133
|
const {
|
19134
|
+
instanceNo,
|
19015
19135
|
transmuxer
|
19016
19136
|
} = this;
|
19017
19137
|
if (this.workerContext) {
|
19018
19138
|
this.workerContext.worker.postMessage({
|
19139
|
+
instanceNo,
|
19019
19140
|
cmd: 'flush',
|
19020
19141
|
chunkMeta
|
19021
19142
|
});
|
19022
19143
|
} else if (transmuxer) {
|
19023
|
-
|
19024
|
-
|
19025
|
-
if (asyncFlush || transmuxer.async) {
|
19026
|
-
if (!isPromise(transmuxResult)) {
|
19027
|
-
transmuxResult = Promise.resolve(transmuxResult);
|
19028
|
-
}
|
19144
|
+
const transmuxResult = transmuxer.flush(chunkMeta);
|
19145
|
+
if (isPromise(transmuxResult)) {
|
19029
19146
|
transmuxResult.then(data => {
|
19030
19147
|
this.handleFlushResult(data, chunkMeta);
|
19031
19148
|
}).catch(error => {
|
@@ -19046,6 +19163,7 @@ class TransmuxerInterface {
|
|
19046
19163
|
details: ErrorDetails.FRAG_PARSING_ERROR,
|
19047
19164
|
chunkMeta,
|
19048
19165
|
frag: this.frag || undefined,
|
19166
|
+
part: this.part || undefined,
|
19049
19167
|
fatal: false,
|
19050
19168
|
error,
|
19051
19169
|
err: error,
|
@@ -19058,60 +19176,14 @@ class TransmuxerInterface {
|
|
19058
19176
|
});
|
19059
19177
|
this.onFlush(chunkMeta);
|
19060
19178
|
}
|
19061
|
-
onWorkerMessage(event) {
|
19062
|
-
const data = event.data;
|
19063
|
-
if (!(data != null && data.event)) {
|
19064
|
-
logger.warn(`worker message received with no ${data ? 'event name' : 'data'}`);
|
19065
|
-
return;
|
19066
|
-
}
|
19067
|
-
const hls = this.hls;
|
19068
|
-
if (!this.hls) {
|
19069
|
-
return;
|
19070
|
-
}
|
19071
|
-
switch (data.event) {
|
19072
|
-
case 'init':
|
19073
|
-
{
|
19074
|
-
var _this$workerContext;
|
19075
|
-
const objectURL = (_this$workerContext = this.workerContext) == null ? void 0 : _this$workerContext.objectURL;
|
19076
|
-
if (objectURL) {
|
19077
|
-
// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
19078
|
-
self.URL.revokeObjectURL(objectURL);
|
19079
|
-
}
|
19080
|
-
break;
|
19081
|
-
}
|
19082
|
-
case 'transmuxComplete':
|
19083
|
-
{
|
19084
|
-
this.handleTransmuxComplete(data.data);
|
19085
|
-
break;
|
19086
|
-
}
|
19087
|
-
case 'flush':
|
19088
|
-
{
|
19089
|
-
this.onFlush(data.data);
|
19090
|
-
break;
|
19091
|
-
}
|
19092
|
-
|
19093
|
-
// pass logs from the worker thread to the main logger
|
19094
|
-
case 'workerLog':
|
19095
|
-
if (logger[data.data.logType]) {
|
19096
|
-
logger[data.data.logType](data.data.message);
|
19097
|
-
}
|
19098
|
-
break;
|
19099
|
-
default:
|
19100
|
-
{
|
19101
|
-
data.data = data.data || {};
|
19102
|
-
data.data.frag = this.frag;
|
19103
|
-
data.data.id = this.id;
|
19104
|
-
hls.trigger(data.event, data.data);
|
19105
|
-
break;
|
19106
|
-
}
|
19107
|
-
}
|
19108
|
-
}
|
19109
19179
|
configureTransmuxer(config) {
|
19110
19180
|
const {
|
19181
|
+
instanceNo,
|
19111
19182
|
transmuxer
|
19112
19183
|
} = this;
|
19113
19184
|
if (this.workerContext) {
|
19114
19185
|
this.workerContext.worker.postMessage({
|
19186
|
+
instanceNo,
|
19115
19187
|
cmd: 'configure',
|
19116
19188
|
config
|
19117
19189
|
});
|
@@ -20640,7 +20712,7 @@ class Hls {
|
|
20640
20712
|
* Get the video-dev/hls.js package version.
|
20641
20713
|
*/
|
20642
20714
|
static get version() {
|
20643
|
-
return
|
20715
|
+
return version;
|
20644
20716
|
}
|
20645
20717
|
|
20646
20718
|
/**
|