hls.js 1.5.2-0.canary.9969 → 1.5.2-0.canary.9971
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 +1 -0
- package/dist/hls-demo.js +5 -0
- package/dist/hls-demo.js.map +1 -1
- package/dist/hls.js +952 -232
- package/dist/hls.js.d.ts +7 -3
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +952 -233
- 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 +921 -211
- 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 +927 -216
- 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/audio-stream-controller.ts +4 -2
- package/src/controller/base-stream-controller.ts +9 -0
- package/src/controller/buffer-controller.ts +1 -0
- package/src/controller/stream-controller.ts +1 -1
- package/src/demux/tsdemuxer.ts +51 -20
- package/src/demux/video/avc-video-parser.ts +208 -119
- package/src/demux/video/base-video-parser.ts +134 -2
- package/src/demux/video/exp-golomb.ts +0 -208
- package/src/demux/video/hevc-video-parser.ts +746 -0
- package/src/hls.ts +9 -14
- package/src/remux/mp4-generator.ts +196 -1
- package/src/remux/mp4-remuxer.ts +3 -3
- package/src/types/component-api.ts +2 -0
- package/src/types/demuxer.ts +2 -0
package/dist/hls.mjs
CHANGED
@@ -431,7 +431,7 @@ function enableLogs(debugConfig, context, id) {
|
|
431
431
|
// Some browsers don't allow to use bind on console object anyway
|
432
432
|
// fallback to default if needed
|
433
433
|
try {
|
434
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.2-0.canary.
|
434
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.2-0.canary.9971"}`);
|
435
435
|
} catch (e) {
|
436
436
|
/* log fn threw an exception. All logger methods are no-ops. */
|
437
437
|
return createLogger();
|
@@ -9180,6 +9180,7 @@ class BaseStreamController extends TaskLoop {
|
|
9180
9180
|
this.startFragRequested = false;
|
9181
9181
|
this.decrypter = void 0;
|
9182
9182
|
this.initPTS = [];
|
9183
|
+
this.buffering = true;
|
9183
9184
|
this.onMediaSeeking = () => {
|
9184
9185
|
const {
|
9185
9186
|
config,
|
@@ -9285,6 +9286,12 @@ class BaseStreamController extends TaskLoop {
|
|
9285
9286
|
this.clearNextTick();
|
9286
9287
|
this.state = State.STOPPED;
|
9287
9288
|
}
|
9289
|
+
pauseBuffering() {
|
9290
|
+
this.buffering = false;
|
9291
|
+
}
|
9292
|
+
resumeBuffering() {
|
9293
|
+
this.buffering = true;
|
9294
|
+
}
|
9288
9295
|
_streamEnded(bufferInfo, levelDetails) {
|
9289
9296
|
// If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
|
9290
9297
|
// of nothing loading/loaded return false
|
@@ -11420,6 +11427,110 @@ class BaseVideoParser {
|
|
11420
11427
|
logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
|
11421
11428
|
}
|
11422
11429
|
}
|
11430
|
+
parseNALu(track, array) {
|
11431
|
+
const len = array.byteLength;
|
11432
|
+
let state = track.naluState || 0;
|
11433
|
+
const lastState = state;
|
11434
|
+
const units = [];
|
11435
|
+
let i = 0;
|
11436
|
+
let value;
|
11437
|
+
let overflow;
|
11438
|
+
let unitType;
|
11439
|
+
let lastUnitStart = -1;
|
11440
|
+
let lastUnitType = 0;
|
11441
|
+
// logger.log('PES:' + Hex.hexDump(array));
|
11442
|
+
|
11443
|
+
if (state === -1) {
|
11444
|
+
// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
11445
|
+
lastUnitStart = 0;
|
11446
|
+
// NALu type is value read from offset 0
|
11447
|
+
lastUnitType = this.getNALuType(array, 0);
|
11448
|
+
state = 0;
|
11449
|
+
i = 1;
|
11450
|
+
}
|
11451
|
+
while (i < len) {
|
11452
|
+
value = array[i++];
|
11453
|
+
// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
11454
|
+
if (!state) {
|
11455
|
+
state = value ? 0 : 1;
|
11456
|
+
continue;
|
11457
|
+
}
|
11458
|
+
if (state === 1) {
|
11459
|
+
state = value ? 0 : 2;
|
11460
|
+
continue;
|
11461
|
+
}
|
11462
|
+
// here we have state either equal to 2 or 3
|
11463
|
+
if (!value) {
|
11464
|
+
state = 3;
|
11465
|
+
} else if (value === 1) {
|
11466
|
+
overflow = i - state - 1;
|
11467
|
+
if (lastUnitStart >= 0) {
|
11468
|
+
const unit = {
|
11469
|
+
data: array.subarray(lastUnitStart, overflow),
|
11470
|
+
type: lastUnitType
|
11471
|
+
};
|
11472
|
+
// logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
11473
|
+
units.push(unit);
|
11474
|
+
} else {
|
11475
|
+
// lastUnitStart is undefined => this is the first start code found in this PES packet
|
11476
|
+
// first check if start code delimiter is overlapping between 2 PES packets,
|
11477
|
+
// ie it started in last packet (lastState not zero)
|
11478
|
+
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
11479
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
11480
|
+
if (lastUnit) {
|
11481
|
+
if (lastState && i <= 4 - lastState) {
|
11482
|
+
// start delimiter overlapping between PES packets
|
11483
|
+
// strip start delimiter bytes from the end of last NAL unit
|
11484
|
+
// check if lastUnit had a state different from zero
|
11485
|
+
if (lastUnit.state) {
|
11486
|
+
// strip last bytes
|
11487
|
+
lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
|
11488
|
+
}
|
11489
|
+
}
|
11490
|
+
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
11491
|
+
|
11492
|
+
if (overflow > 0) {
|
11493
|
+
// logger.log('first NALU found with overflow:' + overflow);
|
11494
|
+
lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
|
11495
|
+
lastUnit.state = 0;
|
11496
|
+
}
|
11497
|
+
}
|
11498
|
+
}
|
11499
|
+
// check if we can read unit type
|
11500
|
+
if (i < len) {
|
11501
|
+
unitType = this.getNALuType(array, i);
|
11502
|
+
// logger.log('find NALU @ offset:' + i + ',type:' + unitType);
|
11503
|
+
lastUnitStart = i;
|
11504
|
+
lastUnitType = unitType;
|
11505
|
+
state = 0;
|
11506
|
+
} else {
|
11507
|
+
// not enough byte to read unit type. let's read it on next PES parsing
|
11508
|
+
state = -1;
|
11509
|
+
}
|
11510
|
+
} else {
|
11511
|
+
state = 0;
|
11512
|
+
}
|
11513
|
+
}
|
11514
|
+
if (lastUnitStart >= 0 && state >= 0) {
|
11515
|
+
const unit = {
|
11516
|
+
data: array.subarray(lastUnitStart, len),
|
11517
|
+
type: lastUnitType,
|
11518
|
+
state: state
|
11519
|
+
};
|
11520
|
+
units.push(unit);
|
11521
|
+
// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
11522
|
+
}
|
11523
|
+
// no NALu found
|
11524
|
+
if (units.length === 0) {
|
11525
|
+
// append pes.data to previous NAL unit
|
11526
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
11527
|
+
if (lastUnit) {
|
11528
|
+
lastUnit.data = appendUint8Array(lastUnit.data, array);
|
11529
|
+
}
|
11530
|
+
}
|
11531
|
+
track.naluState = state;
|
11532
|
+
return units;
|
11533
|
+
}
|
11423
11534
|
}
|
11424
11535
|
|
11425
11536
|
/**
|
@@ -11562,21 +11673,171 @@ class ExpGolomb {
|
|
11562
11673
|
readUInt() {
|
11563
11674
|
return this.readBits(32);
|
11564
11675
|
}
|
11676
|
+
}
|
11677
|
+
|
11678
|
+
class AvcVideoParser extends BaseVideoParser {
|
11679
|
+
parsePES(track, textTrack, pes, last, duration) {
|
11680
|
+
const units = this.parseNALu(track, pes.data);
|
11681
|
+
let VideoSample = this.VideoSample;
|
11682
|
+
let push;
|
11683
|
+
let spsfound = false;
|
11684
|
+
// free pes.data to save up some memory
|
11685
|
+
pes.data = null;
|
11686
|
+
|
11687
|
+
// if new NAL units found and last sample still there, let's push ...
|
11688
|
+
// this helps parsing streams with missing AUD (only do this if AUD never found)
|
11689
|
+
if (VideoSample && units.length && !track.audFound) {
|
11690
|
+
this.pushAccessUnit(VideoSample, track);
|
11691
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
11692
|
+
}
|
11693
|
+
units.forEach(unit => {
|
11694
|
+
var _VideoSample2;
|
11695
|
+
switch (unit.type) {
|
11696
|
+
// NDR
|
11697
|
+
case 1:
|
11698
|
+
{
|
11699
|
+
let iskey = false;
|
11700
|
+
push = true;
|
11701
|
+
const data = unit.data;
|
11702
|
+
// only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
|
11703
|
+
if (spsfound && data.length > 4) {
|
11704
|
+
// retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
|
11705
|
+
const sliceType = this.readSliceType(data);
|
11706
|
+
// 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
|
11707
|
+
// SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
|
11708
|
+
// An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
|
11709
|
+
// I slice: A slice that is not an SI slice that is decoded using intra prediction only.
|
11710
|
+
// if (sliceType === 2 || sliceType === 7) {
|
11711
|
+
if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
|
11712
|
+
iskey = true;
|
11713
|
+
}
|
11714
|
+
}
|
11715
|
+
if (iskey) {
|
11716
|
+
var _VideoSample;
|
11717
|
+
// if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
|
11718
|
+
if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
|
11719
|
+
this.pushAccessUnit(VideoSample, track);
|
11720
|
+
VideoSample = this.VideoSample = null;
|
11721
|
+
}
|
11722
|
+
}
|
11723
|
+
if (!VideoSample) {
|
11724
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
11725
|
+
}
|
11726
|
+
VideoSample.frame = true;
|
11727
|
+
VideoSample.key = iskey;
|
11728
|
+
break;
|
11729
|
+
// IDR
|
11730
|
+
}
|
11731
|
+
case 5:
|
11732
|
+
push = true;
|
11733
|
+
// handle PES not starting with AUD
|
11734
|
+
// if we have frame data already, that cannot belong to the same frame, so force a push
|
11735
|
+
if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
|
11736
|
+
this.pushAccessUnit(VideoSample, track);
|
11737
|
+
VideoSample = this.VideoSample = null;
|
11738
|
+
}
|
11739
|
+
if (!VideoSample) {
|
11740
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
11741
|
+
}
|
11742
|
+
VideoSample.key = true;
|
11743
|
+
VideoSample.frame = true;
|
11744
|
+
break;
|
11745
|
+
// SEI
|
11746
|
+
case 6:
|
11747
|
+
{
|
11748
|
+
push = true;
|
11749
|
+
parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
|
11750
|
+
break;
|
11751
|
+
// SPS
|
11752
|
+
}
|
11753
|
+
case 7:
|
11754
|
+
{
|
11755
|
+
var _track$pixelRatio, _track$pixelRatio2;
|
11756
|
+
push = true;
|
11757
|
+
spsfound = true;
|
11758
|
+
const sps = unit.data;
|
11759
|
+
const config = this.readSPS(sps);
|
11760
|
+
if (!track.sps || track.width !== config.width || track.height !== config.height || ((_track$pixelRatio = track.pixelRatio) == null ? void 0 : _track$pixelRatio[0]) !== config.pixelRatio[0] || ((_track$pixelRatio2 = track.pixelRatio) == null ? void 0 : _track$pixelRatio2[1]) !== config.pixelRatio[1]) {
|
11761
|
+
track.width = config.width;
|
11762
|
+
track.height = config.height;
|
11763
|
+
track.pixelRatio = config.pixelRatio;
|
11764
|
+
track.sps = [sps];
|
11765
|
+
track.duration = duration;
|
11766
|
+
const codecarray = sps.subarray(1, 4);
|
11767
|
+
let codecstring = 'avc1.';
|
11768
|
+
for (let i = 0; i < 3; i++) {
|
11769
|
+
let h = codecarray[i].toString(16);
|
11770
|
+
if (h.length < 2) {
|
11771
|
+
h = '0' + h;
|
11772
|
+
}
|
11773
|
+
codecstring += h;
|
11774
|
+
}
|
11775
|
+
track.codec = codecstring;
|
11776
|
+
}
|
11777
|
+
break;
|
11778
|
+
}
|
11779
|
+
// PPS
|
11780
|
+
case 8:
|
11781
|
+
push = true;
|
11782
|
+
track.pps = [unit.data];
|
11783
|
+
break;
|
11784
|
+
// AUD
|
11785
|
+
case 9:
|
11786
|
+
push = true;
|
11787
|
+
track.audFound = true;
|
11788
|
+
if (VideoSample) {
|
11789
|
+
this.pushAccessUnit(VideoSample, track);
|
11790
|
+
}
|
11791
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
11792
|
+
break;
|
11793
|
+
// Filler Data
|
11794
|
+
case 12:
|
11795
|
+
push = true;
|
11796
|
+
break;
|
11797
|
+
default:
|
11798
|
+
push = false;
|
11799
|
+
if (VideoSample) {
|
11800
|
+
VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
|
11801
|
+
}
|
11802
|
+
break;
|
11803
|
+
}
|
11804
|
+
if (VideoSample && push) {
|
11805
|
+
const units = VideoSample.units;
|
11806
|
+
units.push(unit);
|
11807
|
+
}
|
11808
|
+
});
|
11809
|
+
// if last PES packet, push samples
|
11810
|
+
if (last && VideoSample) {
|
11811
|
+
this.pushAccessUnit(VideoSample, track);
|
11812
|
+
this.VideoSample = null;
|
11813
|
+
}
|
11814
|
+
}
|
11815
|
+
getNALuType(data, offset) {
|
11816
|
+
return data[offset] & 0x1f;
|
11817
|
+
}
|
11818
|
+
readSliceType(data) {
|
11819
|
+
const eg = new ExpGolomb(data);
|
11820
|
+
// skip NALu type
|
11821
|
+
eg.readUByte();
|
11822
|
+
// discard first_mb_in_slice
|
11823
|
+
eg.readUEG();
|
11824
|
+
// return slice_type
|
11825
|
+
return eg.readUEG();
|
11826
|
+
}
|
11565
11827
|
|
11566
11828
|
/**
|
11567
|
-
*
|
11568
|
-
* list is optionally transmitted as part of a sequence parameter
|
11829
|
+
* The scaling list is optionally transmitted as part of a sequence parameter
|
11569
11830
|
* set and is not relevant to transmuxing.
|
11570
11831
|
* @param count the number of entries in this scaling list
|
11571
11832
|
* @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
|
11572
11833
|
*/
|
11573
|
-
skipScalingList(count) {
|
11834
|
+
skipScalingList(count, reader) {
|
11574
11835
|
let lastScale = 8;
|
11575
11836
|
let nextScale = 8;
|
11576
11837
|
let deltaScale;
|
11577
11838
|
for (let j = 0; j < count; j++) {
|
11578
11839
|
if (nextScale !== 0) {
|
11579
|
-
deltaScale =
|
11840
|
+
deltaScale = reader.readEG();
|
11580
11841
|
nextScale = (lastScale + deltaScale + 256) % 256;
|
11581
11842
|
}
|
11582
11843
|
lastScale = nextScale === 0 ? lastScale : nextScale;
|
@@ -11591,7 +11852,8 @@ class ExpGolomb {
|
|
11591
11852
|
* sequence parameter set, including the dimensions of the
|
11592
11853
|
* associated video frames.
|
11593
11854
|
*/
|
11594
|
-
readSPS() {
|
11855
|
+
readSPS(sps) {
|
11856
|
+
const eg = new ExpGolomb(sps);
|
11595
11857
|
let frameCropLeftOffset = 0;
|
11596
11858
|
let frameCropRightOffset = 0;
|
11597
11859
|
let frameCropTopOffset = 0;
|
@@ -11599,13 +11861,13 @@ class ExpGolomb {
|
|
11599
11861
|
let numRefFramesInPicOrderCntCycle;
|
11600
11862
|
let scalingListCount;
|
11601
11863
|
let i;
|
11602
|
-
const readUByte =
|
11603
|
-
const readBits =
|
11604
|
-
const readUEG =
|
11605
|
-
const readBoolean =
|
11606
|
-
const skipBits =
|
11607
|
-
const skipEG =
|
11608
|
-
const skipUEG =
|
11864
|
+
const readUByte = eg.readUByte.bind(eg);
|
11865
|
+
const readBits = eg.readBits.bind(eg);
|
11866
|
+
const readUEG = eg.readUEG.bind(eg);
|
11867
|
+
const readBoolean = eg.readBoolean.bind(eg);
|
11868
|
+
const skipBits = eg.skipBits.bind(eg);
|
11869
|
+
const skipEG = eg.skipEG.bind(eg);
|
11870
|
+
const skipUEG = eg.skipUEG.bind(eg);
|
11609
11871
|
const skipScalingList = this.skipScalingList.bind(this);
|
11610
11872
|
readUByte();
|
11611
11873
|
const profileIdc = readUByte(); // profile_idc
|
@@ -11630,9 +11892,9 @@ class ExpGolomb {
|
|
11630
11892
|
if (readBoolean()) {
|
11631
11893
|
// seq_scaling_list_present_flag[ i ]
|
11632
11894
|
if (i < 6) {
|
11633
|
-
skipScalingList(16);
|
11895
|
+
skipScalingList(16, eg);
|
11634
11896
|
} else {
|
11635
|
-
skipScalingList(64);
|
11897
|
+
skipScalingList(64, eg);
|
11636
11898
|
}
|
11637
11899
|
}
|
11638
11900
|
}
|
@@ -11737,19 +11999,15 @@ class ExpGolomb {
|
|
11737
11999
|
pixelRatio: pixelRatio
|
11738
12000
|
};
|
11739
12001
|
}
|
11740
|
-
readSliceType() {
|
11741
|
-
// skip NALu type
|
11742
|
-
this.readUByte();
|
11743
|
-
// discard first_mb_in_slice
|
11744
|
-
this.readUEG();
|
11745
|
-
// return slice_type
|
11746
|
-
return this.readUEG();
|
11747
|
-
}
|
11748
12002
|
}
|
11749
12003
|
|
11750
|
-
class
|
11751
|
-
|
11752
|
-
|
12004
|
+
class HevcVideoParser extends BaseVideoParser {
|
12005
|
+
constructor(...args) {
|
12006
|
+
super(...args);
|
12007
|
+
this.initVPS = null;
|
12008
|
+
}
|
12009
|
+
parsePES(track, textTrack, pes, last, duration) {
|
12010
|
+
const units = this.parseNALu(track, pes.data);
|
11753
12011
|
let VideoSample = this.VideoSample;
|
11754
12012
|
let push;
|
11755
12013
|
let spsfound = false;
|
@@ -11765,42 +12023,49 @@ class AvcVideoParser extends BaseVideoParser {
|
|
11765
12023
|
units.forEach(unit => {
|
11766
12024
|
var _VideoSample2;
|
11767
12025
|
switch (unit.type) {
|
11768
|
-
//
|
12026
|
+
// NON-IDR, NON RANDOM ACCESS SLICE
|
12027
|
+
case 0:
|
11769
12028
|
case 1:
|
11770
|
-
|
11771
|
-
|
11772
|
-
|
11773
|
-
|
11774
|
-
|
11775
|
-
|
11776
|
-
|
11777
|
-
|
11778
|
-
|
11779
|
-
|
11780
|
-
|
11781
|
-
|
11782
|
-
|
11783
|
-
|
11784
|
-
|
11785
|
-
|
11786
|
-
|
11787
|
-
|
11788
|
-
|
11789
|
-
|
11790
|
-
|
11791
|
-
|
11792
|
-
|
11793
|
-
|
11794
|
-
|
11795
|
-
if (!VideoSample) {
|
11796
|
-
|
12029
|
+
case 2:
|
12030
|
+
case 3:
|
12031
|
+
case 4:
|
12032
|
+
case 5:
|
12033
|
+
case 6:
|
12034
|
+
case 7:
|
12035
|
+
case 8:
|
12036
|
+
case 9:
|
12037
|
+
if (!VideoSample) {
|
12038
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
12039
|
+
}
|
12040
|
+
VideoSample.frame = true;
|
12041
|
+
push = true;
|
12042
|
+
break;
|
12043
|
+
|
12044
|
+
// CRA, BLA (random access picture)
|
12045
|
+
case 16:
|
12046
|
+
case 17:
|
12047
|
+
case 18:
|
12048
|
+
case 21:
|
12049
|
+
push = true;
|
12050
|
+
if (spsfound) {
|
12051
|
+
var _VideoSample;
|
12052
|
+
// handle PES not starting with AUD
|
12053
|
+
// if we have frame data already, that cannot belong to the same frame, so force a push
|
12054
|
+
if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
|
12055
|
+
this.pushAccessUnit(VideoSample, track);
|
12056
|
+
VideoSample = this.VideoSample = null;
|
11797
12057
|
}
|
11798
|
-
VideoSample.frame = true;
|
11799
|
-
VideoSample.key = iskey;
|
11800
|
-
break;
|
11801
|
-
// IDR
|
11802
12058
|
}
|
11803
|
-
|
12059
|
+
if (!VideoSample) {
|
12060
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
12061
|
+
}
|
12062
|
+
VideoSample.key = true;
|
12063
|
+
VideoSample.frame = true;
|
12064
|
+
break;
|
12065
|
+
|
12066
|
+
// IDR
|
12067
|
+
case 19:
|
12068
|
+
case 20:
|
11804
12069
|
push = true;
|
11805
12070
|
// handle PES not starting with AUD
|
11806
12071
|
// if we have frame data already, that cannot belong to the same frame, so force a push
|
@@ -11814,48 +12079,76 @@ class AvcVideoParser extends BaseVideoParser {
|
|
11814
12079
|
VideoSample.key = true;
|
11815
12080
|
VideoSample.frame = true;
|
11816
12081
|
break;
|
12082
|
+
|
11817
12083
|
// SEI
|
11818
|
-
case
|
11819
|
-
|
11820
|
-
|
11821
|
-
|
11822
|
-
|
11823
|
-
|
12084
|
+
case 39:
|
12085
|
+
push = true;
|
12086
|
+
parseSEIMessageFromNALu(unit.data, 2,
|
12087
|
+
// NALu header size
|
12088
|
+
pes.pts, textTrack.samples);
|
12089
|
+
break;
|
12090
|
+
|
12091
|
+
// VPS
|
12092
|
+
case 32:
|
12093
|
+
push = true;
|
12094
|
+
if (!track.vps) {
|
12095
|
+
const config = this.readVPS(unit.data);
|
12096
|
+
track.params = _objectSpread2({}, config);
|
12097
|
+
this.initVPS = unit.data;
|
11824
12098
|
}
|
11825
|
-
|
11826
|
-
|
11827
|
-
|
11828
|
-
|
11829
|
-
|
11830
|
-
|
11831
|
-
|
11832
|
-
|
11833
|
-
if (
|
12099
|
+
track.vps = [unit.data];
|
12100
|
+
break;
|
12101
|
+
|
12102
|
+
// SPS
|
12103
|
+
case 33:
|
12104
|
+
push = true;
|
12105
|
+
spsfound = true;
|
12106
|
+
if (typeof track.params === 'object') {
|
12107
|
+
if (track.vps !== undefined && track.vps[0] !== this.initVPS && track.sps !== undefined && !this.matchSPS(track.sps[0], unit.data)) {
|
12108
|
+
this.initVPS = track.vps[0];
|
12109
|
+
track.sps = track.pps = undefined;
|
12110
|
+
}
|
12111
|
+
if (!track.sps) {
|
12112
|
+
const config = this.readSPS(unit.data);
|
11834
12113
|
track.width = config.width;
|
11835
12114
|
track.height = config.height;
|
11836
12115
|
track.pixelRatio = config.pixelRatio;
|
11837
|
-
track.sps = [sps];
|
11838
12116
|
track.duration = duration;
|
11839
|
-
|
11840
|
-
|
11841
|
-
for (
|
11842
|
-
|
11843
|
-
if (h.length < 2) {
|
11844
|
-
h = '0' + h;
|
11845
|
-
}
|
11846
|
-
codecstring += h;
|
12117
|
+
track.codec = config.codecString;
|
12118
|
+
track.sps = [];
|
12119
|
+
for (const prop in config.params) {
|
12120
|
+
track.params[prop] = config.params[prop];
|
11847
12121
|
}
|
11848
|
-
track.codec = codecstring;
|
11849
12122
|
}
|
11850
|
-
|
12123
|
+
if (track.vps !== undefined && track.vps[0] === this.initVPS) {
|
12124
|
+
track.sps.push(unit.data);
|
12125
|
+
}
|
11851
12126
|
}
|
12127
|
+
if (!VideoSample) {
|
12128
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
12129
|
+
}
|
12130
|
+
VideoSample.key = true;
|
12131
|
+
break;
|
12132
|
+
|
11852
12133
|
// PPS
|
11853
|
-
case
|
12134
|
+
case 34:
|
11854
12135
|
push = true;
|
11855
|
-
track.
|
12136
|
+
if (typeof track.params === 'object') {
|
12137
|
+
if (!track.pps) {
|
12138
|
+
track.pps = [];
|
12139
|
+
const config = this.readPPS(unit.data);
|
12140
|
+
for (const prop in config) {
|
12141
|
+
track.params[prop] = config[prop];
|
12142
|
+
}
|
12143
|
+
}
|
12144
|
+
if (this.initVPS !== null || track.pps.length === 0) {
|
12145
|
+
track.pps.push(unit.data);
|
12146
|
+
}
|
12147
|
+
}
|
11856
12148
|
break;
|
11857
|
-
|
11858
|
-
|
12149
|
+
|
12150
|
+
// ACCESS UNIT DELIMITER
|
12151
|
+
case 35:
|
11859
12152
|
push = true;
|
11860
12153
|
track.audFound = true;
|
11861
12154
|
if (VideoSample) {
|
@@ -11863,14 +12156,10 @@ class AvcVideoParser extends BaseVideoParser {
|
|
11863
12156
|
}
|
11864
12157
|
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
11865
12158
|
break;
|
11866
|
-
// Filler Data
|
11867
|
-
case 12:
|
11868
|
-
push = true;
|
11869
|
-
break;
|
11870
12159
|
default:
|
11871
12160
|
push = false;
|
11872
12161
|
if (VideoSample) {
|
11873
|
-
VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
|
12162
|
+
VideoSample.debug += 'unknown or irrelevant NAL ' + unit.type + ' ';
|
11874
12163
|
}
|
11875
12164
|
break;
|
11876
12165
|
}
|
@@ -11885,109 +12174,423 @@ class AvcVideoParser extends BaseVideoParser {
|
|
11885
12174
|
this.VideoSample = null;
|
11886
12175
|
}
|
11887
12176
|
}
|
11888
|
-
|
11889
|
-
|
11890
|
-
|
11891
|
-
|
11892
|
-
const
|
11893
|
-
let
|
11894
|
-
let
|
11895
|
-
|
11896
|
-
|
11897
|
-
|
11898
|
-
|
11899
|
-
|
11900
|
-
|
11901
|
-
if (state === -1) {
|
11902
|
-
// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
11903
|
-
lastUnitStart = 0;
|
11904
|
-
// NALu type is value read from offset 0
|
11905
|
-
lastUnitType = array[0] & 0x1f;
|
11906
|
-
state = 0;
|
11907
|
-
i = 1;
|
11908
|
-
}
|
11909
|
-
while (i < len) {
|
11910
|
-
value = array[i++];
|
11911
|
-
// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
11912
|
-
if (!state) {
|
11913
|
-
state = value ? 0 : 1;
|
11914
|
-
continue;
|
11915
|
-
}
|
11916
|
-
if (state === 1) {
|
11917
|
-
state = value ? 0 : 2;
|
11918
|
-
continue;
|
12177
|
+
getNALuType(data, offset) {
|
12178
|
+
return (data[offset] & 0x7e) >>> 1;
|
12179
|
+
}
|
12180
|
+
ebsp2rbsp(arr) {
|
12181
|
+
const dst = new Uint8Array(arr.byteLength);
|
12182
|
+
let dstIdx = 0;
|
12183
|
+
for (let i = 0; i < arr.byteLength; i++) {
|
12184
|
+
if (i >= 2) {
|
12185
|
+
// Unescape: Skip 0x03 after 00 00
|
12186
|
+
if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {
|
12187
|
+
continue;
|
12188
|
+
}
|
11919
12189
|
}
|
11920
|
-
|
11921
|
-
|
11922
|
-
|
11923
|
-
|
11924
|
-
|
11925
|
-
|
11926
|
-
|
11927
|
-
|
11928
|
-
|
11929
|
-
|
11930
|
-
|
11931
|
-
|
11932
|
-
|
11933
|
-
|
11934
|
-
|
11935
|
-
|
11936
|
-
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
11937
|
-
const lastUnit = this.getLastNalUnit(track.samples);
|
11938
|
-
if (lastUnit) {
|
11939
|
-
if (lastState && i <= 4 - lastState) {
|
11940
|
-
// start delimiter overlapping between PES packets
|
11941
|
-
// strip start delimiter bytes from the end of last NAL unit
|
11942
|
-
// check if lastUnit had a state different from zero
|
11943
|
-
if (lastUnit.state) {
|
11944
|
-
// strip last bytes
|
11945
|
-
lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
|
11946
|
-
}
|
11947
|
-
}
|
11948
|
-
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
12190
|
+
dst[dstIdx] = arr[i];
|
12191
|
+
dstIdx++;
|
12192
|
+
}
|
12193
|
+
return new Uint8Array(dst.buffer, 0, dstIdx);
|
12194
|
+
}
|
12195
|
+
readVPS(vps) {
|
12196
|
+
const eg = new ExpGolomb(vps);
|
12197
|
+
// remove header
|
12198
|
+
eg.readUByte();
|
12199
|
+
eg.readUByte();
|
12200
|
+
eg.readBits(4); // video_parameter_set_id
|
12201
|
+
eg.skipBits(2);
|
12202
|
+
eg.readBits(6); // max_layers_minus1
|
12203
|
+
const max_sub_layers_minus1 = eg.readBits(3);
|
12204
|
+
const temporal_id_nesting_flag = eg.readBoolean();
|
12205
|
+
// ...vui fps can be here, but empty fps value is not critical for metadata
|
11949
12206
|
|
11950
|
-
|
11951
|
-
|
11952
|
-
|
11953
|
-
|
12207
|
+
return {
|
12208
|
+
numTemporalLayers: max_sub_layers_minus1 + 1,
|
12209
|
+
temporalIdNested: temporal_id_nesting_flag
|
12210
|
+
};
|
12211
|
+
}
|
12212
|
+
readSPS(sps) {
|
12213
|
+
const eg = new ExpGolomb(this.ebsp2rbsp(sps));
|
12214
|
+
eg.readUByte();
|
12215
|
+
eg.readUByte();
|
12216
|
+
eg.readBits(4); //video_parameter_set_id
|
12217
|
+
const max_sub_layers_minus1 = eg.readBits(3);
|
12218
|
+
eg.readBoolean(); // temporal_id_nesting_flag
|
12219
|
+
|
12220
|
+
// profile_tier_level
|
12221
|
+
const general_profile_space = eg.readBits(2);
|
12222
|
+
const general_tier_flag = eg.readBoolean();
|
12223
|
+
const general_profile_idc = eg.readBits(5);
|
12224
|
+
const general_profile_compatibility_flags_1 = eg.readUByte();
|
12225
|
+
const general_profile_compatibility_flags_2 = eg.readUByte();
|
12226
|
+
const general_profile_compatibility_flags_3 = eg.readUByte();
|
12227
|
+
const general_profile_compatibility_flags_4 = eg.readUByte();
|
12228
|
+
const general_constraint_indicator_flags_1 = eg.readUByte();
|
12229
|
+
const general_constraint_indicator_flags_2 = eg.readUByte();
|
12230
|
+
const general_constraint_indicator_flags_3 = eg.readUByte();
|
12231
|
+
const general_constraint_indicator_flags_4 = eg.readUByte();
|
12232
|
+
const general_constraint_indicator_flags_5 = eg.readUByte();
|
12233
|
+
const general_constraint_indicator_flags_6 = eg.readUByte();
|
12234
|
+
const general_level_idc = eg.readUByte();
|
12235
|
+
const sub_layer_profile_present_flags = [];
|
12236
|
+
const sub_layer_level_present_flags = [];
|
12237
|
+
for (let i = 0; i < max_sub_layers_minus1; i++) {
|
12238
|
+
sub_layer_profile_present_flags.push(eg.readBoolean());
|
12239
|
+
sub_layer_level_present_flags.push(eg.readBoolean());
|
12240
|
+
}
|
12241
|
+
if (max_sub_layers_minus1 > 0) {
|
12242
|
+
for (let i = max_sub_layers_minus1; i < 8; i++) {
|
12243
|
+
eg.readBits(2);
|
12244
|
+
}
|
12245
|
+
}
|
12246
|
+
for (let i = 0; i < max_sub_layers_minus1; i++) {
|
12247
|
+
if (sub_layer_profile_present_flags[i]) {
|
12248
|
+
eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
|
12249
|
+
eg.readUByte();
|
12250
|
+
eg.readUByte();
|
12251
|
+
eg.readUByte();
|
12252
|
+
eg.readUByte(); // sub_layer_profile_compatibility_flag
|
12253
|
+
eg.readUByte();
|
12254
|
+
eg.readUByte();
|
12255
|
+
eg.readUByte();
|
12256
|
+
eg.readUByte();
|
12257
|
+
eg.readUByte();
|
12258
|
+
eg.readUByte();
|
12259
|
+
}
|
12260
|
+
if (sub_layer_level_present_flags[i]) {
|
12261
|
+
eg.readUByte();
|
12262
|
+
}
|
12263
|
+
}
|
12264
|
+
eg.readUEG(); // seq_parameter_set_id
|
12265
|
+
const chroma_format_idc = eg.readUEG();
|
12266
|
+
if (chroma_format_idc == 3) {
|
12267
|
+
eg.skipBits(1); //separate_colour_plane_flag
|
12268
|
+
}
|
12269
|
+
const pic_width_in_luma_samples = eg.readUEG();
|
12270
|
+
const pic_height_in_luma_samples = eg.readUEG();
|
12271
|
+
const conformance_window_flag = eg.readBoolean();
|
12272
|
+
let pic_left_offset = 0,
|
12273
|
+
pic_right_offset = 0,
|
12274
|
+
pic_top_offset = 0,
|
12275
|
+
pic_bottom_offset = 0;
|
12276
|
+
if (conformance_window_flag) {
|
12277
|
+
pic_left_offset += eg.readUEG();
|
12278
|
+
pic_right_offset += eg.readUEG();
|
12279
|
+
pic_top_offset += eg.readUEG();
|
12280
|
+
pic_bottom_offset += eg.readUEG();
|
12281
|
+
}
|
12282
|
+
const bit_depth_luma_minus8 = eg.readUEG();
|
12283
|
+
const bit_depth_chroma_minus8 = eg.readUEG();
|
12284
|
+
const log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();
|
12285
|
+
const sub_layer_ordering_info_present_flag = eg.readBoolean();
|
12286
|
+
for (let i = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1; i <= max_sub_layers_minus1; i++) {
|
12287
|
+
eg.skipUEG(); // max_dec_pic_buffering_minus1[i]
|
12288
|
+
eg.skipUEG(); // max_num_reorder_pics[i]
|
12289
|
+
eg.skipUEG(); // max_latency_increase_plus1[i]
|
12290
|
+
}
|
12291
|
+
eg.skipUEG(); // log2_min_luma_coding_block_size_minus3
|
12292
|
+
eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size
|
12293
|
+
eg.skipUEG(); // log2_min_transform_block_size_minus2
|
12294
|
+
eg.skipUEG(); // log2_diff_max_min_transform_block_size
|
12295
|
+
eg.skipUEG(); // max_transform_hierarchy_depth_inter
|
12296
|
+
eg.skipUEG(); // max_transform_hierarchy_depth_intra
|
12297
|
+
const scaling_list_enabled_flag = eg.readBoolean();
|
12298
|
+
if (scaling_list_enabled_flag) {
|
12299
|
+
const sps_scaling_list_data_present_flag = eg.readBoolean();
|
12300
|
+
if (sps_scaling_list_data_present_flag) {
|
12301
|
+
for (let sizeId = 0; sizeId < 4; sizeId++) {
|
12302
|
+
for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
|
12303
|
+
const scaling_list_pred_mode_flag = eg.readBoolean();
|
12304
|
+
if (!scaling_list_pred_mode_flag) {
|
12305
|
+
eg.readUEG(); // scaling_list_pred_matrix_id_delta
|
12306
|
+
} else {
|
12307
|
+
const coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
|
12308
|
+
if (sizeId > 1) {
|
12309
|
+
eg.readEG();
|
12310
|
+
}
|
12311
|
+
for (let i = 0; i < coefNum; i++) {
|
12312
|
+
eg.readEG();
|
12313
|
+
}
|
11954
12314
|
}
|
11955
12315
|
}
|
11956
12316
|
}
|
11957
|
-
// check if we can read unit type
|
11958
|
-
if (i < len) {
|
11959
|
-
unitType = array[i] & 0x1f;
|
11960
|
-
// logger.log('find NALU @ offset:' + i + ',type:' + unitType);
|
11961
|
-
lastUnitStart = i;
|
11962
|
-
lastUnitType = unitType;
|
11963
|
-
state = 0;
|
11964
|
-
} else {
|
11965
|
-
// not enough byte to read unit type. let's read it on next PES parsing
|
11966
|
-
state = -1;
|
11967
|
-
}
|
11968
|
-
} else {
|
11969
|
-
state = 0;
|
11970
12317
|
}
|
11971
12318
|
}
|
11972
|
-
|
11973
|
-
|
11974
|
-
|
11975
|
-
|
11976
|
-
|
11977
|
-
|
11978
|
-
|
11979
|
-
|
11980
|
-
}
|
11981
|
-
|
11982
|
-
|
11983
|
-
|
11984
|
-
|
11985
|
-
if (
|
11986
|
-
|
12319
|
+
eg.readBoolean(); // amp_enabled_flag
|
12320
|
+
eg.readBoolean(); // sample_adaptive_offset_enabled_flag
|
12321
|
+
const pcm_enabled_flag = eg.readBoolean();
|
12322
|
+
if (pcm_enabled_flag) {
|
12323
|
+
eg.readUByte();
|
12324
|
+
eg.skipUEG();
|
12325
|
+
eg.skipUEG();
|
12326
|
+
eg.readBoolean();
|
12327
|
+
}
|
12328
|
+
const num_short_term_ref_pic_sets = eg.readUEG();
|
12329
|
+
let num_delta_pocs = 0;
|
12330
|
+
for (let i = 0; i < num_short_term_ref_pic_sets; i++) {
|
12331
|
+
let inter_ref_pic_set_prediction_flag = false;
|
12332
|
+
if (i !== 0) {
|
12333
|
+
inter_ref_pic_set_prediction_flag = eg.readBoolean();
|
12334
|
+
}
|
12335
|
+
if (inter_ref_pic_set_prediction_flag) {
|
12336
|
+
if (i === num_short_term_ref_pic_sets) {
|
12337
|
+
eg.readUEG();
|
12338
|
+
}
|
12339
|
+
eg.readBoolean();
|
12340
|
+
eg.readUEG();
|
12341
|
+
let next_num_delta_pocs = 0;
|
12342
|
+
for (let j = 0; j <= num_delta_pocs; j++) {
|
12343
|
+
const used_by_curr_pic_flag = eg.readBoolean();
|
12344
|
+
let use_delta_flag = false;
|
12345
|
+
if (!used_by_curr_pic_flag) {
|
12346
|
+
use_delta_flag = eg.readBoolean();
|
12347
|
+
}
|
12348
|
+
if (used_by_curr_pic_flag || use_delta_flag) {
|
12349
|
+
next_num_delta_pocs++;
|
12350
|
+
}
|
12351
|
+
}
|
12352
|
+
num_delta_pocs = next_num_delta_pocs;
|
12353
|
+
} else {
|
12354
|
+
const num_negative_pics = eg.readUEG();
|
12355
|
+
const num_positive_pics = eg.readUEG();
|
12356
|
+
num_delta_pocs = num_negative_pics + num_positive_pics;
|
12357
|
+
for (let j = 0; j < num_negative_pics; j++) {
|
12358
|
+
eg.readUEG();
|
12359
|
+
eg.readBoolean();
|
12360
|
+
}
|
12361
|
+
for (let j = 0; j < num_positive_pics; j++) {
|
12362
|
+
eg.readUEG();
|
12363
|
+
eg.readBoolean();
|
12364
|
+
}
|
12365
|
+
}
|
12366
|
+
}
|
12367
|
+
const long_term_ref_pics_present_flag = eg.readBoolean();
|
12368
|
+
if (long_term_ref_pics_present_flag) {
|
12369
|
+
const num_long_term_ref_pics_sps = eg.readUEG();
|
12370
|
+
for (let i = 0; i < num_long_term_ref_pics_sps; i++) {
|
12371
|
+
for (let j = 0; j < log2_max_pic_order_cnt_lsb_minus4 + 4; j++) {
|
12372
|
+
eg.readBits(1);
|
12373
|
+
}
|
12374
|
+
eg.readBits(1);
|
12375
|
+
}
|
12376
|
+
}
|
12377
|
+
let min_spatial_segmentation_idc = 0;
|
12378
|
+
let sar_width = 1,
|
12379
|
+
sar_height = 1;
|
12380
|
+
let fps_fixed = true,
|
12381
|
+
fps_den = 1,
|
12382
|
+
fps_num = 0;
|
12383
|
+
eg.readBoolean(); // sps_temporal_mvp_enabled_flag
|
12384
|
+
eg.readBoolean(); // strong_intra_smoothing_enabled_flag
|
12385
|
+
let default_display_window_flag = false;
|
12386
|
+
const vui_parameters_present_flag = eg.readBoolean();
|
12387
|
+
if (vui_parameters_present_flag) {
|
12388
|
+
const aspect_ratio_info_present_flag = eg.readBoolean();
|
12389
|
+
if (aspect_ratio_info_present_flag) {
|
12390
|
+
const aspect_ratio_idc = eg.readUByte();
|
12391
|
+
const sar_width_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
|
12392
|
+
const sar_height_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
|
12393
|
+
if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
|
12394
|
+
sar_width = sar_width_table[aspect_ratio_idc - 1];
|
12395
|
+
sar_height = sar_height_table[aspect_ratio_idc - 1];
|
12396
|
+
} else if (aspect_ratio_idc === 255) {
|
12397
|
+
sar_width = eg.readBits(16);
|
12398
|
+
sar_height = eg.readBits(16);
|
12399
|
+
}
|
12400
|
+
}
|
12401
|
+
const overscan_info_present_flag = eg.readBoolean();
|
12402
|
+
if (overscan_info_present_flag) {
|
12403
|
+
eg.readBoolean();
|
12404
|
+
}
|
12405
|
+
const video_signal_type_present_flag = eg.readBoolean();
|
12406
|
+
if (video_signal_type_present_flag) {
|
12407
|
+
eg.readBits(3);
|
12408
|
+
eg.readBoolean();
|
12409
|
+
const colour_description_present_flag = eg.readBoolean();
|
12410
|
+
if (colour_description_present_flag) {
|
12411
|
+
eg.readUByte();
|
12412
|
+
eg.readUByte();
|
12413
|
+
eg.readUByte();
|
12414
|
+
}
|
12415
|
+
}
|
12416
|
+
const chroma_loc_info_present_flag = eg.readBoolean();
|
12417
|
+
if (chroma_loc_info_present_flag) {
|
12418
|
+
eg.readUEG();
|
12419
|
+
eg.readUEG();
|
12420
|
+
}
|
12421
|
+
eg.readBoolean(); // neutral_chroma_indication_flag
|
12422
|
+
eg.readBoolean(); // field_seq_flag
|
12423
|
+
eg.readBoolean(); // frame_field_info_present_flag
|
12424
|
+
default_display_window_flag = eg.readBoolean();
|
12425
|
+
if (default_display_window_flag) {
|
12426
|
+
pic_left_offset += eg.readUEG();
|
12427
|
+
pic_right_offset += eg.readUEG();
|
12428
|
+
pic_top_offset += eg.readUEG();
|
12429
|
+
pic_bottom_offset += eg.readUEG();
|
12430
|
+
}
|
12431
|
+
const vui_timing_info_present_flag = eg.readBoolean();
|
12432
|
+
if (vui_timing_info_present_flag) {
|
12433
|
+
fps_den = eg.readBits(32);
|
12434
|
+
fps_num = eg.readBits(32);
|
12435
|
+
const vui_poc_proportional_to_timing_flag = eg.readBoolean();
|
12436
|
+
if (vui_poc_proportional_to_timing_flag) {
|
12437
|
+
eg.readUEG();
|
12438
|
+
}
|
12439
|
+
const vui_hrd_parameters_present_flag = eg.readBoolean();
|
12440
|
+
if (vui_hrd_parameters_present_flag) {
|
12441
|
+
//const commonInfPresentFlag = true;
|
12442
|
+
//if (commonInfPresentFlag) {
|
12443
|
+
const nal_hrd_parameters_present_flag = eg.readBoolean();
|
12444
|
+
const vcl_hrd_parameters_present_flag = eg.readBoolean();
|
12445
|
+
let sub_pic_hrd_params_present_flag = false;
|
12446
|
+
if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
|
12447
|
+
sub_pic_hrd_params_present_flag = eg.readBoolean();
|
12448
|
+
if (sub_pic_hrd_params_present_flag) {
|
12449
|
+
eg.readUByte();
|
12450
|
+
eg.readBits(5);
|
12451
|
+
eg.readBoolean();
|
12452
|
+
eg.readBits(5);
|
12453
|
+
}
|
12454
|
+
eg.readBits(4); // bit_rate_scale
|
12455
|
+
eg.readBits(4); // cpb_size_scale
|
12456
|
+
if (sub_pic_hrd_params_present_flag) {
|
12457
|
+
eg.readBits(4);
|
12458
|
+
}
|
12459
|
+
eg.readBits(5);
|
12460
|
+
eg.readBits(5);
|
12461
|
+
eg.readBits(5);
|
12462
|
+
}
|
12463
|
+
//}
|
12464
|
+
for (let i = 0; i <= max_sub_layers_minus1; i++) {
|
12465
|
+
fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag
|
12466
|
+
const fixed_pic_rate_within_cvs_flag = fps_fixed || eg.readBoolean();
|
12467
|
+
let low_delay_hrd_flag = false;
|
12468
|
+
if (fixed_pic_rate_within_cvs_flag) {
|
12469
|
+
eg.readEG();
|
12470
|
+
} else {
|
12471
|
+
low_delay_hrd_flag = eg.readBoolean();
|
12472
|
+
}
|
12473
|
+
const cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;
|
12474
|
+
if (nal_hrd_parameters_present_flag) {
|
12475
|
+
for (let j = 0; j < cpb_cnt; j++) {
|
12476
|
+
eg.readUEG();
|
12477
|
+
eg.readUEG();
|
12478
|
+
if (sub_pic_hrd_params_present_flag) {
|
12479
|
+
eg.readUEG();
|
12480
|
+
eg.readUEG();
|
12481
|
+
}
|
12482
|
+
eg.skipBits(1);
|
12483
|
+
}
|
12484
|
+
}
|
12485
|
+
if (vcl_hrd_parameters_present_flag) {
|
12486
|
+
for (let j = 0; j < cpb_cnt; j++) {
|
12487
|
+
eg.readUEG();
|
12488
|
+
eg.readUEG();
|
12489
|
+
if (sub_pic_hrd_params_present_flag) {
|
12490
|
+
eg.readUEG();
|
12491
|
+
eg.readUEG();
|
12492
|
+
}
|
12493
|
+
eg.skipBits(1);
|
12494
|
+
}
|
12495
|
+
}
|
12496
|
+
}
|
12497
|
+
}
|
11987
12498
|
}
|
12499
|
+
const bitstream_restriction_flag = eg.readBoolean();
|
12500
|
+
if (bitstream_restriction_flag) {
|
12501
|
+
eg.readBoolean(); // tiles_fixed_structure_flag
|
12502
|
+
eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag
|
12503
|
+
eg.readBoolean(); // restricted_ref_pic_lists_flag
|
12504
|
+
min_spatial_segmentation_idc = eg.readUEG();
|
12505
|
+
}
|
12506
|
+
}
|
12507
|
+
let width = pic_width_in_luma_samples,
|
12508
|
+
height = pic_height_in_luma_samples;
|
12509
|
+
if (conformance_window_flag || default_display_window_flag) {
|
12510
|
+
let chroma_scale_w = 1,
|
12511
|
+
chroma_scale_h = 1;
|
12512
|
+
if (chroma_format_idc === 1) {
|
12513
|
+
// YUV 420
|
12514
|
+
chroma_scale_w = chroma_scale_h = 2;
|
12515
|
+
} else if (chroma_format_idc == 2) {
|
12516
|
+
// YUV 422
|
12517
|
+
chroma_scale_w = 2;
|
12518
|
+
}
|
12519
|
+
width = pic_width_in_luma_samples - chroma_scale_w * pic_right_offset - chroma_scale_w * pic_left_offset;
|
12520
|
+
height = pic_height_in_luma_samples - chroma_scale_h * pic_bottom_offset - chroma_scale_h * pic_top_offset;
|
12521
|
+
}
|
12522
|
+
const profile_space_string = general_profile_space ? ['A', 'B', 'C'][general_profile_space] : '';
|
12523
|
+
const profile_compatibility_buf = general_profile_compatibility_flags_1 << 24 | general_profile_compatibility_flags_2 << 16 | general_profile_compatibility_flags_3 << 8 | general_profile_compatibility_flags_4;
|
12524
|
+
let profile_compatibility_rev = 0;
|
12525
|
+
for (let i = 0; i < 32; i++) {
|
12526
|
+
profile_compatibility_rev = (profile_compatibility_rev | (profile_compatibility_buf >> i & 1) << 31 - i) >>> 0; // reverse bit position (and cast as UInt32)
|
12527
|
+
}
|
12528
|
+
let profile_compatibility_flags_string = profile_compatibility_rev.toString(16);
|
12529
|
+
if (general_profile_idc === 1 && profile_compatibility_flags_string === '2') {
|
12530
|
+
profile_compatibility_flags_string = '6';
|
12531
|
+
}
|
12532
|
+
const tier_flag_string = general_tier_flag ? 'H' : 'L';
|
12533
|
+
return {
|
12534
|
+
codecString: `hvc1.${profile_space_string}${general_profile_idc}.${profile_compatibility_flags_string}.${tier_flag_string}${general_level_idc}.B0`,
|
12535
|
+
params: {
|
12536
|
+
general_tier_flag,
|
12537
|
+
general_profile_idc,
|
12538
|
+
general_profile_space,
|
12539
|
+
general_profile_compatibility_flags: [general_profile_compatibility_flags_1, general_profile_compatibility_flags_2, general_profile_compatibility_flags_3, general_profile_compatibility_flags_4],
|
12540
|
+
general_constraint_indicator_flags: [general_constraint_indicator_flags_1, general_constraint_indicator_flags_2, general_constraint_indicator_flags_3, general_constraint_indicator_flags_4, general_constraint_indicator_flags_5, general_constraint_indicator_flags_6],
|
12541
|
+
general_level_idc,
|
12542
|
+
bit_depth: bit_depth_luma_minus8 + 8,
|
12543
|
+
bit_depth_luma_minus8,
|
12544
|
+
bit_depth_chroma_minus8,
|
12545
|
+
min_spatial_segmentation_idc,
|
12546
|
+
chroma_format_idc: chroma_format_idc,
|
12547
|
+
frame_rate: {
|
12548
|
+
fixed: fps_fixed,
|
12549
|
+
fps: fps_num / fps_den
|
12550
|
+
}
|
12551
|
+
},
|
12552
|
+
width,
|
12553
|
+
height,
|
12554
|
+
pixelRatio: [sar_width, sar_height]
|
12555
|
+
};
|
12556
|
+
}
|
12557
|
+
readPPS(pps) {
|
12558
|
+
const eg = new ExpGolomb(this.ebsp2rbsp(pps));
|
12559
|
+
eg.readUByte();
|
12560
|
+
eg.readUByte();
|
12561
|
+
eg.skipUEG(); // pic_parameter_set_id
|
12562
|
+
eg.skipUEG(); // seq_parameter_set_id
|
12563
|
+
eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag
|
12564
|
+
eg.skipBits(3); // num_extra_slice_header_bits
|
12565
|
+
eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag
|
12566
|
+
eg.skipUEG();
|
12567
|
+
eg.skipUEG();
|
12568
|
+
eg.skipEG(); // init_qp_minus26
|
12569
|
+
eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag
|
12570
|
+
const cu_qp_delta_enabled_flag = eg.readBoolean();
|
12571
|
+
if (cu_qp_delta_enabled_flag) {
|
12572
|
+
eg.skipUEG();
|
12573
|
+
}
|
12574
|
+
eg.skipEG(); // cb_qp_offset
|
12575
|
+
eg.skipEG(); // cr_qp_offset
|
12576
|
+
eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag
|
12577
|
+
const tiles_enabled_flag = eg.readBoolean();
|
12578
|
+
const entropy_coding_sync_enabled_flag = eg.readBoolean();
|
12579
|
+
let parallelismType = 1; // slice-based parallel decoding
|
12580
|
+
if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {
|
12581
|
+
parallelismType = 0; // mixed-type parallel decoding
|
12582
|
+
} else if (entropy_coding_sync_enabled_flag) {
|
12583
|
+
parallelismType = 3; // wavefront-based parallel decoding
|
12584
|
+
} else if (tiles_enabled_flag) {
|
12585
|
+
parallelismType = 2; // tile-based parallel decoding
|
11988
12586
|
}
|
11989
|
-
|
11990
|
-
|
12587
|
+
return {
|
12588
|
+
parallelismType
|
12589
|
+
};
|
12590
|
+
}
|
12591
|
+
matchSPS(sps1, sps2) {
|
12592
|
+
// compare without headers and VPS related params
|
12593
|
+
return String.fromCharCode.apply(null, sps1).substr(3) === String.fromCharCode.apply(null, sps2).substr(3);
|
11991
12594
|
}
|
11992
12595
|
}
|
11993
12596
|
|
@@ -12119,7 +12722,7 @@ class TSDemuxer {
|
|
12119
12722
|
this.observer = observer;
|
12120
12723
|
this.config = config;
|
12121
12724
|
this.typeSupported = typeSupported;
|
12122
|
-
this.videoParser =
|
12725
|
+
this.videoParser = null;
|
12123
12726
|
}
|
12124
12727
|
static probe(data) {
|
12125
12728
|
const syncOffset = TSDemuxer.syncOffset(data);
|
@@ -12284,7 +12887,19 @@ class TSDemuxer {
|
|
12284
12887
|
case videoPid:
|
12285
12888
|
if (stt) {
|
12286
12889
|
if (videoData && (pes = parsePES(videoData))) {
|
12287
|
-
this.videoParser
|
12890
|
+
if (this.videoParser === null) {
|
12891
|
+
switch (videoTrack.segmentCodec) {
|
12892
|
+
case 'avc':
|
12893
|
+
this.videoParser = new AvcVideoParser();
|
12894
|
+
break;
|
12895
|
+
case 'hevc':
|
12896
|
+
this.videoParser = new HevcVideoParser();
|
12897
|
+
break;
|
12898
|
+
}
|
12899
|
+
}
|
12900
|
+
if (this.videoParser !== null) {
|
12901
|
+
this.videoParser.parsePES(videoTrack, textTrack, pes, false, this._duration);
|
12902
|
+
}
|
12288
12903
|
}
|
12289
12904
|
videoData = {
|
12290
12905
|
data: [],
|
@@ -12451,8 +13066,20 @@ class TSDemuxer {
|
|
12451
13066
|
// try to parse last PES packets
|
12452
13067
|
let pes;
|
12453
13068
|
if (videoData && (pes = parsePES(videoData))) {
|
12454
|
-
this.videoParser
|
12455
|
-
|
13069
|
+
if (this.videoParser === null) {
|
13070
|
+
switch (videoTrack.segmentCodec) {
|
13071
|
+
case 'avc':
|
13072
|
+
this.videoParser = new AvcVideoParser();
|
13073
|
+
break;
|
13074
|
+
case 'hevc':
|
13075
|
+
this.videoParser = new HevcVideoParser();
|
13076
|
+
break;
|
13077
|
+
}
|
13078
|
+
}
|
13079
|
+
if (this.videoParser !== null) {
|
13080
|
+
this.videoParser.parsePES(videoTrack, textTrack, pes, true, this._duration);
|
13081
|
+
videoTrack.pesData = null;
|
13082
|
+
}
|
12456
13083
|
} else {
|
12457
13084
|
// either avcData null or PES truncated, keep it for next frag parsing
|
12458
13085
|
videoTrack.pesData = videoData;
|
@@ -12785,7 +13412,12 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
12785
13412
|
logger.warn('Unsupported EC-3 in M2TS found');
|
12786
13413
|
break;
|
12787
13414
|
case 0x24:
|
12788
|
-
|
13415
|
+
// ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
|
13416
|
+
if (result.videoPid === -1) {
|
13417
|
+
result.videoPid = pid;
|
13418
|
+
result.segmentVideoCodec = 'hevc';
|
13419
|
+
logger.log('HEVC in M2TS found');
|
13420
|
+
}
|
12789
13421
|
break;
|
12790
13422
|
}
|
12791
13423
|
// move to the next table entry
|
@@ -13008,6 +13640,8 @@ class MP4 {
|
|
13008
13640
|
avc1: [],
|
13009
13641
|
// codingname
|
13010
13642
|
avcC: [],
|
13643
|
+
hvc1: [],
|
13644
|
+
hvcC: [],
|
13011
13645
|
btrt: [],
|
13012
13646
|
dinf: [],
|
13013
13647
|
dref: [],
|
@@ -13432,8 +14066,10 @@ class MP4 {
|
|
13432
14066
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));
|
13433
14067
|
}
|
13434
14068
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
|
13435
|
-
} else {
|
14069
|
+
} else if (track.segmentCodec === 'avc') {
|
13436
14070
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
|
14071
|
+
} else {
|
14072
|
+
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.hvc1(track));
|
13437
14073
|
}
|
13438
14074
|
}
|
13439
14075
|
static tkhd(track) {
|
@@ -13571,6 +14207,84 @@ class MP4 {
|
|
13571
14207
|
const result = appendUint8Array(MP4.FTYP, movie);
|
13572
14208
|
return result;
|
13573
14209
|
}
|
14210
|
+
static hvc1(track) {
|
14211
|
+
const ps = track.params;
|
14212
|
+
const units = [track.vps, track.sps, track.pps];
|
14213
|
+
const NALuLengthSize = 4;
|
14214
|
+
const config = new Uint8Array([0x01, ps.general_profile_space << 6 | (ps.general_tier_flag ? 32 : 0) | ps.general_profile_idc, ps.general_profile_compatibility_flags[0], ps.general_profile_compatibility_flags[1], ps.general_profile_compatibility_flags[2], ps.general_profile_compatibility_flags[3], ps.general_constraint_indicator_flags[0], ps.general_constraint_indicator_flags[1], ps.general_constraint_indicator_flags[2], ps.general_constraint_indicator_flags[3], ps.general_constraint_indicator_flags[4], ps.general_constraint_indicator_flags[5], ps.general_level_idc, 240 | ps.min_spatial_segmentation_idc >> 8, 255 & ps.min_spatial_segmentation_idc, 252 | ps.parallelismType, 252 | ps.chroma_format_idc, 248 | ps.bit_depth_luma_minus8, 248 | ps.bit_depth_chroma_minus8, 0x00, parseInt(ps.frame_rate.fps), NALuLengthSize - 1 | ps.temporal_id_nested << 2 | ps.num_temporal_layers << 3 | (ps.frame_rate.fixed ? 64 : 0), units.length]);
|
14215
|
+
|
14216
|
+
// compute hvcC size in bytes
|
14217
|
+
let length = config.length;
|
14218
|
+
for (let i = 0; i < units.length; i += 1) {
|
14219
|
+
length += 3;
|
14220
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
14221
|
+
length += 2 + units[i][j].length;
|
14222
|
+
}
|
14223
|
+
}
|
14224
|
+
const hvcC = new Uint8Array(length);
|
14225
|
+
hvcC.set(config, 0);
|
14226
|
+
length = config.length;
|
14227
|
+
// append parameter set units: one vps, one or more sps and pps
|
14228
|
+
const iMax = units.length - 1;
|
14229
|
+
for (let i = 0; i < units.length; i += 1) {
|
14230
|
+
hvcC.set(new Uint8Array([32 + i | (i === iMax ? 128 : 0), 0x00, units[i].length]), length);
|
14231
|
+
length += 3;
|
14232
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
14233
|
+
hvcC.set(new Uint8Array([units[i][j].length >> 8, units[i][j].length & 255]), length);
|
14234
|
+
length += 2;
|
14235
|
+
hvcC.set(units[i][j], length);
|
14236
|
+
length += units[i][j].length;
|
14237
|
+
}
|
14238
|
+
}
|
14239
|
+
const hvcc = MP4.box(MP4.types.hvcC, hvcC);
|
14240
|
+
const width = track.width;
|
14241
|
+
const height = track.height;
|
14242
|
+
const hSpacing = track.pixelRatio[0];
|
14243
|
+
const vSpacing = track.pixelRatio[1];
|
14244
|
+
return MP4.box(MP4.types.hvc1, new Uint8Array([0x00, 0x00, 0x00,
|
14245
|
+
// reserved
|
14246
|
+
0x00, 0x00, 0x00,
|
14247
|
+
// reserved
|
14248
|
+
0x00, 0x01,
|
14249
|
+
// data_reference_index
|
14250
|
+
0x00, 0x00,
|
14251
|
+
// pre_defined
|
14252
|
+
0x00, 0x00,
|
14253
|
+
// reserved
|
14254
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
14255
|
+
// pre_defined
|
14256
|
+
width >> 8 & 0xff, width & 0xff,
|
14257
|
+
// width
|
14258
|
+
height >> 8 & 0xff, height & 0xff,
|
14259
|
+
// height
|
14260
|
+
0x00, 0x48, 0x00, 0x00,
|
14261
|
+
// horizresolution
|
14262
|
+
0x00, 0x48, 0x00, 0x00,
|
14263
|
+
// vertresolution
|
14264
|
+
0x00, 0x00, 0x00, 0x00,
|
14265
|
+
// reserved
|
14266
|
+
0x00, 0x01,
|
14267
|
+
// frame_count
|
14268
|
+
0x12, 0x64, 0x61, 0x69, 0x6c,
|
14269
|
+
// dailymotion/hls.js
|
14270
|
+
0x79, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x6c, 0x73, 0x2e, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
14271
|
+
// compressorname
|
14272
|
+
0x00, 0x18,
|
14273
|
+
// depth = 24
|
14274
|
+
0x11, 0x11]),
|
14275
|
+
// pre_defined = -1
|
14276
|
+
hvcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80,
|
14277
|
+
// bufferSizeDB
|
14278
|
+
0x00, 0x2d, 0xc6, 0xc0,
|
14279
|
+
// maxBitrate
|
14280
|
+
0x00, 0x2d, 0xc6, 0xc0])),
|
14281
|
+
// avgBitrate
|
14282
|
+
MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24,
|
14283
|
+
// hSpacing
|
14284
|
+
hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24,
|
14285
|
+
// vSpacing
|
14286
|
+
vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff])));
|
14287
|
+
}
|
13574
14288
|
}
|
13575
14289
|
MP4.types = void 0;
|
13576
14290
|
MP4.HDLR_TYPES = void 0;
|
@@ -13952,9 +14666,9 @@ class MP4Remuxer {
|
|
13952
14666
|
const foundOverlap = delta < -1;
|
13953
14667
|
if (foundHole || foundOverlap) {
|
13954
14668
|
if (foundHole) {
|
13955
|
-
logger.warn(
|
14669
|
+
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
|
13956
14670
|
} else {
|
13957
|
-
logger.warn(
|
14671
|
+
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
|
13958
14672
|
}
|
13959
14673
|
if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
|
13960
14674
|
firstDTS = nextAvcDts;
|
@@ -14128,7 +14842,7 @@ class MP4Remuxer {
|
|
14128
14842
|
}
|
14129
14843
|
}
|
14130
14844
|
}
|
14131
|
-
// next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
14845
|
+
// next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
14132
14846
|
mp4SampleDuration = stretchedLastFrame || !mp4SampleDuration ? averageSampleDuration : mp4SampleDuration;
|
14133
14847
|
this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;
|
14134
14848
|
this.videoSampleDuration = mp4SampleDuration;
|
@@ -15962,12 +16676,13 @@ class AudioStreamController extends BaseStreamController {
|
|
15962
16676
|
} = this;
|
15963
16677
|
const config = hls.config;
|
15964
16678
|
|
15965
|
-
// 1. if
|
16679
|
+
// 1. if buffering is suspended
|
16680
|
+
// 2. if video not attached AND
|
15966
16681
|
// start fragment already requested OR start frag prefetch not enabled
|
15967
|
-
//
|
16682
|
+
// 3. if tracks or track not loaded and selected
|
15968
16683
|
// then exit loop
|
15969
16684
|
// => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
|
15970
|
-
if (!media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
|
16685
|
+
if (!this.buffering || !media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
|
15971
16686
|
return;
|
15972
16687
|
}
|
15973
16688
|
const levelInfo = levels[trackId];
|
@@ -18006,6 +18721,7 @@ class BufferController extends Logger {
|
|
18006
18721
|
this.resetBuffer(type);
|
18007
18722
|
});
|
18008
18723
|
this._initSourceBuffer();
|
18724
|
+
this.hls.resumeBuffering();
|
18009
18725
|
}
|
18010
18726
|
resetBuffer(type) {
|
18011
18727
|
const sb = this.sourceBuffer[type];
|
@@ -26844,7 +27560,7 @@ class StreamController extends BaseStreamController {
|
|
26844
27560
|
if (this.altAudio && this.audioOnly) {
|
26845
27561
|
return;
|
26846
27562
|
}
|
26847
|
-
if (!(levels != null && levels[level])) {
|
27563
|
+
if (!this.buffering || !(levels != null && levels[level])) {
|
26848
27564
|
return;
|
26849
27565
|
}
|
26850
27566
|
const levelInfo = levels[level];
|
@@ -27804,7 +28520,7 @@ class Hls {
|
|
27804
28520
|
* Get the video-dev/hls.js package version.
|
27805
28521
|
*/
|
27806
28522
|
static get version() {
|
27807
|
-
return "1.5.2-0.canary.
|
28523
|
+
return "1.5.2-0.canary.9971";
|
27808
28524
|
}
|
27809
28525
|
|
27810
28526
|
/**
|
@@ -27873,7 +28589,6 @@ class Hls {
|
|
27873
28589
|
this.logger = void 0;
|
27874
28590
|
this.coreComponents = void 0;
|
27875
28591
|
this.networkControllers = void 0;
|
27876
|
-
this.started = false;
|
27877
28592
|
this._emitter = new EventEmitter();
|
27878
28593
|
this._autoLevelCapping = -1;
|
27879
28594
|
this._maxHdcpLevel = null;
|
@@ -28088,7 +28803,6 @@ class Hls {
|
|
28088
28803
|
*/
|
28089
28804
|
startLoad(startPosition = -1) {
|
28090
28805
|
this.logger.log(`startLoad(${startPosition})`);
|
28091
|
-
this.started = true;
|
28092
28806
|
this.networkControllers.forEach(controller => {
|
28093
28807
|
controller.startLoad(startPosition);
|
28094
28808
|
});
|
@@ -28099,33 +28813,30 @@ class Hls {
|
|
28099
28813
|
*/
|
28100
28814
|
stopLoad() {
|
28101
28815
|
this.logger.log('stopLoad');
|
28102
|
-
this.started = false;
|
28103
28816
|
this.networkControllers.forEach(controller => {
|
28104
28817
|
controller.stopLoad();
|
28105
28818
|
});
|
28106
28819
|
}
|
28107
28820
|
|
28108
28821
|
/**
|
28109
|
-
* Resumes stream controller segment loading
|
28822
|
+
* Resumes stream controller segment loading after `pauseBuffering` has been called.
|
28110
28823
|
*/
|
28111
28824
|
resumeBuffering() {
|
28112
|
-
|
28113
|
-
|
28114
|
-
|
28115
|
-
|
28116
|
-
|
28117
|
-
});
|
28118
|
-
}
|
28825
|
+
this.networkControllers.forEach(controller => {
|
28826
|
+
if (controller.resumeBuffering) {
|
28827
|
+
controller.resumeBuffering();
|
28828
|
+
}
|
28829
|
+
});
|
28119
28830
|
}
|
28120
28831
|
|
28121
28832
|
/**
|
28122
|
-
*
|
28833
|
+
* Prevents stream controller from loading new segments until `resumeBuffering` is called.
|
28123
28834
|
* This allows for media buffering to be paused without interupting playlist loading.
|
28124
28835
|
*/
|
28125
28836
|
pauseBuffering() {
|
28126
28837
|
this.networkControllers.forEach(controller => {
|
28127
|
-
if (
|
28128
|
-
controller.
|
28838
|
+
if (controller.pauseBuffering) {
|
28839
|
+
controller.pauseBuffering();
|
28129
28840
|
}
|
28130
28841
|
});
|
28131
28842
|
}
|