xgplayer-mp4-loader 0.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.
package/es/loader.js ADDED
@@ -0,0 +1,715 @@
1
+ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
2
+ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
3
+ import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
4
+ import _createClass from '@babel/runtime/helpers/createClass';
5
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
6
+ import 'core-js/modules/es.array.find.js';
7
+ import 'core-js/modules/es.array.slice.js';
8
+ import _regeneratorRuntime from '@babel/runtime/regenerator';
9
+ import { concatUint8Array, NetLoader } from 'xgplayer-streaming-shared';
10
+ import { MP4Parser } from 'xgplayer-transmuxer';
11
+ import { getConfig } from './config.js';
12
+ import { MediaError } from './error.js';
13
+ import { Cache } from './cache.js';
14
+ import { isNumber, moovToMeta, moovToSegments } from './utils.js';
15
+
16
+ var _excluded = ["vid", "moovEnd", "segmentDuration", "cache", "maxDownloadInfoSize"];
17
+ var MP4Loader = /*#__PURE__*/function () {
18
+ function MP4Loader(config) {
19
+ _classCallCheck(this, MP4Loader);
20
+
21
+ _defineProperty(this, "vid", '');
22
+
23
+ _defineProperty(this, "url", '');
24
+
25
+ _defineProperty(this, "meta", {});
26
+
27
+ _defineProperty(this, "downloadInfo", []);
28
+
29
+ _defineProperty(this, "videoSegments", []);
30
+
31
+ _defineProperty(this, "audioSegments", []);
32
+
33
+ _defineProperty(this, "cache", null);
34
+
35
+ _defineProperty(this, "_currentSegmentIndex", -1);
36
+
37
+ _defineProperty(this, "_currentLoadingSegmentIndex", -1);
38
+
39
+ _defineProperty(this, "_transformError", function (error) {
40
+ error.type = 'network';
41
+ return error;
42
+ });
43
+
44
+ this._config = getConfig(config);
45
+
46
+ var _this$_config = this._config,
47
+ vid = _this$_config.vid;
48
+ _this$_config.moovEnd;
49
+ _this$_config.segmentDuration;
50
+ var cache = _this$_config.cache;
51
+ _this$_config.maxDownloadInfoSize;
52
+ var rest = _objectWithoutProperties(_this$_config, _excluded);
53
+
54
+ this.cache = cache || new Cache();
55
+ this.vid = vid || rest.url;
56
+ this.url = rest.url;
57
+ rest.transformError = this._transformError;
58
+ this._loader = new NetLoader(rest);
59
+ }
60
+
61
+ _createClass(MP4Loader, [{
62
+ key: "isMetaLoaded",
63
+ get: function get() {
64
+ return this.videoSegments.length || this.audioSegments.length;
65
+ }
66
+ }, {
67
+ key: "setCurrentSegment",
68
+ value: function setCurrentSegment(segIndex) {
69
+ if (isNumber(segIndex)) {
70
+ this._currentSegmentIndex = segIndex;
71
+ }
72
+ }
73
+ }, {
74
+ key: "isLastSegment",
75
+ value: function isLastSegment(segIndex) {
76
+ if (isNumber(segIndex)) {
77
+ var _this$videoSegments, _this$audioSegments;
78
+
79
+ var lastIndex = ((_this$videoSegments = this.videoSegments[this.videoSegments.length - 1]) === null || _this$videoSegments === void 0 ? void 0 : _this$videoSegments.index) || ((_this$audioSegments = this.audioSegments[this.audioSegments.length - 1]) === null || _this$audioSegments === void 0 ? void 0 : _this$audioSegments.index) || 0;
80
+ return segIndex === lastIndex;
81
+ }
82
+
83
+ return false;
84
+ }
85
+ }, {
86
+ key: "isSegmentLoading",
87
+ value: function isSegmentLoading(segIndex) {
88
+ return segIndex === this._currentLoadingSegmentIndex;
89
+ }
90
+ }, {
91
+ key: "changeUrl",
92
+ value: function () {
93
+ var _changeUrl = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
94
+ var vid,
95
+ moovEnd,
96
+ _args = arguments;
97
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
98
+ while (1) {
99
+ switch (_context.prev = _context.next) {
100
+ case 0:
101
+ vid = _args.length > 1 && _args[1] !== undefined ? _args[1] : url;
102
+ moovEnd = _args.length > 2 ? _args[2] : undefined;
103
+ _context.next = 4;
104
+ return this.reset();
105
+
106
+ case 4:
107
+ if (url) this.url = url;
108
+ if (vid) this.vid = vid;
109
+ if (moovEnd) this._config.moovEnd = moovEnd;
110
+
111
+ case 7:
112
+ case "end":
113
+ return _context.stop();
114
+ }
115
+ }
116
+ }, _callee, this);
117
+ }));
118
+
119
+ function changeUrl(_x) {
120
+ return _changeUrl.apply(this, arguments);
121
+ }
122
+
123
+ return changeUrl;
124
+ }()
125
+ }, {
126
+ key: "getOrLoadMeta",
127
+ value: function () {
128
+ var _getOrLoadMeta = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cache) {
129
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
130
+ while (1) {
131
+ switch (_context2.prev = _context2.next) {
132
+ case 0:
133
+ if (this.isMetaLoaded) {
134
+ _context2.next = 3;
135
+ break;
136
+ }
137
+
138
+ _context2.next = 3;
139
+ return this.loadMeta(cache);
140
+
141
+ case 3:
142
+ return _context2.abrupt("return", this.meta);
143
+
144
+ case 4:
145
+ case "end":
146
+ return _context2.stop();
147
+ }
148
+ }
149
+ }, _callee2, this);
150
+ }));
151
+
152
+ function getOrLoadMeta(_x2) {
153
+ return _getOrLoadMeta.apply(this, arguments);
154
+ }
155
+
156
+ return getOrLoadMeta;
157
+ }()
158
+ }, {
159
+ key: "loadMeta",
160
+ value: function () {
161
+ var _loadMeta = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(cache, moovEnd) {
162
+ var responses, res, moov, mdat, moovStart, parsedMoov, segments, videoSegments, audioSegments;
163
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
164
+ while (1) {
165
+ switch (_context3.prev = _context3.next) {
166
+ case 0:
167
+ responses = [];
168
+ _context3.next = 3;
169
+ return this._loadData([0, moovEnd || this._config.moovEnd], cache);
170
+
171
+ case 3:
172
+ res = _context3.sent;
173
+
174
+ if (res) {
175
+ _context3.next = 6;
176
+ break;
177
+ }
178
+
179
+ return _context3.abrupt("return");
180
+
181
+ case 6:
182
+ responses.push(res);
183
+ moov = MP4Parser.findBox(res.data, ['moov'])[0];
184
+
185
+ if (moov) {
186
+ _context3.next = 22;
187
+ break;
188
+ }
189
+
190
+ mdat = MP4Parser.findBox(res.data, ['mdat'])[0];
191
+
192
+ if (mdat) {
193
+ _context3.next = 12;
194
+ break;
195
+ }
196
+
197
+ throw new MediaError('cannot find moov or mdat box', res.data);
198
+
199
+ case 12:
200
+ moovStart = mdat.start + mdat.size;
201
+ _context3.next = 15;
202
+ return this._loadData([moovStart], cache);
203
+
204
+ case 15:
205
+ res = _context3.sent;
206
+
207
+ if (res) {
208
+ _context3.next = 18;
209
+ break;
210
+ }
211
+
212
+ return _context3.abrupt("return");
213
+
214
+ case 18:
215
+ responses.push(res);
216
+ moov = MP4Parser.findBox(res.data, ['moov'], moovStart)[0];
217
+
218
+ if (moov) {
219
+ _context3.next = 22;
220
+ break;
221
+ }
222
+
223
+ throw new MediaError('cannot find moov box', res.data);
224
+
225
+ case 22:
226
+ if (!(moov.size > moov.data.length)) {
227
+ _context3.next = 30;
228
+ break;
229
+ }
230
+
231
+ _context3.next = 25;
232
+ return this._loadData([res.data.length, moov.start + moov.size - 1], cache);
233
+
234
+ case 25:
235
+ res = _context3.sent;
236
+
237
+ if (res) {
238
+ _context3.next = 28;
239
+ break;
240
+ }
241
+
242
+ return _context3.abrupt("return");
243
+
244
+ case 28:
245
+ responses.push(res);
246
+ moov.data = concatUint8Array(moov.data, res.data);
247
+
248
+ case 30:
249
+ parsedMoov = MP4Parser.moov(moov);
250
+
251
+ if (parsedMoov) {
252
+ _context3.next = 33;
253
+ break;
254
+ }
255
+
256
+ throw new MediaError('cannot parse moov box', moov.data);
257
+
258
+ case 33:
259
+ segments = moovToSegments(parsedMoov, this._config.segmentDuration);
260
+
261
+ if (segments) {
262
+ _context3.next = 36;
263
+ break;
264
+ }
265
+
266
+ throw new MediaError('cannot parse segments', moov.data);
267
+
268
+ case 36:
269
+ this.meta = moovToMeta(parsedMoov);
270
+ videoSegments = segments.videoSegments, audioSegments = segments.audioSegments;
271
+ this.videoSegments = videoSegments;
272
+ this.audioSegments = audioSegments;
273
+ return _context3.abrupt("return", {
274
+ meta: this.meta,
275
+ videoSegments: videoSegments,
276
+ audioSegments: audioSegments,
277
+ responses: responses
278
+ });
279
+
280
+ case 41:
281
+ case "end":
282
+ return _context3.stop();
283
+ }
284
+ }
285
+ }, _callee3, this);
286
+ }));
287
+
288
+ function loadMeta(_x3, _x4) {
289
+ return _loadMeta.apply(this, arguments);
290
+ }
291
+
292
+ return loadMeta;
293
+ }()
294
+ }, {
295
+ key: "getSegmentByTime",
296
+ value: function getSegmentByTime(time) {
297
+ var video;
298
+ var audio;
299
+
300
+ if (!this.videoSegments.length) {
301
+ audio = this.audioSegments.find(function (x) {
302
+ return x.startTime <= time && x.endTime > time;
303
+ });
304
+ } else {
305
+ video = this.videoSegments.find(function (x) {
306
+ return x.startTime <= time && x.endTime > time;
307
+ });
308
+
309
+ if (video) {
310
+ audio = this.audioSegments[video.index];
311
+ }
312
+ }
313
+
314
+ return {
315
+ video: video,
316
+ audio: audio
317
+ };
318
+ }
319
+ }, {
320
+ key: "loadSegmentByTime",
321
+ value: function () {
322
+ var _loadSegmentByTime = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(time, cache) {
323
+ var changeCurrent,
324
+ _this$getSegmentByTim,
325
+ video,
326
+ audio,
327
+ _args4 = arguments;
328
+
329
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
330
+ while (1) {
331
+ switch (_context4.prev = _context4.next) {
332
+ case 0:
333
+ changeCurrent = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : true;
334
+
335
+ if (this.isMetaLoaded) {
336
+ _context4.next = 4;
337
+ break;
338
+ }
339
+
340
+ _context4.next = 4;
341
+ return this.loadMeta(cache);
342
+
343
+ case 4:
344
+ _this$getSegmentByTim = this.getSegmentByTime(time), video = _this$getSegmentByTim.video, audio = _this$getSegmentByTim.audio;
345
+ return _context4.abrupt("return", this._loadSegment(video, audio, cache, changeCurrent));
346
+
347
+ case 6:
348
+ case "end":
349
+ return _context4.stop();
350
+ }
351
+ }
352
+ }, _callee4, this);
353
+ }));
354
+
355
+ function loadSegmentByTime(_x5, _x6) {
356
+ return _loadSegmentByTime.apply(this, arguments);
357
+ }
358
+
359
+ return loadSegmentByTime;
360
+ }()
361
+ }, {
362
+ key: "loadNextSegment",
363
+ value: function () {
364
+ var _loadNextSegment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(cache) {
365
+ var changeCurrent,
366
+ video,
367
+ audio,
368
+ _args5 = arguments;
369
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
370
+ while (1) {
371
+ switch (_context5.prev = _context5.next) {
372
+ case 0:
373
+ changeCurrent = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : true;
374
+
375
+ if (this.isMetaLoaded) {
376
+ _context5.next = 4;
377
+ break;
378
+ }
379
+
380
+ _context5.next = 4;
381
+ return this.loadMeta();
382
+
383
+ case 4:
384
+ video = this.videoSegments[this._currentSegmentIndex + 1];
385
+ audio = this.audioSegments[this._currentSegmentIndex + 1];
386
+ return _context5.abrupt("return", this._loadSegment(video, audio, cache, changeCurrent));
387
+
388
+ case 7:
389
+ case "end":
390
+ return _context5.stop();
391
+ }
392
+ }
393
+ }, _callee5, this);
394
+ }));
395
+
396
+ function loadNextSegment(_x7) {
397
+ return _loadNextSegment.apply(this, arguments);
398
+ }
399
+
400
+ return loadNextSegment;
401
+ }()
402
+ }, {
403
+ key: "preload",
404
+ value: function () {
405
+ var _preload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(time) {
406
+ var _this = this;
407
+
408
+ var _this$getSegmentByTim2, video, audio, index, videos, audios, load;
409
+
410
+ return _regeneratorRuntime.wrap(function _callee7$(_context7) {
411
+ while (1) {
412
+ switch (_context7.prev = _context7.next) {
413
+ case 0:
414
+ if (this.isMetaLoaded) {
415
+ _context7.next = 3;
416
+ break;
417
+ }
418
+
419
+ _context7.next = 3;
420
+ return this.loadMeta(true);
421
+
422
+ case 3:
423
+ if (!(!time || time < 0)) {
424
+ _context7.next = 5;
425
+ break;
426
+ }
427
+
428
+ return _context7.abrupt("return");
429
+
430
+ case 5:
431
+ _this$getSegmentByTim2 = this.getSegmentByTime(time), video = _this$getSegmentByTim2.video, audio = _this$getSegmentByTim2.audio;
432
+ index = Math.max((video === null || video === void 0 ? void 0 : video.index) || 0, (audio === null || audio === void 0 ? void 0 : audio.index) || 0);
433
+
434
+ if (index) {
435
+ _context7.next = 9;
436
+ break;
437
+ }
438
+
439
+ return _context7.abrupt("return");
440
+
441
+ case 9:
442
+ videos = this.videoSegments.slice(0, index);
443
+ audios = this.audioSegments.slice(0, index);
444
+
445
+ load = /*#__PURE__*/function () {
446
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(i) {
447
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
448
+ while (1) {
449
+ switch (_context6.prev = _context6.next) {
450
+ case 0:
451
+ if (!(i > index)) {
452
+ _context6.next = 2;
453
+ break;
454
+ }
455
+
456
+ return _context6.abrupt("return");
457
+
458
+ case 2:
459
+ _context6.next = 4;
460
+ return _this._loadSegment(videos[i], audios[i], true, false);
461
+
462
+ case 4:
463
+ _context6.next = 6;
464
+ return load(i + 1);
465
+
466
+ case 6:
467
+ case "end":
468
+ return _context6.stop();
469
+ }
470
+ }
471
+ }, _callee6);
472
+ }));
473
+
474
+ return function load(_x9) {
475
+ return _ref.apply(this, arguments);
476
+ };
477
+ }();
478
+
479
+ _context7.next = 14;
480
+ return load(0);
481
+
482
+ case 14:
483
+ case "end":
484
+ return _context7.stop();
485
+ }
486
+ }
487
+ }, _callee7, this);
488
+ }));
489
+
490
+ function preload(_x8) {
491
+ return _preload.apply(this, arguments);
492
+ }
493
+
494
+ return preload;
495
+ }()
496
+ }, {
497
+ key: "cancel",
498
+ value: function cancel() {
499
+ return this._loader.cancel();
500
+ }
501
+ }, {
502
+ key: "reset",
503
+ value: function () {
504
+ var _reset = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
505
+ return _regeneratorRuntime.wrap(function _callee8$(_context8) {
506
+ while (1) {
507
+ switch (_context8.prev = _context8.next) {
508
+ case 0:
509
+ _context8.next = 2;
510
+ return this._loader.cancel();
511
+
512
+ case 2:
513
+ this.vid = this.url = '';
514
+ this.meta = {};
515
+ this.downloadInfo = [];
516
+ this.videoSegments = [];
517
+ this.audioSegments = [];
518
+ this._currentSegmentIndex = -1;
519
+ this._currentLoadingSegmentIndex = -1;
520
+
521
+ case 9:
522
+ case "end":
523
+ return _context8.stop();
524
+ }
525
+ }
526
+ }, _callee8, this);
527
+ }));
528
+
529
+ function reset() {
530
+ return _reset.apply(this, arguments);
531
+ }
532
+
533
+ return reset;
534
+ }()
535
+ }, {
536
+ key: "destroy",
537
+ value: function () {
538
+ var _destroy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
539
+ return _regeneratorRuntime.wrap(function _callee9$(_context9) {
540
+ while (1) {
541
+ switch (_context9.prev = _context9.next) {
542
+ case 0:
543
+ _context9.next = 2;
544
+ return this.cancel();
545
+
546
+ case 2:
547
+ this.cache.clear();
548
+
549
+ case 3:
550
+ case "end":
551
+ return _context9.stop();
552
+ }
553
+ }
554
+ }, _callee9, this);
555
+ }));
556
+
557
+ function destroy() {
558
+ return _destroy.apply(this, arguments);
559
+ }
560
+
561
+ return destroy;
562
+ }()
563
+ }, {
564
+ key: "_loadSegment",
565
+ value: function () {
566
+ var _loadSegment2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10(video, audio, cache, changeCurrent) {
567
+ var segIndex, res;
568
+ return _regeneratorRuntime.wrap(function _callee10$(_context10) {
569
+ while (1) {
570
+ switch (_context10.prev = _context10.next) {
571
+ case 0:
572
+ if (!(!video && !audio)) {
573
+ _context10.next = 2;
574
+ break;
575
+ }
576
+
577
+ return _context10.abrupt("return");
578
+
579
+ case 2:
580
+ segIndex = (video === null || video === void 0 ? void 0 : video.index) || (audio === null || audio === void 0 ? void 0 : audio.index) || 0;
581
+ this._currentLoadingSegmentIndex = segIndex;
582
+ _context10.prev = 4;
583
+ _context10.next = 7;
584
+ return this._loadData([Math.min((video === null || video === void 0 ? void 0 : video.range[0]) || Infinity, (audio === null || audio === void 0 ? void 0 : audio.range[0]) || Infinity), Math.max((video === null || video === void 0 ? void 0 : video.range[1]) || 0, (audio === null || audio === void 0 ? void 0 : audio.range[1]) || 0)], cache);
585
+
586
+ case 7:
587
+ res = _context10.sent;
588
+
589
+ case 8:
590
+ _context10.prev = 8;
591
+ this._currentLoadingSegmentIndex = -1;
592
+ return _context10.finish(8);
593
+
594
+ case 11:
595
+ if (res) {
596
+ _context10.next = 13;
597
+ break;
598
+ }
599
+
600
+ return _context10.abrupt("return");
601
+
602
+ case 13:
603
+ if (changeCurrent) {
604
+ this._currentSegmentIndex = segIndex;
605
+ }
606
+
607
+ res.video = video;
608
+ res.audio = audio;
609
+ return _context10.abrupt("return", res);
610
+
611
+ case 17:
612
+ case "end":
613
+ return _context10.stop();
614
+ }
615
+ }
616
+ }, _callee10, this, [[4,, 8, 11]]);
617
+ }));
618
+
619
+ function _loadSegment(_x10, _x11, _x12, _x13) {
620
+ return _loadSegment2.apply(this, arguments);
621
+ }
622
+
623
+ return _loadSegment;
624
+ }()
625
+ }, {
626
+ key: "_loadData",
627
+ value: function () {
628
+ var _loadData2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11(range, cache) {
629
+ var cacheKey, data, res;
630
+ return _regeneratorRuntime.wrap(function _callee11$(_context11) {
631
+ while (1) {
632
+ switch (_context11.prev = _context11.next) {
633
+ case 0:
634
+ cacheKey = this._getCacheKey(range);
635
+ _context11.next = 3;
636
+ return this.cache.get(cacheKey);
637
+
638
+ case 3:
639
+ data = _context11.sent;
640
+
641
+ if (data) {
642
+ _context11.next = 10;
643
+ break;
644
+ }
645
+
646
+ _context11.next = 7;
647
+ return this._loader.load(this.url, {
648
+ range: range
649
+ });
650
+
651
+ case 7:
652
+ res = _context11.sent;
653
+ _context11.next = 11;
654
+ break;
655
+
656
+ case 10:
657
+ res = {
658
+ data: data,
659
+ fromCache: true
660
+ };
661
+
662
+ case 11:
663
+ if (res) {
664
+ _context11.next = 13;
665
+ break;
666
+ }
667
+
668
+ return _context11.abrupt("return");
669
+
670
+ case 13:
671
+ if (!data) {
672
+ this.downloadInfo.push({
673
+ startTime: res.startTime,
674
+ endTime: res.endTime,
675
+ size: res.data.byteLength,
676
+ range: range
677
+ });
678
+
679
+ if (this._addDownloadInfo > this._config.maxDownloadInfoSize) {
680
+ this._downloadInfos = this.downloadInfo.slice(-this._config.maxDownloadInfoSize);
681
+ }
682
+ }
683
+
684
+ if (!data && cache) {
685
+ this.cache.set(cacheKey, res.data);
686
+ }
687
+
688
+ res.range = range;
689
+ return _context11.abrupt("return", res);
690
+
691
+ case 17:
692
+ case "end":
693
+ return _context11.stop();
694
+ }
695
+ }
696
+ }, _callee11, this);
697
+ }));
698
+
699
+ function _loadData(_x14, _x15) {
700
+ return _loadData2.apply(this, arguments);
701
+ }
702
+
703
+ return _loadData;
704
+ }()
705
+ }, {
706
+ key: "_getCacheKey",
707
+ value: function _getCacheKey(range) {
708
+ return (this.vid || this.url) + ':' + range;
709
+ }
710
+ }]);
711
+
712
+ return MP4Loader;
713
+ }();
714
+
715
+ export { MP4Loader };