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/src/hls.ts
CHANGED
@@ -66,7 +66,6 @@ export default class Hls implements HlsEventEmitter {
|
|
66
66
|
|
67
67
|
private coreComponents: ComponentAPI[];
|
68
68
|
private networkControllers: NetworkComponentAPI[];
|
69
|
-
private started: boolean = false;
|
70
69
|
private _emitter: HlsEventEmitter = new EventEmitter();
|
71
70
|
private _autoLevelCapping: number = -1;
|
72
71
|
private _maxHdcpLevel: HdcpLevel = null;
|
@@ -441,7 +440,6 @@ export default class Hls implements HlsEventEmitter {
|
|
441
440
|
*/
|
442
441
|
startLoad(startPosition: number = -1) {
|
443
442
|
this.logger.log(`startLoad(${startPosition})`);
|
444
|
-
this.started = true;
|
445
443
|
this.networkControllers.forEach((controller) => {
|
446
444
|
controller.startLoad(startPosition);
|
447
445
|
});
|
@@ -452,33 +450,30 @@ export default class Hls implements HlsEventEmitter {
|
|
452
450
|
*/
|
453
451
|
stopLoad() {
|
454
452
|
this.logger.log('stopLoad');
|
455
|
-
this.started = false;
|
456
453
|
this.networkControllers.forEach((controller) => {
|
457
454
|
controller.stopLoad();
|
458
455
|
});
|
459
456
|
}
|
460
457
|
|
461
458
|
/**
|
462
|
-
* Resumes stream controller segment loading
|
459
|
+
* Resumes stream controller segment loading after `pauseBuffering` has been called.
|
463
460
|
*/
|
464
461
|
resumeBuffering() {
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
});
|
471
|
-
}
|
462
|
+
this.networkControllers.forEach((controller) => {
|
463
|
+
if (controller.resumeBuffering) {
|
464
|
+
controller.resumeBuffering();
|
465
|
+
}
|
466
|
+
});
|
472
467
|
}
|
473
468
|
|
474
469
|
/**
|
475
|
-
*
|
470
|
+
* Prevents stream controller from loading new segments until `resumeBuffering` is called.
|
476
471
|
* This allows for media buffering to be paused without interupting playlist loading.
|
477
472
|
*/
|
478
473
|
pauseBuffering() {
|
479
474
|
this.networkControllers.forEach((controller) => {
|
480
|
-
if (
|
481
|
-
controller.
|
475
|
+
if (controller.pauseBuffering) {
|
476
|
+
controller.pauseBuffering();
|
482
477
|
}
|
483
478
|
});
|
484
479
|
}
|
@@ -28,6 +28,8 @@ class MP4 {
|
|
28
28
|
MP4.types = {
|
29
29
|
avc1: [], // codingname
|
30
30
|
avcC: [],
|
31
|
+
hvc1: [],
|
32
|
+
hvcC: [],
|
31
33
|
btrt: [],
|
32
34
|
dinf: [],
|
33
35
|
dref: [],
|
@@ -839,8 +841,10 @@ class MP4 {
|
|
839
841
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));
|
840
842
|
}
|
841
843
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
|
842
|
-
} else {
|
844
|
+
} else if (track.segmentCodec === 'avc') {
|
843
845
|
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
|
846
|
+
} else {
|
847
|
+
return MP4.box(MP4.types.stsd, MP4.STSD, MP4.hvc1(track));
|
844
848
|
}
|
845
849
|
}
|
846
850
|
|
@@ -1123,6 +1127,197 @@ class MP4 {
|
|
1123
1127
|
const result = appendUint8Array(MP4.FTYP, movie);
|
1124
1128
|
return result;
|
1125
1129
|
}
|
1130
|
+
|
1131
|
+
static hvc1(track) {
|
1132
|
+
const ps = track.params;
|
1133
|
+
const units = [track.vps, track.sps, track.pps];
|
1134
|
+
const NALuLengthSize = 4;
|
1135
|
+
const config = new Uint8Array([
|
1136
|
+
0x01,
|
1137
|
+
(ps.general_profile_space << 6) |
|
1138
|
+
(ps.general_tier_flag ? 32 : 0) |
|
1139
|
+
ps.general_profile_idc,
|
1140
|
+
ps.general_profile_compatibility_flags[0],
|
1141
|
+
ps.general_profile_compatibility_flags[1],
|
1142
|
+
ps.general_profile_compatibility_flags[2],
|
1143
|
+
ps.general_profile_compatibility_flags[3],
|
1144
|
+
ps.general_constraint_indicator_flags[0],
|
1145
|
+
ps.general_constraint_indicator_flags[1],
|
1146
|
+
ps.general_constraint_indicator_flags[2],
|
1147
|
+
ps.general_constraint_indicator_flags[3],
|
1148
|
+
ps.general_constraint_indicator_flags[4],
|
1149
|
+
ps.general_constraint_indicator_flags[5],
|
1150
|
+
ps.general_level_idc,
|
1151
|
+
240 | (ps.min_spatial_segmentation_idc >> 8),
|
1152
|
+
255 & ps.min_spatial_segmentation_idc,
|
1153
|
+
252 | ps.parallelismType,
|
1154
|
+
252 | ps.chroma_format_idc,
|
1155
|
+
248 | ps.bit_depth_luma_minus8,
|
1156
|
+
248 | ps.bit_depth_chroma_minus8,
|
1157
|
+
0x00,
|
1158
|
+
parseInt(ps.frame_rate.fps),
|
1159
|
+
(NALuLengthSize - 1) |
|
1160
|
+
(ps.temporal_id_nested << 2) |
|
1161
|
+
(ps.num_temporal_layers << 3) |
|
1162
|
+
(ps.frame_rate.fixed ? 64 : 0),
|
1163
|
+
units.length,
|
1164
|
+
]);
|
1165
|
+
|
1166
|
+
// compute hvcC size in bytes
|
1167
|
+
let length = config.length;
|
1168
|
+
for (let i = 0; i < units.length; i += 1) {
|
1169
|
+
length += 3;
|
1170
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
1171
|
+
length += 2 + units[i][j].length;
|
1172
|
+
}
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
const hvcC = new Uint8Array(length);
|
1176
|
+
hvcC.set(config, 0);
|
1177
|
+
length = config.length;
|
1178
|
+
// append parameter set units: one vps, one or more sps and pps
|
1179
|
+
const iMax = units.length - 1;
|
1180
|
+
for (let i = 0; i < units.length; i += 1) {
|
1181
|
+
hvcC.set(
|
1182
|
+
new Uint8Array([
|
1183
|
+
(32 + i) | (i === iMax ? 128 : 0),
|
1184
|
+
0x00,
|
1185
|
+
units[i].length,
|
1186
|
+
]),
|
1187
|
+
length,
|
1188
|
+
);
|
1189
|
+
length += 3;
|
1190
|
+
for (let j = 0; j < units[i].length; j += 1) {
|
1191
|
+
hvcC.set(
|
1192
|
+
new Uint8Array([units[i][j].length >> 8, units[i][j].length & 255]),
|
1193
|
+
length,
|
1194
|
+
);
|
1195
|
+
length += 2;
|
1196
|
+
hvcC.set(units[i][j], length);
|
1197
|
+
length += units[i][j].length;
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
const hvcc = MP4.box(MP4.types.hvcC, hvcC);
|
1201
|
+
const width = track.width;
|
1202
|
+
const height = track.height;
|
1203
|
+
const hSpacing = track.pixelRatio[0];
|
1204
|
+
const vSpacing = track.pixelRatio[1];
|
1205
|
+
|
1206
|
+
return MP4.box(
|
1207
|
+
MP4.types.hvc1,
|
1208
|
+
new Uint8Array([
|
1209
|
+
0x00,
|
1210
|
+
0x00,
|
1211
|
+
0x00, // reserved
|
1212
|
+
0x00,
|
1213
|
+
0x00,
|
1214
|
+
0x00, // reserved
|
1215
|
+
0x00,
|
1216
|
+
0x01, // data_reference_index
|
1217
|
+
0x00,
|
1218
|
+
0x00, // pre_defined
|
1219
|
+
0x00,
|
1220
|
+
0x00, // reserved
|
1221
|
+
0x00,
|
1222
|
+
0x00,
|
1223
|
+
0x00,
|
1224
|
+
0x00,
|
1225
|
+
0x00,
|
1226
|
+
0x00,
|
1227
|
+
0x00,
|
1228
|
+
0x00,
|
1229
|
+
0x00,
|
1230
|
+
0x00,
|
1231
|
+
0x00,
|
1232
|
+
0x00, // pre_defined
|
1233
|
+
(width >> 8) & 0xff,
|
1234
|
+
width & 0xff, // width
|
1235
|
+
(height >> 8) & 0xff,
|
1236
|
+
height & 0xff, // height
|
1237
|
+
0x00,
|
1238
|
+
0x48,
|
1239
|
+
0x00,
|
1240
|
+
0x00, // horizresolution
|
1241
|
+
0x00,
|
1242
|
+
0x48,
|
1243
|
+
0x00,
|
1244
|
+
0x00, // vertresolution
|
1245
|
+
0x00,
|
1246
|
+
0x00,
|
1247
|
+
0x00,
|
1248
|
+
0x00, // reserved
|
1249
|
+
0x00,
|
1250
|
+
0x01, // frame_count
|
1251
|
+
0x12,
|
1252
|
+
0x64,
|
1253
|
+
0x61,
|
1254
|
+
0x69,
|
1255
|
+
0x6c, // dailymotion/hls.js
|
1256
|
+
0x79,
|
1257
|
+
0x6d,
|
1258
|
+
0x6f,
|
1259
|
+
0x74,
|
1260
|
+
0x69,
|
1261
|
+
0x6f,
|
1262
|
+
0x6e,
|
1263
|
+
0x2f,
|
1264
|
+
0x68,
|
1265
|
+
0x6c,
|
1266
|
+
0x73,
|
1267
|
+
0x2e,
|
1268
|
+
0x6a,
|
1269
|
+
0x73,
|
1270
|
+
0x00,
|
1271
|
+
0x00,
|
1272
|
+
0x00,
|
1273
|
+
0x00,
|
1274
|
+
0x00,
|
1275
|
+
0x00,
|
1276
|
+
0x00,
|
1277
|
+
0x00,
|
1278
|
+
0x00,
|
1279
|
+
0x00,
|
1280
|
+
0x00,
|
1281
|
+
0x00,
|
1282
|
+
0x00, // compressorname
|
1283
|
+
0x00,
|
1284
|
+
0x18, // depth = 24
|
1285
|
+
0x11,
|
1286
|
+
0x11,
|
1287
|
+
]), // pre_defined = -1
|
1288
|
+
hvcc,
|
1289
|
+
MP4.box(
|
1290
|
+
MP4.types.btrt,
|
1291
|
+
new Uint8Array([
|
1292
|
+
0x00,
|
1293
|
+
0x1c,
|
1294
|
+
0x9c,
|
1295
|
+
0x80, // bufferSizeDB
|
1296
|
+
0x00,
|
1297
|
+
0x2d,
|
1298
|
+
0xc6,
|
1299
|
+
0xc0, // maxBitrate
|
1300
|
+
0x00,
|
1301
|
+
0x2d,
|
1302
|
+
0xc6,
|
1303
|
+
0xc0,
|
1304
|
+
]),
|
1305
|
+
), // avgBitrate
|
1306
|
+
MP4.box(
|
1307
|
+
MP4.types.pasp,
|
1308
|
+
new Uint8Array([
|
1309
|
+
hSpacing >> 24, // hSpacing
|
1310
|
+
(hSpacing >> 16) & 0xff,
|
1311
|
+
(hSpacing >> 8) & 0xff,
|
1312
|
+
hSpacing & 0xff,
|
1313
|
+
vSpacing >> 24, // vSpacing
|
1314
|
+
(vSpacing >> 16) & 0xff,
|
1315
|
+
(vSpacing >> 8) & 0xff,
|
1316
|
+
vSpacing & 0xff,
|
1317
|
+
]),
|
1318
|
+
),
|
1319
|
+
);
|
1320
|
+
}
|
1126
1321
|
}
|
1127
1322
|
|
1128
1323
|
export default MP4;
|
package/src/remux/mp4-remuxer.ts
CHANGED
@@ -516,7 +516,7 @@ export default class MP4Remuxer implements Remuxer {
|
|
516
516
|
if (foundHole || foundOverlap) {
|
517
517
|
if (foundHole) {
|
518
518
|
logger.warn(
|
519
|
-
|
519
|
+
`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(
|
520
520
|
delta,
|
521
521
|
true,
|
522
522
|
)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(
|
@@ -525,7 +525,7 @@ export default class MP4Remuxer implements Remuxer {
|
|
525
525
|
);
|
526
526
|
} else {
|
527
527
|
logger.warn(
|
528
|
-
|
528
|
+
`${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(
|
529
529
|
-delta,
|
530
530
|
true,
|
531
531
|
)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(
|
@@ -759,7 +759,7 @@ export default class MP4Remuxer implements Remuxer {
|
|
759
759
|
}
|
760
760
|
}
|
761
761
|
}
|
762
|
-
// next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
762
|
+
// next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
763
763
|
mp4SampleDuration =
|
764
764
|
stretchedLastFrame || !mp4SampleDuration
|
765
765
|
? averageSampleDuration
|
package/src/types/demuxer.ts
CHANGED
@@ -73,12 +73,14 @@ export interface DemuxedVideoTrackBase extends DemuxedTrack {
|
|
73
73
|
height?: number;
|
74
74
|
pixelRatio?: [number, number];
|
75
75
|
audFound?: boolean;
|
76
|
+
vps?: Uint8Array[];
|
76
77
|
pps?: Uint8Array[];
|
77
78
|
sps?: Uint8Array[];
|
78
79
|
naluState?: number;
|
79
80
|
segmentCodec?: string;
|
80
81
|
manifestCodec?: string;
|
81
82
|
samples: VideoSample[] | Uint8Array;
|
83
|
+
params?: object;
|
82
84
|
}
|
83
85
|
|
84
86
|
export interface DemuxedVideoTrack extends DemuxedVideoTrackBase {
|