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.light.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();
|
@@ -7245,6 +7245,7 @@ class BufferController extends Logger {
|
|
7245
7245
|
this.resetBuffer(type);
|
7246
7246
|
});
|
7247
7247
|
this._initSourceBuffer();
|
7248
|
+
this.hls.resumeBuffering();
|
7248
7249
|
}
|
7249
7250
|
resetBuffer(type) {
|
7250
7251
|
const sb = this.sourceBuffer[type];
|
@@ -11953,6 +11954,7 @@ class BaseStreamController extends TaskLoop {
|
|
11953
11954
|
this.startFragRequested = false;
|
11954
11955
|
this.decrypter = void 0;
|
11955
11956
|
this.initPTS = [];
|
11957
|
+
this.buffering = true;
|
11956
11958
|
this.onMediaSeeking = () => {
|
11957
11959
|
const {
|
11958
11960
|
config,
|
@@ -12058,6 +12060,12 @@ class BaseStreamController extends TaskLoop {
|
|
12058
12060
|
this.clearNextTick();
|
12059
12061
|
this.state = State.STOPPED;
|
12060
12062
|
}
|
12063
|
+
pauseBuffering() {
|
12064
|
+
this.buffering = false;
|
12065
|
+
}
|
12066
|
+
resumeBuffering() {
|
12067
|
+
this.buffering = true;
|
12068
|
+
}
|
12061
12069
|
_streamEnded(bufferInfo, levelDetails) {
|
12062
12070
|
// If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
|
12063
12071
|
// of nothing loading/loaded return false
|
@@ -14066,6 +14074,110 @@ class BaseVideoParser {
|
|
14066
14074
|
logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
|
14067
14075
|
}
|
14068
14076
|
}
|
14077
|
+
parseNALu(track, array) {
|
14078
|
+
const len = array.byteLength;
|
14079
|
+
let state = track.naluState || 0;
|
14080
|
+
const lastState = state;
|
14081
|
+
const units = [];
|
14082
|
+
let i = 0;
|
14083
|
+
let value;
|
14084
|
+
let overflow;
|
14085
|
+
let unitType;
|
14086
|
+
let lastUnitStart = -1;
|
14087
|
+
let lastUnitType = 0;
|
14088
|
+
// logger.log('PES:' + Hex.hexDump(array));
|
14089
|
+
|
14090
|
+
if (state === -1) {
|
14091
|
+
// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
14092
|
+
lastUnitStart = 0;
|
14093
|
+
// NALu type is value read from offset 0
|
14094
|
+
lastUnitType = this.getNALuType(array, 0);
|
14095
|
+
state = 0;
|
14096
|
+
i = 1;
|
14097
|
+
}
|
14098
|
+
while (i < len) {
|
14099
|
+
value = array[i++];
|
14100
|
+
// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
14101
|
+
if (!state) {
|
14102
|
+
state = value ? 0 : 1;
|
14103
|
+
continue;
|
14104
|
+
}
|
14105
|
+
if (state === 1) {
|
14106
|
+
state = value ? 0 : 2;
|
14107
|
+
continue;
|
14108
|
+
}
|
14109
|
+
// here we have state either equal to 2 or 3
|
14110
|
+
if (!value) {
|
14111
|
+
state = 3;
|
14112
|
+
} else if (value === 1) {
|
14113
|
+
overflow = i - state - 1;
|
14114
|
+
if (lastUnitStart >= 0) {
|
14115
|
+
const unit = {
|
14116
|
+
data: array.subarray(lastUnitStart, overflow),
|
14117
|
+
type: lastUnitType
|
14118
|
+
};
|
14119
|
+
// logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
14120
|
+
units.push(unit);
|
14121
|
+
} else {
|
14122
|
+
// lastUnitStart is undefined => this is the first start code found in this PES packet
|
14123
|
+
// first check if start code delimiter is overlapping between 2 PES packets,
|
14124
|
+
// ie it started in last packet (lastState not zero)
|
14125
|
+
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
14126
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
14127
|
+
if (lastUnit) {
|
14128
|
+
if (lastState && i <= 4 - lastState) {
|
14129
|
+
// start delimiter overlapping between PES packets
|
14130
|
+
// strip start delimiter bytes from the end of last NAL unit
|
14131
|
+
// check if lastUnit had a state different from zero
|
14132
|
+
if (lastUnit.state) {
|
14133
|
+
// strip last bytes
|
14134
|
+
lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
|
14135
|
+
}
|
14136
|
+
}
|
14137
|
+
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
14138
|
+
|
14139
|
+
if (overflow > 0) {
|
14140
|
+
// logger.log('first NALU found with overflow:' + overflow);
|
14141
|
+
lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
|
14142
|
+
lastUnit.state = 0;
|
14143
|
+
}
|
14144
|
+
}
|
14145
|
+
}
|
14146
|
+
// check if we can read unit type
|
14147
|
+
if (i < len) {
|
14148
|
+
unitType = this.getNALuType(array, i);
|
14149
|
+
// logger.log('find NALU @ offset:' + i + ',type:' + unitType);
|
14150
|
+
lastUnitStart = i;
|
14151
|
+
lastUnitType = unitType;
|
14152
|
+
state = 0;
|
14153
|
+
} else {
|
14154
|
+
// not enough byte to read unit type. let's read it on next PES parsing
|
14155
|
+
state = -1;
|
14156
|
+
}
|
14157
|
+
} else {
|
14158
|
+
state = 0;
|
14159
|
+
}
|
14160
|
+
}
|
14161
|
+
if (lastUnitStart >= 0 && state >= 0) {
|
14162
|
+
const unit = {
|
14163
|
+
data: array.subarray(lastUnitStart, len),
|
14164
|
+
type: lastUnitType,
|
14165
|
+
state: state
|
14166
|
+
};
|
14167
|
+
units.push(unit);
|
14168
|
+
// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
14169
|
+
}
|
14170
|
+
// no NALu found
|
14171
|
+
if (units.length === 0) {
|
14172
|
+
// append pes.data to previous NAL unit
|
14173
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
14174
|
+
if (lastUnit) {
|
14175
|
+
lastUnit.data = appendUint8Array(lastUnit.data, array);
|
14176
|
+
}
|
14177
|
+
}
|
14178
|
+
track.naluState = state;
|
14179
|
+
return units;
|
14180
|
+
}
|
14069
14181
|
}
|
14070
14182
|
|
14071
14183
|
/**
|
@@ -14208,21 +14320,171 @@ class ExpGolomb {
|
|
14208
14320
|
readUInt() {
|
14209
14321
|
return this.readBits(32);
|
14210
14322
|
}
|
14323
|
+
}
|
14324
|
+
|
14325
|
+
class AvcVideoParser extends BaseVideoParser {
|
14326
|
+
parsePES(track, textTrack, pes, last, duration) {
|
14327
|
+
const units = this.parseNALu(track, pes.data);
|
14328
|
+
let VideoSample = this.VideoSample;
|
14329
|
+
let push;
|
14330
|
+
let spsfound = false;
|
14331
|
+
// free pes.data to save up some memory
|
14332
|
+
pes.data = null;
|
14333
|
+
|
14334
|
+
// if new NAL units found and last sample still there, let's push ...
|
14335
|
+
// this helps parsing streams with missing AUD (only do this if AUD never found)
|
14336
|
+
if (VideoSample && units.length && !track.audFound) {
|
14337
|
+
this.pushAccessUnit(VideoSample, track);
|
14338
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
14339
|
+
}
|
14340
|
+
units.forEach(unit => {
|
14341
|
+
var _VideoSample2;
|
14342
|
+
switch (unit.type) {
|
14343
|
+
// NDR
|
14344
|
+
case 1:
|
14345
|
+
{
|
14346
|
+
let iskey = false;
|
14347
|
+
push = true;
|
14348
|
+
const data = unit.data;
|
14349
|
+
// only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
|
14350
|
+
if (spsfound && data.length > 4) {
|
14351
|
+
// retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
|
14352
|
+
const sliceType = this.readSliceType(data);
|
14353
|
+
// 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
|
14354
|
+
// SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
|
14355
|
+
// An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
|
14356
|
+
// I slice: A slice that is not an SI slice that is decoded using intra prediction only.
|
14357
|
+
// if (sliceType === 2 || sliceType === 7) {
|
14358
|
+
if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
|
14359
|
+
iskey = true;
|
14360
|
+
}
|
14361
|
+
}
|
14362
|
+
if (iskey) {
|
14363
|
+
var _VideoSample;
|
14364
|
+
// if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
|
14365
|
+
if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
|
14366
|
+
this.pushAccessUnit(VideoSample, track);
|
14367
|
+
VideoSample = this.VideoSample = null;
|
14368
|
+
}
|
14369
|
+
}
|
14370
|
+
if (!VideoSample) {
|
14371
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
14372
|
+
}
|
14373
|
+
VideoSample.frame = true;
|
14374
|
+
VideoSample.key = iskey;
|
14375
|
+
break;
|
14376
|
+
// IDR
|
14377
|
+
}
|
14378
|
+
case 5:
|
14379
|
+
push = true;
|
14380
|
+
// handle PES not starting with AUD
|
14381
|
+
// if we have frame data already, that cannot belong to the same frame, so force a push
|
14382
|
+
if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
|
14383
|
+
this.pushAccessUnit(VideoSample, track);
|
14384
|
+
VideoSample = this.VideoSample = null;
|
14385
|
+
}
|
14386
|
+
if (!VideoSample) {
|
14387
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
14388
|
+
}
|
14389
|
+
VideoSample.key = true;
|
14390
|
+
VideoSample.frame = true;
|
14391
|
+
break;
|
14392
|
+
// SEI
|
14393
|
+
case 6:
|
14394
|
+
{
|
14395
|
+
push = true;
|
14396
|
+
parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
|
14397
|
+
break;
|
14398
|
+
// SPS
|
14399
|
+
}
|
14400
|
+
case 7:
|
14401
|
+
{
|
14402
|
+
var _track$pixelRatio, _track$pixelRatio2;
|
14403
|
+
push = true;
|
14404
|
+
spsfound = true;
|
14405
|
+
const sps = unit.data;
|
14406
|
+
const config = this.readSPS(sps);
|
14407
|
+
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]) {
|
14408
|
+
track.width = config.width;
|
14409
|
+
track.height = config.height;
|
14410
|
+
track.pixelRatio = config.pixelRatio;
|
14411
|
+
track.sps = [sps];
|
14412
|
+
track.duration = duration;
|
14413
|
+
const codecarray = sps.subarray(1, 4);
|
14414
|
+
let codecstring = 'avc1.';
|
14415
|
+
for (let i = 0; i < 3; i++) {
|
14416
|
+
let h = codecarray[i].toString(16);
|
14417
|
+
if (h.length < 2) {
|
14418
|
+
h = '0' + h;
|
14419
|
+
}
|
14420
|
+
codecstring += h;
|
14421
|
+
}
|
14422
|
+
track.codec = codecstring;
|
14423
|
+
}
|
14424
|
+
break;
|
14425
|
+
}
|
14426
|
+
// PPS
|
14427
|
+
case 8:
|
14428
|
+
push = true;
|
14429
|
+
track.pps = [unit.data];
|
14430
|
+
break;
|
14431
|
+
// AUD
|
14432
|
+
case 9:
|
14433
|
+
push = true;
|
14434
|
+
track.audFound = true;
|
14435
|
+
if (VideoSample) {
|
14436
|
+
this.pushAccessUnit(VideoSample, track);
|
14437
|
+
}
|
14438
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
14439
|
+
break;
|
14440
|
+
// Filler Data
|
14441
|
+
case 12:
|
14442
|
+
push = true;
|
14443
|
+
break;
|
14444
|
+
default:
|
14445
|
+
push = false;
|
14446
|
+
if (VideoSample) {
|
14447
|
+
VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
|
14448
|
+
}
|
14449
|
+
break;
|
14450
|
+
}
|
14451
|
+
if (VideoSample && push) {
|
14452
|
+
const units = VideoSample.units;
|
14453
|
+
units.push(unit);
|
14454
|
+
}
|
14455
|
+
});
|
14456
|
+
// if last PES packet, push samples
|
14457
|
+
if (last && VideoSample) {
|
14458
|
+
this.pushAccessUnit(VideoSample, track);
|
14459
|
+
this.VideoSample = null;
|
14460
|
+
}
|
14461
|
+
}
|
14462
|
+
getNALuType(data, offset) {
|
14463
|
+
return data[offset] & 0x1f;
|
14464
|
+
}
|
14465
|
+
readSliceType(data) {
|
14466
|
+
const eg = new ExpGolomb(data);
|
14467
|
+
// skip NALu type
|
14468
|
+
eg.readUByte();
|
14469
|
+
// discard first_mb_in_slice
|
14470
|
+
eg.readUEG();
|
14471
|
+
// return slice_type
|
14472
|
+
return eg.readUEG();
|
14473
|
+
}
|
14211
14474
|
|
14212
14475
|
/**
|
14213
|
-
*
|
14214
|
-
* list is optionally transmitted as part of a sequence parameter
|
14476
|
+
* The scaling list is optionally transmitted as part of a sequence parameter
|
14215
14477
|
* set and is not relevant to transmuxing.
|
14216
14478
|
* @param count the number of entries in this scaling list
|
14217
14479
|
* @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
|
14218
14480
|
*/
|
14219
|
-
skipScalingList(count) {
|
14481
|
+
skipScalingList(count, reader) {
|
14220
14482
|
let lastScale = 8;
|
14221
14483
|
let nextScale = 8;
|
14222
14484
|
let deltaScale;
|
14223
14485
|
for (let j = 0; j < count; j++) {
|
14224
14486
|
if (nextScale !== 0) {
|
14225
|
-
deltaScale =
|
14487
|
+
deltaScale = reader.readEG();
|
14226
14488
|
nextScale = (lastScale + deltaScale + 256) % 256;
|
14227
14489
|
}
|
14228
14490
|
lastScale = nextScale === 0 ? lastScale : nextScale;
|
@@ -14237,7 +14499,8 @@ class ExpGolomb {
|
|
14237
14499
|
* sequence parameter set, including the dimensions of the
|
14238
14500
|
* associated video frames.
|
14239
14501
|
*/
|
14240
|
-
readSPS() {
|
14502
|
+
readSPS(sps) {
|
14503
|
+
const eg = new ExpGolomb(sps);
|
14241
14504
|
let frameCropLeftOffset = 0;
|
14242
14505
|
let frameCropRightOffset = 0;
|
14243
14506
|
let frameCropTopOffset = 0;
|
@@ -14245,13 +14508,13 @@ class ExpGolomb {
|
|
14245
14508
|
let numRefFramesInPicOrderCntCycle;
|
14246
14509
|
let scalingListCount;
|
14247
14510
|
let i;
|
14248
|
-
const readUByte =
|
14249
|
-
const readBits =
|
14250
|
-
const readUEG =
|
14251
|
-
const readBoolean =
|
14252
|
-
const skipBits =
|
14253
|
-
const skipEG =
|
14254
|
-
const skipUEG =
|
14511
|
+
const readUByte = eg.readUByte.bind(eg);
|
14512
|
+
const readBits = eg.readBits.bind(eg);
|
14513
|
+
const readUEG = eg.readUEG.bind(eg);
|
14514
|
+
const readBoolean = eg.readBoolean.bind(eg);
|
14515
|
+
const skipBits = eg.skipBits.bind(eg);
|
14516
|
+
const skipEG = eg.skipEG.bind(eg);
|
14517
|
+
const skipUEG = eg.skipUEG.bind(eg);
|
14255
14518
|
const skipScalingList = this.skipScalingList.bind(this);
|
14256
14519
|
readUByte();
|
14257
14520
|
const profileIdc = readUByte(); // profile_idc
|
@@ -14276,9 +14539,9 @@ class ExpGolomb {
|
|
14276
14539
|
if (readBoolean()) {
|
14277
14540
|
// seq_scaling_list_present_flag[ i ]
|
14278
14541
|
if (i < 6) {
|
14279
|
-
skipScalingList(16);
|
14542
|
+
skipScalingList(16, eg);
|
14280
14543
|
} else {
|
14281
|
-
skipScalingList(64);
|
14544
|
+
skipScalingList(64, eg);
|
14282
14545
|
}
|
14283
14546
|
}
|
14284
14547
|
}
|
@@ -14383,19 +14646,15 @@ class ExpGolomb {
|
|
14383
14646
|
pixelRatio: pixelRatio
|
14384
14647
|
};
|
14385
14648
|
}
|
14386
|
-
readSliceType() {
|
14387
|
-
// skip NALu type
|
14388
|
-
this.readUByte();
|
14389
|
-
// discard first_mb_in_slice
|
14390
|
-
this.readUEG();
|
14391
|
-
// return slice_type
|
14392
|
-
return this.readUEG();
|
14393
|
-
}
|
14394
14649
|
}
|
14395
14650
|
|
14396
|
-
class
|
14397
|
-
|
14398
|
-
|
14651
|
+
class HevcVideoParser extends BaseVideoParser {
|
14652
|
+
constructor(...args) {
|
14653
|
+
super(...args);
|
14654
|
+
this.initVPS = null;
|
14655
|
+
}
|
14656
|
+
parsePES(track, textTrack, pes, last, duration) {
|
14657
|
+
const units = this.parseNALu(track, pes.data);
|
14399
14658
|
let VideoSample = this.VideoSample;
|
14400
14659
|
let push;
|
14401
14660
|
let spsfound = false;
|
@@ -14411,42 +14670,49 @@ class AvcVideoParser extends BaseVideoParser {
|
|
14411
14670
|
units.forEach(unit => {
|
14412
14671
|
var _VideoSample2;
|
14413
14672
|
switch (unit.type) {
|
14414
|
-
//
|
14673
|
+
// NON-IDR, NON RANDOM ACCESS SLICE
|
14674
|
+
case 0:
|
14415
14675
|
case 1:
|
14416
|
-
|
14417
|
-
|
14418
|
-
|
14419
|
-
|
14420
|
-
|
14421
|
-
|
14422
|
-
|
14423
|
-
|
14424
|
-
|
14425
|
-
|
14426
|
-
|
14427
|
-
|
14428
|
-
|
14429
|
-
|
14430
|
-
|
14431
|
-
|
14432
|
-
|
14433
|
-
|
14434
|
-
|
14435
|
-
|
14436
|
-
|
14437
|
-
|
14438
|
-
|
14439
|
-
|
14440
|
-
|
14441
|
-
if (!VideoSample) {
|
14442
|
-
|
14676
|
+
case 2:
|
14677
|
+
case 3:
|
14678
|
+
case 4:
|
14679
|
+
case 5:
|
14680
|
+
case 6:
|
14681
|
+
case 7:
|
14682
|
+
case 8:
|
14683
|
+
case 9:
|
14684
|
+
if (!VideoSample) {
|
14685
|
+
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
14686
|
+
}
|
14687
|
+
VideoSample.frame = true;
|
14688
|
+
push = true;
|
14689
|
+
break;
|
14690
|
+
|
14691
|
+
// CRA, BLA (random access picture)
|
14692
|
+
case 16:
|
14693
|
+
case 17:
|
14694
|
+
case 18:
|
14695
|
+
case 21:
|
14696
|
+
push = true;
|
14697
|
+
if (spsfound) {
|
14698
|
+
var _VideoSample;
|
14699
|
+
// handle PES not starting with AUD
|
14700
|
+
// if we have frame data already, that cannot belong to the same frame, so force a push
|
14701
|
+
if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
|
14702
|
+
this.pushAccessUnit(VideoSample, track);
|
14703
|
+
VideoSample = this.VideoSample = null;
|
14443
14704
|
}
|
14444
|
-
VideoSample.frame = true;
|
14445
|
-
VideoSample.key = iskey;
|
14446
|
-
break;
|
14447
|
-
// IDR
|
14448
14705
|
}
|
14449
|
-
|
14706
|
+
if (!VideoSample) {
|
14707
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
14708
|
+
}
|
14709
|
+
VideoSample.key = true;
|
14710
|
+
VideoSample.frame = true;
|
14711
|
+
break;
|
14712
|
+
|
14713
|
+
// IDR
|
14714
|
+
case 19:
|
14715
|
+
case 20:
|
14450
14716
|
push = true;
|
14451
14717
|
// handle PES not starting with AUD
|
14452
14718
|
// if we have frame data already, that cannot belong to the same frame, so force a push
|
@@ -14460,48 +14726,76 @@ class AvcVideoParser extends BaseVideoParser {
|
|
14460
14726
|
VideoSample.key = true;
|
14461
14727
|
VideoSample.frame = true;
|
14462
14728
|
break;
|
14729
|
+
|
14463
14730
|
// SEI
|
14464
|
-
case
|
14465
|
-
|
14466
|
-
|
14467
|
-
|
14468
|
-
|
14469
|
-
|
14731
|
+
case 39:
|
14732
|
+
push = true;
|
14733
|
+
parseSEIMessageFromNALu(unit.data, 2,
|
14734
|
+
// NALu header size
|
14735
|
+
pes.pts, textTrack.samples);
|
14736
|
+
break;
|
14737
|
+
|
14738
|
+
// VPS
|
14739
|
+
case 32:
|
14740
|
+
push = true;
|
14741
|
+
if (!track.vps) {
|
14742
|
+
const config = this.readVPS(unit.data);
|
14743
|
+
track.params = _objectSpread2({}, config);
|
14744
|
+
this.initVPS = unit.data;
|
14470
14745
|
}
|
14471
|
-
|
14472
|
-
|
14473
|
-
|
14474
|
-
|
14475
|
-
|
14476
|
-
|
14477
|
-
|
14478
|
-
|
14479
|
-
if (
|
14746
|
+
track.vps = [unit.data];
|
14747
|
+
break;
|
14748
|
+
|
14749
|
+
// SPS
|
14750
|
+
case 33:
|
14751
|
+
push = true;
|
14752
|
+
spsfound = true;
|
14753
|
+
if (typeof track.params === 'object') {
|
14754
|
+
if (track.vps !== undefined && track.vps[0] !== this.initVPS && track.sps !== undefined && !this.matchSPS(track.sps[0], unit.data)) {
|
14755
|
+
this.initVPS = track.vps[0];
|
14756
|
+
track.sps = track.pps = undefined;
|
14757
|
+
}
|
14758
|
+
if (!track.sps) {
|
14759
|
+
const config = this.readSPS(unit.data);
|
14480
14760
|
track.width = config.width;
|
14481
14761
|
track.height = config.height;
|
14482
14762
|
track.pixelRatio = config.pixelRatio;
|
14483
|
-
track.sps = [sps];
|
14484
14763
|
track.duration = duration;
|
14485
|
-
|
14486
|
-
|
14487
|
-
for (
|
14488
|
-
|
14489
|
-
if (h.length < 2) {
|
14490
|
-
h = '0' + h;
|
14491
|
-
}
|
14492
|
-
codecstring += h;
|
14764
|
+
track.codec = config.codecString;
|
14765
|
+
track.sps = [];
|
14766
|
+
for (const prop in config.params) {
|
14767
|
+
track.params[prop] = config.params[prop];
|
14493
14768
|
}
|
14494
|
-
track.codec = codecstring;
|
14495
14769
|
}
|
14496
|
-
|
14770
|
+
if (track.vps !== undefined && track.vps[0] === this.initVPS) {
|
14771
|
+
track.sps.push(unit.data);
|
14772
|
+
}
|
14773
|
+
}
|
14774
|
+
if (!VideoSample) {
|
14775
|
+
VideoSample = this.VideoSample = this.createVideoSample(true, pes.pts, pes.dts, '');
|
14497
14776
|
}
|
14777
|
+
VideoSample.key = true;
|
14778
|
+
break;
|
14779
|
+
|
14498
14780
|
// PPS
|
14499
|
-
case
|
14781
|
+
case 34:
|
14500
14782
|
push = true;
|
14501
|
-
track.
|
14783
|
+
if (typeof track.params === 'object') {
|
14784
|
+
if (!track.pps) {
|
14785
|
+
track.pps = [];
|
14786
|
+
const config = this.readPPS(unit.data);
|
14787
|
+
for (const prop in config) {
|
14788
|
+
track.params[prop] = config[prop];
|
14789
|
+
}
|
14790
|
+
}
|
14791
|
+
if (this.initVPS !== null || track.pps.length === 0) {
|
14792
|
+
track.pps.push(unit.data);
|
14793
|
+
}
|
14794
|
+
}
|
14502
14795
|
break;
|
14503
|
-
|
14504
|
-
|
14796
|
+
|
14797
|
+
// ACCESS UNIT DELIMITER
|
14798
|
+
case 35:
|
14505
14799
|
push = true;
|
14506
14800
|
track.audFound = true;
|
14507
14801
|
if (VideoSample) {
|
@@ -14509,14 +14803,10 @@ class AvcVideoParser extends BaseVideoParser {
|
|
14509
14803
|
}
|
14510
14804
|
VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
|
14511
14805
|
break;
|
14512
|
-
// Filler Data
|
14513
|
-
case 12:
|
14514
|
-
push = true;
|
14515
|
-
break;
|
14516
14806
|
default:
|
14517
14807
|
push = false;
|
14518
14808
|
if (VideoSample) {
|
14519
|
-
VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
|
14809
|
+
VideoSample.debug += 'unknown or irrelevant NAL ' + unit.type + ' ';
|
14520
14810
|
}
|
14521
14811
|
break;
|
14522
14812
|
}
|
@@ -14531,109 +14821,423 @@ class AvcVideoParser extends BaseVideoParser {
|
|
14531
14821
|
this.VideoSample = null;
|
14532
14822
|
}
|
14533
14823
|
}
|
14534
|
-
|
14535
|
-
|
14536
|
-
|
14537
|
-
|
14538
|
-
const
|
14539
|
-
let
|
14540
|
-
let
|
14541
|
-
|
14542
|
-
|
14543
|
-
|
14544
|
-
|
14545
|
-
|
14546
|
-
|
14547
|
-
if (state === -1) {
|
14548
|
-
// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
14549
|
-
lastUnitStart = 0;
|
14550
|
-
// NALu type is value read from offset 0
|
14551
|
-
lastUnitType = array[0] & 0x1f;
|
14552
|
-
state = 0;
|
14553
|
-
i = 1;
|
14554
|
-
}
|
14555
|
-
while (i < len) {
|
14556
|
-
value = array[i++];
|
14557
|
-
// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
14558
|
-
if (!state) {
|
14559
|
-
state = value ? 0 : 1;
|
14560
|
-
continue;
|
14561
|
-
}
|
14562
|
-
if (state === 1) {
|
14563
|
-
state = value ? 0 : 2;
|
14564
|
-
continue;
|
14824
|
+
getNALuType(data, offset) {
|
14825
|
+
return (data[offset] & 0x7e) >>> 1;
|
14826
|
+
}
|
14827
|
+
ebsp2rbsp(arr) {
|
14828
|
+
const dst = new Uint8Array(arr.byteLength);
|
14829
|
+
let dstIdx = 0;
|
14830
|
+
for (let i = 0; i < arr.byteLength; i++) {
|
14831
|
+
if (i >= 2) {
|
14832
|
+
// Unescape: Skip 0x03 after 00 00
|
14833
|
+
if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {
|
14834
|
+
continue;
|
14835
|
+
}
|
14565
14836
|
}
|
14566
|
-
|
14567
|
-
|
14568
|
-
|
14569
|
-
|
14570
|
-
|
14571
|
-
|
14572
|
-
|
14573
|
-
|
14574
|
-
|
14575
|
-
|
14576
|
-
|
14577
|
-
|
14578
|
-
|
14579
|
-
|
14580
|
-
|
14581
|
-
|
14582
|
-
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
14583
|
-
const lastUnit = this.getLastNalUnit(track.samples);
|
14584
|
-
if (lastUnit) {
|
14585
|
-
if (lastState && i <= 4 - lastState) {
|
14586
|
-
// start delimiter overlapping between PES packets
|
14587
|
-
// strip start delimiter bytes from the end of last NAL unit
|
14588
|
-
// check if lastUnit had a state different from zero
|
14589
|
-
if (lastUnit.state) {
|
14590
|
-
// strip last bytes
|
14591
|
-
lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
|
14592
|
-
}
|
14593
|
-
}
|
14594
|
-
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
14837
|
+
dst[dstIdx] = arr[i];
|
14838
|
+
dstIdx++;
|
14839
|
+
}
|
14840
|
+
return new Uint8Array(dst.buffer, 0, dstIdx);
|
14841
|
+
}
|
14842
|
+
readVPS(vps) {
|
14843
|
+
const eg = new ExpGolomb(vps);
|
14844
|
+
// remove header
|
14845
|
+
eg.readUByte();
|
14846
|
+
eg.readUByte();
|
14847
|
+
eg.readBits(4); // video_parameter_set_id
|
14848
|
+
eg.skipBits(2);
|
14849
|
+
eg.readBits(6); // max_layers_minus1
|
14850
|
+
const max_sub_layers_minus1 = eg.readBits(3);
|
14851
|
+
const temporal_id_nesting_flag = eg.readBoolean();
|
14852
|
+
// ...vui fps can be here, but empty fps value is not critical for metadata
|
14595
14853
|
|
14596
|
-
|
14597
|
-
|
14598
|
-
|
14599
|
-
|
14854
|
+
return {
|
14855
|
+
numTemporalLayers: max_sub_layers_minus1 + 1,
|
14856
|
+
temporalIdNested: temporal_id_nesting_flag
|
14857
|
+
};
|
14858
|
+
}
|
14859
|
+
readSPS(sps) {
|
14860
|
+
const eg = new ExpGolomb(this.ebsp2rbsp(sps));
|
14861
|
+
eg.readUByte();
|
14862
|
+
eg.readUByte();
|
14863
|
+
eg.readBits(4); //video_parameter_set_id
|
14864
|
+
const max_sub_layers_minus1 = eg.readBits(3);
|
14865
|
+
eg.readBoolean(); // temporal_id_nesting_flag
|
14866
|
+
|
14867
|
+
// profile_tier_level
|
14868
|
+
const general_profile_space = eg.readBits(2);
|
14869
|
+
const general_tier_flag = eg.readBoolean();
|
14870
|
+
const general_profile_idc = eg.readBits(5);
|
14871
|
+
const general_profile_compatibility_flags_1 = eg.readUByte();
|
14872
|
+
const general_profile_compatibility_flags_2 = eg.readUByte();
|
14873
|
+
const general_profile_compatibility_flags_3 = eg.readUByte();
|
14874
|
+
const general_profile_compatibility_flags_4 = eg.readUByte();
|
14875
|
+
const general_constraint_indicator_flags_1 = eg.readUByte();
|
14876
|
+
const general_constraint_indicator_flags_2 = eg.readUByte();
|
14877
|
+
const general_constraint_indicator_flags_3 = eg.readUByte();
|
14878
|
+
const general_constraint_indicator_flags_4 = eg.readUByte();
|
14879
|
+
const general_constraint_indicator_flags_5 = eg.readUByte();
|
14880
|
+
const general_constraint_indicator_flags_6 = eg.readUByte();
|
14881
|
+
const general_level_idc = eg.readUByte();
|
14882
|
+
const sub_layer_profile_present_flags = [];
|
14883
|
+
const sub_layer_level_present_flags = [];
|
14884
|
+
for (let i = 0; i < max_sub_layers_minus1; i++) {
|
14885
|
+
sub_layer_profile_present_flags.push(eg.readBoolean());
|
14886
|
+
sub_layer_level_present_flags.push(eg.readBoolean());
|
14887
|
+
}
|
14888
|
+
if (max_sub_layers_minus1 > 0) {
|
14889
|
+
for (let i = max_sub_layers_minus1; i < 8; i++) {
|
14890
|
+
eg.readBits(2);
|
14891
|
+
}
|
14892
|
+
}
|
14893
|
+
for (let i = 0; i < max_sub_layers_minus1; i++) {
|
14894
|
+
if (sub_layer_profile_present_flags[i]) {
|
14895
|
+
eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
|
14896
|
+
eg.readUByte();
|
14897
|
+
eg.readUByte();
|
14898
|
+
eg.readUByte();
|
14899
|
+
eg.readUByte(); // sub_layer_profile_compatibility_flag
|
14900
|
+
eg.readUByte();
|
14901
|
+
eg.readUByte();
|
14902
|
+
eg.readUByte();
|
14903
|
+
eg.readUByte();
|
14904
|
+
eg.readUByte();
|
14905
|
+
eg.readUByte();
|
14906
|
+
}
|
14907
|
+
if (sub_layer_level_present_flags[i]) {
|
14908
|
+
eg.readUByte();
|
14909
|
+
}
|
14910
|
+
}
|
14911
|
+
eg.readUEG(); // seq_parameter_set_id
|
14912
|
+
const chroma_format_idc = eg.readUEG();
|
14913
|
+
if (chroma_format_idc == 3) {
|
14914
|
+
eg.skipBits(1); //separate_colour_plane_flag
|
14915
|
+
}
|
14916
|
+
const pic_width_in_luma_samples = eg.readUEG();
|
14917
|
+
const pic_height_in_luma_samples = eg.readUEG();
|
14918
|
+
const conformance_window_flag = eg.readBoolean();
|
14919
|
+
let pic_left_offset = 0,
|
14920
|
+
pic_right_offset = 0,
|
14921
|
+
pic_top_offset = 0,
|
14922
|
+
pic_bottom_offset = 0;
|
14923
|
+
if (conformance_window_flag) {
|
14924
|
+
pic_left_offset += eg.readUEG();
|
14925
|
+
pic_right_offset += eg.readUEG();
|
14926
|
+
pic_top_offset += eg.readUEG();
|
14927
|
+
pic_bottom_offset += eg.readUEG();
|
14928
|
+
}
|
14929
|
+
const bit_depth_luma_minus8 = eg.readUEG();
|
14930
|
+
const bit_depth_chroma_minus8 = eg.readUEG();
|
14931
|
+
const log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();
|
14932
|
+
const sub_layer_ordering_info_present_flag = eg.readBoolean();
|
14933
|
+
for (let i = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1; i <= max_sub_layers_minus1; i++) {
|
14934
|
+
eg.skipUEG(); // max_dec_pic_buffering_minus1[i]
|
14935
|
+
eg.skipUEG(); // max_num_reorder_pics[i]
|
14936
|
+
eg.skipUEG(); // max_latency_increase_plus1[i]
|
14937
|
+
}
|
14938
|
+
eg.skipUEG(); // log2_min_luma_coding_block_size_minus3
|
14939
|
+
eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size
|
14940
|
+
eg.skipUEG(); // log2_min_transform_block_size_minus2
|
14941
|
+
eg.skipUEG(); // log2_diff_max_min_transform_block_size
|
14942
|
+
eg.skipUEG(); // max_transform_hierarchy_depth_inter
|
14943
|
+
eg.skipUEG(); // max_transform_hierarchy_depth_intra
|
14944
|
+
const scaling_list_enabled_flag = eg.readBoolean();
|
14945
|
+
if (scaling_list_enabled_flag) {
|
14946
|
+
const sps_scaling_list_data_present_flag = eg.readBoolean();
|
14947
|
+
if (sps_scaling_list_data_present_flag) {
|
14948
|
+
for (let sizeId = 0; sizeId < 4; sizeId++) {
|
14949
|
+
for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
|
14950
|
+
const scaling_list_pred_mode_flag = eg.readBoolean();
|
14951
|
+
if (!scaling_list_pred_mode_flag) {
|
14952
|
+
eg.readUEG(); // scaling_list_pred_matrix_id_delta
|
14953
|
+
} else {
|
14954
|
+
const coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
|
14955
|
+
if (sizeId > 1) {
|
14956
|
+
eg.readEG();
|
14957
|
+
}
|
14958
|
+
for (let i = 0; i < coefNum; i++) {
|
14959
|
+
eg.readEG();
|
14960
|
+
}
|
14600
14961
|
}
|
14601
14962
|
}
|
14602
14963
|
}
|
14603
|
-
|
14604
|
-
|
14605
|
-
|
14606
|
-
|
14607
|
-
|
14608
|
-
|
14609
|
-
|
14610
|
-
|
14611
|
-
|
14612
|
-
|
14964
|
+
}
|
14965
|
+
}
|
14966
|
+
eg.readBoolean(); // amp_enabled_flag
|
14967
|
+
eg.readBoolean(); // sample_adaptive_offset_enabled_flag
|
14968
|
+
const pcm_enabled_flag = eg.readBoolean();
|
14969
|
+
if (pcm_enabled_flag) {
|
14970
|
+
eg.readUByte();
|
14971
|
+
eg.skipUEG();
|
14972
|
+
eg.skipUEG();
|
14973
|
+
eg.readBoolean();
|
14974
|
+
}
|
14975
|
+
const num_short_term_ref_pic_sets = eg.readUEG();
|
14976
|
+
let num_delta_pocs = 0;
|
14977
|
+
for (let i = 0; i < num_short_term_ref_pic_sets; i++) {
|
14978
|
+
let inter_ref_pic_set_prediction_flag = false;
|
14979
|
+
if (i !== 0) {
|
14980
|
+
inter_ref_pic_set_prediction_flag = eg.readBoolean();
|
14981
|
+
}
|
14982
|
+
if (inter_ref_pic_set_prediction_flag) {
|
14983
|
+
if (i === num_short_term_ref_pic_sets) {
|
14984
|
+
eg.readUEG();
|
14985
|
+
}
|
14986
|
+
eg.readBoolean();
|
14987
|
+
eg.readUEG();
|
14988
|
+
let next_num_delta_pocs = 0;
|
14989
|
+
for (let j = 0; j <= num_delta_pocs; j++) {
|
14990
|
+
const used_by_curr_pic_flag = eg.readBoolean();
|
14991
|
+
let use_delta_flag = false;
|
14992
|
+
if (!used_by_curr_pic_flag) {
|
14993
|
+
use_delta_flag = eg.readBoolean();
|
14994
|
+
}
|
14995
|
+
if (used_by_curr_pic_flag || use_delta_flag) {
|
14996
|
+
next_num_delta_pocs++;
|
14997
|
+
}
|
14613
14998
|
}
|
14999
|
+
num_delta_pocs = next_num_delta_pocs;
|
14614
15000
|
} else {
|
14615
|
-
|
15001
|
+
const num_negative_pics = eg.readUEG();
|
15002
|
+
const num_positive_pics = eg.readUEG();
|
15003
|
+
num_delta_pocs = num_negative_pics + num_positive_pics;
|
15004
|
+
for (let j = 0; j < num_negative_pics; j++) {
|
15005
|
+
eg.readUEG();
|
15006
|
+
eg.readBoolean();
|
15007
|
+
}
|
15008
|
+
for (let j = 0; j < num_positive_pics; j++) {
|
15009
|
+
eg.readUEG();
|
15010
|
+
eg.readBoolean();
|
15011
|
+
}
|
14616
15012
|
}
|
14617
15013
|
}
|
14618
|
-
|
14619
|
-
|
14620
|
-
|
14621
|
-
|
14622
|
-
|
14623
|
-
|
14624
|
-
|
14625
|
-
|
14626
|
-
|
14627
|
-
|
14628
|
-
|
14629
|
-
|
14630
|
-
|
14631
|
-
|
14632
|
-
|
15014
|
+
const long_term_ref_pics_present_flag = eg.readBoolean();
|
15015
|
+
if (long_term_ref_pics_present_flag) {
|
15016
|
+
const num_long_term_ref_pics_sps = eg.readUEG();
|
15017
|
+
for (let i = 0; i < num_long_term_ref_pics_sps; i++) {
|
15018
|
+
for (let j = 0; j < log2_max_pic_order_cnt_lsb_minus4 + 4; j++) {
|
15019
|
+
eg.readBits(1);
|
15020
|
+
}
|
15021
|
+
eg.readBits(1);
|
15022
|
+
}
|
15023
|
+
}
|
15024
|
+
let min_spatial_segmentation_idc = 0;
|
15025
|
+
let sar_width = 1,
|
15026
|
+
sar_height = 1;
|
15027
|
+
let fps_fixed = true,
|
15028
|
+
fps_den = 1,
|
15029
|
+
fps_num = 0;
|
15030
|
+
eg.readBoolean(); // sps_temporal_mvp_enabled_flag
|
15031
|
+
eg.readBoolean(); // strong_intra_smoothing_enabled_flag
|
15032
|
+
let default_display_window_flag = false;
|
15033
|
+
const vui_parameters_present_flag = eg.readBoolean();
|
15034
|
+
if (vui_parameters_present_flag) {
|
15035
|
+
const aspect_ratio_info_present_flag = eg.readBoolean();
|
15036
|
+
if (aspect_ratio_info_present_flag) {
|
15037
|
+
const aspect_ratio_idc = eg.readUByte();
|
15038
|
+
const sar_width_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
|
15039
|
+
const sar_height_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
|
15040
|
+
if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
|
15041
|
+
sar_width = sar_width_table[aspect_ratio_idc - 1];
|
15042
|
+
sar_height = sar_height_table[aspect_ratio_idc - 1];
|
15043
|
+
} else if (aspect_ratio_idc === 255) {
|
15044
|
+
sar_width = eg.readBits(16);
|
15045
|
+
sar_height = eg.readBits(16);
|
15046
|
+
}
|
14633
15047
|
}
|
15048
|
+
const overscan_info_present_flag = eg.readBoolean();
|
15049
|
+
if (overscan_info_present_flag) {
|
15050
|
+
eg.readBoolean();
|
15051
|
+
}
|
15052
|
+
const video_signal_type_present_flag = eg.readBoolean();
|
15053
|
+
if (video_signal_type_present_flag) {
|
15054
|
+
eg.readBits(3);
|
15055
|
+
eg.readBoolean();
|
15056
|
+
const colour_description_present_flag = eg.readBoolean();
|
15057
|
+
if (colour_description_present_flag) {
|
15058
|
+
eg.readUByte();
|
15059
|
+
eg.readUByte();
|
15060
|
+
eg.readUByte();
|
15061
|
+
}
|
15062
|
+
}
|
15063
|
+
const chroma_loc_info_present_flag = eg.readBoolean();
|
15064
|
+
if (chroma_loc_info_present_flag) {
|
15065
|
+
eg.readUEG();
|
15066
|
+
eg.readUEG();
|
15067
|
+
}
|
15068
|
+
eg.readBoolean(); // neutral_chroma_indication_flag
|
15069
|
+
eg.readBoolean(); // field_seq_flag
|
15070
|
+
eg.readBoolean(); // frame_field_info_present_flag
|
15071
|
+
default_display_window_flag = eg.readBoolean();
|
15072
|
+
if (default_display_window_flag) {
|
15073
|
+
pic_left_offset += eg.readUEG();
|
15074
|
+
pic_right_offset += eg.readUEG();
|
15075
|
+
pic_top_offset += eg.readUEG();
|
15076
|
+
pic_bottom_offset += eg.readUEG();
|
15077
|
+
}
|
15078
|
+
const vui_timing_info_present_flag = eg.readBoolean();
|
15079
|
+
if (vui_timing_info_present_flag) {
|
15080
|
+
fps_den = eg.readBits(32);
|
15081
|
+
fps_num = eg.readBits(32);
|
15082
|
+
const vui_poc_proportional_to_timing_flag = eg.readBoolean();
|
15083
|
+
if (vui_poc_proportional_to_timing_flag) {
|
15084
|
+
eg.readUEG();
|
15085
|
+
}
|
15086
|
+
const vui_hrd_parameters_present_flag = eg.readBoolean();
|
15087
|
+
if (vui_hrd_parameters_present_flag) {
|
15088
|
+
//const commonInfPresentFlag = true;
|
15089
|
+
//if (commonInfPresentFlag) {
|
15090
|
+
const nal_hrd_parameters_present_flag = eg.readBoolean();
|
15091
|
+
const vcl_hrd_parameters_present_flag = eg.readBoolean();
|
15092
|
+
let sub_pic_hrd_params_present_flag = false;
|
15093
|
+
if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
|
15094
|
+
sub_pic_hrd_params_present_flag = eg.readBoolean();
|
15095
|
+
if (sub_pic_hrd_params_present_flag) {
|
15096
|
+
eg.readUByte();
|
15097
|
+
eg.readBits(5);
|
15098
|
+
eg.readBoolean();
|
15099
|
+
eg.readBits(5);
|
15100
|
+
}
|
15101
|
+
eg.readBits(4); // bit_rate_scale
|
15102
|
+
eg.readBits(4); // cpb_size_scale
|
15103
|
+
if (sub_pic_hrd_params_present_flag) {
|
15104
|
+
eg.readBits(4);
|
15105
|
+
}
|
15106
|
+
eg.readBits(5);
|
15107
|
+
eg.readBits(5);
|
15108
|
+
eg.readBits(5);
|
15109
|
+
}
|
15110
|
+
//}
|
15111
|
+
for (let i = 0; i <= max_sub_layers_minus1; i++) {
|
15112
|
+
fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag
|
15113
|
+
const fixed_pic_rate_within_cvs_flag = fps_fixed || eg.readBoolean();
|
15114
|
+
let low_delay_hrd_flag = false;
|
15115
|
+
if (fixed_pic_rate_within_cvs_flag) {
|
15116
|
+
eg.readEG();
|
15117
|
+
} else {
|
15118
|
+
low_delay_hrd_flag = eg.readBoolean();
|
15119
|
+
}
|
15120
|
+
const cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;
|
15121
|
+
if (nal_hrd_parameters_present_flag) {
|
15122
|
+
for (let j = 0; j < cpb_cnt; j++) {
|
15123
|
+
eg.readUEG();
|
15124
|
+
eg.readUEG();
|
15125
|
+
if (sub_pic_hrd_params_present_flag) {
|
15126
|
+
eg.readUEG();
|
15127
|
+
eg.readUEG();
|
15128
|
+
}
|
15129
|
+
eg.skipBits(1);
|
15130
|
+
}
|
15131
|
+
}
|
15132
|
+
if (vcl_hrd_parameters_present_flag) {
|
15133
|
+
for (let j = 0; j < cpb_cnt; j++) {
|
15134
|
+
eg.readUEG();
|
15135
|
+
eg.readUEG();
|
15136
|
+
if (sub_pic_hrd_params_present_flag) {
|
15137
|
+
eg.readUEG();
|
15138
|
+
eg.readUEG();
|
15139
|
+
}
|
15140
|
+
eg.skipBits(1);
|
15141
|
+
}
|
15142
|
+
}
|
15143
|
+
}
|
15144
|
+
}
|
15145
|
+
}
|
15146
|
+
const bitstream_restriction_flag = eg.readBoolean();
|
15147
|
+
if (bitstream_restriction_flag) {
|
15148
|
+
eg.readBoolean(); // tiles_fixed_structure_flag
|
15149
|
+
eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag
|
15150
|
+
eg.readBoolean(); // restricted_ref_pic_lists_flag
|
15151
|
+
min_spatial_segmentation_idc = eg.readUEG();
|
15152
|
+
}
|
15153
|
+
}
|
15154
|
+
let width = pic_width_in_luma_samples,
|
15155
|
+
height = pic_height_in_luma_samples;
|
15156
|
+
if (conformance_window_flag || default_display_window_flag) {
|
15157
|
+
let chroma_scale_w = 1,
|
15158
|
+
chroma_scale_h = 1;
|
15159
|
+
if (chroma_format_idc === 1) {
|
15160
|
+
// YUV 420
|
15161
|
+
chroma_scale_w = chroma_scale_h = 2;
|
15162
|
+
} else if (chroma_format_idc == 2) {
|
15163
|
+
// YUV 422
|
15164
|
+
chroma_scale_w = 2;
|
15165
|
+
}
|
15166
|
+
width = pic_width_in_luma_samples - chroma_scale_w * pic_right_offset - chroma_scale_w * pic_left_offset;
|
15167
|
+
height = pic_height_in_luma_samples - chroma_scale_h * pic_bottom_offset - chroma_scale_h * pic_top_offset;
|
15168
|
+
}
|
15169
|
+
const profile_space_string = general_profile_space ? ['A', 'B', 'C'][general_profile_space] : '';
|
15170
|
+
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;
|
15171
|
+
let profile_compatibility_rev = 0;
|
15172
|
+
for (let i = 0; i < 32; i++) {
|
15173
|
+
profile_compatibility_rev = (profile_compatibility_rev | (profile_compatibility_buf >> i & 1) << 31 - i) >>> 0; // reverse bit position (and cast as UInt32)
|
15174
|
+
}
|
15175
|
+
let profile_compatibility_flags_string = profile_compatibility_rev.toString(16);
|
15176
|
+
if (general_profile_idc === 1 && profile_compatibility_flags_string === '2') {
|
15177
|
+
profile_compatibility_flags_string = '6';
|
15178
|
+
}
|
15179
|
+
const tier_flag_string = general_tier_flag ? 'H' : 'L';
|
15180
|
+
return {
|
15181
|
+
codecString: `hvc1.${profile_space_string}${general_profile_idc}.${profile_compatibility_flags_string}.${tier_flag_string}${general_level_idc}.B0`,
|
15182
|
+
params: {
|
15183
|
+
general_tier_flag,
|
15184
|
+
general_profile_idc,
|
15185
|
+
general_profile_space,
|
15186
|
+
general_profile_compatibility_flags: [general_profile_compatibility_flags_1, general_profile_compatibility_flags_2, general_profile_compatibility_flags_3, general_profile_compatibility_flags_4],
|
15187
|
+
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],
|
15188
|
+
general_level_idc,
|
15189
|
+
bit_depth: bit_depth_luma_minus8 + 8,
|
15190
|
+
bit_depth_luma_minus8,
|
15191
|
+
bit_depth_chroma_minus8,
|
15192
|
+
min_spatial_segmentation_idc,
|
15193
|
+
chroma_format_idc: chroma_format_idc,
|
15194
|
+
frame_rate: {
|
15195
|
+
fixed: fps_fixed,
|
15196
|
+
fps: fps_num / fps_den
|
15197
|
+
}
|
15198
|
+
},
|
15199
|
+
width,
|
15200
|
+
height,
|
15201
|
+
pixelRatio: [sar_width, sar_height]
|
15202
|
+
};
|
15203
|
+
}
|
15204
|
+
readPPS(pps) {
|
15205
|
+
const eg = new ExpGolomb(this.ebsp2rbsp(pps));
|
15206
|
+
eg.readUByte();
|
15207
|
+
eg.readUByte();
|
15208
|
+
eg.skipUEG(); // pic_parameter_set_id
|
15209
|
+
eg.skipUEG(); // seq_parameter_set_id
|
15210
|
+
eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag
|
15211
|
+
eg.skipBits(3); // num_extra_slice_header_bits
|
15212
|
+
eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag
|
15213
|
+
eg.skipUEG();
|
15214
|
+
eg.skipUEG();
|
15215
|
+
eg.skipEG(); // init_qp_minus26
|
15216
|
+
eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag
|
15217
|
+
const cu_qp_delta_enabled_flag = eg.readBoolean();
|
15218
|
+
if (cu_qp_delta_enabled_flag) {
|
15219
|
+
eg.skipUEG();
|
15220
|
+
}
|
15221
|
+
eg.skipEG(); // cb_qp_offset
|
15222
|
+
eg.skipEG(); // cr_qp_offset
|
15223
|
+
eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag
|
15224
|
+
const tiles_enabled_flag = eg.readBoolean();
|
15225
|
+
const entropy_coding_sync_enabled_flag = eg.readBoolean();
|
15226
|
+
let parallelismType = 1; // slice-based parallel decoding
|
15227
|
+
if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {
|
15228
|
+
parallelismType = 0; // mixed-type parallel decoding
|
15229
|
+
} else if (entropy_coding_sync_enabled_flag) {
|
15230
|
+
parallelismType = 3; // wavefront-based parallel decoding
|
15231
|
+
} else if (tiles_enabled_flag) {
|
15232
|
+
parallelismType = 2; // tile-based parallel decoding
|
14634
15233
|
}
|
14635
|
-
|
14636
|
-
|
15234
|
+
return {
|
15235
|
+
parallelismType
|
15236
|
+
};
|
15237
|
+
}
|
15238
|
+
matchSPS(sps1, sps2) {
|
15239
|
+
// compare without headers and VPS related params
|
15240
|
+
return String.fromCharCode.apply(null, sps1).substr(3) === String.fromCharCode.apply(null, sps2).substr(3);
|
14637
15241
|
}
|
14638
15242
|
}
|
14639
15243
|
|
@@ -14765,7 +15369,7 @@ class TSDemuxer {
|
|
14765
15369
|
this.observer = observer;
|
14766
15370
|
this.config = config;
|
14767
15371
|
this.typeSupported = typeSupported;
|
14768
|
-
this.videoParser =
|
15372
|
+
this.videoParser = null;
|
14769
15373
|
}
|
14770
15374
|
static probe(data) {
|
14771
15375
|
const syncOffset = TSDemuxer.syncOffset(data);
|
@@ -14930,7 +15534,19 @@ class TSDemuxer {
|
|
14930
15534
|
case videoPid:
|
14931
15535
|
if (stt) {
|
14932
15536
|
if (videoData && (pes = parsePES(videoData))) {
|
14933
|
-
this.videoParser
|
15537
|
+
if (this.videoParser === null) {
|
15538
|
+
switch (videoTrack.segmentCodec) {
|
15539
|
+
case 'avc':
|
15540
|
+
this.videoParser = new AvcVideoParser();
|
15541
|
+
break;
|
15542
|
+
case 'hevc':
|
15543
|
+
this.videoParser = new HevcVideoParser();
|
15544
|
+
break;
|
15545
|
+
}
|
15546
|
+
}
|
15547
|
+
if (this.videoParser !== null) {
|
15548
|
+
this.videoParser.parsePES(videoTrack, textTrack, pes, false, this._duration);
|
15549
|
+
}
|
14934
15550
|
}
|
14935
15551
|
videoData = {
|
14936
15552
|
data: [],
|
@@ -15092,8 +15708,20 @@ class TSDemuxer {
|
|
15092
15708
|
// try to parse last PES packets
|
15093
15709
|
let pes;
|
15094
15710
|
if (videoData && (pes = parsePES(videoData))) {
|
15095
|
-
this.videoParser
|
15096
|
-
|
15711
|
+
if (this.videoParser === null) {
|
15712
|
+
switch (videoTrack.segmentCodec) {
|
15713
|
+
case 'avc':
|
15714
|
+
this.videoParser = new AvcVideoParser();
|
15715
|
+
break;
|
15716
|
+
case 'hevc':
|
15717
|
+
this.videoParser = new HevcVideoParser();
|
15718
|
+
break;
|
15719
|
+
}
|
15720
|
+
}
|
15721
|
+
if (this.videoParser !== null) {
|
15722
|
+
this.videoParser.parsePES(videoTrack, textTrack, pes, true, this._duration);
|
15723
|
+
videoTrack.pesData = null;
|
15724
|
+
}
|
15097
15725
|
} else {
|
15098
15726
|
// either avcData null or PES truncated, keep it for next frag parsing
|
15099
15727
|
videoTrack.pesData = videoData;
|
@@ -15396,7 +16024,12 @@ function parsePMT(data, offset, typeSupported, isSampleAes) {
|
|
15396
16024
|
logger.warn('Unsupported EC-3 in M2TS found');
|
15397
16025
|
break;
|
15398
16026
|
case 0x24:
|
15399
|
-
|
16027
|
+
// ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
|
16028
|
+
if (result.videoPid === -1) {
|
16029
|
+
result.videoPid = pid;
|
16030
|
+
result.segmentVideoCodec = 'hevc';
|
16031
|
+
logger.log('HEVC in M2TS found');
|
16032
|
+
}
|
15400
16033
|
break;
|
15401
16034
|
}
|
15402
16035
|
// move to the next table entry
|
@@ -15619,6 +16252,8 @@ class MP4 {
|
|
15619
16252
|
avc1: [],
|
15620
16253
|
// codingname
|
15621
16254
|
avcC: [],
|
16255
|
+
hvc1: [],
|
16256
|
+
hvcC: [],
|
15622
16257
|
btrt: [],
|
15623
16258
|
dinf: [],
|
15624
16259
|
dref: [],
|
@@ -16043,8 +16678,10 @@ class MP4 {
|
|
16043
16678
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));
|
16044
16679
|
}
|
16045
16680
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
|
16046
|
-
} else {
|
16681
|
+
} else if (track.segmentCodec === 'avc') {
|
16047
16682
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
|
16683
|
+
} else {
|
16684
|
+
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.hvc1(track));
|
16048
16685
|
}
|
16049
16686
|
}
|
16050
16687
|
static tkhd(track) {
|
@@ -16182,6 +16819,84 @@ class MP4 {
|
|
16182
16819
|
const result = appendUint8Array(MP4.FTYP, movie);
|
16183
16820
|
return result;
|
16184
16821
|
}
|
16822
|
+
static hvc1(track) {
|
16823
|
+
const ps = track.params;
|
16824
|
+
const units = [track.vps, track.sps, track.pps];
|
16825
|
+
const NALuLengthSize = 4;
|
16826
|
+
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]);
|
16827
|
+
|
16828
|
+
// compute hvcC size in bytes
|
16829
|
+
let length = config.length;
|
16830
|
+
for (let i = 0; i < units.length; i += 1) {
|
16831
|
+
length += 3;
|
16832
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
16833
|
+
length += 2 + units[i][j].length;
|
16834
|
+
}
|
16835
|
+
}
|
16836
|
+
const hvcC = new Uint8Array(length);
|
16837
|
+
hvcC.set(config, 0);
|
16838
|
+
length = config.length;
|
16839
|
+
// append parameter set units: one vps, one or more sps and pps
|
16840
|
+
const iMax = units.length - 1;
|
16841
|
+
for (let i = 0; i < units.length; i += 1) {
|
16842
|
+
hvcC.set(new Uint8Array([32 + i | (i === iMax ? 128 : 0), 0x00, units[i].length]), length);
|
16843
|
+
length += 3;
|
16844
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
16845
|
+
hvcC.set(new Uint8Array([units[i][j].length >> 8, units[i][j].length & 255]), length);
|
16846
|
+
length += 2;
|
16847
|
+
hvcC.set(units[i][j], length);
|
16848
|
+
length += units[i][j].length;
|
16849
|
+
}
|
16850
|
+
}
|
16851
|
+
const hvcc = MP4.box(MP4.types.hvcC, hvcC);
|
16852
|
+
const width = track.width;
|
16853
|
+
const height = track.height;
|
16854
|
+
const hSpacing = track.pixelRatio[0];
|
16855
|
+
const vSpacing = track.pixelRatio[1];
|
16856
|
+
return MP4.box(MP4.types.hvc1, new Uint8Array([0x00, 0x00, 0x00,
|
16857
|
+
// reserved
|
16858
|
+
0x00, 0x00, 0x00,
|
16859
|
+
// reserved
|
16860
|
+
0x00, 0x01,
|
16861
|
+
// data_reference_index
|
16862
|
+
0x00, 0x00,
|
16863
|
+
// pre_defined
|
16864
|
+
0x00, 0x00,
|
16865
|
+
// reserved
|
16866
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
16867
|
+
// pre_defined
|
16868
|
+
width >> 8 & 0xff, width & 0xff,
|
16869
|
+
// width
|
16870
|
+
height >> 8 & 0xff, height & 0xff,
|
16871
|
+
// height
|
16872
|
+
0x00, 0x48, 0x00, 0x00,
|
16873
|
+
// horizresolution
|
16874
|
+
0x00, 0x48, 0x00, 0x00,
|
16875
|
+
// vertresolution
|
16876
|
+
0x00, 0x00, 0x00, 0x00,
|
16877
|
+
// reserved
|
16878
|
+
0x00, 0x01,
|
16879
|
+
// frame_count
|
16880
|
+
0x12, 0x64, 0x61, 0x69, 0x6c,
|
16881
|
+
// dailymotion/hls.js
|
16882
|
+
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,
|
16883
|
+
// compressorname
|
16884
|
+
0x00, 0x18,
|
16885
|
+
// depth = 24
|
16886
|
+
0x11, 0x11]),
|
16887
|
+
// pre_defined = -1
|
16888
|
+
hvcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80,
|
16889
|
+
// bufferSizeDB
|
16890
|
+
0x00, 0x2d, 0xc6, 0xc0,
|
16891
|
+
// maxBitrate
|
16892
|
+
0x00, 0x2d, 0xc6, 0xc0])),
|
16893
|
+
// avgBitrate
|
16894
|
+
MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24,
|
16895
|
+
// hSpacing
|
16896
|
+
hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24,
|
16897
|
+
// vSpacing
|
16898
|
+
vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff])));
|
16899
|
+
}
|
16185
16900
|
}
|
16186
16901
|
MP4.types = void 0;
|
16187
16902
|
MP4.HDLR_TYPES = void 0;
|
@@ -16557,9 +17272,9 @@ class MP4Remuxer {
|
|
16557
17272
|
const foundOverlap = delta < -1;
|
16558
17273
|
if (foundHole || foundOverlap) {
|
16559
17274
|
if (foundHole) {
|
16560
|
-
logger.warn(
|
17275
|
+
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
|
16561
17276
|
} else {
|
16562
|
-
logger.warn(
|
17277
|
+
logger.warn(`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
|
16563
17278
|
}
|
16564
17279
|
if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
|
16565
17280
|
firstDTS = nextAvcDts;
|
@@ -16733,7 +17448,7 @@ class MP4Remuxer {
|
|
16733
17448
|
}
|
16734
17449
|
}
|
16735
17450
|
}
|
16736
|
-
// next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
17451
|
+
// next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
16737
17452
|
mp4SampleDuration = stretchedLastFrame || !mp4SampleDuration ? averageSampleDuration : mp4SampleDuration;
|
16738
17453
|
this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;
|
16739
17454
|
this.videoSampleDuration = mp4SampleDuration;
|
@@ -18849,7 +19564,7 @@ class StreamController extends BaseStreamController {
|
|
18849
19564
|
if (this.altAudio && this.audioOnly) {
|
18850
19565
|
return;
|
18851
19566
|
}
|
18852
|
-
if (!(levels != null && levels[level])) {
|
19567
|
+
if (!this.buffering || !(levels != null && levels[level])) {
|
18853
19568
|
return;
|
18854
19569
|
}
|
18855
19570
|
const levelInfo = levels[level];
|
@@ -19809,7 +20524,7 @@ class Hls {
|
|
19809
20524
|
* Get the video-dev/hls.js package version.
|
19810
20525
|
*/
|
19811
20526
|
static get version() {
|
19812
|
-
return "1.5.2-0.canary.
|
20527
|
+
return "1.5.2-0.canary.9971";
|
19813
20528
|
}
|
19814
20529
|
|
19815
20530
|
/**
|
@@ -19878,7 +20593,6 @@ class Hls {
|
|
19878
20593
|
this.logger = void 0;
|
19879
20594
|
this.coreComponents = void 0;
|
19880
20595
|
this.networkControllers = void 0;
|
19881
|
-
this.started = false;
|
19882
20596
|
this._emitter = new EventEmitter();
|
19883
20597
|
this._autoLevelCapping = -1;
|
19884
20598
|
this._maxHdcpLevel = null;
|
@@ -20093,7 +20807,6 @@ class Hls {
|
|
20093
20807
|
*/
|
20094
20808
|
startLoad(startPosition = -1) {
|
20095
20809
|
this.logger.log(`startLoad(${startPosition})`);
|
20096
|
-
this.started = true;
|
20097
20810
|
this.networkControllers.forEach(controller => {
|
20098
20811
|
controller.startLoad(startPosition);
|
20099
20812
|
});
|
@@ -20104,33 +20817,30 @@ class Hls {
|
|
20104
20817
|
*/
|
20105
20818
|
stopLoad() {
|
20106
20819
|
this.logger.log('stopLoad');
|
20107
|
-
this.started = false;
|
20108
20820
|
this.networkControllers.forEach(controller => {
|
20109
20821
|
controller.stopLoad();
|
20110
20822
|
});
|
20111
20823
|
}
|
20112
20824
|
|
20113
20825
|
/**
|
20114
|
-
* Resumes stream controller segment loading
|
20826
|
+
* Resumes stream controller segment loading after `pauseBuffering` has been called.
|
20115
20827
|
*/
|
20116
20828
|
resumeBuffering() {
|
20117
|
-
|
20118
|
-
|
20119
|
-
|
20120
|
-
|
20121
|
-
|
20122
|
-
});
|
20123
|
-
}
|
20829
|
+
this.networkControllers.forEach(controller => {
|
20830
|
+
if (controller.resumeBuffering) {
|
20831
|
+
controller.resumeBuffering();
|
20832
|
+
}
|
20833
|
+
});
|
20124
20834
|
}
|
20125
20835
|
|
20126
20836
|
/**
|
20127
|
-
*
|
20837
|
+
* Prevents stream controller from loading new segments until `resumeBuffering` is called.
|
20128
20838
|
* This allows for media buffering to be paused without interupting playlist loading.
|
20129
20839
|
*/
|
20130
20840
|
pauseBuffering() {
|
20131
20841
|
this.networkControllers.forEach(controller => {
|
20132
|
-
if (
|
20133
|
-
controller.
|
20842
|
+
if (controller.pauseBuffering) {
|
20843
|
+
controller.pauseBuffering();
|
20134
20844
|
}
|
20135
20845
|
});
|
20136
20846
|
}
|