video-player-dd 2.0.1

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.
@@ -0,0 +1,2546 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global.JMuxer = factory());
5
+ }(this, (function () { 'use strict';
6
+
7
+ var logger = void 0;
8
+ var errorLogger = void 0;
9
+
10
+ function setLogger() {
11
+ /*eslint-disable */
12
+ logger = console.log;
13
+ errorLogger = console.error;
14
+ /*eslint-enable */
15
+ }
16
+
17
+
18
+
19
+ function log(message) {
20
+ if (logger) {
21
+ for (var _len = arguments.length, optionalParams = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
22
+ optionalParams[_key - 1] = arguments[_key];
23
+ }
24
+
25
+ logger.apply(undefined, [message].concat(optionalParams));
26
+ }
27
+ }
28
+ function error(message) {
29
+ if (errorLogger) {
30
+ for (var _len2 = arguments.length, optionalParams = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
31
+ optionalParams[_key2 - 1] = arguments[_key2];
32
+ }
33
+
34
+ errorLogger.apply(undefined, [message].concat(optionalParams));
35
+ }
36
+ }
37
+
38
+ var asyncGenerator = function () {
39
+ function AwaitValue(value) {
40
+ this.value = value;
41
+ }
42
+
43
+ function AsyncGenerator(gen) {
44
+ var front, back;
45
+
46
+ function send(key, arg) {
47
+ return new Promise(function (resolve, reject) {
48
+ var request = {
49
+ key: key,
50
+ arg: arg,
51
+ resolve: resolve,
52
+ reject: reject,
53
+ next: null
54
+ };
55
+
56
+ if (back) {
57
+ back = back.next = request;
58
+ } else {
59
+ front = back = request;
60
+ resume(key, arg);
61
+ }
62
+ });
63
+ }
64
+
65
+ function resume(key, arg) {
66
+ try {
67
+ var result = gen[key](arg);
68
+ var value = result.value;
69
+
70
+ if (value instanceof AwaitValue) {
71
+ Promise.resolve(value.value).then(function (arg) {
72
+ resume("next", arg);
73
+ }, function (arg) {
74
+ resume("throw", arg);
75
+ });
76
+ } else {
77
+ settle(result.done ? "return" : "normal", result.value);
78
+ }
79
+ } catch (err) {
80
+ settle("throw", err);
81
+ }
82
+ }
83
+
84
+ function settle(type, value) {
85
+ switch (type) {
86
+ case "return":
87
+ front.resolve({
88
+ value: value,
89
+ done: true
90
+ });
91
+ break;
92
+
93
+ case "throw":
94
+ front.reject(value);
95
+ break;
96
+
97
+ default:
98
+ front.resolve({
99
+ value: value,
100
+ done: false
101
+ });
102
+ break;
103
+ }
104
+
105
+ front = front.next;
106
+
107
+ if (front) {
108
+ resume(front.key, front.arg);
109
+ } else {
110
+ back = null;
111
+ }
112
+ }
113
+
114
+ this._invoke = send;
115
+
116
+ if (typeof gen.return !== "function") {
117
+ this.return = undefined;
118
+ }
119
+ }
120
+
121
+ if (typeof Symbol === "function" && Symbol.asyncIterator) {
122
+ AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
123
+ return this;
124
+ };
125
+ }
126
+
127
+ AsyncGenerator.prototype.next = function (arg) {
128
+ return this._invoke("next", arg);
129
+ };
130
+
131
+ AsyncGenerator.prototype.throw = function (arg) {
132
+ return this._invoke("throw", arg);
133
+ };
134
+
135
+ AsyncGenerator.prototype.return = function (arg) {
136
+ return this._invoke("return", arg);
137
+ };
138
+
139
+ return {
140
+ wrap: function (fn) {
141
+ return function () {
142
+ return new AsyncGenerator(fn.apply(this, arguments));
143
+ };
144
+ },
145
+ await: function (value) {
146
+ return new AwaitValue(value);
147
+ }
148
+ };
149
+ }();
150
+
151
+
152
+
153
+
154
+
155
+ var classCallCheck = function (instance, Constructor) {
156
+ if (!(instance instanceof Constructor)) {
157
+ throw new TypeError("Cannot call a class as a function");
158
+ }
159
+ };
160
+
161
+ var createClass = function () {
162
+ function defineProperties(target, props) {
163
+ for (var i = 0; i < props.length; i++) {
164
+ var descriptor = props[i];
165
+ descriptor.enumerable = descriptor.enumerable || false;
166
+ descriptor.configurable = true;
167
+ if ("value" in descriptor) descriptor.writable = true;
168
+ Object.defineProperty(target, descriptor.key, descriptor);
169
+ }
170
+ }
171
+
172
+ return function (Constructor, protoProps, staticProps) {
173
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
174
+ if (staticProps) defineProperties(Constructor, staticProps);
175
+ return Constructor;
176
+ };
177
+ }();
178
+
179
+
180
+
181
+
182
+
183
+ var defineProperty = function (obj, key, value) {
184
+ if (key in obj) {
185
+ Object.defineProperty(obj, key, {
186
+ value: value,
187
+ enumerable: true,
188
+ configurable: true,
189
+ writable: true
190
+ });
191
+ } else {
192
+ obj[key] = value;
193
+ }
194
+
195
+ return obj;
196
+ };
197
+
198
+
199
+
200
+ var inherits = function (subClass, superClass) {
201
+ if (typeof superClass !== "function" && superClass !== null) {
202
+ throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
203
+ }
204
+
205
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
206
+ constructor: {
207
+ value: subClass,
208
+ enumerable: false,
209
+ writable: true,
210
+ configurable: true
211
+ }
212
+ });
213
+ if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
214
+ };
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+ var possibleConstructorReturn = function (self, call) {
227
+ if (!self) {
228
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
229
+ }
230
+
231
+ return call && (typeof call === "object" || typeof call === "function") ? call : self;
232
+ };
233
+
234
+ var NALU = function () {
235
+ createClass(NALU, null, [{
236
+ key: 'type',
237
+ value: function type(nalu) {
238
+ if (nalu.ntype in NALU.TYPES) {
239
+ return NALU.TYPES[nalu.ntype];
240
+ } else {
241
+ return 'UNKNOWN';
242
+ }
243
+ }
244
+ }, {
245
+ key: 'NDR',
246
+ get: function get$$1() {
247
+ return 1;
248
+ }
249
+ }, {
250
+ key: 'IDR',
251
+ get: function get$$1() {
252
+ return 5;
253
+ }
254
+ }, {
255
+ key: 'SEI',
256
+ get: function get$$1() {
257
+ return 6;
258
+ }
259
+ }, {
260
+ key: 'SPS',
261
+ get: function get$$1() {
262
+ return 7;
263
+ }
264
+ }, {
265
+ key: 'PPS',
266
+ get: function get$$1() {
267
+ return 8;
268
+ }
269
+ }, {
270
+ key: 'AUD',
271
+ get: function get$$1() {
272
+ return 9;
273
+ }
274
+ }, {
275
+ key: 'TYPES',
276
+ get: function get$$1() {
277
+ var _ref;
278
+
279
+ return _ref = {}, babelHelpers.defineProperty(_ref, NALU.IDR, 'IDR'), babelHelpers.defineProperty(_ref, NALU.SEI, 'SEI'), babelHelpers.defineProperty(_ref, NALU.SPS, 'SPS'), babelHelpers.defineProperty(_ref, NALU.PPS, 'PPS'), babelHelpers.defineProperty(_ref, NALU.NDR, 'NDR'), babelHelpers.defineProperty(_ref, NALU.AUD, 'AUD'), _ref;
280
+ }
281
+ }]);
282
+
283
+ function NALU(data) {
284
+ classCallCheck(this, NALU);
285
+
286
+ this.payload = data;
287
+ this.nri = (this.payload[0] & 0x60) >> 5;
288
+ this.ntype = this.payload[0] & 0x1f;
289
+ }
290
+
291
+ createClass(NALU, [{
292
+ key: 'toString',
293
+ value: function toString() {
294
+ return NALU.type(this) + ': NRI: ' + this.getNri();
295
+ }
296
+ }, {
297
+ key: 'getNri',
298
+ value: function getNri() {
299
+ return this.nri >> 6;
300
+ }
301
+ }, {
302
+ key: 'type',
303
+ value: function type() {
304
+ return this.ntype;
305
+ }
306
+ }, {
307
+ key: 'isKeyframe',
308
+ value: function isKeyframe() {
309
+ return this.ntype == NALU.IDR;
310
+ }
311
+ }, {
312
+ key: 'getSize',
313
+ value: function getSize() {
314
+ return 4 + this.payload.byteLength;
315
+ }
316
+ }, {
317
+ key: 'getData',
318
+ value: function getData() {
319
+ var result = new Uint8Array(this.getSize());
320
+ var view = new DataView(result.buffer);
321
+ view.setUint32(0, this.getSize() - 4);
322
+
323
+ result.set(this.payload, 4);
324
+ return result;
325
+ }
326
+ }]);
327
+ return NALU;
328
+ }();
329
+
330
+ /**
331
+ * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
332
+ */
333
+
334
+ var ExpGolomb = function () {
335
+ function ExpGolomb(data) {
336
+ classCallCheck(this, ExpGolomb);
337
+
338
+ this.data = data;
339
+ this.index = 0;
340
+ this.bitLength = data.byteLength * 8;
341
+ }
342
+
343
+ createClass(ExpGolomb, [{
344
+ key: "skipBits",
345
+ value: function skipBits(size) {
346
+ // console.log(` skip bits: size=${size}, ${this.index}.`);
347
+ if (this.bitsAvailable < size) {
348
+ //throw new Error('no bytes available');
349
+ return false;
350
+ }
351
+ this.index += size;
352
+ }
353
+ }, {
354
+ key: "readBits",
355
+ value: function readBits(size) {
356
+ var moveIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
357
+
358
+ // console.log(` read bits: size=${size}, ${this.index}.`);
359
+ var result = this.getBits(size, this.index, moveIndex);
360
+ // console.log(` read bits: result=${result}`);
361
+ return result;
362
+ }
363
+ }, {
364
+ key: "getBits",
365
+ value: function getBits(size, offsetBits) {
366
+ var moveIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
367
+
368
+ if (this.bitsAvailable < size) {
369
+ //throw new Error('no bytes available');
370
+ return 0;
371
+ }
372
+ var offset = offsetBits % 8;
373
+ var byte = this.data[offsetBits / 8 | 0] & 0xff >>> offset;
374
+ var bits = 8 - offset;
375
+ if (bits >= size) {
376
+ if (moveIndex) {
377
+ this.index += size;
378
+ }
379
+ return byte >> bits - size;
380
+ } else {
381
+ if (moveIndex) {
382
+ this.index += bits;
383
+ }
384
+ var nextSize = size - bits;
385
+ return byte << nextSize | this.getBits(nextSize, offsetBits + bits, moveIndex);
386
+ }
387
+ }
388
+ }, {
389
+ key: "skipLZ",
390
+ value: function skipLZ() {
391
+ var leadingZeroCount = void 0;
392
+ for (leadingZeroCount = 0; leadingZeroCount < this.bitLength - this.index; ++leadingZeroCount) {
393
+ if (this.getBits(1, this.index + leadingZeroCount, false) !== 0) {
394
+ // console.log(` skip LZ : size=${leadingZeroCount}, ${this.index}.`);
395
+ this.index += leadingZeroCount;
396
+ return leadingZeroCount;
397
+ }
398
+ }
399
+ return leadingZeroCount;
400
+ }
401
+ }, {
402
+ key: "skipUEG",
403
+ value: function skipUEG() {
404
+ this.skipBits(1 + this.skipLZ());
405
+ }
406
+ }, {
407
+ key: "skipEG",
408
+ value: function skipEG() {
409
+ this.skipBits(1 + this.skipLZ());
410
+ }
411
+ }, {
412
+ key: "readUEG",
413
+ value: function readUEG() {
414
+ var prefix = this.skipLZ();
415
+ return this.readBits(prefix + 1) - 1;
416
+ }
417
+ }, {
418
+ key: "readEG",
419
+ value: function readEG() {
420
+ var value = this.readUEG();
421
+ if (0x01 & value) {
422
+ // the number is odd if the low order bit is set
423
+ return 1 + value >>> 1; // add 1 to make it even, and divide by 2
424
+ } else {
425
+ return -1 * (value >>> 1); // divide by two then make it negative
426
+ }
427
+ }
428
+ }, {
429
+ key: "readBoolean",
430
+ value: function readBoolean() {
431
+ return this.readBits(1) === 1;
432
+ }
433
+ }, {
434
+ key: "readUByte",
435
+ value: function readUByte() {
436
+ var numberOfBytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
437
+
438
+ return this.readBits(numberOfBytes * 8);
439
+ }
440
+ }, {
441
+ key: "readUShort",
442
+ value: function readUShort() {
443
+ return this.readBits(16);
444
+ }
445
+ }, {
446
+ key: "readUInt",
447
+ value: function readUInt() {
448
+ return this.readBits(32);
449
+ }
450
+ }, {
451
+ key: "bitsAvailable",
452
+ get: function get$$1() {
453
+ return this.bitLength - this.index;
454
+ }
455
+ }]);
456
+ return ExpGolomb;
457
+ }();
458
+
459
+ var H264Parser = function () {
460
+ createClass(H264Parser, null, [{
461
+ key: 'extractNALu',
462
+ value: function extractNALu(buffer) {
463
+ var i = 0,
464
+ length = buffer.byteLength,
465
+ value = void 0,
466
+ state = 0,
467
+ result = [],
468
+ lastIndex = void 0;
469
+
470
+ while (i < length) {
471
+ value = buffer[i++];
472
+ // finding 3 or 4-byte start codes (00 00 01 OR 00 00 00 01)
473
+ switch (state) {
474
+ case 0:
475
+ if (value === 0) {
476
+ state = 1;
477
+ }
478
+ break;
479
+ case 1:
480
+ if (value === 0) {
481
+ state = 2;
482
+ } else {
483
+ state = 0;
484
+ }
485
+ break;
486
+ case 2:
487
+ case 3:
488
+ if (value === 0) {
489
+ state = 3;
490
+ } else if (value === 1 && i < length) {
491
+ if (lastIndex) {
492
+ result.push(buffer.subarray(lastIndex, i - state - 1));
493
+ }
494
+ lastIndex = i;
495
+ state = 0;
496
+ } else {
497
+ state = 0;
498
+ }
499
+ break;
500
+ default:
501
+ break;
502
+ }
503
+ }
504
+
505
+ if (lastIndex) {
506
+ result.push(buffer.subarray(lastIndex, length));
507
+ }
508
+ return result;
509
+ }
510
+
511
+ /**
512
+ * Advance the ExpGolomb decoder past a scaling list. The scaling
513
+ * list is optionally transmitted as part of a sequence parameter
514
+ * set and is not relevant to transmuxing.
515
+ * @param decoder {ExpGolomb} exp golomb decoder
516
+ * @param count {number} the number of entries in this scaling list
517
+ * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
518
+ */
519
+
520
+ }, {
521
+ key: 'skipScalingList',
522
+ value: function skipScalingList(decoder, count) {
523
+ var lastScale = 8,
524
+ nextScale = 8,
525
+ deltaScale = void 0;
526
+ for (var j = 0; j < count; j++) {
527
+ if (nextScale !== 0) {
528
+ deltaScale = decoder.readEG();
529
+ nextScale = (lastScale + deltaScale + 256) % 256;
530
+ }
531
+ lastScale = nextScale === 0 ? lastScale : nextScale;
532
+ }
533
+ }
534
+
535
+ /**
536
+ * Read a sequence parameter set and return some interesting video
537
+ * properties. A sequence parameter set is the H264 metadata that
538
+ * describes the properties of upcoming video frames.
539
+ * @param data {Uint8Array} the bytes of a sequence parameter set
540
+ * @return {object} an object with configuration parsed from the
541
+ * sequence parameter set, including the dimensions of the
542
+ * associated video frames.
543
+ */
544
+
545
+ }, {
546
+ key: 'readSPS',
547
+ value: function readSPS(data) {
548
+ var decoder = new ExpGolomb(data);
549
+ var frameCropLeftOffset = 0,
550
+ frameCropRightOffset = 0,
551
+ frameCropTopOffset = 0,
552
+ frameCropBottomOffset = 0,
553
+ sarScale = 1,
554
+ profileIdc = void 0,
555
+ profileCompat = void 0,
556
+ levelIdc = void 0,
557
+ numRefFramesInPicOrderCntCycle = void 0,
558
+ picWidthInMbsMinus1 = void 0,
559
+ picHeightInMapUnitsMinus1 = void 0,
560
+ frameMbsOnlyFlag = void 0,
561
+ scalingListCount = void 0;
562
+ decoder.readUByte();
563
+ profileIdc = decoder.readUByte(); // profile_idc
564
+ profileCompat = decoder.readBits(5); // constraint_set[0-4]_flag, u(5)
565
+ decoder.skipBits(3); // reserved_zero_3bits u(3),
566
+ levelIdc = decoder.readUByte(); // level_idc u(8)
567
+ decoder.skipUEG(); // seq_parameter_set_id
568
+ // some profiles have more optional data we don't need
569
+ if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
570
+ var chromaFormatIdc = decoder.readUEG();
571
+ if (chromaFormatIdc === 3) {
572
+ decoder.skipBits(1); // separate_colour_plane_flag
573
+ }
574
+ decoder.skipUEG(); // bit_depth_luma_minus8
575
+ decoder.skipUEG(); // bit_depth_chroma_minus8
576
+ decoder.skipBits(1); // qpprime_y_zero_transform_bypass_flag
577
+ if (decoder.readBoolean()) {
578
+ // seq_scaling_matrix_present_flag
579
+ scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
580
+ for (var i = 0; i < scalingListCount; ++i) {
581
+ if (decoder.readBoolean()) {
582
+ // seq_scaling_list_present_flag[ i ]
583
+ if (i < 6) {
584
+ H264Parser.skipScalingList(decoder, 16);
585
+ } else {
586
+ H264Parser.skipScalingList(decoder, 64);
587
+ }
588
+ }
589
+ }
590
+ }
591
+ }
592
+ decoder.skipUEG(); // log2_max_frame_num_minus4
593
+ var picOrderCntType = decoder.readUEG();
594
+ if (picOrderCntType === 0) {
595
+ decoder.readUEG(); // log2_max_pic_order_cnt_lsb_minus4
596
+ } else if (picOrderCntType === 1) {
597
+ decoder.skipBits(1); // delta_pic_order_always_zero_flag
598
+ decoder.skipEG(); // offset_for_non_ref_pic
599
+ decoder.skipEG(); // offset_for_top_to_bottom_field
600
+ numRefFramesInPicOrderCntCycle = decoder.readUEG();
601
+ for (var _i = 0; _i < numRefFramesInPicOrderCntCycle; ++_i) {
602
+ decoder.skipEG(); // offset_for_ref_frame[ i ]
603
+ }
604
+ }
605
+ decoder.skipUEG(); // max_num_ref_frames
606
+ decoder.skipBits(1); // gaps_in_frame_num_value_allowed_flag
607
+ picWidthInMbsMinus1 = decoder.readUEG();
608
+ picHeightInMapUnitsMinus1 = decoder.readUEG();
609
+ frameMbsOnlyFlag = decoder.readBits(1);
610
+ if (frameMbsOnlyFlag === 0) {
611
+ decoder.skipBits(1); // mb_adaptive_frame_field_flag
612
+ }
613
+ decoder.skipBits(1); // direct_8x8_inference_flag
614
+ if (decoder.readBoolean()) {
615
+ // frame_cropping_flag
616
+ frameCropLeftOffset = decoder.readUEG();
617
+ frameCropRightOffset = decoder.readUEG();
618
+ frameCropTopOffset = decoder.readUEG();
619
+ frameCropBottomOffset = decoder.readUEG();
620
+ }
621
+ if (decoder.readBoolean()) {
622
+ // vui_parameters_present_flag
623
+ if (decoder.readBoolean()) {
624
+ // aspect_ratio_info_present_flag
625
+ var sarRatio = void 0;
626
+ var aspectRatioIdc = decoder.readUByte();
627
+ switch (aspectRatioIdc) {
628
+ case 1:
629
+ sarRatio = [1, 1];break;
630
+ case 2:
631
+ sarRatio = [12, 11];break;
632
+ case 3:
633
+ sarRatio = [10, 11];break;
634
+ case 4:
635
+ sarRatio = [16, 11];break;
636
+ case 5:
637
+ sarRatio = [40, 33];break;
638
+ case 6:
639
+ sarRatio = [24, 11];break;
640
+ case 7:
641
+ sarRatio = [20, 11];break;
642
+ case 8:
643
+ sarRatio = [32, 11];break;
644
+ case 9:
645
+ sarRatio = [80, 33];break;
646
+ case 10:
647
+ sarRatio = [18, 11];break;
648
+ case 11:
649
+ sarRatio = [15, 11];break;
650
+ case 12:
651
+ sarRatio = [64, 33];break;
652
+ case 13:
653
+ sarRatio = [160, 99];break;
654
+ case 14:
655
+ sarRatio = [4, 3];break;
656
+ case 15:
657
+ sarRatio = [3, 2];break;
658
+ case 16:
659
+ sarRatio = [2, 1];break;
660
+ case 255:
661
+ {
662
+ sarRatio = [decoder.readUByte() << 8 | decoder.readUByte(), decoder.readUByte() << 8 | decoder.readUByte()];
663
+ break;
664
+ }
665
+ }
666
+ if (sarRatio) {
667
+ sarScale = sarRatio[0] / sarRatio[1];
668
+ }
669
+ }
670
+ if (decoder.readBoolean()) {
671
+ decoder.skipBits(1);
672
+ }
673
+
674
+ if (decoder.readBoolean()) {
675
+ decoder.skipBits(4);
676
+ if (decoder.readBoolean()) {
677
+ decoder.skipBits(24);
678
+ }
679
+ }
680
+ if (decoder.readBoolean()) {
681
+ decoder.skipUEG();
682
+ decoder.skipUEG();
683
+ }
684
+ if (decoder.readBoolean()) {
685
+ var unitsInTick = decoder.readUInt();
686
+ var timeScale = decoder.readUInt();
687
+ var fixedFrameRate = decoder.readBoolean();
688
+
689
+ }
690
+ }
691
+ return {
692
+ width: Math.ceil(((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2) * sarScale),
693
+ height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset)
694
+ };
695
+ }
696
+ }]);
697
+
698
+ function H264Parser(remuxer) {
699
+ classCallCheck(this, H264Parser);
700
+
701
+ this.remuxer = remuxer;
702
+ this.track = remuxer.mp4track;
703
+ }
704
+
705
+ createClass(H264Parser, [{
706
+ key: 'parseSPS',
707
+ value: function parseSPS(sps) {
708
+ var config = H264Parser.readSPS(new Uint8Array(sps));
709
+
710
+ this.track.width = config.width;
711
+ this.track.height = config.height;
712
+ this.track.sps = [new Uint8Array(sps)];
713
+ this.track.codec = 'avc1.';
714
+
715
+ var codecarray = new DataView(sps.buffer, sps.byteOffset + 1, 4);
716
+ for (var i = 0; i < 3; ++i) {
717
+ var h = codecarray.getUint8(i).toString(16);
718
+ if (h.length < 2) {
719
+ h = '0' + h;
720
+ }
721
+ this.track.codec += h;
722
+ }
723
+ }
724
+ }, {
725
+ key: 'parsePPS',
726
+ value: function parsePPS(pps) {
727
+ this.track.pps = [new Uint8Array(pps)];
728
+ }
729
+ }, {
730
+ key: 'parseNAL',
731
+ value: function parseNAL(unit) {
732
+ if (!unit) return false;
733
+
734
+ var push = false;
735
+ switch (unit.type()) {
736
+ case NALU.NDR:
737
+ push = true;
738
+ break;
739
+ case NALU.IDR:
740
+ push = true;
741
+ break;
742
+ case NALU.PPS:
743
+ if (!this.track.pps) {
744
+ this.parsePPS(unit.getData().subarray(4));
745
+ if (!this.remuxer.readyToDecode && this.track.pps && this.track.sps) {
746
+ this.remuxer.readyToDecode = true;
747
+ }
748
+ }
749
+ push = true;
750
+ break;
751
+ case NALU.SPS:
752
+ if (!this.track.sps) {
753
+ this.parseSPS(unit.getData().subarray(4));
754
+ if (!this.remuxer.readyToDecode && this.track.pps && this.track.sps) {
755
+ this.remuxer.readyToDecode = true;
756
+ }
757
+ }
758
+ push = true;
759
+ break;
760
+ case NALU.AUD:
761
+ log('AUD - ignoing and disable HD mode for live channel');
762
+ if (this.remuxer.isHDAvail) {
763
+ this.remuxer.isHDAvail = false;
764
+ }
765
+ break;
766
+ case NALU.SEI:
767
+ log('SEI - ignoing');
768
+ break;
769
+ default:
770
+ }
771
+ return push;
772
+ }
773
+ }]);
774
+ return H264Parser;
775
+ }();
776
+
777
+ var aacHeader = void 0;
778
+ var AACParser = function () {
779
+ createClass(AACParser, null, [{
780
+ key: 'getHeaderLength',
781
+ value: function getHeaderLength(data) {
782
+ return data[1] & 0x01 ? 7 : 9; // without CRC 7 and with CRC 9 Refs: https://wiki.multimedia.cx/index.php?title=ADTS
783
+ }
784
+ }, {
785
+ key: 'getFrameLength',
786
+ value: function getFrameLength(data) {
787
+ return (data[3] & 0x03) << 11 | data[4] << 3 | (data[5] & 0xE0) >>> 5; // 13 bits length ref: https://wiki.multimedia.cx/index.php?title=ADTS
788
+ }
789
+ }, {
790
+ key: 'isAACPattern',
791
+ value: function isAACPattern(data) {
792
+ return data[0] === 0xff && (data[1] & 0xf0) === 0xf0 && (data[1] & 0x06) === 0x00;
793
+ }
794
+ }, {
795
+ key: 'extractAAC',
796
+ value: function extractAAC(buffer) {
797
+ var i = 0,
798
+ length = buffer.byteLength,
799
+ result = [],
800
+ headerLength = void 0,
801
+ frameLength = void 0;
802
+
803
+ if (!AACParser.isAACPattern(buffer)) {
804
+ error('Invalid ADTS audio format');
805
+ return result;
806
+ }
807
+ headerLength = AACParser.getHeaderLength(buffer);
808
+ if (!aacHeader) {
809
+ aacHeader = buffer.subarray(0, headerLength);
810
+ }
811
+
812
+ while (i < length) {
813
+ frameLength = AACParser.getFrameLength(buffer);
814
+ result.push(buffer.subarray(headerLength, frameLength));
815
+ buffer = buffer.slice(frameLength);
816
+ i += frameLength;
817
+ }
818
+ return result;
819
+ }
820
+ }, {
821
+ key: 'samplingRateMap',
822
+ get: function get$$1() {
823
+ return [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
824
+ }
825
+ }, {
826
+ key: 'getAACHeaderData',
827
+ get: function get$$1() {
828
+ return aacHeader;
829
+ }
830
+ }]);
831
+
832
+ function AACParser(remuxer) {
833
+ classCallCheck(this, AACParser);
834
+
835
+ this.remuxer = remuxer;
836
+ this.track = remuxer.mp4track;
837
+ }
838
+
839
+ createClass(AACParser, [{
840
+ key: 'setAACConfig',
841
+ value: function setAACConfig() {
842
+ var objectType = void 0,
843
+ sampleIndex = void 0,
844
+ channelCount = void 0,
845
+ config = new Uint8Array(2),
846
+ headerData = AACParser.getAACHeaderData;
847
+
848
+ if (!headerData) return;
849
+
850
+ objectType = ((headerData[2] & 0xC0) >>> 6) + 1;
851
+ sampleIndex = (headerData[2] & 0x3C) >>> 2;
852
+ channelCount = (headerData[2] & 0x01) << 2;
853
+ channelCount |= (headerData[3] & 0xC0) >>> 6;
854
+
855
+ /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config */
856
+ config[0] = objectType << 3;
857
+ config[0] |= (sampleIndex & 0x0E) >> 1;
858
+ config[1] |= (sampleIndex & 0x01) << 7;
859
+ config[1] |= channelCount << 3;
860
+
861
+ this.track.codec = 'mp4a.40.' + objectType;
862
+ this.track.channelCount = channelCount;
863
+ this.track.config = config;
864
+ this.remuxer.readyToDecode = true;
865
+ }
866
+ }]);
867
+ return AACParser;
868
+ }();
869
+
870
+ var Event = function () {
871
+ function Event(type) {
872
+ classCallCheck(this, Event);
873
+
874
+ this.listener = {};
875
+ this.type = type | '';
876
+ }
877
+
878
+ createClass(Event, [{
879
+ key: 'on',
880
+ value: function on(event, fn) {
881
+ if (!this.listener[event]) {
882
+ this.listener[event] = [];
883
+ }
884
+ this.listener[event].push(fn);
885
+ return true;
886
+ }
887
+ }, {
888
+ key: 'off',
889
+ value: function off(event, fn) {
890
+ if (this.listener[event]) {
891
+ var index = this.listener[event].indexOf(fn);
892
+ if (index > -1) {
893
+ this.listener[event].splice(index, 1);
894
+ }
895
+ return true;
896
+ }
897
+ return false;
898
+ }
899
+ }, {
900
+ key: 'offAll',
901
+ value: function offAll() {
902
+ this.listener = {};
903
+ }
904
+ }, {
905
+ key: 'dispatch',
906
+ value: function dispatch(event, data) {
907
+ if (this.listener[event]) {
908
+ this.listener[event].map(function (each) {
909
+ each.apply(null, [data]);
910
+ });
911
+ return true;
912
+ }
913
+ return false;
914
+ }
915
+ }]);
916
+ return Event;
917
+ }();
918
+
919
+ /**
920
+ * Generate MP4 Box
921
+ * taken from: https://github.com/dailymotion/hls.js
922
+ */
923
+
924
+ var MP4 = function () {
925
+ function MP4() {
926
+ classCallCheck(this, MP4);
927
+ }
928
+
929
+ createClass(MP4, null, [{
930
+ key: 'init',
931
+ value: function init() {
932
+ MP4.types = {
933
+ avc1: [], // codingname
934
+ avcC: [],
935
+ btrt: [],
936
+ dinf: [],
937
+ dref: [],
938
+ esds: [],
939
+ ftyp: [],
940
+ hdlr: [],
941
+ mdat: [],
942
+ mdhd: [],
943
+ mdia: [],
944
+ mfhd: [],
945
+ minf: [],
946
+ moof: [],
947
+ moov: [],
948
+ mp4a: [],
949
+ mvex: [],
950
+ mvhd: [],
951
+ sdtp: [],
952
+ stbl: [],
953
+ stco: [],
954
+ stsc: [],
955
+ stsd: [],
956
+ stsz: [],
957
+ stts: [],
958
+ tfdt: [],
959
+ tfhd: [],
960
+ traf: [],
961
+ trak: [],
962
+ trun: [],
963
+ trex: [],
964
+ tkhd: [],
965
+ vmhd: [],
966
+ smhd: []
967
+ };
968
+
969
+ var i;
970
+ for (i in MP4.types) {
971
+ if (MP4.types.hasOwnProperty(i)) {
972
+ MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];
973
+ }
974
+ }
975
+
976
+ var videoHdlr = new Uint8Array([0x00, // version 0
977
+ 0x00, 0x00, 0x00, // flags
978
+ 0x00, 0x00, 0x00, 0x00, // pre_defined
979
+ 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
980
+ 0x00, 0x00, 0x00, 0x00, // reserved
981
+ 0x00, 0x00, 0x00, 0x00, // reserved
982
+ 0x00, 0x00, 0x00, 0x00, // reserved
983
+ 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00]);
984
+
985
+ var audioHdlr = new Uint8Array([0x00, // version 0
986
+ 0x00, 0x00, 0x00, // flags
987
+ 0x00, 0x00, 0x00, 0x00, // pre_defined
988
+ 0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun'
989
+ 0x00, 0x00, 0x00, 0x00, // reserved
990
+ 0x00, 0x00, 0x00, 0x00, // reserved
991
+ 0x00, 0x00, 0x00, 0x00, // reserved
992
+ 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00]);
993
+
994
+ MP4.HDLR_TYPES = {
995
+ video: videoHdlr,
996
+ audio: audioHdlr
997
+ };
998
+
999
+ var dref = new Uint8Array([0x00, // version 0
1000
+ 0x00, 0x00, 0x00, // flags
1001
+ 0x00, 0x00, 0x00, 0x01, // entry_count
1002
+ 0x00, 0x00, 0x00, 0x0c, // entry_size
1003
+ 0x75, 0x72, 0x6c, 0x20, // 'url' type
1004
+ 0x00, // version 0
1005
+ 0x00, 0x00, 0x01]);
1006
+
1007
+ var stco = new Uint8Array([0x00, // version
1008
+ 0x00, 0x00, 0x00, // flags
1009
+ 0x00, 0x00, 0x00, 0x00]);
1010
+
1011
+ MP4.STTS = MP4.STSC = MP4.STCO = stco;
1012
+
1013
+ MP4.STSZ = new Uint8Array([0x00, // version
1014
+ 0x00, 0x00, 0x00, // flags
1015
+ 0x00, 0x00, 0x00, 0x00, // sample_size
1016
+ 0x00, 0x00, 0x00, 0x00]);
1017
+ MP4.VMHD = new Uint8Array([0x00, // version
1018
+ 0x00, 0x00, 0x01, // flags
1019
+ 0x00, 0x00, // graphicsmode
1020
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
1021
+ MP4.SMHD = new Uint8Array([0x00, // version
1022
+ 0x00, 0x00, 0x00, // flags
1023
+ 0x00, 0x00, // balance
1024
+ 0x00, 0x00]);
1025
+
1026
+ MP4.STSD = new Uint8Array([0x00, // version 0
1027
+ 0x00, 0x00, 0x00, // flags
1028
+ 0x00, 0x00, 0x00, 0x01]); // entry_count
1029
+
1030
+ var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom
1031
+ var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1
1032
+ var minorVersion = new Uint8Array([0, 0, 0, 1]);
1033
+
1034
+ MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
1035
+ MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
1036
+ }
1037
+ }, {
1038
+ key: 'box',
1039
+ value: function box(type) {
1040
+ for (var _len = arguments.length, payload = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1041
+ payload[_key - 1] = arguments[_key];
1042
+ }
1043
+
1044
+ var size = 8,
1045
+ i = payload.length,
1046
+ len = i,
1047
+ result;
1048
+ // calculate the total size we need to allocate
1049
+ while (i--) {
1050
+ size += payload[i].byteLength;
1051
+ }
1052
+ result = new Uint8Array(size);
1053
+ result[0] = size >> 24 & 0xff;
1054
+ result[1] = size >> 16 & 0xff;
1055
+ result[2] = size >> 8 & 0xff;
1056
+ result[3] = size & 0xff;
1057
+ result.set(type, 4);
1058
+ // copy the payload into the result
1059
+ for (i = 0, size = 8; i < len; ++i) {
1060
+ // copy payload[i] array @ offset size
1061
+ result.set(payload[i], size);
1062
+ size += payload[i].byteLength;
1063
+ }
1064
+ return result;
1065
+ }
1066
+ }, {
1067
+ key: 'hdlr',
1068
+ value: function hdlr(type) {
1069
+ return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
1070
+ }
1071
+ }, {
1072
+ key: 'mdat',
1073
+ value: function mdat(data) {
1074
+ return MP4.box(MP4.types.mdat, data);
1075
+ }
1076
+ }, {
1077
+ key: 'mdhd',
1078
+ value: function mdhd(timescale, duration) {
1079
+ return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, // version 0
1080
+ 0x00, 0x00, 0x00, // flags
1081
+ 0x00, 0x00, 0x00, 0x02, // creation_time
1082
+ 0x00, 0x00, 0x00, 0x03, // modification_time
1083
+ timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
1084
+ duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
1085
+ 0x55, 0xc4, // 'und' language (undetermined)
1086
+ 0x00, 0x00]));
1087
+ }
1088
+ }, {
1089
+ key: 'mdia',
1090
+ value: function mdia(track) {
1091
+ return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
1092
+ }
1093
+ }, {
1094
+ key: 'mfhd',
1095
+ value: function mfhd(sequenceNumber) {
1096
+ return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags
1097
+ sequenceNumber >> 24, sequenceNumber >> 16 & 0xFF, sequenceNumber >> 8 & 0xFF, sequenceNumber & 0xFF]) // sequence_number
1098
+ );
1099
+ }
1100
+ }, {
1101
+ key: 'minf',
1102
+ value: function minf(track) {
1103
+ if (track.type === 'audio') {
1104
+ return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
1105
+ } else {
1106
+ return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
1107
+ }
1108
+ }
1109
+ }, {
1110
+ key: 'moof',
1111
+ value: function moof(sn, baseMediaDecodeTime, track) {
1112
+ return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
1113
+ }
1114
+ /**
1115
+ * @param tracks... (optional) {array} the tracks associated with this movie
1116
+ */
1117
+
1118
+ }, {
1119
+ key: 'moov',
1120
+ value: function moov(tracks, duration, timescale) {
1121
+ var i = tracks.length,
1122
+ boxes = [];
1123
+
1124
+ while (i--) {
1125
+ boxes[i] = MP4.trak(tracks[i]);
1126
+ }
1127
+
1128
+ return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(timescale, duration)].concat(boxes).concat(MP4.mvex(tracks)));
1129
+ }
1130
+ }, {
1131
+ key: 'mvex',
1132
+ value: function mvex(tracks) {
1133
+ var i = tracks.length,
1134
+ boxes = [];
1135
+
1136
+ while (i--) {
1137
+ boxes[i] = MP4.trex(tracks[i]);
1138
+ }
1139
+ return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));
1140
+ }
1141
+ }, {
1142
+ key: 'mvhd',
1143
+ value: function mvhd(timescale, duration) {
1144
+ var bytes = new Uint8Array([0x00, // version 0
1145
+ 0x00, 0x00, 0x00, // flags
1146
+ 0x00, 0x00, 0x00, 0x01, // creation_time
1147
+ 0x00, 0x00, 0x00, 0x02, // modification_time
1148
+ timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
1149
+ duration >> 24 & 0xFF, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
1150
+ 0x00, 0x01, 0x00, 0x00, // 1.0 rate
1151
+ 0x01, 0x00, // 1.0 volume
1152
+ 0x00, 0x00, // reserved
1153
+ 0x00, 0x00, 0x00, 0x00, // reserved
1154
+ 0x00, 0x00, 0x00, 0x00, // reserved
1155
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
1156
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
1157
+ 0xff, 0xff, 0xff, 0xff]);
1158
+ return MP4.box(MP4.types.mvhd, bytes);
1159
+ }
1160
+ }, {
1161
+ key: 'sdtp',
1162
+ value: function sdtp(track) {
1163
+ var samples = track.samples || [],
1164
+ bytes = new Uint8Array(4 + samples.length),
1165
+ flags,
1166
+ i;
1167
+ // leave the full box header (4 bytes) all zero
1168
+ // write the sample table
1169
+ for (i = 0; i < samples.length; i++) {
1170
+ flags = samples[i].flags;
1171
+ bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
1172
+ }
1173
+
1174
+ return MP4.box(MP4.types.sdtp, bytes);
1175
+ }
1176
+ }, {
1177
+ key: 'stbl',
1178
+ value: function stbl(track) {
1179
+ return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
1180
+ }
1181
+ }, {
1182
+ key: 'avc1',
1183
+ value: function avc1(track) {
1184
+ var sps = [],
1185
+ pps = [],
1186
+ i,
1187
+ data,
1188
+ len;
1189
+ // assemble the SPSs
1190
+
1191
+ for (i = 0; i < track.sps.length; i++) {
1192
+ data = track.sps[i];
1193
+ len = data.byteLength;
1194
+ sps.push(len >>> 8 & 0xFF);
1195
+ sps.push(len & 0xFF);
1196
+ sps = sps.concat(Array.prototype.slice.call(data)); // SPS
1197
+ }
1198
+
1199
+ // assemble the PPSs
1200
+ for (i = 0; i < track.pps.length; i++) {
1201
+ data = track.pps[i];
1202
+ len = data.byteLength;
1203
+ pps.push(len >>> 8 & 0xFF);
1204
+ pps.push(len & 0xFF);
1205
+ pps = pps.concat(Array.prototype.slice.call(data));
1206
+ }
1207
+
1208
+ var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version
1209
+ sps[3], // profile
1210
+ sps[4], // profile compat
1211
+ sps[5], // level
1212
+ 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes
1213
+ 0xE0 | track.sps.length].concat(sps).concat([track.pps.length] // numOfPictureParameterSets
1214
+ ).concat(pps))),
1215
+ // "PPS"
1216
+ width = track.width,
1217
+ height = track.height;
1218
+ // console.log('avcc:' + Hex.hexDump(avcc));
1219
+ return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved
1220
+ 0x00, 0x00, 0x00, // reserved
1221
+ 0x00, 0x01, // data_reference_index
1222
+ 0x00, 0x00, // pre_defined
1223
+ 0x00, 0x00, // reserved
1224
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
1225
+ width >> 8 & 0xFF, width & 0xff, // width
1226
+ height >> 8 & 0xFF, height & 0xff, // height
1227
+ 0x00, 0x48, 0x00, 0x00, // horizresolution
1228
+ 0x00, 0x48, 0x00, 0x00, // vertresolution
1229
+ 0x00, 0x00, 0x00, 0x00, // reserved
1230
+ 0x00, 0x01, // frame_count
1231
+ 0x12, 0x62, 0x69, 0x6E, 0x65, // binelpro.ru
1232
+ 0x6C, 0x70, 0x72, 0x6F, 0x2E, 0x72, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname
1233
+ 0x00, 0x18, // depth = 24
1234
+ 0x11, 0x11]), // pre_defined = -1
1235
+ avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB
1236
+ 0x00, 0x2d, 0xc6, 0xc0, // maxBitrate
1237
+ 0x00, 0x2d, 0xc6, 0xc0])) // avgBitrate
1238
+ );
1239
+ }
1240
+ }, {
1241
+ key: 'esds',
1242
+ value: function esds(track) {
1243
+ var configlen = track.config.byteLength;
1244
+ var data = new Uint8Array(26 + configlen + 3);
1245
+ data.set([0x00, // version 0
1246
+ 0x00, 0x00, 0x00, // flags
1247
+
1248
+ 0x03, // descriptor_type
1249
+ 0x17 + configlen, // length
1250
+ 0x00, 0x01, // es_id
1251
+ 0x00, // stream_priority
1252
+
1253
+ 0x04, // descriptor_type
1254
+ 0x0f + configlen, // length
1255
+ 0x40, // codec : mpeg4_audio
1256
+ 0x15, // stream_type
1257
+ 0x00, 0x00, 0x00, // buffer_size
1258
+ 0x00, 0x00, 0x00, 0x00, // maxBitrate
1259
+ 0x00, 0x00, 0x00, 0x00, // avgBitrate
1260
+
1261
+ 0x05, // descriptor_type
1262
+ configlen]);
1263
+ data.set(track.config, 26);
1264
+ data.set([0x06, 0x01, 0x02], 26 + configlen);
1265
+ // return new Uint8Array([
1266
+ // 0x00, // version 0
1267
+ // 0x00, 0x00, 0x00, // flags
1268
+ //
1269
+ // 0x03, // descriptor_type
1270
+ // 0x17+configlen, // length
1271
+ // 0x00, 0x01, //es_id
1272
+ // 0x00, // stream_priority
1273
+ //
1274
+ // 0x04, // descriptor_type
1275
+ // 0x0f+configlen, // length
1276
+ // 0x40, //codec : mpeg4_audio
1277
+ // 0x15, // stream_type
1278
+ // 0x00, 0x00, 0x00, // buffer_size
1279
+ // 0x00, 0x00, 0x00, 0x00, // maxBitrate
1280
+ // 0x00, 0x00, 0x00, 0x00, // avgBitrate
1281
+ //
1282
+ // 0x05 // descriptor_type
1283
+ // ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
1284
+ return data;
1285
+ }
1286
+ }, {
1287
+ key: 'mp4a',
1288
+ value: function mp4a(track) {
1289
+ var audiosamplerate = track.audiosamplerate;
1290
+ return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved
1291
+ 0x00, 0x00, 0x00, // reserved
1292
+ 0x00, 0x01, // data_reference_index
1293
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
1294
+ 0x00, track.channelCount, // channelcount
1295
+ 0x00, 0x10, // sampleSize:16bits
1296
+ 0x00, 0x00, // pre_defined
1297
+ 0x00, 0x00, // reserved2
1298
+ audiosamplerate >> 8 & 0xFF, audiosamplerate & 0xff, //
1299
+ 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
1300
+ }
1301
+ }, {
1302
+ key: 'stsd',
1303
+ value: function stsd(track) {
1304
+ if (track.type === 'audio') {
1305
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
1306
+ } else {
1307
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
1308
+ }
1309
+ }
1310
+ }, {
1311
+ key: 'tkhd',
1312
+ value: function tkhd(track) {
1313
+ var id = track.id,
1314
+ duration = track.duration,
1315
+ width = track.width,
1316
+ height = track.height,
1317
+ volume = track.volume;
1318
+ return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, // version 0
1319
+ 0x00, 0x00, 0x07, // flags
1320
+ 0x00, 0x00, 0x00, 0x00, // creation_time
1321
+ 0x00, 0x00, 0x00, 0x00, // modification_time
1322
+ id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID
1323
+ 0x00, 0x00, 0x00, 0x00, // reserved
1324
+ duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
1325
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
1326
+ 0x00, 0x00, // layer
1327
+ 0x00, 0x00, // alternate_group
1328
+ volume >> 0 & 0xff, volume % 1 * 10 >> 0 & 0xff, // track volume // FIXME
1329
+ 0x00, 0x00, // reserved
1330
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
1331
+ width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width
1332
+ height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00]) // height
1333
+ );
1334
+ }
1335
+ }, {
1336
+ key: 'traf',
1337
+ value: function traf(track, baseMediaDecodeTime) {
1338
+ var sampleDependencyTable = MP4.sdtp(track),
1339
+ id = track.id;
1340
+ return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0
1341
+ 0x00, 0x00, 0x00, // flags
1342
+ id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF]) // track_ID
1343
+ ), MP4.box(MP4.types.tfdt, new Uint8Array([0x00, // version 0
1344
+ 0x00, 0x00, 0x00, // flags
1345
+ baseMediaDecodeTime >> 24, baseMediaDecodeTime >> 16 & 0XFF, baseMediaDecodeTime >> 8 & 0XFF, baseMediaDecodeTime & 0xFF]) // baseMediaDecodeTime
1346
+ ), MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd
1347
+ 16 + // tfdt
1348
+ 8 + // traf header
1349
+ 16 + // mfhd
1350
+ 8 + // moof header
1351
+ 8), // mdat header
1352
+ sampleDependencyTable);
1353
+ }
1354
+
1355
+ /**
1356
+ * Generate a track box.
1357
+ * @param track {object} a track definition
1358
+ * @return {Uint8Array} the track box
1359
+ */
1360
+
1361
+ }, {
1362
+ key: 'trak',
1363
+ value: function trak(track) {
1364
+ track.duration = track.duration || 0xffffffff;
1365
+ return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
1366
+ }
1367
+ }, {
1368
+ key: 'trex',
1369
+ value: function trex(track) {
1370
+ var id = track.id;
1371
+ return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0
1372
+ 0x00, 0x00, 0x00, // flags
1373
+ id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID
1374
+ 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
1375
+ 0x00, 0x00, 0x00, 0x00, // default_sample_duration
1376
+ 0x00, 0x00, 0x00, 0x00, // default_sample_size
1377
+ 0x00, 0x01, 0x00, 0x01]) // default_sample_flags
1378
+ );
1379
+ }
1380
+ }, {
1381
+ key: 'trun',
1382
+ value: function trun(track, offset) {
1383
+ var samples = track.samples || [],
1384
+ len = samples.length,
1385
+ arraylen = 12 + 16 * len,
1386
+ array = new Uint8Array(arraylen),
1387
+ i,
1388
+ sample,
1389
+ duration,
1390
+ size,
1391
+ flags,
1392
+ cts;
1393
+ offset += 8 + arraylen;
1394
+ array.set([0x00, // version 0
1395
+ 0x00, 0x0f, 0x01, // flags
1396
+ len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count
1397
+ offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF], 0);
1398
+ for (i = 0; i < len; i++) {
1399
+ sample = samples[i];
1400
+ duration = sample.duration;
1401
+ size = sample.size;
1402
+ flags = sample.flags;
1403
+ cts = sample.cts;
1404
+ array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration
1405
+ size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size
1406
+ flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags
1407
+ cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF], 12 + 16 * i);
1408
+ }
1409
+ return MP4.box(MP4.types.trun, array);
1410
+ }
1411
+ }, {
1412
+ key: 'initSegment',
1413
+ value: function initSegment(tracks, duration, timescale) {
1414
+ if (!MP4.types) {
1415
+ MP4.init();
1416
+ }
1417
+ var movie = MP4.moov(tracks, duration, timescale),
1418
+ result;
1419
+ result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
1420
+ result.set(MP4.FTYP);
1421
+ result.set(movie, MP4.FTYP.byteLength);
1422
+ return result;
1423
+ }
1424
+ }]);
1425
+ return MP4;
1426
+ }();
1427
+
1428
+ var track_id = 1;
1429
+ var BaseRemuxer = function () {
1430
+ createClass(BaseRemuxer, null, [{
1431
+ key: 'getTrackID',
1432
+ value: function getTrackID() {
1433
+ return track_id++;
1434
+ }
1435
+ }]);
1436
+
1437
+ function BaseRemuxer() {
1438
+ classCallCheck(this, BaseRemuxer);
1439
+
1440
+ this.seq = 1;
1441
+ }
1442
+
1443
+ createClass(BaseRemuxer, [{
1444
+ key: 'flush',
1445
+ value: function flush() {
1446
+ this.seq++;
1447
+ this.mp4track.len = 0;
1448
+ this.mp4track.samples = [];
1449
+ }
1450
+ }, {
1451
+ key: 'isReady',
1452
+ value: function isReady() {
1453
+ if (!this.readyToDecode || !this.samples.length) return null;
1454
+ return true;
1455
+ }
1456
+ }]);
1457
+ return BaseRemuxer;
1458
+ }();
1459
+
1460
+ var AACRemuxer = function (_BaseRemuxer) {
1461
+ inherits(AACRemuxer, _BaseRemuxer);
1462
+
1463
+ function AACRemuxer() {
1464
+ classCallCheck(this, AACRemuxer);
1465
+
1466
+ var _this = possibleConstructorReturn(this, (AACRemuxer.__proto__ || Object.getPrototypeOf(AACRemuxer)).call(this));
1467
+
1468
+ _this.readyToDecode = false;
1469
+ _this.nextDts = 0;
1470
+ _this.dts = 0;
1471
+ _this.timescale = 1000;
1472
+
1473
+ _this.mp4track = {
1474
+ id: BaseRemuxer.getTrackID(),
1475
+ type: 'audio',
1476
+ channelCount: 0,
1477
+ len: 0,
1478
+ fragmented: true,
1479
+ timescale: _this.timescale,
1480
+ duration: _this.timescale,
1481
+ samples: [],
1482
+ config: '',
1483
+ codec: ''
1484
+ };
1485
+
1486
+ _this.samples = [];
1487
+ _this.aac = new AACParser(_this);
1488
+ return _this;
1489
+ }
1490
+
1491
+ createClass(AACRemuxer, [{
1492
+ key: 'resetTrack',
1493
+ value: function resetTrack() {
1494
+ this.readyToDecode = false;
1495
+ this.mp4track.codec = '';
1496
+ this.mp4track.channelCount = '';
1497
+ this.mp4track.config = '';
1498
+ this.mp4track.timescale = this.timescale;
1499
+ }
1500
+ }, {
1501
+ key: 'remux',
1502
+ value: function remux(samples) {
1503
+ var config = void 0,
1504
+ sample = void 0,
1505
+ size = void 0,
1506
+ payload = void 0;
1507
+ var _iteratorNormalCompletion = true;
1508
+ var _didIteratorError = false;
1509
+ var _iteratorError = undefined;
1510
+
1511
+ try {
1512
+ for (var _iterator = samples[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1513
+ var _sample = _step.value;
1514
+
1515
+ payload = _sample.units;
1516
+ size = payload.byteLength;
1517
+ this.samples.push({
1518
+ units: payload,
1519
+ size: size,
1520
+ duration: _sample.duration
1521
+ });
1522
+ this.mp4track.len += size;
1523
+ if (!this.readyToDecode) {
1524
+ this.aac.setAACConfig();
1525
+ }
1526
+ }
1527
+ } catch (err) {
1528
+ _didIteratorError = true;
1529
+ _iteratorError = err;
1530
+ } finally {
1531
+ try {
1532
+ if (!_iteratorNormalCompletion && _iterator.return) {
1533
+ _iterator.return();
1534
+ }
1535
+ } finally {
1536
+ if (_didIteratorError) {
1537
+ throw _iteratorError;
1538
+ }
1539
+ }
1540
+ }
1541
+ }
1542
+ }, {
1543
+ key: 'getPayload',
1544
+ value: function getPayload() {
1545
+ if (!this.isReady()) {
1546
+ return null;
1547
+ }
1548
+
1549
+ var payload = new Uint8Array(this.mp4track.len);
1550
+ var offset = 0;
1551
+ var samples = this.mp4track.samples;
1552
+ var mp4Sample = void 0,
1553
+ duration = void 0;
1554
+
1555
+ this.dts = this.nextDts;
1556
+
1557
+ while (this.samples.length) {
1558
+ var sample = this.samples.shift();
1559
+
1560
+ duration = sample.duration;
1561
+
1562
+ if (duration <= 0) {
1563
+ log('remuxer: invalid sample duration at DTS: ' + this.nextDts + ' :' + duration);
1564
+ this.mp4track.len -= sample.size;
1565
+ continue;
1566
+ }
1567
+
1568
+ this.nextDts += duration;
1569
+ mp4Sample = {
1570
+ size: sample.size,
1571
+ duration: duration,
1572
+ cts: 0,
1573
+ flags: {
1574
+ isLeading: 0,
1575
+ isDependedOn: 0,
1576
+ hasRedundancy: 0,
1577
+ degradPrio: 0,
1578
+ dependsOn: 1
1579
+ }
1580
+ };
1581
+
1582
+ payload.set(sample.units, offset);
1583
+ offset += sample.size;
1584
+ samples.push(mp4Sample);
1585
+ }
1586
+
1587
+ if (!samples.length) return null;
1588
+
1589
+ return new Uint8Array(payload.buffer, 0, this.mp4track.len);
1590
+ }
1591
+ }]);
1592
+ return AACRemuxer;
1593
+ }(BaseRemuxer);
1594
+
1595
+ var H264Remuxer = function (_BaseRemuxer) {
1596
+ inherits(H264Remuxer, _BaseRemuxer);
1597
+
1598
+ function H264Remuxer() {
1599
+ classCallCheck(this, H264Remuxer);
1600
+
1601
+ var _this = possibleConstructorReturn(this, (H264Remuxer.__proto__ || Object.getPrototypeOf(H264Remuxer)).call(this));
1602
+
1603
+ _this.readyToDecode = false;
1604
+ _this.nextDts = 0;
1605
+ _this.dts = 0;
1606
+ _this.timescale = 1000;
1607
+
1608
+ _this.mp4track = {
1609
+ id: BaseRemuxer.getTrackID(),
1610
+ type: 'video',
1611
+ len: 0,
1612
+ fragmented: true,
1613
+ sps: '',
1614
+ pps: '',
1615
+ width: 0,
1616
+ height: 0,
1617
+ timescale: _this.timescale,
1618
+ duration: _this.timescale,
1619
+ samples: []
1620
+ };
1621
+
1622
+ _this.samples = [];
1623
+ _this.h264 = new H264Parser(_this);
1624
+ return _this;
1625
+ }
1626
+
1627
+ createClass(H264Remuxer, [{
1628
+ key: 'resetTrack',
1629
+ value: function resetTrack() {
1630
+ this.readyToDecode = false;
1631
+ this.mp4track.sps = '';
1632
+ this.mp4track.pps = '';
1633
+ }
1634
+ }, {
1635
+ key: 'remux',
1636
+ value: function remux(samples) {
1637
+ var sample = void 0,
1638
+ units = void 0,
1639
+ unit = void 0,
1640
+ size = void 0,
1641
+ keyFrame = void 0;
1642
+ var _iteratorNormalCompletion = true;
1643
+ var _didIteratorError = false;
1644
+ var _iteratorError = undefined;
1645
+
1646
+ try {
1647
+ for (var _iterator = samples[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1648
+ sample = _step.value;
1649
+
1650
+ units = [];
1651
+ size = 0;
1652
+ keyFrame = false;
1653
+ var _iteratorNormalCompletion2 = true;
1654
+ var _didIteratorError2 = false;
1655
+ var _iteratorError2 = undefined;
1656
+
1657
+ try {
1658
+ for (var _iterator2 = sample.units[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
1659
+ unit = _step2.value;
1660
+
1661
+ if (this.h264.parseNAL(unit)) {
1662
+ units.push(unit);
1663
+ size += unit.getSize();
1664
+ if (!keyFrame) {
1665
+ keyFrame = unit.isKeyframe();
1666
+ }
1667
+ }
1668
+ }
1669
+ } catch (err) {
1670
+ _didIteratorError2 = true;
1671
+ _iteratorError2 = err;
1672
+ } finally {
1673
+ try {
1674
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
1675
+ _iterator2.return();
1676
+ }
1677
+ } finally {
1678
+ if (_didIteratorError2) {
1679
+ throw _iteratorError2;
1680
+ }
1681
+ }
1682
+ }
1683
+
1684
+ if (units.length > 0 && this.readyToDecode) {
1685
+ this.mp4track.len += size;
1686
+ this.samples.push({
1687
+ units: units,
1688
+ size: size,
1689
+ keyFrame: keyFrame,
1690
+ duration: sample.duration
1691
+ });
1692
+ }
1693
+ }
1694
+ } catch (err) {
1695
+ _didIteratorError = true;
1696
+ _iteratorError = err;
1697
+ } finally {
1698
+ try {
1699
+ if (!_iteratorNormalCompletion && _iterator.return) {
1700
+ _iterator.return();
1701
+ }
1702
+ } finally {
1703
+ if (_didIteratorError) {
1704
+ throw _iteratorError;
1705
+ }
1706
+ }
1707
+ }
1708
+ }
1709
+ }, {
1710
+ key: 'getPayload',
1711
+ value: function getPayload() {
1712
+ if (!this.isReady()) {
1713
+ return null;
1714
+ }
1715
+
1716
+ var payload = new Uint8Array(this.mp4track.len);
1717
+ var offset = 0;
1718
+ var samples = this.mp4track.samples;
1719
+ var mp4Sample = void 0,
1720
+ duration = void 0;
1721
+
1722
+ this.dts = this.nextDts;
1723
+
1724
+ while (this.samples.length) {
1725
+ var sample = this.samples.shift(),
1726
+ units = sample.units;
1727
+
1728
+ duration = sample.duration;
1729
+
1730
+ if (duration <= 0) {
1731
+ log('remuxer: invalid sample duration at DTS: ' + this.nextDts + ' :' + duration);
1732
+ this.mp4track.len -= sample.size;
1733
+ continue;
1734
+ }
1735
+
1736
+ this.nextDts += duration;
1737
+ mp4Sample = {
1738
+ size: sample.size,
1739
+ duration: duration,
1740
+ cts: 0,
1741
+ flags: {
1742
+ isLeading: 0,
1743
+ isDependedOn: 0,
1744
+ hasRedundancy: 0,
1745
+ degradPrio: 0,
1746
+ isNonSync: sample.keyFrame ? 0 : 1,
1747
+ dependsOn: sample.keyFrame ? 2 : 1
1748
+ }
1749
+ };
1750
+
1751
+ var _iteratorNormalCompletion3 = true;
1752
+ var _didIteratorError3 = false;
1753
+ var _iteratorError3 = undefined;
1754
+
1755
+ try {
1756
+ for (var _iterator3 = units[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
1757
+ var unit = _step3.value;
1758
+
1759
+ payload.set(unit.getData(), offset);
1760
+ offset += unit.getSize();
1761
+ }
1762
+ } catch (err) {
1763
+ _didIteratorError3 = true;
1764
+ _iteratorError3 = err;
1765
+ } finally {
1766
+ try {
1767
+ if (!_iteratorNormalCompletion3 && _iterator3.return) {
1768
+ _iterator3.return();
1769
+ }
1770
+ } finally {
1771
+ if (_didIteratorError3) {
1772
+ throw _iteratorError3;
1773
+ }
1774
+ }
1775
+ }
1776
+
1777
+ samples.push(mp4Sample);
1778
+ }
1779
+
1780
+ if (!samples.length) return null;
1781
+
1782
+ return new Uint8Array(payload.buffer, 0, this.mp4track.len);
1783
+ }
1784
+ }]);
1785
+ return H264Remuxer;
1786
+ }(BaseRemuxer);
1787
+
1788
+ function appendByteArray(buffer1, buffer2) {
1789
+ var tmp = new Uint8Array((buffer1.byteLength | 0) + (buffer2.byteLength | 0));
1790
+ tmp.set(buffer1, 0);
1791
+ tmp.set(buffer2, buffer1.byteLength | 0);
1792
+ return tmp;
1793
+ }
1794
+
1795
+ function secToTime(sec) {
1796
+ var seconds = void 0,
1797
+ hours = void 0,
1798
+ minutes = void 0,
1799
+ result = '';
1800
+
1801
+ seconds = Math.floor(sec);
1802
+ hours = parseInt(seconds / 3600, 10) % 24;
1803
+ minutes = parseInt(seconds / 60, 10) % 60;
1804
+ seconds = seconds < 0 ? 0 : seconds % 60;
1805
+
1806
+ if (hours > 0) {
1807
+ result += (hours < 10 ? '0' + hours : hours) + ':';
1808
+ }
1809
+ result += (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds);
1810
+ return result;
1811
+ }
1812
+
1813
+ var RemuxController = function (_Event) {
1814
+ inherits(RemuxController, _Event);
1815
+
1816
+ function RemuxController(streaming) {
1817
+ classCallCheck(this, RemuxController);
1818
+
1819
+ var _this = possibleConstructorReturn(this, (RemuxController.__proto__ || Object.getPrototypeOf(RemuxController)).call(this, 'remuxer'));
1820
+
1821
+ _this.initialized = false;
1822
+ _this.trackTypes = [];
1823
+ _this.tracks = {};
1824
+ _this.mediaDuration = streaming ? Infinity : 1000;
1825
+ return _this;
1826
+ }
1827
+
1828
+ createClass(RemuxController, [{
1829
+ key: 'addTrack',
1830
+ value: function addTrack(type) {
1831
+ if (type === 'video' || type === 'both') {
1832
+ this.tracks.video = new H264Remuxer();
1833
+ this.trackTypes.push('video');
1834
+ }
1835
+ if (type === 'audio' || type === 'both') {
1836
+ this.tracks.audio = new AACRemuxer();
1837
+ this.trackTypes.push('audio');
1838
+ }
1839
+ }
1840
+ }, {
1841
+ key: 'reset',
1842
+ value: function reset() {
1843
+ var _iteratorNormalCompletion = true;
1844
+ var _didIteratorError = false;
1845
+ var _iteratorError = undefined;
1846
+
1847
+ try {
1848
+ for (var _iterator = this.trackTypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1849
+ var type = _step.value;
1850
+
1851
+ this.tracks[type].resetTrack();
1852
+ }
1853
+ } catch (err) {
1854
+ _didIteratorError = true;
1855
+ _iteratorError = err;
1856
+ } finally {
1857
+ try {
1858
+ if (!_iteratorNormalCompletion && _iterator.return) {
1859
+ _iterator.return();
1860
+ }
1861
+ } finally {
1862
+ if (_didIteratorError) {
1863
+ throw _iteratorError;
1864
+ }
1865
+ }
1866
+ }
1867
+
1868
+ this.initialized = false;
1869
+ }
1870
+ }, {
1871
+ key: 'destroy',
1872
+ value: function destroy() {
1873
+ this.tracks = {};
1874
+ this.offAll();
1875
+ }
1876
+ }, {
1877
+ key: 'flush',
1878
+ value: function flush() {
1879
+ if (!this.initialized) {
1880
+ if (this.isReady()) {
1881
+ this.dispatch('ready');
1882
+ var _iteratorNormalCompletion2 = true;
1883
+ var _didIteratorError2 = false;
1884
+ var _iteratorError2 = undefined;
1885
+
1886
+ try {
1887
+ for (var _iterator2 = this.trackTypes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
1888
+ var type = _step2.value;
1889
+
1890
+ var track = this.tracks[type];
1891
+ var data = {
1892
+ type: type,
1893
+ payload: MP4.initSegment([track.mp4track], this.mediaDuration, track.mp4track.timescale)
1894
+ };
1895
+ this.dispatch('buffer', data);
1896
+ }
1897
+ } catch (err) {
1898
+ _didIteratorError2 = true;
1899
+ _iteratorError2 = err;
1900
+ } finally {
1901
+ try {
1902
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
1903
+ _iterator2.return();
1904
+ }
1905
+ } finally {
1906
+ if (_didIteratorError2) {
1907
+ throw _iteratorError2;
1908
+ }
1909
+ }
1910
+ }
1911
+
1912
+ log('Initial segment generated.');
1913
+ this.initialized = true;
1914
+ }
1915
+ } else {
1916
+ var _iteratorNormalCompletion3 = true;
1917
+ var _didIteratorError3 = false;
1918
+ var _iteratorError3 = undefined;
1919
+
1920
+ try {
1921
+ for (var _iterator3 = this.trackTypes[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
1922
+ var _type = _step3.value;
1923
+
1924
+ var _track = this.tracks[_type];
1925
+ var pay = _track.getPayload();
1926
+ if (pay && pay.byteLength) {
1927
+ var moof = MP4.moof(_track.seq, _track.dts, _track.mp4track);
1928
+ var mdat = MP4.mdat(pay);
1929
+ var payload = appendByteArray(moof, mdat);
1930
+ var _data = {
1931
+ type: _type,
1932
+ payload: payload,
1933
+ dts: _track.dts
1934
+ };
1935
+ this.dispatch('buffer', _data);
1936
+ var duration = secToTime(_track.dts / 1000);
1937
+ log('put segment (' + _type + '): ' + _track.seq + ' dts: ' + _track.dts + ' samples: ' + _track.mp4track.samples.length + ' second: ' + duration);
1938
+ _track.flush();
1939
+ }
1940
+ }
1941
+ } catch (err) {
1942
+ _didIteratorError3 = true;
1943
+ _iteratorError3 = err;
1944
+ } finally {
1945
+ try {
1946
+ if (!_iteratorNormalCompletion3 && _iterator3.return) {
1947
+ _iterator3.return();
1948
+ }
1949
+ } finally {
1950
+ if (_didIteratorError3) {
1951
+ throw _iteratorError3;
1952
+ }
1953
+ }
1954
+ }
1955
+ }
1956
+ }
1957
+ }, {
1958
+ key: 'isReady',
1959
+ value: function isReady() {
1960
+ var _iteratorNormalCompletion4 = true;
1961
+ var _didIteratorError4 = false;
1962
+ var _iteratorError4 = undefined;
1963
+
1964
+ try {
1965
+ for (var _iterator4 = this.trackTypes[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
1966
+ var type = _step4.value;
1967
+
1968
+ if (!this.tracks[type].readyToDecode || !this.tracks[type].samples.length) return false;
1969
+ }
1970
+ } catch (err) {
1971
+ _didIteratorError4 = true;
1972
+ _iteratorError4 = err;
1973
+ } finally {
1974
+ try {
1975
+ if (!_iteratorNormalCompletion4 && _iterator4.return) {
1976
+ _iterator4.return();
1977
+ }
1978
+ } finally {
1979
+ if (_didIteratorError4) {
1980
+ throw _iteratorError4;
1981
+ }
1982
+ }
1983
+ }
1984
+
1985
+ return true;
1986
+ }
1987
+ }, {
1988
+ key: 'remux',
1989
+ value: function remux(data) {
1990
+ var _iteratorNormalCompletion5 = true;
1991
+ var _didIteratorError5 = false;
1992
+ var _iteratorError5 = undefined;
1993
+
1994
+ try {
1995
+ for (var _iterator5 = this.trackTypes[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
1996
+ var type = _step5.value;
1997
+
1998
+ var samples = data[type];
1999
+ if (type === 'audio' && this.tracks.video && !this.tracks.video.readyToDecode) continue; /* if video is present, don't add audio until video get ready */
2000
+ if (samples.length > 0) {
2001
+ this.tracks[type].remux(samples);
2002
+ }
2003
+ }
2004
+ } catch (err) {
2005
+ _didIteratorError5 = true;
2006
+ _iteratorError5 = err;
2007
+ } finally {
2008
+ try {
2009
+ if (!_iteratorNormalCompletion5 && _iterator5.return) {
2010
+ _iterator5.return();
2011
+ }
2012
+ } finally {
2013
+ if (_didIteratorError5) {
2014
+ throw _iteratorError5;
2015
+ }
2016
+ }
2017
+ }
2018
+
2019
+ this.flush();
2020
+ }
2021
+ }]);
2022
+ return RemuxController;
2023
+ }(Event);
2024
+
2025
+ var BufferController = function (_Event) {
2026
+ inherits(BufferController, _Event);
2027
+
2028
+ function BufferController(sourceBuffer, type) {
2029
+ classCallCheck(this, BufferController);
2030
+
2031
+ var _this = possibleConstructorReturn(this, (BufferController.__proto__ || Object.getPrototypeOf(BufferController)).call(this, 'buffer'));
2032
+
2033
+ _this.type = type;
2034
+ _this.queue = new Uint8Array();
2035
+
2036
+ _this.cleaning = false;
2037
+ _this.pendingCleaning = 0;
2038
+ _this.cleanOffset = 30;
2039
+ _this.cleanRanges = [];
2040
+
2041
+ _this.sourceBuffer = sourceBuffer;
2042
+ _this.sourceBuffer.addEventListener('updateend', function () {
2043
+ if (_this.pendingCleaning > 0) {
2044
+ _this.initCleanup(_this.pendingCleaning);
2045
+ _this.pendingCleaning = 0;
2046
+ }
2047
+ _this.cleaning = false;
2048
+ if (_this.cleanRanges.length) {
2049
+ _this.doCleanup();
2050
+ return;
2051
+ }
2052
+ });
2053
+
2054
+ _this.sourceBuffer.addEventListener('error', function () {
2055
+ _this.dispatch('error', { type: _this.type, name: 'buffer', error: 'buffer error' });
2056
+ });
2057
+ return _this;
2058
+ }
2059
+
2060
+ createClass(BufferController, [{
2061
+ key: 'destroy',
2062
+ value: function destroy() {
2063
+ this.queue = null;
2064
+ this.sourceBuffer = null;
2065
+ this.offAll();
2066
+ }
2067
+ }, {
2068
+ key: 'doCleanup',
2069
+ value: function doCleanup() {
2070
+ if (!this.cleanRanges.length) {
2071
+ this.cleaning = false;
2072
+ return;
2073
+ }
2074
+ var range = this.cleanRanges.shift();
2075
+ log(this.type + ' remove range [' + range[0] + ' - ' + range[1] + ')');
2076
+ this.cleaning = true;
2077
+ this.sourceBuffer.remove(range[0], range[1]);
2078
+ }
2079
+ }, {
2080
+ key: 'initCleanup',
2081
+ value: function initCleanup(cleanMaxLimit) {
2082
+ if (this.sourceBuffer.updating) {
2083
+ this.pendingCleaning = cleanMaxLimit;
2084
+ return;
2085
+ }
2086
+ if (this.sourceBuffer.buffered && this.sourceBuffer.buffered.length && !this.cleaning) {
2087
+ for (var i = 0; i < this.sourceBuffer.buffered.length; ++i) {
2088
+ var start = this.sourceBuffer.buffered.start(i);
2089
+ var end = this.sourceBuffer.buffered.end(i);
2090
+
2091
+ if (cleanMaxLimit - start > this.cleanOffset) {
2092
+ end = cleanMaxLimit - this.cleanOffset;
2093
+ if (start < end) {
2094
+ this.cleanRanges.push([start, end]);
2095
+ }
2096
+ }
2097
+ }
2098
+ this.doCleanup();
2099
+ }
2100
+ }
2101
+ }, {
2102
+ key: 'doAppend',
2103
+ value: function doAppend() {
2104
+ if (!this.queue.length) return;
2105
+
2106
+ if (this.sourceBuffer.updating) {
2107
+ return;
2108
+ }
2109
+
2110
+ try {
2111
+ this.sourceBuffer.appendBuffer(this.queue);
2112
+ this.queue = new Uint8Array();
2113
+ } catch (e) {
2114
+ if (e.name === 'QuotaExceededError') {
2115
+ log(this.type + ' buffer quota full');
2116
+ this.dispatch('error', { type: this.type, name: 'QuotaExceeded', error: 'buffer error' });
2117
+ return;
2118
+ }
2119
+ error('Error occured while appending ' + this.type + ' buffer - ' + e.name + ': ' + e.message);
2120
+ this.dispatch('error', { type: this.type, name: 'unexpectedError', error: 'buffer error' });
2121
+ }
2122
+ }
2123
+ }, {
2124
+ key: 'feed',
2125
+ value: function feed(data) {
2126
+ this.queue = appendByteArray(this.queue, data);
2127
+ }
2128
+ }]);
2129
+ return BufferController;
2130
+ }(Event);
2131
+
2132
+ window.MediaSource = window.MediaSource || window.WebKitMediaSource;
2133
+
2134
+ var JMuxmer = function (_Event) {
2135
+ inherits(JMuxmer, _Event);
2136
+ createClass(JMuxmer, null, [{
2137
+ key: 'isSupported',
2138
+ value: function isSupported(codec) {
2139
+ return window.MediaSource && window.MediaSource.isTypeSupported(codec);
2140
+ }
2141
+ }]);
2142
+
2143
+ function JMuxmer(options) {
2144
+ classCallCheck(this, JMuxmer);
2145
+
2146
+ var _this = possibleConstructorReturn(this, (JMuxmer.__proto__ || Object.getPrototypeOf(JMuxmer)).call(this, 'jmuxer'));
2147
+
2148
+ window.MediaSource = window.MediaSource || window.WebKitMediaSource;
2149
+
2150
+ var defaults$$1 = {
2151
+ node: '',
2152
+ mode: 'both', // both, audio, video
2153
+ flushingTime: 1500,
2154
+ clearBuffer: true,
2155
+ onReady: null, // function called when MSE is ready to accept frames
2156
+ fps: 30,
2157
+ debug: false
2158
+ };
2159
+ _this.options = Object.assign({}, defaults$$1, options);
2160
+
2161
+ if (_this.options.debug) {
2162
+ setLogger();
2163
+ }
2164
+
2165
+ if (typeof _this.options.node === 'string' && _this.options.node == '') {
2166
+ error('no video element were found to render, provide a valid video element');
2167
+ }
2168
+
2169
+ if (!_this.options.fps) {
2170
+ _this.options.fps = 30;
2171
+ }
2172
+ _this.frameDuration = 1000 / _this.options.fps | 0;
2173
+
2174
+ _this.lastVideoTimestamp = 0;
2175
+ _this.lastAudioTimestamp = 0;
2176
+
2177
+ _this.node = typeof _this.options.node === 'string' ? document.getElementById(_this.options.node) : _this.options.node;
2178
+
2179
+ _this.sourceBuffers = {};
2180
+ _this.isMSESupported = !!window.MediaSource;
2181
+
2182
+ if (!_this.isMSESupported) {
2183
+ throw 'Oops! Browser does not support media source extension.';
2184
+ }
2185
+
2186
+ _this.setupMSE();
2187
+ _this.remuxController = new RemuxController(_this.options.clearBuffer);
2188
+ _this.remuxController.addTrack(_this.options.mode);
2189
+
2190
+ _this.mseReady = false;
2191
+ _this.lastCleaningTime = Date.now();
2192
+ _this.keyframeCache = [];
2193
+ _this.frameCounter = 0;
2194
+
2195
+ /* events callback */
2196
+ _this.remuxController.on('buffer', _this.onBuffer.bind(_this));
2197
+ _this.remuxController.on('ready', _this.createBuffer.bind(_this));
2198
+ _this.startInterval();
2199
+ return _this;
2200
+ }
2201
+
2202
+ createClass(JMuxmer, [{
2203
+ key: 'setupMSE',
2204
+ value: function setupMSE() {
2205
+ this.mediaSource = new MediaSource();
2206
+ this.node.src = URL.createObjectURL(this.mediaSource);
2207
+ this.mediaSource.addEventListener('sourceopen', this.onMSEOpen.bind(this));
2208
+ this.mediaSource.addEventListener('sourceclose', this.onMSEClose.bind(this));
2209
+ this.mediaSource.addEventListener('webkitsourceopen', this.onMSEOpen.bind(this));
2210
+ this.mediaSource.addEventListener('webkitsourceclose', this.onMSEClose.bind(this));
2211
+ }
2212
+ }, {
2213
+ key: 'feed',
2214
+ value: function feed(data) {
2215
+ var remux = false,
2216
+ nalus = void 0,
2217
+ aacFrames = void 0,
2218
+ duration = void 0,
2219
+ chunks = {
2220
+ video: [],
2221
+ audio: []
2222
+ };
2223
+
2224
+ if (!data || !this.remuxController) return;
2225
+
2226
+ duration = data.duration ? parseInt(data.duration) : 0;
2227
+ if (data.video) {
2228
+
2229
+ duration = this.getVideoDuration(data.video_timestamp);
2230
+
2231
+ nalus = H264Parser.extractNALu(data.video);
2232
+ if (nalus.length > 0) {
2233
+ chunks.video = this.getVideoFrames(nalus, duration);
2234
+ remux = true;
2235
+ }
2236
+ }
2237
+ if (data.audio) {
2238
+
2239
+ duration = this.getAudioDuration(data.audio_timestamp);
2240
+
2241
+ aacFrames = AACParser.extractAAC(data.audio);
2242
+ if (aacFrames.length > 0) {
2243
+ chunks.audio = this.getAudioFrames(aacFrames, duration);
2244
+ remux = true;
2245
+ }
2246
+ }
2247
+ if (!remux) {
2248
+ error('Input object must have video and/or audio property. Make sure it is not empty and valid typed array');
2249
+ return;
2250
+ }
2251
+ this.remuxController.remux(chunks);
2252
+
2253
+ }
2254
+ }, {
2255
+ key: 'getVideoDuration',
2256
+ value: function getVideoDuration(timestamp) {
2257
+ let duration = timestamp - this.lastVideoTimestamp
2258
+ this.lastVideoTimestamp = timestamp
2259
+ if(duration > 1000){
2260
+ duration = 0
2261
+ }
2262
+ return duration
2263
+ }
2264
+ }, {
2265
+ key: 'getAudioDuration',
2266
+ value: function getAudioDuration(timestamp) {
2267
+ let duration = timestamp - this.lastAudioTimestamp
2268
+ this.lastAudioTimestamp = timestamp
2269
+ if(duration > 1000){
2270
+ duration = 0
2271
+ }
2272
+ return duration
2273
+ }
2274
+ }, {
2275
+ key: 'getVideoFrames',
2276
+ value: function getVideoFrames(nalus, duration) {
2277
+ var nalu = void 0,
2278
+ units = [],
2279
+ samples = [],
2280
+ naluObj = void 0,
2281
+ sampleDuration = void 0,
2282
+ adjustDuration = 0,
2283
+ numberOfFrames = [];
2284
+
2285
+ var _iteratorNormalCompletion = true;
2286
+ var _didIteratorError = false;
2287
+ var _iteratorError = undefined;
2288
+
2289
+ try {
2290
+ for (var _iterator = nalus[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
2291
+ nalu = _step.value;
2292
+
2293
+ naluObj = new NALU(nalu);
2294
+ units.push(naluObj);
2295
+ if (naluObj.type() === NALU.IDR || naluObj.type() === NALU.NDR) {
2296
+ samples.push({ units: units });
2297
+ units = [];
2298
+ if (this.options.clearBuffer) {
2299
+ if (naluObj.type() === NALU.IDR) {
2300
+ numberOfFrames.push(this.frameCounter);
2301
+ }
2302
+ this.frameCounter++;
2303
+ }
2304
+ }
2305
+ }
2306
+ } catch (err) {
2307
+ _didIteratorError = true;
2308
+ _iteratorError = err;
2309
+ } finally {
2310
+ try {
2311
+ if (!_iteratorNormalCompletion && _iterator.return) {
2312
+ _iterator.return();
2313
+ }
2314
+ } finally {
2315
+ if (_didIteratorError) {
2316
+ throw _iteratorError;
2317
+ }
2318
+ }
2319
+ }
2320
+ if (duration) {
2321
+ sampleDuration = duration / samples.length | 0;
2322
+ adjustDuration = duration - sampleDuration * samples.length;
2323
+ } else {
2324
+ sampleDuration = this.frameDuration;
2325
+ }
2326
+ samples.map(function (sample) {
2327
+ sample.duration = adjustDuration > 0 ? sampleDuration + 1 : sampleDuration;
2328
+ if (adjustDuration !== 0) {
2329
+ adjustDuration--;
2330
+ }
2331
+ });
2332
+
2333
+ /* cache keyframe times if clearBuffer set true */
2334
+ if (this.options.clearBuffer) {
2335
+ numberOfFrames = numberOfFrames.map(function (total) {
2336
+ return total * sampleDuration / 1000;
2337
+ });
2338
+ this.keyframeCache = this.keyframeCache.concat(numberOfFrames);
2339
+ }
2340
+ return samples;
2341
+ }
2342
+ }, {
2343
+ key: 'getAudioFrames',
2344
+ value: function getAudioFrames(aacFrames, duration) {
2345
+ var samples = [],
2346
+ units = void 0,
2347
+ sampleDuration = void 0,
2348
+ adjustDuration = 0;
2349
+
2350
+ var _iteratorNormalCompletion2 = true;
2351
+ var _didIteratorError2 = false;
2352
+ var _iteratorError2 = undefined;
2353
+
2354
+ try {
2355
+ for (var _iterator2 = aacFrames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
2356
+ units = _step2.value;
2357
+
2358
+ samples.push({ units: units });
2359
+ }
2360
+ } catch (err) {
2361
+ _didIteratorError2 = true;
2362
+ _iteratorError2 = err;
2363
+ } finally {
2364
+ try {
2365
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
2366
+ _iterator2.return();
2367
+ }
2368
+ } finally {
2369
+ if (_didIteratorError2) {
2370
+ throw _iteratorError2;
2371
+ }
2372
+ }
2373
+ }
2374
+
2375
+ if (duration) {
2376
+ sampleDuration = duration / samples.length | 0;
2377
+ adjustDuration = duration - sampleDuration * samples.length;
2378
+ } else {
2379
+ sampleDuration = this.frameDuration;
2380
+ }
2381
+ samples.map(function (sample) {
2382
+ sample.duration = adjustDuration > 0 ? sampleDuration + 1 : sampleDuration;
2383
+ if (adjustDuration !== 0) {
2384
+ adjustDuration--;
2385
+ }
2386
+ });
2387
+ return samples;
2388
+ }
2389
+ }, {
2390
+ key: 'destroy',
2391
+ value: function destroy() {
2392
+ this.stopInterval();
2393
+ if (this.mediaSource) {
2394
+ try {
2395
+ if (this.bufferControllers) {
2396
+ this.mediaSource.endOfStream();
2397
+ }
2398
+ } catch (e) {
2399
+ error('mediasource is not available to end ' + e.message);
2400
+ }
2401
+ this.mediaSource = null;
2402
+ }
2403
+ if (this.remuxController) {
2404
+ this.remuxController.destroy();
2405
+ this.remuxController = null;
2406
+ }
2407
+ if (this.bufferControllers) {
2408
+ for (var type in this.bufferControllers) {
2409
+ this.bufferControllers[type].destroy();
2410
+ }
2411
+ this.bufferControllers = null;
2412
+ }
2413
+ this.node = false;
2414
+ this.mseReady = false;
2415
+ this.videoStarted = false;
2416
+ }
2417
+ }, {
2418
+ key: 'createBuffer',
2419
+ value: function createBuffer() {
2420
+ if (!this.mseReady || !this.remuxController || !this.remuxController.isReady() || this.bufferControllers) return;
2421
+ this.bufferControllers = {};
2422
+ for (var type in this.remuxController.tracks) {
2423
+ var track = this.remuxController.tracks[type];
2424
+ if (!JMuxmer.isSupported(type + '/mp4; codecs="' + track.mp4track.codec + '"')) {
2425
+ error('Browser does not support codec');
2426
+ return false;
2427
+ }
2428
+ var sb = this.mediaSource.addSourceBuffer(type + '/mp4; codecs="' + track.mp4track.codec + '"');
2429
+ this.bufferControllers[type] = new BufferController(sb, type);
2430
+ this.sourceBuffers[type] = sb;
2431
+ this.bufferControllers[type].on('error', this.onBufferError.bind(this));
2432
+ }
2433
+ }
2434
+ }, {
2435
+ key: 'startInterval',
2436
+ value: function startInterval() {
2437
+ var _this2 = this;
2438
+
2439
+ this.interval = setInterval(function () {
2440
+ if (_this2.bufferControllers) {
2441
+ _this2.releaseBuffer();
2442
+ _this2.clearBuffer();
2443
+ }
2444
+ }, this.options.flushingTime);
2445
+ }
2446
+ }, {
2447
+ key: 'stopInterval',
2448
+ value: function stopInterval() {
2449
+ if (this.interval) {
2450
+ clearInterval(this.interval);
2451
+ }
2452
+ }
2453
+ }, {
2454
+ key: 'releaseBuffer',
2455
+ value: function releaseBuffer() {
2456
+ for (var type in this.bufferControllers) {
2457
+ this.bufferControllers[type].doAppend();
2458
+ }
2459
+ }
2460
+ }, {
2461
+ key: 'getSafeBufferClearLimit',
2462
+ value: function getSafeBufferClearLimit(offset) {
2463
+ var maxLimit = this.options.mode === 'audio' && offset || 0,
2464
+ adjacentOffset = void 0;
2465
+
2466
+ for (var i = 0; i < this.keyframeCache.length; i++) {
2467
+ if (this.keyframeCache[i] >= offset) {
2468
+ break;
2469
+ }
2470
+ adjacentOffset = this.keyframeCache[i];
2471
+ }
2472
+
2473
+ if (adjacentOffset) {
2474
+ this.keyframeCache = this.keyframeCache.filter(function (keyframePoint) {
2475
+ if (keyframePoint < adjacentOffset) {
2476
+ maxLimit = keyframePoint;
2477
+ }
2478
+ return keyframePoint >= adjacentOffset;
2479
+ });
2480
+ }
2481
+
2482
+ return maxLimit;
2483
+ }
2484
+ }, {
2485
+ key: 'clearBuffer',
2486
+ value: function clearBuffer() {
2487
+ if (this.options.clearBuffer && Date.now() - this.lastCleaningTime > 10000) {
2488
+ for (var type in this.bufferControllers) {
2489
+ var cleanMaxLimit = this.getSafeBufferClearLimit(this.node.currentTime);
2490
+ this.bufferControllers[type].initCleanup(cleanMaxLimit);
2491
+ }
2492
+ this.lastCleaningTime = Date.now();
2493
+ }
2494
+ }
2495
+ }, {
2496
+ key: 'onBuffer',
2497
+ value: function onBuffer(data) {
2498
+ if (this.bufferControllers && this.bufferControllers[data.type]) {
2499
+ this.bufferControllers[data.type].feed(data.payload);
2500
+ }
2501
+ }
2502
+
2503
+ /* Events on MSE */
2504
+
2505
+ }, {
2506
+ key: 'onMSEOpen',
2507
+ value: function onMSEOpen() {
2508
+ this.mseReady = true;
2509
+ if (typeof this.options.onReady === 'function') {
2510
+ this.options.onReady();
2511
+ this.options.onReady = null;
2512
+ }
2513
+ this.createBuffer();
2514
+ }
2515
+ }, {
2516
+ key: 'onMSEClose',
2517
+ value: function onMSEClose() {
2518
+ this.mseReady = false;
2519
+ this.videoStarted = false;
2520
+ }
2521
+ }, {
2522
+ key: 'onBufferError',
2523
+ value: function onBufferError(data) {
2524
+ if (data.name == 'QuotaExceeded') {
2525
+ this.bufferControllers[data.type].initCleanup(this.node.currentTime);
2526
+ return;
2527
+ }
2528
+
2529
+ if (this.mediaSource.sourceBuffers.length > 0 && this.sourceBuffers[data.type]) {
2530
+ this.mediaSource.removeSourceBuffer(this.sourceBuffers[data.type]);
2531
+ }
2532
+ if (this.mediaSource.sourceBuffers.length == 0) {
2533
+ try {
2534
+ this.mediaSource.endOfStream();
2535
+ } catch (e) {
2536
+ error('mediasource is not available to end');
2537
+ }
2538
+ }
2539
+ }
2540
+ }]);
2541
+ return JMuxmer;
2542
+ }(Event);
2543
+
2544
+ return JMuxmer;
2545
+
2546
+ })));