PageSourceSearch

https://members.trainingindustry.com/content/plugins/buddyboss-platform/bp-core/js/vendor/flv.js?ver=3.4.2

js trainingindustry.com collected 2026-09-24 08:37:42 UTC 632,676 bytes, 12,054 lines download raw bytes

1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.flvjs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
2(function (process,global){
3/*!
4 * @overview es6-promise - a tiny implementation of Promises/A+.
5 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
6 * @license   Licensed under MIT license
7 *            See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
8 * @version   v4.2.5+7f2b526d
9 */
10
11(function (global, factory) {
12	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
13	typeof define === 'function' && define.amd ? define(factory) :
14	(global.ES6Promise = factory());
15}(this, (function () { 'use strict';
16
17function objectOrFunction(x) {
18  var type = typeof x;
19  return x !== null && (type === 'object' || type === 'function');
20}
21
22function isFunction(x) {
23  return typeof x === 'function';
24}
25
26
27
28var _isArray = void 0;
29if (Array.isArray) {
30  _isArray = Array.isArray;
31} else {
32  _isArray = function (x) {
33    return Object.prototype.toString.call(x) === '[object Array]';
34  };
35}
36
37var isArray = _isArray;
38
39var len = 0;
40var vertxNext = void 0;
41var customSchedulerFn = void 0;
42
43var asap = function asap(callback, arg) {
44  queue[len] = callback;
45  queue[len + 1] = arg;
46  len += 2;
47  if (len === 2) {
48    // If len is 2, that means that we need to schedule an async flush.
49    // If additional callbacks are queued before the queue is flushed, they
50    // will be processed by this flush that we are scheduling.
51    if (customSchedulerFn) {
52      customSchedulerFn(flush);
53    } else {
54      scheduleFlush();
55    }
56  }
57};
58
59function setScheduler(scheduleFn) {
60  customSchedulerFn = scheduleFn;
61}
62
63function setAsap(asapFn) {
64  asap = asapFn;
65}
66
67var browserWindow = typeof window !== 'undefined' ? window : undefined;
68var browserGlobal = browserWindow || {};
69var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
70var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
71
72// test for web worker but not in IE10
73var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
74
75// node
76function useNextTick() {
77  // node version 0.10.x displays a deprecation warning when nextTick is used recursively
78  // see https://github.com/cujojs/when/issues/410 for details
79  return function () {
80    return process.nextTick(flush);
81  };
82}
83
84// vertx
85function useVertxTimer() {
86  if (typeof vertxNext !== 'undefined') {
87    return function () {
88      vertxNext(flush);
89    };
90  }
91
92  return useSetTimeout();
93}
94
95function useMutationObserver() {
96  var iterations = 0;
97  var observer = new BrowserMutationObserver(flush);
98  var node = document.createTextNode('');
99  observer.observe(node, { characterData: true });
100
101  return function () {
102    node.data = iterations = ++iterations % 2;
103  };
104}
105
106// web worker
107function useMessageChannel() {
108  var channel = new MessageChannel();
109  channel.port1.onmessage = flush;
110  return function () {
111    return channel.port2.postMessage(0);
112  };
113}
114
115function useSetTimeout() {
116  // Store setTimeout reference so es6-promise will be unaffected by
117  // other code modifying setTimeout (like sinon.useFakeTimers())
118  var globalSetTimeout = setTimeout;
119  return function () {
120    return globalSetTimeout(flush, 1);
121  };
122}
123
124var queue = new Array(1000);
125function flush() {
126  for (var i = 0; i < len; i += 2) {
127    var callback = queue[i];
128    var arg = queue[i + 1];
129
130    callback(arg);
131
132    queue[i] = undefined;
133    queue[i + 1] = undefined;
134  }
135
136  len = 0;
137}
138
139function attemptVertx() {
140  try {
141    var vertx = Function('return this')().require('vertx');
142    vertxNext = vertx.runOnLoop || vertx.runOnContext;
143    return useVertxTimer();
144  } catch (e) {
145    return useSetTimeout();
146  }
147}
148
149var scheduleFlush = void 0;
150// Decide what async method to use to triggering processing of queued callbacks:
151if (isNode) {
152  scheduleFlush = useNextTick();
153} else if (BrowserMutationObserver) {
154  scheduleFlush = useMutationObserver();
155} else if (isWorker) {
156  scheduleFlush = useMessageChannel();
157} else if (browserWindow === undefined && typeof _dereq_
vendor: 8,702 bytes, lines 157-538
157 === 'function') {
158  scheduleFlush = attemptVertx();
159} else {
160  scheduleFlush = useSetTimeout();
161}
162
163function then(onFulfillment, onRejection) {
164  var parent = this;
165
166  var child = new this.constructor(noop);
167
168  if (child[PROMISE_ID] === undefined) {
169    makePromise(child);
170  }
171
172  var _state = parent._state;
173
174
175  if (_state) {
176    var callback = arguments[_state - 1];
177    asap(function () {
178      return invokeCallback(_state, child, callback, parent._result);
179    });
180  } else {
181    subscribe(parent, child, onFulfillment, onRejection);
182  }
183
184  return child;
185}
186
187/**
188  `Promise.resolve` returns a promise that will become resolved with the
189  passed `value`. It is shorthand for the following:
190
191  ```javascript
192  let promise = new Promise(function(resolve, reject){
193    resolve(1);
194  });
195
196  promise.then(function(value){
197    // value === 1
198  });
199  ```
200
201  Instead of writing the above, your code now simply becomes the following:
202
203  ```javascript
204  let promise = Promise.resolve(1);
205
206  promise.then(function(value){
207    // value === 1
208  });
209  ```
210
211  @method resolve
212  @static
213  @param {Any} value value that the returned promise will be resolved with
214  Useful for tooling.
215  @return {Promise} a promise that will become fulfilled with the given
216  `value`
217*/
218function resolve$1(object) {
219  /*jshint validthis:true */
220  var Constructor = this;
221
222  if (object && typeof object === 'object' && object.constructor === Constructor) {
223    return object;
224  }
225
226  var promise = new Constructor(noop);
227  resolve(promise, object);
228  return promise;
229}
230
231var PROMISE_ID = Math.random().toString(36).substring(2);
232
233function noop() {}
234
235var PENDING = void 0;
236var FULFILLED = 1;
237var REJECTED = 2;
238
239var TRY_CATCH_ERROR = { error: null };
240
241function selfFulfillment() {
242  return new TypeError("You cannot resolve a promise with itself");
243}
244
245function cannotReturnOwn() {
246  return new TypeError('A promises callback cannot return that same promise.');
247}
248
249function getThen(promise) {
250  try {
251    return promise.then;
252  } catch (error) {
253    TRY_CATCH_ERROR.error = error;
254    return TRY_CATCH_ERROR;
255  }
256}
257
258function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
259  try {
260    then$$1.call(value, fulfillmentHandler, rejectionHandler);
261  } catch (e) {
262    return e;
263  }
264}
265
266function handleForeignThenable(promise, thenable, then$$1) {
267  asap(function (promise) {
268    var sealed = false;
269    var error = tryThen(then$$1, thenable, function (value) {
270      if (sealed) {
271        return;
272      }
273      sealed = true;
274      if (thenable !== value) {
275        resolve(promise, value);
276      } else {
277        fulfill(promise, value);
278      }
279    }, function (reason) {
280      if (sealed) {
281        return;
282      }
283      sealed = true;
284
285      reject(promise, reason);
286    }, 'Settle: ' + (promise._label || ' unknown promise'));
287
288    if (!sealed && error) {
289      sealed = true;
290      reject(promise, error);
291    }
292  }, promise);
293}
294
295function handleOwnThenable(promise, thenable) {
296  if (thenable._state === FULFILLED) {
297    fulfill(promise, thenable._result);
298  } else if (thenable._state === REJECTED) {
299    reject(promise, thenable._result);
300  } else {
301    subscribe(thenable, undefined, function (value) {
302      return resolve(promise, value);
303    }, function (reason) {
304      return reject(promise, reason);
305    });
306  }
307}
308
309function handleMaybeThenable(promise, maybeThenable, then$$1) {
310  if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
311    handleOwnThenable(promise, maybeThenable);
312  } else {
313    if (then$$1 === TRY_CATCH_ERROR) {
314      reject(promise, TRY_CATCH_ERROR.error);
315      TRY_CATCH_ERROR.error = null;
316    } else if (then$$1 === undefined) {
317      fulfill(promise, maybeThenable);
318    } else if (isFunction(then$$1)) {
319      handleForeignThenable(promise, maybeThenable, then$$1);
320    } else {
321      fulfill(promise, maybeThenable);
322    }
323  }
324}
325
326function resolve(promise, value) {
327  if (promise === value) {
328    reject(promise, selfFulfillment());
329  } else if (objectOrFunction(value)) {
330    handleMaybeThenable(promise, value, getThen(value));
331  } else {
332    fulfill(promise, value);
333  }
334}
335
336function publishRejection(promise) {
337  if (promise._onerror) {
338    promise._onerror(promise._result);
339  }
340
341  publish(promise);
342}
343
344function fulfill(promise, value) {
345  if (promise._state !== PENDING) {
346    return;
347  }
348
349  promise._result = value;
350  promise._state = FULFILLED;
351
352  if (promise._subscribers.length !== 0) {
353    asap(publish, promise);
354  }
355}
356
357function reject(promise, reason) {
358  if (promise._state !== PENDING) {
359    return;
360  }
361  promise._state = REJECTED;
362  promise._result = reason;
363
364  asap(publishRejection, promise);
365}
366
367function subscribe(parent, child, onFulfillment, onRejection) {
368  var _subscribers = parent._subscribers;
369  var length = _subscribers.length;
370
371
372  parent._onerror = null;
373
374  _subscribers[length] = child;
375  _subscribers[length + FULFILLED] = onFulfillment;
376  _subscribers[length + REJECTED] = onRejection;
377
378  if (length === 0 && parent._state) {
379    asap(publish, parent);
380  }
381}
382
383function publish(promise) {
384  var subscribers = promise._subscribers;
385  var settled = promise._state;
386
387  if (subscribers.length === 0) {
388    return;
389  }
390
391  var child = void 0,
392      callback = void 0,
393      detail = promise._result;
394
395  for (var i = 0; i < subscribers.length; i += 3) {
396    child = subscribers[i];
397    callback = subscribers[i + settled];
398
399    if (child) {
400      invokeCallback(settled, child, callback, detail);
401    } else {
402      callback(detail);
403    }
404  }
405
406  promise._subscribers.length = 0;
407}
408
409function tryCatch(callback, detail) {
410  try {
411    return callback(detail);
412  } catch (e) {
413    TRY_CATCH_ERROR.error = e;
414    return TRY_CATCH_ERROR;
415  }
416}
417
418function invokeCallback(settled, promise, callback, detail) {
419  var hasCallback = isFunction(callback),
420      value = void 0,
421      error = void 0,
422      succeeded = void 0,
423      failed = void 0;
424
425  if (hasCallback) {
426    value = tryCatch(callback, detail);
427
428    if (value === TRY_CATCH_ERROR) {
429      failed = true;
430      error = value.error;
431      value.error = null;
432    } else {
433      succeeded = true;
434    }
435
436    if (promise === value) {
437      reject(promise, cannotReturnOwn());
438      return;
439    }
440  } else {
441    value = detail;
442    succeeded = true;
443  }
444
445  if (promise._state !== PENDING) {
446    // noop
447  } else if (hasCallback && succeeded) {
448    resolve(promise, value);
449  } else if (failed) {
450    reject(promise, error);
451  } else if (settled === FULFILLED) {
452    fulfill(promise, value);
453  } else if (settled === REJECTED) {
454    reject(promise, value);
455  }
456}
457
458function initializePromise(promise, resolver) {
459  try {
460    resolver(function resolvePromise(value) {
461      resolve(promise, value);
462    }, function rejectPromise(reason) {
463      reject(promise, reason);
464    });
465  } catch (e) {
466    reject(promise, e);
467  }
468}
469
470var id = 0;
471function nextId() {
472  return id++;
473}
474
475function makePromise(promise) {
476  promise[PROMISE_ID] = id++;
477  promise._state = undefined;
478  promise._result = undefined;
479  promise._subscribers = [];
480}
481
482function validationError() {
483  return new Error('Array Methods must be provided an Array');
484}
485
486var Enumerator = function () {
487  function Enumerator(Constructor, input) {
488    this._instanceConstructor = Constructor;
489    this.promise = new Constructor(noop);
490
491    if (!this.promise[PROMISE_ID]) {
492      makePromise(this.promise);
493    }
494
495    if (isArray(input)) {
496      this.length = input.length;
497      this._remaining = input.length;
498
499      this._result = new Array(this.length);
500
501      if (this.length === 0) {
502        fulfill(this.promise, this._result);
503      } else {
504        this.length = this.length || 0;
505        this._enumerate(input);
506        if (this._remaining === 0) {
507          fulfill(this.promise, this._result);
508        }
509      }
510    } else {
511      reject(this.promise, validationError());
512    }
513  }
514
515  Enumerator.prototype._enumerate = function _enumerate(input) {
516    for (var i = 0; this._state === PENDING && i < input.length; i++) {
517      this._eachEntry(input[i], i);
518    }
519  };
520
521  Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
522    var c = this._instanceConstructor;
523    var resolve$$1 = c.resolve;
524
525
526    if (resolve$$1 === resolve$1) {
527      var _then = getThen(entry);
528
529      if (_then === then && entry._state !== PENDING) {
530        this._settledAt(entry._state, i, entry._result);
531      } else if (typeof _then !== 'function') {
532        this._remaining--;
533        this._result[i] = entry;
534      } else if (c === Promise$1) {
535        var promise = new c(noop);
536        handleMaybeThenable(promise, entry, _then);
537        this._willSettleAt(promise, i);
538      } else {
vendor: 16,494 bytes, lines 539-1184
539        this._willSettleAt(new c(function (resolve$$1) {
540          return resolve$$1(entry);
541        }), i);
542      }
543    } else {
544      this._willSettleAt(resolve$$1(entry), i);
545    }
546  };
547
548  Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
549    var promise = this.promise;
550
551
552    if (promise._state === PENDING) {
553      this._remaining--;
554
555      if (state === REJECTED) {
556        reject(promise, value);
557      } else {
558        this._result[i] = value;
559      }
560    }
561
562    if (this._remaining === 0) {
563      fulfill(promise, this._result);
564    }
565  };
566
567  Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
568    var enumerator = this;
569
570    subscribe(promise, undefined, function (value) {
571      return enumerator._settledAt(FULFILLED, i, value);
572    }, function (reason) {
573      return enumerator._settledAt(REJECTED, i, reason);
574    });
575  };
576
577  return Enumerator;
578}();
579
580/**
581  `Promise.all` accepts an array of promises, and returns a new promise which
582  is fulfilled with an array of fulfillment values for the passed promises, or
583  rejected with the reason of the first passed promise to be rejected. It casts all
584  elements of the passed iterable to promises as it runs this algorithm.
585
586  Example:
587
588  ```javascript
589  let promise1 = resolve(1);
590  let promise2 = resolve(2);
591  let promise3 = resolve(3);
592  let promises = [ promise1, promise2, promise3 ];
593
594  Promise.all(promises).then(function(array){
595    // The array here would be [ 1, 2, 3 ];
596  });
597  ```
598
599  If any of the `promises` given to `all` are rejected, the first promise
600  that is rejected will be given as an argument to the returned promises's
601  rejection handler. For example:
602
603  Example:
604
605  ```javascript
606  let promise1 = resolve(1);
607  let promise2 = reject(new Error("2"));
608  let promise3 = reject(new Error("3"));
609  let promises = [ promise1, promise2, promise3 ];
610
611  Promise.all(promises).then(function(array){
612    // Code here never runs because there are rejected promises!
613  }, function(error) {
614    // error.message === "2"
615  });
616  ```
617
618  @method all
619  @static
620  @param {Array} entries array of promises
621  @param {String} label optional string for labeling the promise.
622  Useful for tooling.
623  @return {Promise} promise that is fulfilled when all `promises` have been
624  fulfilled, or rejected if any of them become rejected.
625  @static
626*/
627function all(entries) {
628  return new Enumerator(this, entries).promise;
629}
630
631/**
632  `Promise.race` returns a new promise which is settled in the same way as the
633  first passed promise to settle.
634
635  Example:
636
637  ```javascript
638  let promise1 = new Promise(function(resolve, reject){
639    setTimeout(function(){
640      resolve('promise 1');
641    }, 200);
642  });
643
644  let promise2 = new Promise(function(resolve, reject){
645    setTimeout(function(){
646      resolve('promise 2');
647    }, 100);
648  });
649
650  Promise.race([promise1, promise2]).then(function(result){
651    // result === 'promise 2' because it was resolved before promise1
652    // was resolved.
653  });
654  ```
655
656  `Promise.race` is deterministic in that only the state of the first
657  settled promise matters. For example, even if other promises given to the
658  `promises` array argument are resolved, but the first settled promise has
659  become rejected before the other promises became fulfilled, the returned
660  promise will become rejected:
661
662  ```javascript
663  let promise1 = new Promise(function(resolve, reject){
664    setTimeout(function(){
665      resolve('promise 1');
666    }, 200);
667  });
668
669  let promise2 = new Promise(function(resolve, reject){
670    setTimeout(function(){
671      reject(new Error('promise 2'));
672    }, 100);
673  });
674
675  Promise.race([promise1, promise2]).then(function(result){
676    // Code here never runs
677  }, function(reason){
678    // reason.message === 'promise 2' because promise 2 became rejected before
679    // promise 1 became fulfilled
680  });
681  ```
682
683  An example real-world use case is implementing timeouts:
684
685  ```javascript
686  Promise.race([ajax('foo.json'), timeout(5000)])
687  ```
688
689  @method race
690  @static
691  @param {Array} promises array of promises to observe
692  Useful for tooling.
693  @return {Promise} a promise which settles in the same way as the first passed
694  promise to settle.
695*/
696function race(entries) {
697  /*jshint validthis:true */
698  var Constructor = this;
699
700  if (!isArray(entries)) {
701    return new Constructor(function (_, reject) {
702      return reject(new TypeError('You must pass an array to race.'));
703    });
704  } else {
705    return new Constructor(function (resolve, reject) {
706      var length = entries.length;
707      for (var i = 0; i < length; i++) {
708        Constructor.resolve(entries[i]).then(resolve, reject);
709      }
710    });
711  }
712}
713
714/**
715  `Promise.reject` returns a promise rejected with the passed `reason`.
716  It is shorthand for the following:
717
718  ```javascript
719  let promise = new Promise(function(resolve, reject){
720    reject(new Error('WHOOPS'));
721  });
722
723  promise.then(function(value){
724    // Code here doesn't run because the promise is rejected!
725  }, function(reason){
726    // reason.message === 'WHOOPS'
727  });
728  ```
729
730  Instead of writing the above, your code now simply becomes the following:
731
732  ```javascript
733  let promise = Promise.reject(new Error('WHOOPS'));
734
735  promise.then(function(value){
736    // Code here doesn't run because the promise is rejected!
737  }, function(reason){
738    // reason.message === 'WHOOPS'
739  });
740  ```
741
742  @method reject
743  @static
744  @param {Any} reason value that the returned promise will be rejected with.
745  Useful for tooling.
746  @return {Promise} a promise rejected with the given `reason`.
747*/
748function reject$1(reason) {
749  /*jshint validthis:true */
750  var Constructor = this;
751  var promise = new Constructor(noop);
752  reject(promise, reason);
753  return promise;
754}
755
756function needsResolver() {
757  throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
758}
759
760function needsNew() {
761  throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
762}
763
764/**
765  Promise objects represent the eventual result of an asynchronous operation. The
766  primary way of interacting with a promise is through its `then` method, which
767  registers callbacks to receive either a promise's eventual value or the reason
768  why the promise cannot be fulfilled.
769
770  Terminology
771  -----------
772
773  - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
774  - `thenable` is an object or function that defines a `then` method.
775  - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
776  - `exception` is a value that is thrown using the throw statement.
777  - `reason` is a value that indicates why a promise was rejected.
778  - `settled` the final resting state of a promise, fulfilled or rejected.
779
780  A promise can be in one of three states: pending, fulfilled, or rejected.
781
782  Promises that are fulfilled have a fulfillment value and are in the fulfilled
783  state.  Promises that are rejected have a rejection reason and are in the
784  rejected state.  A fulfillment value is never a thenable.
785
786  Promises can also be said to *resolve* a value.  If this value is also a
787  promise, then the original promise's settled state will match the value's
788  settled state.  So a promise that *resolves* a promise that rejects will
789  itself reject, and a promise that *resolves* a promise that fulfills will
790  itself fulfill.
791
792
793  Basic Usage:
794  ------------
795
796  ```js
797  let promise = new Promise(function(resolve, reject) {
798    // on success
799    resolve(value);
800
801    // on failure
802    reject(reason);
803  });
804
805  promise.then(function(value) {
806    // on fulfillment
807  }, function(reason) {
808    // on rejection
809  });
810  ```
811
812  Advanced Usage:
813  ---------------
814
815  Promises shine when abstracting away asynchronous interactions such as
816  `XMLHttpRequest`s.
817
818  ```js
819  function getJSON(url) {
820    return new Promise(function(resolve, reject){
821      let xhr = new XMLHttpRequest();
822
823      xhr.open('GET', url);
824      xhr.onreadystatechange = handler;
825      xhr.responseType = 'json';
826      xhr.setRequestHeader('Accept', 'application/json');
827      xhr.send();
828
829      function handler() {
830        if (this.readyState === this.DONE) {
831          if (this.status === 200) {
832            resolve(this.response);
833          } else {
834            reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
835          }
836        }
837      };
838    });
839  }
840
841  getJSON('/posts.json').then(function(json) {
842    // on fulfillment
843  }, function(reason) {
844    // on rejection
845  });
846  ```
847
848  Unlike callbacks, promises are great composable primitives.
849
850  ```js
851  Promise.all([
852    getJSON('/posts'),
853    getJSON('/comments')
854  ]).then(function(values){
855    values[0] // => postsJSON
856    values[1] // => commentsJSON
857
858    return values;
859  });
860  ```
861
862  @class Promise
863  @param {Function} resolver
864  Useful for tooling.
865  @constructor
866*/
867
868var Promise$1 = function () {
869  function Promise(resolver) {
870    this[PROMISE_ID] = nextId();
871    this._result = this._state = undefined;
872    this._subscribers = [];
873
874    if (noop !== resolver) {
875      typeof resolver !== 'function' && needsResolver();
876      this instanceof Promise ? initializePromise(this, resolver) : needsNew();
877    }
878  }
879
880  /**
881  The primary way of interacting with a promise is through its `then` method,
882  which registers callbacks to receive either a promise's eventual value or the
883  reason why the promise cannot be fulfilled.
884   ```js
885  findUser().then(function(user){
886    // user is available
887  }, function(reason){
888    // user is unavailable, and you are given the reason why
889  });
890  ```
891   Chaining
892  --------
893   The return value of `then` is itself a promise.  This second, 'downstream'
894  promise is resolved with the return value of the first promise's fulfillment
895  or rejection handler, or rejected if the handler throws an exception.
896   ```js
897  findUser().then(function (user) {
898    return user.name;
899  }, function (reason) {
900    return 'default name';
901  }).then(function (userName) {
902    // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
903    // will be `'default name'`
904  });
905   findUser().then(function (user) {
906    throw new Error('Found user, but still unhappy');
907  }, function (reason) {
908    throw new Error('`findUser` rejected and we're unhappy');
909  }).then(function (value) {
910    // never reached
911  }, function (reason) {
912    // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
913    // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
914  });
915  ```
916  If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
917   ```js
918  findUser().then(function (user) {
919    throw new PedagogicalException('Upstream error');
920  }).then(function (value) {
921    // never reached
922  }).then(function (value) {
923    // never reached
924  }, function (reason) {
925    // The `PedgagocialException` is propagated all the way down to here
926  });
927  ```
928   Assimilation
929  ------------
930   Sometimes the value you want to propagate to a downstream promise can only be
931  retrieved asynchronously. This can be achieved by returning a promise in the
932  fulfillment or rejection handler. The downstream promise will then be pending
933  until the returned promise is settled. This is called *assimilation*.
934   ```js
935  findUser().then(function (user) {
936    return findCommentsByAuthor(user);
937  }).then(function (comments) {
938    // The user's comments are now available
939  });
940  ```
941   If the assimliated promise rejects, then the downstream promise will also reject.
942   ```js
943  findUser().then(function (user) {
944    return findCommentsByAuthor(user);
945  }).then(function (comments) {
946    // If `findCommentsByAuthor` fulfills, we'll have the value here
947  }, function (reason) {
948    // If `findCommentsByAuthor` rejects, we'll have the reason here
949  });
950  ```
951   Simple Example
952  --------------
953   Synchronous Example
954   ```javascript
955  let result;
956   try {
957    result = findResult();
958    // success
959  } catch(reason) {
960    // failure
961  }
962  ```
963   Errback Example
964   ```js
965  findResult(function(result, err){
966    if (err) {
967      // failure
968    } else {
969      // success
970    }
971  });
972  ```
973   Promise Example;
974   ```javascript
975  findResult().then(function(result){
976    // success
977  }, function(reason){
978    // failure
979  });
980  ```
981   Advanced Example
982  --------------
983   Synchronous Example
984   ```javascript
985  let author, books;
986   try {
987    author = findAuthor();
988    books  = findBooksByAuthor(author);
989    // success
990  } catch(reason) {
991    // failure
992  }
993  ```
994   Errback Example
995   ```js
996   function foundBooks(books) {
997   }
998   function failure(reason) {
999   }
1000   findAuthor(function(author, err){
1001    if (err) {
1002      failure(err);
1003      // failure
1004    } else {
1005      try {
1006        findBoooksByAuthor(author, function(books, err) {
1007          if (err) {
1008            failure(err);
1009          } else {
1010            try {
1011              foundBooks(books);
1012            } catch(reason) {
1013              failure(reason);
1014            }
1015          }
1016        });
1017      } catch(error) {
1018        failure(err);
1019      }
1020      // success
1021    }
1022  });
1023  ```
1024   Promise Example;
1025   ```javascript
1026  findAuthor().
1027    then(findBooksByAuthor).
1028    then(function(books){
1029      // found books
1030  }).catch(function(reason){
1031    // something went wrong
1032  });
1033  ```
1034   @method then
1035  @param {Function} onFulfilled
1036  @param {Function} onRejected
1037  Useful for tooling.
1038  @return {Promise}
1039  */
1040
1041  /**
1042  `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
1043  as the catch block of a try/catch statement.
1044  ```js
1045  function findAuthor(){
1046  throw new Error('couldn't find that author');
1047  }
1048  // synchronous
1049  try {
1050  findAuthor();
1051  } catch(reason) {
1052  // something went wrong
1053  }
1054  // async with promises
1055  findAuthor().catch(function(reason){
1056  // something went wrong
1057  });
1058  ```
1059  @method catch
1060  @param {Function} onRejection
1061  Useful for tooling.
1062  @return {Promise}
1063  */
1064
1065
1066  Promise.prototype.catch = function _catch(onRejection) {
1067    return this.then(null, onRejection);
1068  };
1069
1070  /**
1071    `finally` will be invoked regardless of the promise's fate just as native
1072    try/catch/finally behaves
1073  
1074    Synchronous example:
1075  
1076    ```js
1077    findAuthor() {
1078      if (Math.random() > 0.5) {
1079        throw new Error();
1080      }
1081      return new Author();
1082    }
1083  
1084    try {
1085      return findAuthor(); // succeed or fail
1086    } catch(error) {
1087      return findOtherAuther();
1088    } finally {
1089      // always runs
1090      // doesn't affect the return value
1091    }
1092    ```
1093  
1094    Asynchronous example:
1095  
1096    ```js
1097    findAuthor().catch(function(reason){
1098      return findOtherAuther();
1099    }).finally(function(){
1100      // author was either found, or not
1101    });
1102    ```
1103  
1104    @method finally
1105    @param {Function} callback
1106    @return {Promise}
1107  */
1108
1109
1110  Promise.prototype.finally = function _finally(callback) {
1111    var promise = this;
1112    var constructor = promise.constructor;
1113
1114    if (isFunction(callback)) {
1115      return promise.then(function (value) {
1116        return constructor.resolve(callback()).then(function () {
1117          return value;
1118        });
1119      }, function (reason) {
1120        return constructor.resolve(callback()).then(function () {
1121          throw reason;
1122        });
1123      });
1124    }
1125
1126    return promise.then(callback, callback);
1127  };
1128
1129  return Promise;
1130}();
1131
1132Promise$1.prototype.then = then;
1133Promise$1.all = all;
1134Promise$1.race = race;
1135Promise$1.resolve = resolve$1;
1136Promise$1.reject = reject$1;
1137Promise$1._setScheduler = setScheduler;
1138Promise$1._setAsap = setAsap;
1139Promise$1._asap = asap;
1140
1141/*global self*/
1142function polyfill() {
1143  var local = void 0;
1144
1145  if (typeof global !== 'undefined') {
1146    local = global;
1147  } else if (typeof self !== 'undefined') {
1148    local = self;
1149  } else {
1150    try {
1151      local = Function('return this')();
1152    } catch (e) {
1153      throw new Error('polyfill failed because global object is unavailable in this environment');
1154    }
1155  }
1156
1157  var P = local.Promise;
1158
1159  if (P) {
1160    var promiseToString = null;
1161    try {
1162      promiseToString = Object.prototype.toString.call(P.resolve());
1163    } catch (e) {
1164      // silently ignored
1165    }
1166
1167    if (promiseToString === '[object Promise]' && !P.cast) {
1168      return;
1169    }
1170  }
1171
1172  local.Promise = Promise$1;
1173}
1174
1175// Strange compat..
1176Promise$1.polyfill = polyfill;
1177Promise$1.Promise = Promise$1;
1178
1179return Promise$1;
1180
1181})));
1182
1183
1184
1185
1186
1187}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1188
1189},{"_process":3}],2:[function(_dereq_,module,exports){
1190// Copyright Joyent, Inc. and other Node contributors.
1191//
1192// Permission is hereby granted, free of charge, to any person obtaining a
1193// copy of this software and associated documentation files (the
1194// "Software"), to deal in the Software without restriction, including
1195// without limitation the rights to use, copy, modify, merge, publish,
1196// distribute, sublicense, and/or sell copies of the Software, and to permit
1197// persons to whom the Software is furnished to do so, subject to the
1198// following conditions:
1199//
1200// The above copyright notice and this permission notice shall be included
1201// in all copies or substantial portions of the Software.
1202//
1203// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1204// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1205// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
1206// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
1207// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1208// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
1209// USE OR OTHER DEALINGS IN THE SOFTWARE.
1210
1211function EventEmitter() {
1212  this._events = this._events || {};
1213  this._maxListeners = this._maxListeners || undefined;
1214}
1215module.exports = EventEmitter;
1216
1217// Backwards-compat with node 0.10.x
1218EventEmitter.EventEmitter = EventEmitter;
1219
1220EventEmitter.prototype._events = undefined;
1221EventEmitter.prototype._maxListeners = undefined;
1222
1223// By default EventEmitters will print a warning if more than 10 listeners are
1224// added to it. This is a useful default which helps finding memory leaks.
1225EventEmitter.defaultMaxListeners = 10;
1226
1227// Obviously not all Emitters should be limited to 10. This function allows
1228// that to be increased. Set to zero for unlimited.
1229EventEmitter.prototype.setMaxListeners = function(n) {
1230  if (!isNumber(n) || n < 0 || isNaN(n))
1231    throw TypeError('n must be a positive number');
1232  this._maxListeners = n;
1233  return this;
1234};
1235
1236EventEmitter.prototype.emit = function(type) {
1237  var er, handler, len, args, i, listeners;
1238
1239  if (!this._events)
1240    this._events = {};
1241
1242  // If there is no 'error' event listener then throw.
1243  if (type === 'error') {
1244    if (!this._events.error ||
1245        (isObject(this._events.error) && !this._events.error.length)) {
1246      er = arguments[1];
1247      if (er instanceof Error) {
1248        //throw er; // Unhandled 'error' event //Edited By BuddyBoss
1249      } else {
1250        // At least give some kind of context to the user
1251        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
1252        err.context = er;
1253        //throw err; //Edited By BuddyBoss
1254      }
1255    }
1256  }
1257
1258  handler = this._events[type];
1259
1260  if (isUndefined(handler))
1261    return false;
vendor: 5,655 bytes, lines 1262-1493
1262
1263  if (isFunction(handler)) {
1264    switch (arguments.length) {
1265      // fast cases
1266      case 1:
1267        handler.call(this);
1268        break;
1269      case 2:
1270        handler.call(this, arguments[1]);
1271        break;
1272      case 3:
1273        handler.call(this, arguments[1], arguments[2]);
1274        break;
1275      // slower
1276      default:
1277        args = Array.prototype.slice.call(arguments, 1);
1278        handler.apply(this, args);
1279    }
1280  } else if (isObject(handler)) {
1281    args = Array.prototype.slice.call(arguments, 1);
1282    listeners = handler.slice();
1283    len = listeners.length;
1284    for (i = 0; i < len; i++)
1285      listeners[i].apply(this, args);
1286  }
1287
1288  return true;
1289};
1290
1291EventEmitter.prototype.addListener = function(type, listener) {
1292  var m;
1293
1294  if (!isFunction(listener))
1295    throw TypeError('listener must be a function');
1296
1297  if (!this._events)
1298    this._events = {};
1299
1300  // To avoid recursion in the case that type === "newListener"! Before
1301  // adding it to the listeners, first emit "newListener".
1302  if (this._events.newListener)
1303    this.emit('newListener', type,
1304              isFunction(listener.listener) ?
1305              listener.listener : listener);
1306
1307  if (!this._events[type])
1308    // Optimize the case of one listener. Don't need the extra array object.
1309    this._events[type] = listener;
1310  else if (isObject(this._events[type]))
1311    // If we've already got an array, just append.
1312    this._events[type].push(listener);
1313  else
1314    // Adding the second element, need to change to array.
1315    this._events[type] = [this._events[type], listener];
1316
1317  // Check for listener leak
1318  if (isObject(this._events[type]) && !this._events[type].warned) {
1319    if (!isUndefined(this._maxListeners)) {
1320      m = this._maxListeners;
1321    } else {
1322      m = EventEmitter.defaultMaxListeners;
1323    }
1324
1325    if (m && m > 0 && this._events[type].length > m) {
1326      this._events[type].warned = true;
1327      console.error('(node) warning: possible EventEmitter memory ' +
1328                    'leak detected. %d listeners added. ' +
1329                    'Use emitter.setMaxListeners() to increase limit.',
1330                    this._events[type].length);
1331      if (typeof console.trace === 'function') {
1332        // not supported in IE 10
1333        console.trace();
1334      }
1335    }
1336  }
1337
1338  return this;
1339};
1340
1341EventEmitter.prototype.on = EventEmitter.prototype.addListener;
1342
1343EventEmitter.prototype.once = function(type, listener) {
1344  if (!isFunction(listener))
1345    throw TypeError('listener must be a function');
1346
1347  var fired = false;
1348
1349  function g() {
1350    this.removeListener(type, g);
1351
1352    if (!fired) {
1353      fired = true;
1354      listener.apply(this, arguments);
1355    }
1356  }
1357
1358  g.listener = listener;
1359  this.on(type, g);
1360
1361  return this;
1362};
1363
1364// emits a 'removeListener' event iff the listener was removed
1365EventEmitter.prototype.removeListener = function(type, listener) {
1366  var list, position, length, i;
1367
1368  if (!isFunction(listener))
1369    throw TypeError('listener must be a function');
1370
1371  if (!this._events || !this._events[type])
1372    return this;
1373
1374  list = this._events[type];
1375  length = list.length;
1376  position = -1;
1377
1378  if (list === listener ||
1379      (isFunction(list.listener) && list.listener === listener)) {
1380    delete this._events[type];
1381    if (this._events.removeListener)
1382      this.emit('removeListener', type, listener);
1383
1384  } else if (isObject(list)) {
1385    for (i = length; i-- > 0;) {
1386      if (list[i] === listener ||
1387          (list[i].listener && list[i].listener === listener)) {
1388        position = i;
1389        break;
1390      }
1391    }
1392
1393    if (position < 0)
1394      return this;
1395
1396    if (list.length === 1) {
1397      list.length = 0;
1398      delete this._events[type];
1399    } else {
1400      list.splice(position, 1);
1401    }
1402
1403    if (this._events.removeListener)
1404      this.emit('removeListener', type, listener);
1405  }
1406
1407  return this;
1408};
1409
1410EventEmitter.prototype.removeAllListeners = function(type) {
1411  var key, listeners;
1412
1413  if (!this._events)
1414    return this;
1415
1416  // not listening for removeListener, no need to emit
1417  if (!this._events.removeListener) {
1418    if (arguments.length === 0)
1419      this._events = {};
1420    else if (this._events[type])
1421      delete this._events[type];
1422    return this;
1423  }
1424
1425  // emit removeListener for all listeners on all events
1426  if (arguments.length === 0) {
1427    for (key in this._events) {
1428      if (key === 'removeListener') continue;
1429      this.removeAllListeners(key);
1430    }
1431    this.removeAllListeners('removeListener');
1432    this._events = {};
1433    return this;
1434  }
1435
1436  listeners = this._events[type];
1437
1438  if (isFunction(listeners)) {
1439    this.removeListener(type, listeners);
1440  } else if (listeners) {
1441    // LIFO order
1442    while (listeners.length)
1443      this.removeListener(type, listeners[listeners.length - 1]);
1444  }
1445  delete this._events[type];
1446
1447  return this;
1448};
1449
1450EventEmitter.prototype.listeners = function(type) {
1451  var ret;
1452  if (!this._events || !this._events[type])
1453    ret = [];
1454  else if (isFunction(this._events[type]))
1455    ret = [this._events[type]];
1456  else
1457    ret = this._events[type].slice();
1458  return ret;
1459};
1460
1461EventEmitter.prototype.listenerCount = function(type) {
1462  if (this._events) {
1463    var evlistener = this._events[type];
1464
1465    if (isFunction(evlistener))
1466      return 1;
1467    else if (evlistener)
1468      return evlistener.length;
1469  }
1470  return 0;
1471};
1472
1473EventEmitter.listenerCount = function(emitter, type) {
1474  return emitter.listenerCount(type);
1475};
1476
1477function isFunction(arg) {
1478  return typeof arg === 'function';
1479}
1480
1481function isNumber(arg) {
1482  return typeof arg === 'number';
1483}
1484
1485function isObject(arg) {
1486  return typeof arg === 'object' && arg !== null;
1487}
1488
1489function isUndefined(arg) {
1490  return arg === void 0;
1491}
1492
1493},{}],3:[function(_dereq_
vendor: 5,443 bytes, lines 1493-1679
1493,module,exports){
1494// shim for using process in browser
1495var process = module.exports = {};
1496
1497// cached from whatever global is present so that test runners that stub it
1498// don't break things.  But we need to wrap it in a try catch in case it is
1499// wrapped in strict mode code which doesn't define any globals.  It's inside a
1500// function because try/catches deoptimize in certain engines.
1501
1502var cachedSetTimeout;
1503var cachedClearTimeout;
1504
1505function defaultSetTimout() {
1506    throw new Error('setTimeout has not been defined');
1507}
1508function defaultClearTimeout () {
1509    throw new Error('clearTimeout has not been defined');
1510}
1511(function () {
1512    try {
1513        if (typeof setTimeout === 'function') {
1514            cachedSetTimeout = setTimeout;
1515        } else {
1516            cachedSetTimeout = defaultSetTimout;
1517        }
1518    } catch (e) {
1519        cachedSetTimeout = defaultSetTimout;
1520    }
1521    try {
1522        if (typeof clearTimeout === 'function') {
1523            cachedClearTimeout = clearTimeout;
1524        } else {
1525            cachedClearTimeout = defaultClearTimeout;
1526        }
1527    } catch (e) {
1528        cachedClearTimeout = defaultClearTimeout;
1529    }
1530} ())
1531function runTimeout(fun) {
1532    if (cachedSetTimeout === setTimeout) {
1533        //normal enviroments in sane situations
1534        return setTimeout(fun, 0);
1535    }
1536    // if setTimeout wasn't available but was latter defined
1537    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
1538        cachedSetTimeout = setTimeout;
1539        return setTimeout(fun, 0);
1540    }
1541    try {
1542        // when when somebody has screwed with setTimeout but no I.E. maddness
1543        return cachedSetTimeout(fun, 0);
1544    } catch(e){
1545        try {
1546            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
1547            return cachedSetTimeout.call(null, fun, 0);
1548        } catch(e){
1549            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
1550            return cachedSetTimeout.call(this, fun, 0);
1551        }
1552    }
1553
1554
1555}
1556function runClearTimeout(marker) {
1557    if (cachedClearTimeout === clearTimeout) {
1558        //normal enviroments in sane situations
1559        return clearTimeout(marker);
1560    }
1561    // if clearTimeout wasn't available but was latter defined
1562    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
1563        cachedClearTimeout = clearTimeout;
1564        return clearTimeout(marker);
1565    }
1566    try {
1567        // when when somebody has screwed with setTimeout but no I.E. maddness
1568        return cachedClearTimeout(marker);
1569    } catch (e){
1570        try {
1571            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
1572            return cachedClearTimeout.call(null, marker);
1573        } catch (e){
1574            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
1575            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
1576            return cachedClearTimeout.call(this, marker);
1577        }
1578    }
1579
1580
1581
1582}
1583var queue = [];
1584var draining = false;
1585var currentQueue;
1586var queueIndex = -1;
1587
1588function cleanUpNextTick() {
1589    if (!draining || !currentQueue) {
1590        return;
1591    }
1592    draining = false;
1593    if (currentQueue.length) {
1594        queue = currentQueue.concat(queue);
1595    } else {
1596        queueIndex = -1;
1597    }
1598    if (queue.length) {
1599        drainQueue();
1600    }
1601}
1602
1603function drainQueue() {
1604    if (draining) {
1605        return;
1606    }
1607    var timeout = runTimeout(cleanUpNextTick);
1608    draining = true;
1609
1610    var len = queue.length;
1611    while(len) {
1612        currentQueue = queue;
1613        queue = [];
1614        while (++queueIndex < len) {
1615            if (currentQueue) {
1616                currentQueue[queueIndex].run();
1617            }
1618        }
1619        queueIndex = -1;
1620        len = queue.length;
1621    }
1622    currentQueue = null;
1623    draining = false;
1624    runClearTimeout(timeout);
1625}
1626
1627process.nextTick = function (fun) {
1628    var args = new Array(arguments.length - 1);
1629    if (arguments.length > 1) {
1630        for (var i = 1; i < arguments.length; i++) {
1631            args[i - 1] = arguments[i];
1632        }
1633    }
1634    queue.push(new Item(fun, args));
1635    if (queue.length === 1 && !draining) {
1636        runTimeout(drainQueue);
1637    }
1638};
1639
1640// v8 likes predictible objects
1641function Item(fun, array) {
1642    this.fun = fun;
1643    this.array = array;
1644}
1645Item.prototype.run = function () {
1646    this.fun.apply(null, this.array);
1647};
1648process.title = 'browser';
1649process.browser = true;
1650process.env = {};
1651process.argv = [];
1652process.version = ''; // empty string to avoid regexp issues
1653process.versions = {};
1654
1655function noop() {}
1656
1657process.on = noop;
1658process.addListener = noop;
1659process.once = noop;
1660process.off = noop;
1661process.removeListener = noop;
1662process.removeAllListeners = noop;
1663process.emit = noop;
1664process.prependListener = noop;
1665process.prependOnceListener = noop;
1666
1667process.listeners = function (name) { return [] }
1668
1669process.binding = function (name) {
1670    throw new Error('process.binding is not supported');
1671};
1672
1673process.cwd = function () { return '/' };
1674process.chdir = function (dir) {
1675    throw new Error('process.chdir is not supported');
1676};
1677process.umask = function() { return 0; };
1678
1679},{}],
16794:[function(_dereq_,module,exports){
1680var bundleFn = arguments[3];
1681var sources = arguments[4];
1682var cache = arguments[5];
1683
1684var stringify = JSON.stringify;
1685
1686module.exports = function (fn, options) {
1687    var wkey;
1688    var cacheKeys = Object.keys(cache);
1689
1690    for (var i = 0, l = cacheKeys.length; i < l; i++) {
1691        var key = cacheKeys[i];
1692        var exp = cache[key].exports;
1693        // Using babel as a transpiler to use esmodule, the export will always
1694        // be an object with the default export as a property of it. To ensure
1695        // the existing api and babel esmodule exports are both supported we
1696        // check for both
1697        if (exp === fn || exp && exp.default === fn) {
1698            wkey = key;
1699            break;
1700        }
1701    }
1702
1703    if (!wkey) {
1704        wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
1705        var wcache = {};
1706        for (var i = 0, l = cacheKeys.length; i < l; i++) {
1707            var key = cacheKeys[i];
1708            wcache[key] = key;
1709        }
1710        sources[wkey] = [
1711            'function(require,module,exports){' + fn + '(self); }',
1712            wcache
1713        ];
1714    }
1715    var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
1716
1717    var scache = {}; scache[wkey] = wkey;
1718    sources[skey] = [
1719        'function(require,module,exports){' +
1720            // try to call default if defined to also support babel esmodule exports
1721            'var f = require(' + stringify(wkey) + ');' +
1722            '(f.default ? f.default : f)(self);' +
1723        '}',
1724        scache
1725    ];
1726
1727    var workerSources = {};
1728    resolveSources(skey);
1729
1730    function resolveSources(key) {
1731        workerSources[key] = true;
1732
1733        for (var depPath in sources[key][1]) {
1734            var depKey = sources[key][1][depPath];
1735            if (!workerSources[depKey]) {
1736                resolveSources(depKey);
1737            }
1738        }
1739    }
1740
1741    var src = '(' + bundleFn + ')({'
1742        + Object.keys(workerSources).map(function (key) {
1743            return stringify(key) + ':['
1744                + sources[key][0]
1745                + ',' + stringify(sources[key][1]) + ']'
1746            ;
1747        }).join(',')
1748        + '},{},[' + stringify(skey) + '])'
1749    ;
1750
1751    var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
1752
1753    var blob = new Blob([src], { type: 'text/javascript' });
1754    if (options && options.bare) { return blob; }
1755    var workerUrl = URL.createObjectURL(blob);
1756    var worker = new Worker(workerUrl);
1757    worker.objectURL = workerUrl;
1758    return worker;
1759};
1760
1761},{}],5:[function(_dereq_,module,exports){
1762'use strict';
1763
1764Object.defineProperty(exports, "__esModule", {
1765    value: true
1766});
1767exports.createDefaultConfig = createDefaultConfig;
1768/*
1769 * Copyright (C) 2016 Bilibili. All Rights Reserved.
1770 *
1771 * @author zheng qian <[email protected]>
1772 *
1773 * Licensed under the Apache License, Version 2.0 (the "License");
1774 * you may not use this file except in compliance with the License.
1775 * You may obtain a copy of the License at
1776 *
1777 *     http://www.apache.org/licenses/LICENSE-2.0
1778 *
1779 * Unless required by applicable law or agreed to in writing, software
1780 * distributed under the License is distributed on an "AS IS" BASIS,
1781 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1782 * See the License for the specific language governing permissions and
1783 * limitations under the License.
1784 */
1785
1786var defaultConfig = exports.defaultConfig = {
1787    enableWorker: false,
1788    enableStashBuffer: true,
1789    stashInitialSize: undefined,
1790
1791    isLive: false,
1792
1793    lazyLoad: true,
1794    lazyLoadMaxDuration: 3 * 60,
1795    lazyLoadRecoverDuration: 30,
1796    deferLoadAfterSourceOpen: true,
1797
1798    // autoCleanupSourceBuffer: default as false, leave unspecified
1799    autoCleanupMaxBackwardDuration: 3 * 60,
1800    autoCleanupMinBackwardDuration: 2 * 60,
1801
1802    statisticsInfoReportInterval: 600,
1803
1804    fixAudioTimestampGap: true,
1805
1806    accurateSeek: false,
1807    seekType: 'range', // [range, param, custom]
1808    seekParamStart: 'bstart',
1809    seekParamEnd: 'bend',
1810    rangeLoadZeroStart: false,
1811    customSeekHandler: undefined,
1812    reuseRedirectedURL: false,
1813    // referrerPolicy: leave as unspecified
1814
1815    headers: undefined,
1816    customLoader: undefined
1817};
1818
1819function createDefaultConfig() {
1820    return Object.assign({}, defaultConfig);
1821}
1822
1823},{}],6:[function(_dereq_,module,exports){
1824'use strict';
1825
1826Object.defineProperty(exports, "__esModule", {
1827    value: true
1828});
1829
1830var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
1831                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
1832                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
1833                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
1834                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
1835                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
1836                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
1836not use this file except in compliance with the License.
1837                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
1838                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
1839                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
1840                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
1841                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
1842                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
1843                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1844                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
1845                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
1846                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
1847
1848var _ioController = _dereq_('../io/io-controller.js');
1849
1850var _ioController2 = _interopRequireDefault(_ioController);
1851
1852var _config = _dereq_('../config.js');
1853
1854function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1855
1856function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1857
1858var Features = function () {
1859    function Features() {
1860        _classCallCheck(this, Features);
1861    }
1862
1863    _createClass(Features, null, [{
1864        key: 'supportMSEH264Playback',
1865        value: function supportMSEH264Playback() {
1866            return window.MediaSource && window.MediaSource.isTypeSupp
1866orted('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
1867        }
1868    }, {
1869        key: 'supportNetworkStreamIO',
1870        value: function supportNetworkStreamIO() {
1871            var ioctl = new _ioController2.default({}, (0, _config.createDefaultConfig)());
1872            var loaderType = ioctl.loaderType;
1873            ioctl.destroy();
1874            return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';
1875        }
1876    }, {
1877        key: 'getNetworkLoaderTypeName',
1878        value: function getNetworkLoaderTypeName() {
1879            var ioctl = new _ioController2.default({}, (0, _config.createDefaultConfig)());
1880            var loaderType = ioctl.loaderType;
1881            ioctl.destroy();
1882            return loaderType;
1883        }
1884    }, {
1885        key: 'supportNativeMediaPlayback',
1886        value: function supportNativeMediaPlayback(mimeType) {
1887            if (Features.videoElement == undefined) {
1888                Features.videoElement = window.document.createElement('video');
1889            }
1890            var canPlay = Features.videoElement.canPlayType(mimeType);
1891            return canPlay === 'probably' || canPlay == 'maybe';
1892        }
1893    }, {
1894        key: 'getFeatureList',
1895        value: function getFeatureList() {
1896            var features = {
1897                mseFlvPlayback: false,
1898                mseLiveFlvPlayback: false,
1899                networkStreamIO: false,
1900                networkLoaderName: '',
1901                nativeMP4H264Playback: false,
1902                nativeWebmVP8Playback: false,
1903                nativeWebmVP9Playback: false
1904            };
1905
1906            features.mseFlvPlayback = Features.supportMSEH264Playback();
1907            features.networkStreamIO = Features.supportNetworkStreamIO();
1908            features.networkLoaderName = Features.getNetworkLoaderTypeName();
1909            features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;
1910            features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs="avc1.42001E, mp4a.40.2"');
1911            features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs="vp8.0, vorbis"');
1912            features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs="vp9"');
1913
1914            return features;
1915        }
1916    }]);
1917
1918    return Features;
1919}();
1920
1921exports.default = Features;
1922
1923},{"../config.js":5,"../io/io-controller.js":23}],7:[function(_dereq_,module,exports){
1924"use strict";
1925
1926Object.defineProperty(exports, "__esModule", {
1927    value: true
1928});
1929
1930var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
1931
1932function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1933
1934/*
1935 * Copyright (C) 2016 Bilibili. All Rights Reserved.
1936 *
1937 * @author zheng qian <[email protected]>
1938 *
1939 * Licensed under the Apache License, Version 2.0 (the "License");
1940 * you may not use this file except in compliance with the License.
1941 * You may obtain a copy of the License at
1942 *
1943 *     http://www.apache.org/licenses/LICENSE-2.0
1944 *
1945 * Unless required by applicable law or agreed to in writing, software
1946 * distributed under the License is distributed on an "AS IS" BASIS,
1947 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1948 * See the License for the specific language governing permissions and
1949 * limitations under the License.
1950 */
1951
1952var MediaInfo = function () {
1953    function MediaInfo() {
1954        _classCallCheck(this, MediaInfo);
1955
1956        this.mimeType = null;
1957        this.duration = null;
1958
1959        this.hasAudio = null;
1960        this.hasVideo = null;
1961        this.audioCodec = null;
1962        this.videoCodec = null;
1963        this.audioDataRate = null;
1964        this.videoDataRate = null;
1965
1966        this.audioSampleRate = null;
1967        this.audioChannelCount = null;
1968
1969        this.width = null;
1970        this.height = null;
1971        this.fps = null;
1972        this.profile = null;
1973        this.level = null;
1974        this.refFrames = null;
1975        this.chromaFormat = null;
1976        this.sarNum = null;
1977        this.sarDen = null;
1978
1979        this.metadata = null;
1980        this.segments = null; // MediaInfo[]
1981        this.segmentCount = null;
1982        this.hasKeyframesIndex = null;
1983        this.keyframesIndex = null;
1984    }
1985
1986    _createClass(MediaInfo, [{
1987        key: "isComplete",
1988        value: function isComplete() {
1989            var audioInfoComplete = this.hasAudio === false || this.hasAudio === true && this.audioCodec != null && this.audioSampleRate != null && this.audioChannelCount != null;
1990
1991            var videoInfoComplete = this.hasVideo === false || this.hasVideo === true && this.videoCodec != null && this.width != null && this.height != null && this.fps != null && this.profile != null && this.level != null && this.refFrames != null && this.chromaFormat != null && this.sarNum != null && this.sarDen != null;
1992
1993            // keyframesIndex may not be present
1994            return this.mimeType != null && this.duration != null && this.metadata != null && this.hasKeyframesIndex != null && audioInfoComplete && videoInfoComplete;
1995        }
1996    }, {
1997        key: "isSeekable",
1998        value: function isSeekable() {
1999            return this.hasKeyframesIndex === true;
2000        }
2001    }, {
2002        key: "getNearestKeyframe",
2003        value: function getNearestKeyframe(milliseconds) {
2004            if (this.keyframesIndex == null) {
2005                return null;
2006            }
2007
2008            var table = this.keyframesIndex;
2009            var keyframeIdx = this._search(table.times, milliseconds);
2010
2011            return {
2012                index: keyframeIdx,
2013                milliseconds: table.times[keyframeIdx],
2014                fileposition: table.filepositions[keyframeIdx]
2015            };
2016        }
2017    }, {
2018        key: "_search",
2019        value: function _search(list, value) {
2020            var idx = 0;
2021
2022            var last = list.length - 1;
2023            var mid = 0;
2024            var lbound = 0;
2025            var ubound = last;
2026
2027            if (value < list[0]) {
2028                idx = 0;
2029                lbound = ubound + 1; // skip search
2030            }
2031
2032            while (lbound <= ubound) {
2033                mid = lbound + Math.floor((ubound - lbound) / 2);
2034                if (mid === last || value >= list[mid] && value < list[mid + 1]) {
2035                    idx = mid;
2036                    break;
2037                } else if (list[mid] < value) {
2038                    lbound = mid + 1;
2039                } else {
2040                    ubound = mid - 1;
2041                }
2042            }
2043
2044            return idx;
2045        }
2046    }]);
2047
2048    return MediaInfo;
2049}();
2050
2051exports.default = MediaInfo;
2052
2053},{}],8:[function(_dereq_,module,exports){
2054"use strict";
2055
2056Object.defineProperty(exports, "__esModule", {
2057    value: true
2058});
2059
2060var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2061
2062function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2063
2064/*
2065 * Copyright (C) 2016 Bilibili. All Rights Reserved.
2066 *
2067 * @author zheng qian <[email protected]>
2068 *
2069 * Licensed under the Apache License, Version 2.0 (the "License");
2070 * you may not use this file except in compliance with the License.
2071 * You may obtain a copy of the License at
2072 *
2073 *     http://www.apache.org/licenses/LICENSE-2.0
2074 *
2075 * Unless required by applicable law or agreed to in writing, software
2076 * distributed under the License is distributed on an "AS IS" BASIS,
2077 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2078 * See the License for the specific language governing permissions and
2079 * limitations under the License.
2080 */
2081
2082// Represents an media sample (audio / video)
2083var SampleInfo = exports.SampleInfo = function SampleInfo(dts, pts, duration, originalDts, isSync) {
2084    _classCallCheck(this, SampleInfo);
2085
2086    this.dts = dts;
2087    this.pts = pts;
2088    this.duration = duration;
2089    this.originalDts = originalDts;
2090    this.isSyncPoint = isSync;
2091    this.fileposition = null;
2092};
2093
2094// Media Segment concept is defined in Media Source Extensions spec.
2095// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.
2096
2097
2098var MediaSegmentInfo = exports.MediaSegmentInfo = function () {
2099    function MediaSegmentInfo() {
2100        _classCallCheck(this, MediaSegmentInfo);
2101
2102        this.beginDts = 0;
2103        this.endDts = 0;
2104        this.beginPts = 0;
2105        this.endPts = 0;
2106        this.originalBeginDts = 0;
2107        this.originalEndDts = 0;
2108        this.syncPoints = []; // SampleInfo[n], for video IDR frames only
2109        this.firstSample = null; // SampleInfo
2110        this.lastSample = null; // SampleInfo
2111    }
2112
2113    _createClass(MediaSegmentInfo, [{
2114        key: "appendSyncPoint",
2115        value: function appendSyncPoint(sampleInfo) {
2116            // also called Random Access Point
2117            sampleInfo.isSyncPoint = true;
2118            this.syncPoints.push(sampleInfo);
2119        }
2120    }]);
2121
2122    return MediaSegmentInfo;
2123}();
2124
2125// Ordered list for recording video IDR frames, sorted by originalDts
2126
2127
2128var IDRSampleList = exports.IDRSampleList = function () {
2129    function IDRSampleList() {
2130        _classCallCheck(this, IDRSampleList);
2131
2132        this._list = [];
2133    }
2134
2135    _createClass(IDRSampleList, [{
2136        key: "clear",
2137        value: function clear() {
2138            this._list = [];
2139        }
2140    }, {
2141        key: "appendArray",
2142        value: function appendArray(syncPoints) {
2143            var list = this._list;
2144
2145            if (syncPoints.length === 0) {
2146                return;
2147            }
2148
2149            if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {
2150                this.clear();
2151            }
2152
2153            Array.prototype.push.apply(list, syncPoints);
2154        }
2155    }, {
2156        key: "getLastSyncPointBeforeDts",
2157        value: function getLastSyncPointBeforeDts(dts) {
2158            if (this._list.length == 0) {
2159                return null;
2160            }
2161
2162            var list = this._list;
2163            var idx = 0;
2164            var last = list.length - 1;
2165            var mid = 0;
2166            var lbound = 0;
2167            var ubound = last;
2168
2169            if (dts < list[0].dts) {
2170                idx = 0;
2171                lbound = ubound + 1;
2172            }
2173
2174            while (lbound <= ubound) {
2175                mid = lbound + Math.floor((ubound - lbound) / 2);
2176                if (mid === last || dts >= list[mid].dts && dts < list[mid + 1].dts) {
2177                    idx = mid;
2178                    break;
2179                } else if (list[mid].dts < dts) {
2180                    lbound = mid + 1;
2181                } else {
2182                    ubound = mid - 1;
2183                }
2184            }
2185            return this._list[idx];
2186        }
2187    }]);
2188
2189    return IDRSampleList;
2190}();
2191
2192// Data structure for recording information of media segments in single track.
2193
2194
2195var MediaSegmentInfoList = exports.MediaSegmentInfoList = function () {
2196    function MediaSegmentInfoList(type) {
2197        _classCallCheck(this, MediaSegmentInfoList);
2198
2199        this._type = type;
2200        this._list = [];
2201        this._lastAppendLocation = -1; // cached last insert location
2202    }
2203
2204    _createClass(MediaSegmentInfoList, [{
2205        key: "isEmpty",
2206        value: function isEmpty() {
2207            return this._list.length === 0;
2208        }
2209    }, {
2210        key: "clear",
2211        value: function clear() {
2212            this._list = [];
2213            this._lastAppendLocation = -1;
2214        }
2215    }, {
2216        key: "_searchNearestSegmentBefore",
2217        value: function _searchNearestSegmentBefore(originalBeginDts) {
2218            var list = this._list;
2219            if (list.length === 0) {
2220                return -2;
2221            }
2222            var last = list.length - 1;
2223            var mid = 0;
2224            var lbound = 0;
2225            var ubound = last;
2226
2227            var idx = 0;
2228
2229            if (originalBeginDts < list[0].originalBeginDts) {
2230                idx = -1;
2231                return idx;
2232            }
2233
2234            while (lbound <= ubound) {
2235                mid = lbound + Math.floor((ubound - lbound) / 2);
2236                if (mid === last || originalBeginDts > list[mid].lastSample.originalDts && originalBeginDts < list[mid + 1].originalBeginDts) {
2237                    idx = mid;
2238                    break;
2239                } else if (list[mid].originalBeginDts < originalBeginDts) {
2240                    lbound = mid + 1;
2241                } else {
2242                    ubound = mid - 1;
2243                }
2244            }
2245            return idx;
2246        }
2247    }, {
2248        key: "_searchNearestSegmentAfter",
2249        value: function _searchNearestSegmentAfter(originalBeginDts) {
2250            return this._searchNearestSegmentBefore(originalBeginDts) + 1;
2251        }
2252    }, {
2253        key: "append",
2254        value: function append(mediaSegmentInfo) {
2255            var list = this._list;
2256            var msi = mediaSegmentInfo;
2257            var lastAppendIdx = this._lastAppendLocation;
2258            var insertIdx = 0;
2259
2260            if (lastAppendIdx !== -1 && lastAppendIdx < list.length && msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts && (lastAppendIdx === list.length - 1 || lastAppendIdx < list.length - 1 && msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts)) {
2261                insertIdx = lastAppendIdx + 1; // use cached location idx
2262            } else {
2263                if (list.length > 0) {
2264                    insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;
2265                }
2266            }
2267
2268            this._lastAppendLocation = insertIdx;
2269            this._list.splice(insertIdx, 0, msi);
2270        }
2271    }, {
2272        key: "getLastSegmentBefore",
2273        value: function getLastSegmentBefore(originalBeginDts) {
2274            var idx = this._searchNearestSegmentBefore(originalBeginDts);
2275            if (idx >= 0) {
2276                return this._list[idx];
2277            } else {
2278                // -1
2279                return null;
2280            }
2281        }
2282    }, {
2283        key: "getLastSampleBefore",
2284        value: function getLastSampleBefore(originalBeginDts) {
2285            var segment = this.getLastSegmentBefore(originalBeginDts);
2286            if (segment != null) {
2287                return segment.lastSample;
2288            } else {
2289                return null;
2290            }
2291        }
2292    }, {
2293        key: "getLastSyncPointBefore",
2294        value: function getLastSyncPointBefore(originalBeginDts) {
2295            var segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);
2296            var syncPoints = this._list[segmentIdx].syncPoints;
2297            while (syncPoints.length === 0 && segmentIdx > 0) {
2298                segmentIdx--;
2299                syncPoints = this._list[segmentIdx].syncPoints;
2300            }
2301            if (syncPoints.length > 0) {
2302                return syncPoints[syncPoints.length - 1];
2303            } else {
2304                return null;
2305            }
2306        }
2307    }, {
2308        key: "type",
2309        get: function get() {
2310            return this._type;
2311        }
2312    }, {
2313        key: "length",
2314        get: function get() {
2315            return this._list.length;
2316        }
2317    }]);
2318
2319    return MediaSegmentInfoList;
2320}();
2321
2322},{}],9:[function(_dereq_,module,exports){
2323'use strict';
2324
2325Object.defineProperty(exports, "__esModule", {
2326    value: true
2327});
2328
2329var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
2330                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
2331                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2332                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
2333                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2334                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
2335                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
2335not use this file except in compliance with the License.
2336                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
2337                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2338                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
2339                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2340                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
2341                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
2342                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2343                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
2344                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
2345                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
2346
2347var _events = _dereq_('events');
2348
2349var _events2 = _interopRequireDefault(_events);
2350
2351var _logger = _dereq_('../utils/logger.js');
2352
2353var _logger2 = _interopRequireDefault(_logger);
2354
2355var _browser = _dereq_('../utils/browser.js');
2356
2357var _browser2 = _interopRequireDefault(_browser);
2358
2359var _mseEvents = _dereq_('./mse-events.js');
2360
2361var _mseEvents2 = _interopRequireDefault(_mseEvents);
2362
2363var _mediaSegmentInfo = _dereq_('./media-segment-info.js');
2364
2365var _exception = _dereq_('../utils/exception.js');
2366
2367function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2368
2369function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2370
2371// Media Source Extensions controller
2372var MSEController = function () {
2373    function MSEController(config) {
2374        _classCallCheck(this, MSEController);
2375
2376        this.TAG = 'MSEController';
2377
2378        this._config = config;
2379        this._emitter = new _events2.default();
2380
2381        if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {
2382            // For live stream, do auto cleanup by default
2383            this._config.autoCleanupSourceBuffer = true;
2384        }
2385
2386        this.e = {
2387            onSourceOpen: this._onSourceOpen.bind(this),
2388            onSourceEnded: this._onSourceEnded.bind(this),
2389            onSourceClose: this._onSourceClose.bind(this),
2390            onSourceBufferError: this._onSourceBufferError.bind(this),
2391            onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)
2392        };
2393
2394        this._mediaSource = null;
2395        this._mediaSourceObjectURL = null;
2396        this._mediaElement = null;
2397
2398        this._isBufferFull = false;
vendor: 12,391 bytes, lines 2399-2692
2399        this._hasPendingEos = false;
2400
2401        this._requireSetMediaDuration = false;
2402        this._pendingMediaDuration = 0;
2403
2404        this._pendingSourceBufferInit = [];
2405        this._mimeTypes = {
2406            video: null,
2407            audio: null
2408        };
2409        this._sourceBuffers = {
2410            video: null,
2411            audio: null
2412        };
2413        this._lastInitSegments = {
2414            video: null,
2415            audio: null
2416        };
2417        this._pendingSegments = {
2418            video: [],
2419            audio: []
2420        };
2421        this._pendingRemoveRanges = {
2422            video: [],
2423            audio: []
2424        };
2425        this._idrList = new _mediaSegmentInfo.IDRSampleList();
2426    }
2427
2428    _createClass(MSEController, [{
2429        key: 'destroy',
2430        value: function destroy() {
2431            if (this._mediaElement || this._mediaSource) {
2432                this.detachMediaElement();
2433            }
2434            this.e = null;
2435            this._emitter.removeAllListeners();
2436            this._emitter = null;
2437        }
2438    }, {
2439        key: 'on',
2440        value: function on(event, listener) {
2441            this._emitter.addListener(event, listener);
2442        }
2443    }, {
2444        key: 'off',
2445        value: function off(event, listener) {
2446            this._emitter.removeListener(event, listener);
2447        }
2448    }, {
2449        key: 'attachMediaElement',
2450        value: function attachMediaElement(mediaElement) {
2451            if (this._mediaSource) {
2452                throw new _exception.IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');
2453            }
2454            var ms = this._mediaSource = new window.MediaSource();
2455            ms.addEventListener('sourceopen', this.e.onSourceOpen);
2456            ms.addEventListener('sourceended', this.e.onSourceEnded);
2457            ms.addEventListener('sourceclose', this.e.onSourceClose);
2458
2459            this._mediaElement = mediaElement;
2460            this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);
2461            mediaElement.src = this._mediaSourceObjectURL;
2462        }
2463    }, {
2464        key: 'detachMediaElement',
2465        value: function detachMediaElement() {
2466            if (this._mediaSource) {
2467                var ms = this._mediaSource;
2468                for (var type in this._sourceBuffers) {
2469                    // pending segments should be discard
2470                    var ps = this._pendingSegments[type];
2471                    ps.splice(0, ps.length);
2472                    this._pendingSegments[type] = null;
2473                    this._pendingRemoveRanges[type] = null;
2474                    this._lastInitSegments[type] = null;
2475
2476                    // remove all sourcebuffers
2477                    var sb = this._sourceBuffers[type];
2478                    if (sb) {
2479                        if (ms.readyState !== 'closed') {
2480                            // ms edge can throw an error: Unexpected call to method or property access
2481                            try {
2482                                ms.removeSourceBuffer(sb);
2483                            } catch (error) {
2484                                _logger2.default.e(this.TAG, error.message);
2485                            }
2486                            sb.removeEventListener('error', this.e.onSourceBufferError);
2487                            sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);
2488                        }
2489                        this._mimeTypes[type] = null;
2490                        this._sourceBuffers[type] = null;
2491                    }
2492                }
2493                if (ms.readyState === 'open') {
2494                    try {
2495                        ms.endOfStream();
2496                    } catch (error) {
2497                        _logger2.default.e(this.TAG, error.message);
2498                    }
2499                }
2500                ms.removeEventListener('sourceopen', this.e.onSourceOpen);
2501                ms.removeEventListener('sourceended', this.e.onSourceEnded);
2502                ms.removeEventListener('sourceclose', this.e.onSourceClose);
2503                this._pendingSourceBufferInit = [];
2504                this._isBufferFull = false;
2505                this._idrList.clear();
2506                this._mediaSource = null;
2507            }
2508
2509            if (this._mediaElement) {
2510                this._mediaElement.src = '';
2511                this._mediaElement.removeAttribute('src');
2512                this._mediaElement = null;
2513            }
2514            if (this._mediaSourceObjectURL) {
2515                window.URL.revokeObjectURL(this._mediaSourceObjectURL);
2516                this._mediaSourceObjectURL = null;
2517            }
2518        }
2519    }, {
2520        key: 'appendInitSegment',
2521        value: function appendInitSegment(initSegment, deferred) {
2522            if (!this._mediaSource || this._mediaSource.readyState !== 'open') {
2523                // sourcebuffer creation requires mediaSource.readyState === 'open'
2524                // so we defer the sourcebuffer creation, until sourceopen event triggered
2525                this._pendingSourceBufferInit.push(initSegment);
2526                // make sure that this InitSegment is in the front of pending segments queue
2527                this._pendingSegments[initSegment.type].push(initSegment);
2528                return;
2529            }
2530
2531            var is = initSegment;
2532            var mimeType = '' + is.container;
2533            if (is.codec && is.codec.length > 0) {
2534                mimeType += ';codecs=' + is.codec;
2535            }
2536
2537            var firstInitSegment = false;
2538
2539            _logger2.default.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);
2540            this._lastInitSegments[is.type] = is;
2541
2542            if (mimeType !== this._mimeTypes[is.type]) {
2543                if (!this._mimeTypes[is.type]) {
2544                    // empty, first chance create sourcebuffer
2545                    firstInitSegment = true;
2546                    try {
2547                        var sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);
2548                        sb.addEventListener('error', this.e.onSourceBufferError);
2549                        sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);
2550                    } catch (error) {
2551                        _logger2.default.e(this.TAG, error.message);
2552                        this._emitter.emit(_mseEvents2.default.ERROR, { code: error.code, msg: error.message });
2553                        return;
2554                    }
2555                } else {
2556                    _logger2.default.v(this.TAG, 'Notice: ' + is.type + ' mimeType changed, origin: ' + this._mimeTypes[is.type] + ', target: ' + mimeType);
2557                }
2558                this._mimeTypes[is.type] = mimeType;
2559            }
2560
2561            if (!deferred) {
2562                // deferred means this InitSegment has been pushed to pendingSegments queue
2563                this._pendingSegments[is.type].push(is);
2564            }
2565            if (!firstInitSegment) {
2566                // append immediately only if init segment in subsequence
2567                if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {
2568                    this._doAppendSegments();
2569                }
2570            }
2571            if (_browser2.default.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {
2572                // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN
2573                // Manually correct MediaSource.duration to make progress bar seekable, and report right duration
2574                this._requireSetMediaDuration = true;
2575                this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds
2576                this._updateMediaSourceDuration();
2577            }
2578        }
2579    }, {
2580        key: 'appendMediaSegment',
2581        value: function appendMediaSegment(mediaSegment) {
2582            var ms = mediaSegment;
2583            this._pendingSegments[ms.type].push(ms);
2584
2585            if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {
2586                this._doCleanupSourceBuffer();
2587            }
2588
2589            var sb = this._sourceBuffers[ms.type];
2590            if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {
2591                this._doAppendSegments();
2592            }
2593        }
2594    }, {
2595        key: 'seek',
2596        value: function seek(seconds) {
2597            // remove all appended buffers
2598            for (var type in this._sourceBuffers) {
2599                if (!this._sourceBuffers[type]) {
2600                    continue;
2601                }
2602
2603                // abort current buffer append algorithm
2604                var sb = this._sourceBuffers[type];
2605                if (this._mediaSource.readyState === 'open') {
2606                    try {
2607                        // If range removal algorithm is running, InvalidStateError will be throwed
2608                        // Ignore it.
2609                        sb.abort();
2610                    } catch (error) {
2611                        _logger2.default.e(this.TAG, error.message);
2612                    }
2613                }
2614
2615                // IDRList should be clear
2616                this._idrList.clear();
2617
2618                // pending segments should be discard
2619                var ps = this._pendingSegments[type];
2620                ps.splice(0, ps.length);
2621
2622                if (this._mediaSource.readyState === 'closed') {
2623                    // Parent MediaSource object has been detached from HTMLMediaElement
2624                    continue;
2625                }
2626
2627                // record ranges to be remove from SourceBuffer
2628                for (var i = 0; i < sb.buffered.length; i++) {
2629                    var start = sb.buffered.start(i);
2630                    var end = sb.buffered.end(i);
2631                    this._pendingRemoveRanges[type].push({ start: start, end: end });
2632                }
2633
2634                // if sb is not updating, let's remove ranges now!
2635                if (!sb.updating) {
2636                    this._doRemoveRanges();
2637                }
2638
2639                // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call
2640                // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.
2641                // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230
2642                if (_browser2.default.safari) {
2643                    var lastInitSegment = this._lastInitSegments[type];
2644                    if (lastInitSegment) {
2645                        this._pendingSegments[type].push(lastInitSegment);
2646                        if (!sb.updating) {
2647                            this._doAppendSegments();
2648                        }
2649                    }
2650                }
2651            }
2652        }
2653    }, {
2654        key: 'endOfStream',
2655        value: function endOfStream() {
2656            var ms = this._mediaSource;
2657            var sb = this._sourceBuffers;
2658            if (!ms || ms.readyState !== 'open') {
2659                if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {
2660                    // If MediaSource hasn't turned into open state, and there're pending segments
2661                    // Mark pending endOfStream, defer call until all pending segments appended complete
2662                    this._hasPendingEos = true;
2663                }
2664                return;
2665            }
2666            if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {
2667                // If any sourcebuffer is updating, defer endOfStream operation
2668                // See _onSourceBufferUpdateEnd()
2669                this._hasPendingEos = true;
2670            } else {
2671                this._hasPendingEos = false;
2672                // Notify media data loading complete
2673                // This is helpful for correcting total duration to match last media segment
2674                // Otherwise MediaElement's ended event may not be triggered
2675                ms.endOfStream();
2676            }
2677        }
2678    }, {
2679        key: 'getNearestKeyframe',
2680        value: function getNearestKeyframe(dts) {
2681            return this._idrList.getLastSyncPointBeforeDts(dts);
2682        }
2683    }, {
2684        key: '_needCleanupSourceBuffer',
2685        value: function _needCleanupSourceBuffer() {
2686            if (!this._config.autoCleanupSourceBuffer) {
2687                return false;
2688            }
2689
2690            var currentTime = this._mediaElement.currentTime;
2691
2692            for (var type in this._sourceBuffers) {
2693                var sb = this._sourceBuffers[type];
2694                if (sb) {
2695                    var buffered = sb.buffered;
2696                    if (buffered.length >= 1) {
2697                        if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {
2698                            return true;
2699                        }
2700                    }
2701                }
2702            }
2703
2704            return false;
2705        }
2706    }, {
2707        key: '_doCleanupSourceBuffer',
2708        value: function _doCleanupSourceBuffer() {
2709            var currentTime = this._mediaElement.currentTime;
2710
2711            for (var type in this._sourceBuffers) {
2712                var sb = this._sourceBuffers[type];
2713                if (sb) {
2714                    var buffered = sb.buffered;
2715                    var doRemove = false;
2716
2717                    for (var i = 0; i < buffered.length; i++) {
2718                        var start = buffered.start(i);
2719                        var end = buffered.end(i);
2720
2721                        if (start <= currentTime && currentTime < end + 3) {
2722                            // padding 3 seconds
2723                            if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {
2724                                doRemove = true;
2725                                var removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;
2726                                this._pendingRemoveRanges[type].push({ start: start, end: removeEnd });
2727                            }
2728                        } else if (end < currentTime) {
2729                            doRemove = true;
2730                            this._pendingRemoveRanges[type].push({ start: start, end: end });
2731                        }
2732                    }
2733
2734                    if (doRemove && !sb.updating) {
2735                        this._doRemoveRanges();
2736                    }
2737                }
2738            }
2739        }
2740    }, {
2741        key: '_updateMediaSourceDuration',
2742        value: function _updateMediaSourceDuration() {
2743            var sb = this._sourceBuffers;
2744            if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {
2745                return;
2746            }
2747            if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {
2748                return;
2749            }
2750
2751            var current = this._mediaSource.duration;
2752            var target = this._pendingMediaDuration;
2753
2754            if (target > 0 && (isNaN(current) || target > current)) {
2755                _logger2.default.v(this.TAG, 'Update MediaSource duration from ' + current + ' to ' + target);
2756                this._mediaSource.duration = target;
2757            }
2758
2759            this._requireSetMediaDuration = false;
2760            this._pendingMediaDuration = 0;
2761        }
2762    }, {
2763        key: '_doRemoveRanges',
2764        value: function _doRemoveRanges() {
2765            for (var type in this._pendingRemoveRanges) {
2766                if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {
2767                    continue;
2768                }
2769                var sb = this._sourceBuffers[type];
2770                var ranges = this._pendingRemoveRanges[type];
2771                while (ranges.length && !sb.updating) {
2772                    var range = ranges.shift();
2773                    sb.remove(range.start, range.end);
2774                }
2775            }
2776        }
2777    }, {
2778        key: '_doAppendSegments',
2779        value: function _doAppendSegments() {
2780            var pendingSegments = this._pendingSegments;
2781
2782            for (var type in pendingSegments) {
2783                if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {
2784                    continue;
2785                }
2786
2787                if (pendingSegments[type].length > 0) {
2788                    var segment = pendingSegments[type].shift();
2789
2790                    if (segment.timestampOffset) {
2791                        // For MPEG audio stream in MSE, if unbuffered-seeking occurred
2792                        // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.
2793                        var currentOffset = this._sourceBuffers[t
vendor: 4,171 bytes, lines 2793-2878
2793ype].timestampOffset;
2794                        var targetOffset = segment.timestampOffset / 1000; // in seconds
2795
2796                        var delta = Math.abs(currentOffset - targetOffset);
2797                        if (delta > 0.1) {
2798                            // If time delta > 100ms
2799                            _logger2.default.v(this.TAG, 'Update MPEG audio timestampOffset from ' + currentOffset + ' to ' + targetOffset);
2800                            this._sourceBuffers[type].timestampOffset = targetOffset;
2801                        }
2802                        delete segment.timestampOffset;
2803                    }
2804
2805                    if (!segment.data || segment.data.byteLength === 0) {
2806                        // Ignore empty buffer
2807                        continue;
2808                    }
2809
2810                    try {
2811                        this._sourceBuffers[type].appendBuffer(segment.data);
2812                        this._isBufferFull = false;
2813                        if (type === 'video' && segment.hasOwnProperty('info')) {
2814                            this._idrList.appendArray(segment.info.syncPoints);
2815                        }
2816                    } catch (error) {
2817                        this._pendingSegments[type].unshift(segment);
2818                        if (error.code === 22) {
2819                            // QuotaExceededError
2820                            /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full
2821                             * Currently we can only do lazy-load to avoid SourceBuffer become scattered.
2822                             * SourceBuffer eviction policy may be changed in future version of FireFox.
2823                             *
2824                             * Related issues:
2825                             * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885
2826                             * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023
2827                             */
2828
2829                            // report buffer full, abort network IO
2830                            if (!this._isBufferFull) {
2831                                this._emitter.emit(_mseEvents2.default.BUFFER_FULL);
2832                            }
2833                            this._isBufferFull = true;
2834                        } else {
2835                            _logger2.default.e(this.TAG, error.message);
2836                            this._emitter.emit(_mseEvents2.default.ERROR, { code: error.code, msg: error.message });
2837                        }
2838                    }
2839                }
2840            }
2841        }
2842    }, {
2843        key: '_onSourceOpen',
2844        value: function _onSourceOpen() {
2845            _logger2.default.v(this.TAG, 'MediaSource onSourceOpen');
2846            this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);
2847            // deferred sourcebuffer creation / initialization
2848            if (this._pendingSourceBufferInit.length > 0) {
2849                var pendings = this._pendingSourceBufferInit;
2850                while (pendings.length) {
2851                    var segment = pendings.shift();
2852                    this.appendInitSegment(segment, true);
2853                }
2854            }
2855            // there may be some pending media segments, append them
2856            if (this._hasPendingSegments()) {
2857                this._doAppendSegments();
2858            }
2859            this._emitter.emit(_mseEvents2.default.SOURCE_OPEN);
2860        }
2861    }, {
2862        key: '_onSourceEnded',
2863        value: function _onSourceEnded() {
2864            // fired on endOfStream
2865            _logger2.default.v(this.TAG, 'MediaSource onSourceEnded');
2866        }
2867    }, {
2868        key: '_onSourceClose',
2869        value: function _onSourceClose() {
2870            // fired on detaching from media element
2871            _logger2.default.v(this.TAG, 'MediaSource onSourceClose');
2872            if (this._mediaSource && this.e != null) {
2873                this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);
2874                this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);
2875                this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);
2876            }
2877        }
2878    }, {
2879        key: '_hasPendingSegments',
2880        value: function _hasPendingSegments() {
2881            var ps = this._pendingSegments;
2882            return ps.video.length > 0 || ps.audio.length > 0;
2883        }
2884    }, {
2885        key: '_hasPendingRemoveRanges',
2886        value: function _hasPendingRemoveRanges() {
2887            var prr = this._pendingRemoveRanges;
2888            return prr.video.length > 0 || prr.audio.length > 0;
2889        }
2890    }, {
2891        key: '_onSourceBufferUpdateEnd',
2892        value: function _onSourceBufferUpdateEnd() {
2893            if (this._requireSetMediaDuration) {
2894                this._updateMediaSourceDuration();
2895            } else if (this._hasPendingRemoveRanges()) {
2896                this._doRemoveRanges();
2897            } else if (this._hasPendingSegments()) {
2898                this._doAppendSegments();
2899            } else if (this._hasPendingEos) {
2900                this.endOfStream();
2901            }
2902            this._emitter.emit(_mseEvents2.default.UPDATE_END);
2903        }
2904    }, {
2905        key: '_onSourceBufferError',
2906        value: function _onSourceBufferError(e) {
2907            _logger2.default.e(this.TAG, 'SourceBuffer Error: ' + e);
2908            // this error might not always be fatal, just ignore it
2909        }
2910    }]);
2911
2912    return MSEController;
2913}();
2914
2915exports.default = MSEController;
2916
2917},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./media-segment-info.js":8,"./mse-events.js":10,"events":2}],10:[function(_dereq_,module,exports){
2918'use strict';
2919
2920Object.defineProperty(exports, "__esModule", {
2921  value: true
2922});
2923/*
2924 * Copyright (C) 2016 Bilibili. All Rights Reserved.
2925 *
2926 * @author zheng qian <[email protected]>
2927 *
2928 * Licensed under the Apache License, Version 2.0 (the "License");
2929 * you may not use this file except in compliance with the License.
2930 * You may obtain a copy of the License at
2931 *
2932 *     http://www.apache.org/licenses/LICENSE-2.0
2933 *
2934 * Unless required by applicable law or agreed to in writing, software
2935 * distributed under the License is distributed on an "AS IS" BASIS,
2936 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2937 * See the License for the specific language governing permissions and
2938 * limitations under the License.
2939 */
2940
2941var MSEEvents = {
2942  ERROR: 'error',
2943  SOURCE_OPEN: 'source_open',
2944  UPDATE_END: 'update_end',
2945  BUFFER_FULL: 'buffer_full'
2946};
2947
2948exports.default = MSEEvents;
2949
2950},{}],11:[function(_dereq_,module,exports){
2951'use strict';
2952
2953Object.defineProperty(exports, "__esModule", {
2954    value: true
2955});
2956
2957var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
2958                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
2959                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2960                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
2961                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2962                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
2963                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
2963not use this file except in compliance with the License.
2964                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
2965                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2966                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
2967                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
2968                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
2969                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
2970                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2971                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
2972                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
2973                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
2974
2975var _events = _dereq_('events');
2976
2977var _events2 = _interopRequireDefault(_events);
2978
2979var _logger = _dereq_('../utils/logger.js');
2980
2981var _logger2 = _interopRequireDefault(_logger);
2982
2983var _loggingControl = _dereq_('../utils/logging-control.js');
2984
2985var _loggingControl2 = _interopRequireDefault(_loggingControl);
2986
2987var _transmuxingController = _dereq_('./transmuxing-controller.js');
2988
2989var _transmuxingController2 = _interopRequireDefault(_transmuxingController);
2990
2991var _transmuxingEvents = _dereq_('./transmuxing-events.js');
2992
2993var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
2994
2995var _transmuxingWorker = _dereq_('./transmuxing-worker.js');
2996
2997var _transmuxingWorker2 = _interopRequireDefault(_transmuxingWorker);
2998
2999var _mediaInfo = _dereq_('./media-info.js');
3000
3001var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
3002
3003function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3004
3005function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3006
3007var Transmuxer = function () {
3008    function Transmuxer(mediaDataSource, config) {
3009        _classCallCheck(this, Transmuxer);
3010
3011        this.TAG = 'Transmuxer';
3012        this._emitter = new _events2.default();
3013
3014        if (config.enableWorker && typeof Worker !== 'undefined') {
3015            try {
3016                var work = _dereq_('webworkify');
3017                this._worker = work(_transmuxingWorker2.default);
3018                this._workerDestroying = false;
3019                this._worker.addEventListener('message', this._onWorkerMessage.bind(this));
3020                this._worker.postMessage({ cmd: 'init', param: [mediaDataSource, config] });
3021                this.e = {
3022                    onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)
3023                };
3024                _loggingControl2.default.registerListener(this.e.onLoggingConfigChanged);
3025                this._worker.postMessage({ cmd: 'logging_config', param: _loggingControl2.default.getConfig() });
3026            } catch (error) {
3027                _logger2.default.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');
3028                this._worker = null;
3029                this._controller = new _transmuxingController2.default(mediaDataSource, config);
3030            }
3031        } else {
3032            this._controller = new _transmuxingController2.default(mediaDataSource, config);
3033        }
3034
3035        if (this._controller) {
3036            var ctl = this._controller;
3037            ctl.on(_transmuxingEvents2.default.IO_ERROR, this._onIOError.bind(this));
3038            ctl.on(_transmuxingEvents2.default.DEMUX_ERROR, this._onDemuxError.bind(this));
3039            ctl.on(_transmuxingEvents2.default.INIT_SEGMENT, this._onInitSegment.bind(this));
3040            ctl.on(_transmuxingEvents2.default.MEDIA_SEGMENT, this._onMediaSegment.bind(this));
3041            ctl.on(_transmuxingEvents2.default.LOADING_COMPLETE, this._onLoadingComplete.bind(this));
3042            ctl.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));
3043            ctl.on(_transmuxingEvents2.default.MEDIA_INFO, this._onMediaInfo.bind(this));
3044            ctl.on(_transmuxingEvents2.default.METADATA_ARRIVED, this._onMetaDataArrived.bind(this));
3045            ctl.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, this._onScriptDataArrived.bind(this));
3046            ctl.on(_transmuxingEvents2.default.STATISTICS_INFO, this._onStatisticsInfo.bind(this));
3047            ctl.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));
3048        }
3049    }
3050
3051    _createClass(Transmuxer, [{
3052        key: 'destroy',
3053        value: function destroy() {
3054            if (this._worker) {
3055                if (!this._workerDestroying) {
3056                    this._workerDestroying = true;
3057                    this._worker.postMessage({ cmd: 'destroy' });
3058                    _loggingControl2.default.removeListener(this.e.onLoggingConfigChanged);
3059                    this.e = null;
3060                }
3061            } else {
3062                this._controller.destroy();
3063                this._controller = null;
3064            }
3065            this._emitter.removeAllListeners();
3066            this._emitter = null;
3067        }
3068    }, {
3069        key: 'on',
3070        value: function on(event, listener) {
3071            this._emitter.addListener(event, listener);
3072        }
3073    }, {
3074        key: 'off',
3075        value: function off(event, listener) {
3076            this._emitter.removeListener(event, listener);
3077        }
3078    }, {
3079        key: 'hasWorker',
3080        value: function hasWorker() {
3081            return this._worker != null;
3082        }
3083    }, {
3084        key: 'open',
3085        value: function open() {
3086            if (this._worker) {
3087                this._worker.postMessage({ cmd: 'start' });
3088            } else {
3089                this._controller.start();
3090            }
3091        }
3092    }, {
3093        key: 'close',
3094        value: function close() {
3095            if (this._worker) {
3096                this._worker.postMessage({ cmd: 'stop' });
3097            } else {
3098                this._controller.stop();
3099            }
3100        }
3101    }, {
3102        key: 'seek',
3103        value: function seek(milliseconds) {
3104            if (this._worker) {
3105                this._worker.postMessage({ cmd: 'seek', param: milliseconds });
3106            } else {
3107                this._controller.seek(milliseconds);
3108            }
3109        }
3110    }, {
3111        key: 'pause',
3112        value: function pause() {
3113            if (this._worker) {
3114                this._worker.postMessage({ cmd: 'pause' });
3115            } else {
3116                this._controller.pause();
3117            }
3118        }
3119    }, {
3120        key: 'resume',
3121        value: function resume() {
3122            if (this._worker) {
3123                this._worker.postMessage({ cmd: 'resume' });
3124            } else {
3125                this._controller.resume();
3126            }
3127        }
3128    }, {
3129        key: '_onInitSegment',
3130        value: function _onInitSegment(type, initSegment) {
3131            var _this = this;
3132
3133            // do async invoke
3134            Promise.resolve().then(function () {
3135                _this._emitter.emit(_transmuxingEvents2.default.INIT_SEGMENT, type, initSegment);
3136            });
3137        }
3138    }, {
3139        key: '_onMediaSegment',
3140        value: function _onMediaSegment(type, mediaSegment) {
3141            var _this2 = this;
3142
3143            Promise.resolve().then(function () {
3144                _this2._emitter.emit(_transmuxingEvents2.default.MEDIA_SEGMENT, type, mediaSegment);
3145            });
3146        }
3147    }, {
3148        key: '_onLoadingComplete',
3149        value: function _onLoadingComplete() {
3150            var _this3 = this;
3151
3152            Promise.resolve().then(function () {
3153                _this3._emitter.emit(_transmuxingEvents2.default.LOADING_COMPLETE);
3154            });
3155        }
3156    }, {
3157        key: '_onRecoveredEarlyEof',
3158        value: function _onRecoveredEarlyEof() {
3159            var _this4 = this;
3160
3161            Promise.resolve().then(function () {
3162                _this4._emitter.emit(_transmuxingEvents2.default.RECOVERED_EARLY_EOF);
3163            });
3164        }
3165    }, {
3166        key: '_onMediaInfo',
3167        value: function _onMediaInfo(mediaInfo) {
3168            var _this5 = this;
3169
3170            Promise.resolve().then(function () {
3171                _this5._emitter.emit(_transmuxingEvents2.default.MEDIA_INFO, mediaInfo);
3172            });
3173        }
3174    }, {
3175        key: '_onMetaDataArrived',
3176        value: function _onMetaDataArrived(metadata) {
3177            var _this6 = this;
3178
3179            Promise.resolve().then(function () {
3180                _this6._emitter.emit(_transmuxingEvents2.default.METADATA_ARRIVED, metadata);
3181            });
3182        }
3183    }, {
3184        key: '_onScriptDataArrived',
3185        value: function _onScriptDataArrived(data) {
3186            var _this7 = this;
3187
3188            Promise.resolve().then(function () {
3189                _this7._emitter.emit(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, data);
3190            });
3191        }
3192    }, {
3193        key: '_onStatisticsInfo',
3194        value: function _onStatisticsInfo(statisticsInfo) {
3195            var _this8 = this;
3196
3197            Promise.resolve().then(function () {
3198                _this8._emitter.emit(_transmuxingEvents2.default.STATISTICS_INFO, statisticsInfo);
3199            });
3200        }
3201    }, {
3202        key: '_onIOError',
3203        value: function _onIOError(type, info) {
3204            var _this9 = this;
3205
3206            Promise.resolve().then(function () {
3207                _this9._emitter.emit(_transmuxingEvents2.default.IO_ERROR, type, info);
3208            });
3209        }
3210    }, {
3211        key: '_onDemuxError',
3212        value: function _onDemuxError(type, info) {
3213            var _this10 = this;
3214
3215            Promise.resolve().then(function () {
3216                _this10._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, type, info);
3217            });
3218        }
3219    }, {
3220        key: '_onRecommendSeekpoint',
3221        value: function _onRecommendSeekpoint(milliseconds) {
3222            var _this11 = this;
3223
3224            Promise.resolve().then(function () {
3225                _this11._emitter.emit(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, milliseconds);
3226            });
3227        }
3228    }, {
3229        key: '_onLoggingConfigChanged',
3230        value: function _onLoggingConfigChanged(config) {
3231            if (this._worker) {
3232                this._worker.postMessage({ cmd: 'logging_config', param: config });
3233            }
3234        }
3235    }, {
3236        key: '_onWorkerMessage',
3237        value: function _onWorkerMessage(e) {
3238            var message = e.data;
3239            var data = message.data;
3240
3241            if (message.msg === 'destroyed' || this._workerDestroying) {
3242                this._workerDestroying = false;
3243                this._worker.terminate();
3244                this._worker = null;
3245                return;
3246            }
3247
3248            switch (message.msg) {
3249                case _transmuxingEvents2.default.INIT_SEGMENT:
3250                case _transmuxingEvents2.default.MEDIA_SEGMENT:
3251                    this._emitter.emit(message.msg, data.type, data.data);
3252                    break;
3253                case _transmuxingEvents2.default.LOADING_COMPLETE:
3254                case _transmuxingEvents2.default.RECOVERED_EARLY_EOF:
3255                    this._emitter.emit(message.msg);
3256                    break;
3257                case _transmuxingEvents2.default.MEDIA_INFO:
3258                    Object.setPrototypeOf(data, _mediaInfo2.default.prototype);
3259                    this._emitter.emit(message.msg, data);
3260                    break;
3261                case _transmuxingEvents2.default.METADATA_ARRIVED:
3262                case _transmuxingEvents2.default.SCRIPTDATA_ARRIVED:
3263                case _transmuxingEvents2.default.STATISTICS_INFO:
3264                    this._emitter.emit(message.msg, data);
3265                    break;
3266                case _transmuxingEvents2.default.IO_ERROR:
3267                case _transmuxingEvents2.default.DEMUX_ERROR:
3268                    this._emitter.emit(message.msg, data.type, data.info);
3269                    break;
3270                case _transmuxingEvents2.default.RECOMMEND_SEEKPOINT:
3271                    this._emitter.emit(message.msg, data);
3272                    break;
3273                case 'logcat_callback':
3274                    _logger2.default.emitter.emit('log', data.type, data.logcat);
3275                    break;
3276                default:
3277                    break;
3278            }
3279        }
3280    }]);
3281
3282    return Transmuxer;
3283}();
3284
3285exports.default = Transmuxer;
3286
3287},{"../utils/logger.js":41,"../utils/logging-control.js":42,"./media-info.js":7,"./transmuxing-controller.js":12,"./transmuxing-events.js":13,"./transmuxing-worker.js":14,"events":2,"webworkify":4}],12:[function(_dereq_,module,exports){
3288'use strict';
3289
3290Object.defineProperty(exports, "__esModule", {
3291    value: true
3292});
3293
3294var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
3295                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
3296                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
3297                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
3298                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
3299                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
3300                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
3300not use this file except in compliance with the License.
3301                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
3302                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
3303                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
3304                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
3305                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
3306                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
3307                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3308                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
3309                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
3310                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
3311
3312var _events = _dereq_('events');
3313
3314var _events2 = _interopRequireDefault(_events);
3315
3316var _logger = _dereq_('../utils/logger.js');
3317
3318var _logger2 = _interopRequireDefault(_logger);
3319
3320var _browser = _dereq_('../utils/browser.js');
3321
3322var _browser2 = _interopRequireDefault(_browser);
3323
3324var _mediaInfo = _dereq_('./media-info.js');
3325
3326var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
3327
3328var _flvDemuxer = _dereq_('../demux/flv-demuxer.js');
3329
3330var _flvDemuxer2 = _interopRequireDefault(_flvDemuxer);
3331
3332var _mp4Remuxer = _dereq_('../remux/mp4-remuxer.js');
3333
3334var _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);
3335
3336var _demuxErrors = _dereq_('../demux/demux-errors.js');
3337
3338var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
3339
3340var _ioController = _dereq_('../io/io-controller.js');
3341
3342var _ioController2 = _interopRequireDefault(_ioController);
3343
3344var _transmuxingEvents = _dereq_('./transmuxing-events.js');
3345
3346var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
3347
3348var _loader = _dereq_('../io/loader.js');
3349
3350function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3351
3352function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3353
3354// Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support
3355var TransmuxingController = function () {
3356    function TransmuxingController(mediaDataSource, config) {
3357        _classCallCheck(this, TransmuxingController);
3358
3359        this.TAG = 'TransmuxingController';
3360        this._emitter = new _events2.default();
3361
3362        this._config = config;
3363
3364        // treat single part media as multipart media, which has only one segment
3365        if (!mediaDataSource.segments) {
3366            mediaDataSource.segments = [{
3367                duration: mediaDataSource.duration,
3368                filesize: mediaDataSource.filesize,
3369                url: mediaDataSource.url
3370            }];
3371        }
3372
3373        // fill in default IO params if not exists
3374        if (typeof mediaDataSource.cors !== 'boolean') {
3375            mediaDataSource.cors = true;
3376        }
3377        if (typeof mediaDataSource.withCredentials !== 'boolean') {
3378            mediaDataSource.withCredentials = false;
3379        }
3380
3381        this._mediaDataSource = mediaDataSource;
3382        this._currentSegmentIndex = 0;
3383        var totalDuration = 0;
3384
3385        this._mediaDataSource.segments.forEach(function (segment) {
3386            // timestampBase for each segment, and calculate total duration
3387            segment.timestampBase = totalDuration;
3388            totalDuration += segment.duration;
3389            // params needed by IOController
3390            segment.cors = mediaDataSource.cors;
3391            segment.withCredentials = mediaDataSource.withCredentials;
3392            // referrer policy control, if exist
3393            if (config.referrerPolicy) {
3394                segment.referrerPolicy = config.referrerPolicy;
3395            }
3396        });
3397
3398        if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {
3399            this._mediaDataSource.duration = totalDuration;
3400        }
3401
3402        this._mediaInfo = null;
3403        this._demuxer = null;
3404        this._remuxer = null;
3405        this._ioctl = null;
3406
3407        this._pendingSeekTime = null;
3408        this._pendingResolveSeekPoint = null;
3409
3410        this._statisticsReporter = null;
3411    }
3412
3413    _createClass(TransmuxingController, [{
3414        key: 'destroy',
3415        value: function destroy() {
3416            this._mediaInfo = null;
3417            this._mediaDataSource = null;
3418
3419            if (this._statisticsReporter) {
3420                this._disableStatisticsReporter();
3421            }
3422            if (this._ioctl) {
3423                this._ioctl.destroy();
3424                this._ioctl = null;
3425            }
3426            if (this._demuxer) {
3427                this._demuxer.destroy();
3428                this._demuxer = null;
3429            }
3430            if (this._remuxer) {
3431                this._remuxer.destroy();
3432                this._remuxer = null;
3433            }
3434
3435            this._emitter.removeAllListeners();
3436            this._emitter = null;
3437        }
3438    }, {
3439        key: 'on',
3440        value: function on(event, listener) {
3441            this._emitter.addListener(event, listener);
3442        }
3443    }, {
3444        key: 'off',
3445        value: function off(event, listener) {
3446            this._emitter.removeListener(event, listener);
3447        }
3448    }, {
3449        key: 'start',
3450        value: function start() {
3451            this._loadSegment(0);
3452            this._enableStatisticsReporter();
3453        }
3454    }, {
3455        key: '_loadSegment',
3456        value: function _loadSegment(segmentIndex, optionalFrom) {
3457            this._currentSegmentIndex = segmentIndex;
3458            var dataSource = this._mediaDataSource.segments[segmentIndex];
3459
3460            var ioctl = this._ioctl = new _ioController2.default(dataSource, this._config, segmentIndex);
3461            ioctl.onError = this._onIOException.bind(this);
3462            ioctl.onSeeked = this._onIOSeeked.bind(this);
3463            ioctl.onComplete = this._onIOComplete.bind(this);
3464            ioctl.onRedirect = this._onIORedirect.bind(this);
3465            ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);
3466
3467            if (optionalFrom) {
3468                this._demuxer.bindDataSource(this._ioctl);
3469            } else {
3470                ioctl.onDataArrival = this._onInitChunkArrival.bind(this);
3471            }
3472
3473            ioctl.open(optionalFrom);
3474        }
3475    }, {
3476        key: 'stop',
3477        value: function stop() {
3478            this._internalAbort();
3479            this._disableStatisticsReporter();
3480        }
3481    }, {
3482        key: '_internalAbort',
3483        value: function _internalAbort() {
3484            if (this._ioctl) {
3485                this._ioctl.destroy();
3486                this._ioctl = null;
3487            }
3488        }
3489    }, {
3490        key: 'pause',
3491        value: function pause() {
3492            // take a rest
3493            if (this._ioctl && this._ioctl.isWorking()) {
3494                this._ioctl.pause();
3495                this._disableStatisticsReporter();
3496            }
3497        }
3498    }, {
3499        key: 'resume',
3500        value: function resume() {
3501            if (this._ioctl && this._ioctl.isPaused()) {
3502                this._ioctl.resume();
3503                this._enableStatisticsReporter();
3504            }
3505        }
3506    }, {
vendor: 5,808 bytes, lines 3507-3631
3507        key: 'seek',
3508        value: function seek(milliseconds) {
3509            if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {
3510                return;
3511            }
3512
3513            var targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);
3514
3515            if (targetSegmentIndex === this._currentSegmentIndex) {
3516                // intra-segment seeking
3517                var segmentInfo = this._mediaInfo.segments[targetSegmentIndex];
3518
3519                if (segmentInfo == undefined) {
3520                    // current segment loading started, but mediainfo hasn't received yet
3521                    // wait for the metadata loaded, then seek to expected position
3522                    this._pendingSeekTime = milliseconds;
3523                } else {
3524                    var keyframe = segmentInfo.getNearestKeyframe(milliseconds);
3525                    this._remuxer.seek(keyframe.milliseconds);
3526                    this._ioctl.seek(keyframe.fileposition);
3527                    // Will be resolved in _onRemuxerMediaSegmentArrival()
3528                    this._pendingResolveSeekPoint = keyframe.milliseconds;
3529                }
3530            } else {
3531                // cross-segment seeking
3532                var targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];
3533
3534                if (targetSegmentInfo == undefined) {
3535                    // target segment hasn't been loaded. We need metadata then seek to expected time
3536                    this._pendingSeekTime = milliseconds;
3537                    this._internalAbort();
3538                    this._remuxer.seek();
3539                    this._remuxer.insertDiscontinuity();
3540                    this._loadSegment(targetSegmentIndex);
3541                    // Here we wait for the metadata loaded, then seek to expected position
3542                } else {
3543                    // We have target segment's metadata, direct seek to target position
3544                    var _keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);
3545                    this._internalAbort();
3546                    this._remuxer.seek(milliseconds);
3547                    this._remuxer.insertDiscontinuity();
3548                    this._demuxer.resetMediaInfo();
3549                    this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;
3550                    this._loadSegment(targetSegmentIndex, _keyframe.fileposition);
3551                    this._pendingResolveSeekPoint = _keyframe.milliseconds;
3552                    this._reportSegmentMediaInfo(targetSegmentIndex);
3553                }
3554            }
3555
3556            this._enableStatisticsReporter();
3557        }
3558    }, {
3559        key: '_searchSegmentIndexContains',
3560        value: function _searchSegmentIndexContains(milliseconds) {
3561            var segments = this._mediaDataSource.segments;
3562            var idx = segments.length - 1;
3563
3564            for (var i = 0; i < segments.length; i++) {
3565                if (milliseconds < segments[i].timestampBase) {
3566                    idx = i - 1;
3567                    break;
3568                }
3569            }
3570            return idx;
3571        }
3572    }, {
3573        key: '_onInitChunkArrival',
3574        value: function _onInitChunkArrival(data, byteStart) {
3575            var _this = this;
3576
3577            var probeData = null;
3578            var consumed = 0;
3579
3580            if (byteStart > 0) {
3581                // IOController seeked immediately after opened, byteStart > 0 callback may received
3582                this._demuxer.bindDataSource(this._ioctl);
3583                this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;
3584
3585                consumed = this._demuxer.parseChunks(data, byteStart);
3586            } else if ((probeData = _flvDemuxer2.default.probe(data)).match) {
3587                // Always create new FLVDemuxer
3588                this._demuxer = new _flvDemuxer2.default(probeData, this._config);
3589
3590                if (!this._remuxer) {
3591                    this._remuxer = new _mp4Remuxer2.default(this._config);
3592                }
3593
3594                var mds = this._mediaDataSource;
3595                if (mds.duration != undefined && !isNaN(mds.duration)) {
3596                    this._demuxer.overridedDuration = mds.duration;
3597                }
3598                if (typeof mds.hasAudio === 'boolean') {
3599                    this._demuxer.overridedHasAudio = mds.hasAudio;
3600                }
3601                if (typeof mds.hasVideo === 'boolean') {
3602                    this._demuxer.overridedHasVideo = mds.hasVideo;
3603                }
3604
3605                this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;
3606
3607                this._demuxer.onError = this._onDemuxException.bind(this);
3608                this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);
3609                this._demuxer.onMetaDataArrived = this._onMetaDataArrived.bind(this);
3610                this._demuxer.onScriptDataArrived = this._onScriptDataArrived.bind(this);
3611
3612                this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl));
3613
3614                this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);
3615                this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);
3616
3617                consumed = this._demuxer.parseChunks(data, byteStart);
3618            } else {
3619                probeData = null;
3620                _logger2.default.e(this.TAG, 'Non-FLV, Unsupported media type!');
3621                Promise.resolve().then(function () {
3622                    _this._internalAbort();
3623                });
3624                this._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, _demuxErrors2.default.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');
3625
3626                consumed = 0;
3627            }
3628
3629            return consumed;
3630        }
3631    }, {
3632        key: '_onMediaInfo',
3633        value: function _onMediaInfo(mediaInfo) {
3634            var _this2 = this;
3635
3636            if (this._mediaInfo == null) {
3637                // Store first segment's mediainfo as global mediaInfo
3638                this._mediaInfo = Object.assign({}, mediaInfo);
3639                this._mediaInfo.keyframesIndex = null;
3640                this._mediaInfo.segments = [];
3641                this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;
3642                Object.setPrototypeOf(this._mediaInfo, _mediaInfo2.default.prototype);
3643            }
3644
3645            var segmentInfo = Object.assign({}, mediaInfo);
3646            Object.setPrototypeOf(segmentInfo, _mediaInfo2.default.prototype);
3647            this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;
3648
3649            // notify mediaInfo update
3650            this._reportSegmentMediaInfo(this._currentSegmentIndex);
3651
3652            if (this._pendingSeekTime != null) {
3653                Promise.resolve().then(function () {
3654                    var target = _this2._pendingSeekTime;
3655                    _this2._pendingSeekTime = null;
3656                    _this2.seek(target);
3657                });
3658            }
3659        }
3660    }, {
3661        key: '_onMetaDataArrived',
3662        value: function _onMetaDataArrived(metadata) {
3663            this._emitter.emit(_transmuxingEvents2.default.METADATA_ARRIVED, metadata);
3664        }
3665    }, {
3666        key: '_onScriptDataArrived',
3667        value: function _onScriptDataArrived(data) {
3668            this._emitter.emit(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, data);
3669        }
3670    }, {
3671        key: '_onIOSeeked',
3672        value: function _onIOSeeked() {
3673            this._remuxer.insertDiscontinuity();
3674        }
3675    }, {
3676        key: '_onIOComplete',
3677        value: function _onIOComplete(extraData) {
3678            var segmentIndex = extraData;
3679            var nextSegmentIndex = segmentIndex + 1;
3680
3681            if (nextSegmentIndex < this._mediaDataSource.segments.length) {
3682                this._internalAbort();
3683                this._remuxer.flushStashedSamples();
3684                this._loadSegment(nextSegmentIndex);
3685            } else {
3686                this._remuxer.flushStashedSamples();
3687                this._emitter.emit(_transmuxingEvents2.default.LOADING_COMPLETE);
3688                this._disableStatisticsReporter();
3689            }
3690        }
3691    }, {
3692        key: '_onIORedirect',
3693        value: function _onIORedirect(redirectedURL) {
3694            var segmentIndex = this._ioctl.extraData;
3695            this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;
3696        }
3697    }, {
3698        key: '_onIORecoveredEarlyEof',
3699        value: function _onIORecoveredEarlyEof() {
3700            this._emitter.emit(_transmuxingEvents2.default.RECOVERED_EARLY_EOF);
3701        }
3702    }, {
3703        key: '_onIOException',
3704        value: function _onIOException(type, info) {
3705            _logger2.default.e(this.TAG, 'IOException: type = ' + type + ', code = ' + info.code + ', msg = ' + info.msg);
3706            this._emitter.emit(_transmuxingEvents2.default.IO_ERROR, type, info);
3707            this._disableStatisticsReporter();
3708        }
3709    }, {
3710        key: '_onDemuxException',
3711        value: function _onDemuxException(type, info) {
3712            _logger2.default.e(this.TAG, 'DemuxException: type = ' + type + ', info = ' + info);
3713            this._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, type, info);
3714        }
3715    }, {
3716        key: '_onRemuxerInitSegmentArrival',
3717        value: function _onRemuxerInitSegmentArrival(type, initSegment) {
3718            this._emitter.emit(_transmuxingEvents2.default.INIT_SEGMENT, type, initSegment);
3719        }
3720    }, {
3721        key: '_onRemuxerMediaSegmentArrival',
3722        value: function _onRemuxerMediaSegmentArrival(type, mediaSegment) {
3723            if (this._pendingSeekTime != null) {
3724                // Media segments after new-segment cross-seeking should be dropped.
3725                return;
3726            }
3727            this._emitter.emit(_transmuxingEvents2.default.MEDIA_SEGMENT, type, mediaSegment);
3728
3729            // Resolve pending seekPoint
vendor: 10,704 bytes, lines 3730-4049
3730            if (this._pendingResolveSeekPoint != null && type === 'video') {
3731                var syncPoints = mediaSegment.info.syncPoints;
3732                var seekpoint = this._pendingResolveSeekPoint;
3733                this._pendingResolveSeekPoint = null;
3734
3735                // Safari: Pass PTS for recommend_seekpoint
3736                if (_browser2.default.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {
3737                    seekpoint = syncPoints[0].pts;
3738                }
3739                // else: use original DTS (keyframe.milliseconds)
3740
3741                this._emitter.emit(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, seekpoint);
3742            }
3743        }
3744    }, {
3745        key: '_enableStatisticsReporter',
3746        value: function _enableStatisticsReporter() {
3747            if (this._statisticsReporter == null) {
3748                this._statisticsReporter = self.setInterval(this._reportStatisticsInfo.bind(this), this._config.statisticsInfoReportInterval);
3749            }
3750        }
3751    }, {
3752        key: '_disableStatisticsReporter',
3753        value: function _disableStatisticsReporter() {
3754            if (this._statisticsReporter) {
3755                self.clearInterval(this._statisticsReporter);
3756                this._statisticsReporter = null;
3757            }
3758        }
3759    }, {
3760        key: '_reportSegmentMediaInfo',
3761        value: function _reportSegmentMediaInfo(segmentIndex) {
3762            var segmentInfo = this._mediaInfo.segments[segmentIndex];
3763            var exportInfo = Object.assign({}, segmentInfo);
3764
3765            exportInfo.duration = this._mediaInfo.duration;
3766            exportInfo.segmentCount = this._mediaInfo.segmentCount;
3767            delete exportInfo.segments;
3768            delete exportInfo.keyframesIndex;
3769
3770            this._emitter.emit(_transmuxingEvents2.default.MEDIA_INFO, exportInfo);
3771        }
3772    }, {
3773        key: '_reportStatisticsInfo',
3774        value: function _reportStatisticsInfo() {
3775            var info = {};
3776
3777            info.url = this._ioctl.currentURL;
3778            info.hasRedirect = this._ioctl.hasRedirect;
3779            if (info.hasRedirect) {
3780                info.redirectedURL = this._ioctl.currentRedirectedURL;
3781            }
3782
3783            info.speed = this._ioctl.currentSpeed;
3784            info.loaderType = this._ioctl.loaderType;
3785            info.currentSegmentIndex = this._currentSegmentIndex;
3786            info.totalSegmentCount = this._mediaDataSource.segments.length;
3787
3788            this._emitter.emit(_transmuxingEvents2.default.STATISTICS_INFO, info);
3789        }
3790    }]);
3791
3792    return TransmuxingController;
3793}();
3794
3795exports.default = TransmuxingController;
3796
3797},{"../demux/demux-errors.js":16,"../demux/flv-demuxer.js":18,"../io/io-controller.js":23,"../io/loader.js":24,"../remux/mp4-remuxer.js":38,"../utils/browser.js":39,"../utils/logger.js":41,"./media-info.js":7,"./transmuxing-events.js":13,"events":2}],13:[function(_dereq_,module,exports){
3798'use strict';
3799
3800Object.defineProperty(exports, "__esModule", {
3801  value: true
3802});
3803/*
3804 * Copyright (C) 2016 Bilibili. All Rights Reserved.
3805 *
3806 * @author zheng qian <[email protected]>
3807 *
3808 * Licensed under the Apache License, Version 2.0 (the "License");
3809 * you may not use this file except in compliance with the License.
3810 * You may obtain a copy of the License at
3811 *
3812 *     http://www.apache.org/licenses/LICENSE-2.0
3813 *
3814 * Unless required by applicable law or agreed to in writing, software
3815 * distributed under the License is distributed on an "AS IS" BASIS,
3816 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3817 * See the License for the specific language governing permissions and
3818 * limitations under the License.
3819 */
3820
3821var TransmuxingEvents = {
3822  IO_ERROR: 'io_error',
3823  DEMUX_ERROR: 'demux_error',
3824  INIT_SEGMENT: 'init_segment',
3825  MEDIA_SEGMENT: 'media_segment',
3826  LOADING_COMPLETE: 'loading_complete',
3827  RECOVERED_EARLY_EOF: 'recovered_early_eof',
3828  MEDIA_INFO: 'media_info',
3829  METADATA_ARRIVED: 'metadata_arrived',
3830  SCRIPTDATA_ARRIVED: 'scriptdata_arrived',
3831  STATISTICS_INFO: 'statistics_info',
3832  RECOMMEND_SEEKPOINT: 'recommend_seekpoint'
3833};
3834
3835exports.default = TransmuxingEvents;
3836
3837},{}],14:[function(_dereq_,module,exports){
3838'use strict';
3839
3840Object.defineProperty(exports, "__esModule", {
3841    value: true
3842});
3843
3844var _logger = _dereq_('../utils/logger.js');
3845
3846var _logger2 = _interopRequireDefault(_logger);
3847
3848var _loggingControl = _dereq_('../utils/logging-control.js');
3849
3850var _loggingControl2 = _interopRequireDefault(_loggingControl);
3851
3852var _polyfill = _dereq_('../utils/polyfill.js');
3853
3854var _polyfill2 = _interopRequireDefault(_polyfill);
3855
3856var _transmuxingController = _dereq_('./transmuxing-controller.js');
3857
3858var _transmuxingController2 = _interopRequireDefault(_transmuxingController);
3859
3860var _transmuxingEvents = _dereq_('./transmuxing-events.js');
3861
3862var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
3863
3864function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3865
3866/* post message to worker:
3867   data: {
3868       cmd: string
3869       param: any
3870   }
3871
3872   receive message from worker:
3873   data: {
3874       msg: string,
3875       data: any
3876   }
3877 */
3878
3879var TransmuxingWorker = function TransmuxingWorker(self) {
3880
3881    var TAG = 'TransmuxingWorker';
3882    var controller = null;
3883    var logcatListener = onLogcatCallback.bind(this);
3884
3885    _polyfill2.default.install();
3886
3887    self.addEventListener('message', function (e) {
3888        switch (e.data.cmd) {
3889            case 'init':
3890                controller = new _transmuxingController2.default(e.data.param[0], e.data.param[1]);
3891                controller.on(_transmuxingEvents2.default.IO_ERROR, onIOError.bind(this));
3892                controller.on(_transmuxingEvents2.default.DEMUX_ERROR, onDemuxError.bind(this));
3893                controller.on(_transmuxingEvents2.default.INIT_SEGMENT, onInitSegment.bind(this));
3894                controller.on(_transmuxingEvents2.default.MEDIA_SEGMENT, onMediaSegment.bind(this));
3895                controller.on(_transmuxingEvents2.default.LOADING_COMPLETE, onLoadingComplete.bind(this));
3896                controller.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));
3897                controller.on(_transmuxingEvents2.default.MEDIA_INFO, onMediaInfo.bind(this));
3898                controller.on(_transmuxingEvents2.default.METADATA_ARRIVED, onMetaDataArrived.bind(this));
3899                controller.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, onScriptDataArrived.bind(this));
3900                controller.on(_transmuxingEvents2.default.STATISTICS_INFO, onStatisticsInfo.bind(this));
3901                controller.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));
3902                break;
3903            case 'destroy':
3904                if (controller) {
3905                    controller.destroy();
3906                    controller = null;
3907                }
3908                self.postMessage({ msg: 'destroyed' });
3909                break;
3910            case 'start':
3911                controller.start();
3912                break;
3913            case 'stop':
3914                controller.stop();
3915                break;
3916            case 'seek':
3917                controller.seek(e.data.param);
3918                break;
3919            case 'pause':
3920                controller.pause();
3921                break;
3922            case 'resume':
3923                controller.resume();
3924                break;
3925            case 'logging_config':
3926                {
3927                    var config = e.data.param;
3928                    _loggingControl2.default.applyConfig(config);
3929
3930                    if (config.enableCallback === true) {
3931                        _loggingControl2.default.addLogListener(logcatListener);
3932                    } else {
3933                        _loggingControl2.default.removeLogListener(logcatListener);
3934                    }
3935                    break;
3936                }
3937        }
3938    });
3939
3940    function onInitSegment(type, initSegment) {
3941        var obj = {
3942            msg: _transmuxingEvents2.default.INIT_SEGMENT,
3943            data: {
3944                type: type,
3945                data: initSegment
3946            }
3947        };
3948        self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer
3949    }
3950
3951    function onMediaSegment(type, mediaSegment) {
3952        var obj = {
3953            msg: _transmuxingEvents2.default.MEDIA_SEGMENT,
3954            data: {
3955                type: type,
3956                data: mediaSegment
3957            }
3958        };
3959        self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer
3960    }
3961
3962    function onLoadingComplete() {
3963        var obj = {
3964            msg: _transmuxingEvents2.default.LOADING_COMPLETE
3965        };
3966        self.postMessage(obj);
3967    }
3968
3969    function onRecoveredEarlyEof() {
3970        var obj = {
3971            msg: _transmuxingEvents2.default.RECOVERED_EARLY_EOF
3972        };
3973        self.postMessage(obj);
3974    }
3975
3976    function onMediaInfo(mediaInfo) {
3977        var obj = {
3978            msg: _transmuxingEvents2.default.MEDIA_INFO,
3979            data: mediaInfo
3980        };
3981        self.postMessage(obj);
3982    }
3983
3984    function onMetaDataArrived(metadata) {
3985        var obj = {
3986            msg: _transmuxingEvents2.default.METADATA_ARRIVED,
3987            data: metadata
3988        };
3989        self.postMessage(obj);
3990    }
3991
3992    function onScriptDataArrived(data) {
3993        var obj = {
3994            msg: _transmuxingEvents2.default.SCRIPTDATA_ARRIVED,
3995            data: data
3996        };
3997        self.postMessage(obj);
3998    }
3999
4000    function onStatisticsInfo(statInfo) {
4001        var obj = {
4002            msg: _transmuxingEvents2.default.STATISTICS_INFO,
4003            data: statInfo
4004        };
4005        self.postMessage(obj);
4006    }
4007
4008    function onIOError(type, info) {
4009        self.postMessage({
4010            msg: _transmuxingEvents2.default.IO_ERROR,
4011            data: {
4012                type: type,
4013                info: info
4014            }
4015        });
4016    }
4017
4018    function onDemuxError(type, info) {
4019        self.postMessage({
4020            msg: _transmuxingEvents2.default.DEMUX_ERROR,
4021            data: {
4022                type: type,
4023                info: info
4024            }
4025        });
4026    }
4027
4028    function onRecommendSeekpoint(milliseconds) {
4029        self.postMessage({
4030            msg: _transmuxingEvents2.default.RECOMMEND_SEEKPOINT,
4031            data: milliseconds
4032        });
4033    }
4034
4035    function onLogcatCallback(type, str) {
4036        self.postMessage({
4037            msg: 'logcat_callback',
4038            data: {
4039                type: type,
4040                logcat: str
4041            }
4042        });
4043    }
4044}; /*
4045    * Copyright (C) 2016 Bilibili. All Rights Reserved.
4046    *
4047    * @author zheng qian <[email protected]>
4048    *
4049    * Licensed under the Apache License, Version 2.0 (the "License");
4050    * you may not use this file except in compliance with the License.
4051    * You may obtain a copy of the License at
4052    *
4053    *     http://www.apache.org/licenses/LICENSE-2.0
4054    *
4055    * Unless required by applicable law or agreed to in writing, software
4056    * distributed under the License is distributed on an "AS IS" BASIS,
4057    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4058    * See the License for the specific language governing permissions and
4059    * limitations under the License.
4060    */
4061
4062exports.default = TransmuxingWorker;
4063
4064},{"../utils/logger.js":41,"../utils/logging-control.js":42,"../utils/polyfill.js":43,"./transmuxing-controller.js":12,"./transmuxing-events.js":13}],15:[function(_dereq_,module,exports){
4065'use strict';
4066
4067Object.defineProperty(exports, "__esModule", {
4068    value: true
4069});
4070
4071var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
4072                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
4073                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4074                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
4075                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4076                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
4077                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
4077not use this file except in compliance with the License.
4078                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
4079                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4080                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
4081                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4082                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
4083                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
4084                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4085                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
4086                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
4087                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
4088
4089var _logger = _dereq_('../utils/logger.js');
4090
4091var _logger2 = _interopRequireDefault(_logger);
4092
4093var _utf8Conv = _dereq_('../utils/utf8-conv.js');
4094
4095var _utf8Conv2 = _interopRequireDefault(_utf8Conv);
4096
4097var _exception = _dereq_('../utils/exception.js');
4098
4099function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
4100
4101function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4102
4103var le = function () {
4104    var buf = new ArrayBuffer(2);
4105    new DataView(buf).setInt16(0, 256, true); // little-endian write
4106    return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
4107}();
4108
4109var AMF = function () {
4110    function AMF() {
4111        _classCallCheck(this, AMF);
4112    }
4113
4114    _createClass(AMF, null, [{
4115        key: 'parseScriptData',
4116        value: function parseScriptData(arrayBuffer, dataOffset, dataSize) {
4117            var data = {};
4118
4119            try {
4120                var name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);
4121                var value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);
4122
4123                data[name.data] = value.data;
4124            } catch (e) {
4125                _logger2.default.e('AMF', e.toString());
4126            }
4127
4128            return data;
4129        }
4130    }, {
4131        key: 'parseObject',
4132        value: function parseObject(arrayBuffer, dataOffset, dataSize) {
4133            if (dataSize < 3) {
4134                throw new _exception.IllegalStateException('Data not enough when parse ScriptDataObject');
4135            }
4136            var name = AMF.parseString(arrayBuffer, dataOffset, dataSize);
4137            var value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);
4138            var isObjectEnd = value.objectEnd;
4139
4140            return {
4141                data: {
4142                    name: name.data,
4143                    value: value.data
4144                },
4145                size: name.size + value.size,
4146                objectEnd: isObjectEnd
4147            };
4148        }
4149    }, {
4150        key: 'parseVariable',
4151        value: function parseVariable(arrayBuffer, dataOffset, dataSize) {
4152            return AMF.parseObject(arrayBuffer, dataOffset, dataSize);
4153        }
4154    }, {
4155        key: 'parseString',
4156        value: function parseString(arrayBuffer, dataOffset, dataSize) {
4157            if (dataSize < 2) {
4158                throw new _exception.IllegalStateException('Data not enough when parse String');
4159            }
4160            var v = new DataView(arrayBuffer, dataOffset, dataSize);
4161            var length = v.getUint16(0, !le);
4162
4163            var str = void 0;
4164            if (length > 0) {
4165                str = (0, _utf8Conv2.default)(new Uint8Array(arrayBuffer, dataOffset + 2, length));
4166            } else {
4167                str = '';
4168            }
4169
4170            return {
4171                data: str,
4172                size: 2 + length
4173            };
4174        }
4175    }, {
4176        key: 'parseLongString',
4177        value: function parseLongString(arrayBuffer, dataOffset, dataSize) {
4178            if (dataSize < 4) {
4179                throw new _exception.IllegalStateException('Data not enough when parse LongString');
4180            }
4181            var v = new DataView(arrayBuffer, dataOffset, dataSize);
4182            var length = v.getUint32(0, !le);
4183
4184            var str = void 0;
4185            if (length > 0) {
4186                str = (0, _utf8Conv2.default)(new Uint8Array(arrayBuffer, dataOffset + 4, length));
4187            } else {
4188                str = '';
4189            }
4190
4191            return {
4192                data: str,
4193                size: 4 + length
4194            };
4195        }
4196    }, {
4197        key: 'parseDate',
4198        value: function parseDate(arrayBuffer, dataOffset, dataSize) {
4199            if (dataSize < 10) {
4200                throw new _exception.IllegalStateException('Data size invalid when parse Date');
4201            }
4202            var v = new DataView(arrayBuffer, dataOffset, dataSize);
4203            var timestamp = v.getFloat64(0, !le);
4204            var localTimeOffset = v.getInt16(8, !le);
4205            timestamp += localTimeOffset * 60 * 1000; // get UTC time
4206
4207            return {
4208                data: new Date(timestamp),
4209                size: 8 + 2
4210            };
4211        }
4212    }, {
4213        key: 'parseValue',
4214        value: function parseValue(arrayBuffer, dataOffset, dataSize) {
4215            if (dataSize < 1) {
4216                throw new _exception.IllegalStateException('Data not enough when parse Value');
4217            }
4218
4219            var v = new DataView(arrayBuffer, dataOffset, dataSize);
4220
4221            var offset = 1;
4222            var type = v.getUint8(0);
4223            var value = void 0;
4224            var objectEnd = false;
4225
4226            try {
4227                switch (type) {
4228                    case 0:
4229                        // Number(Double) type
4230                        value = v.getFloat64(1, !le);
4231                        offset += 8;
4232                        break;
4233                    case 1:
4234                        {
4235                            // Boolean type
4236                            var b = v.getUint8(1);
4237                            value = b ? true : false;
4238                            offset += 1;
4239                            break;
4240                        }
4241                    case 2:
4242                        {
4243                            // String type
4244                            var amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);
4245                            value = amfstr.data;
4246                            offset += amfstr.size;
4247                            break;
4248                        }
4249                    case 3:
4250                        {
4251                            // Object(s) type
4252                            value = {};
4253                            var terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd
vendor: 2,898 bytes, lines 4254-4306
4254                            if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
4255                                terminal = 3;
4256                            }
4257                            while (offset < dataSize - 4) {
4258                                // 4 === type(UI8) + ScriptDataObjectEnd(UI24)
4259                                var amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);
4260                                if (amfobj.objectEnd) break;
4261                                value[amfobj.data.name] = amfobj.data.value;
4262                                offset += amfobj.size;
4263                            }
4264                            if (offset <= dataSize - 3) {
4265                                var marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;
4266                                if (marker === 9) {
4267                                    offset += 3;
4268                                }
4269                            }
4270                            break;
4271                        }
4272                    case 8:
4273                        {
4274                            // ECMA array type (Mixed array)
4275                            value = {};
4276                            offset += 4; // ECMAArrayLength(UI32)
4277                            var _terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd
4278                            if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
4279                                _terminal = 3;
4280                            }
4281                            while (offset < dataSize - 8) {
4282                                // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)
4283                                var amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - _terminal);
4284                                if (amfvar.objectEnd) break;
4285                                value[amfvar.data.name] = amfvar.data.value;
4286                                offset += amfvar.size;
4287                            }
4288                            if (offset <= dataSize - 3) {
4289                                var _marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;
4290                                if (_marker === 9) {
4291                                    offset += 3;
4292                                }
4293                            }
4294                            break;
4295                        }
4296                    case 9:
4297                        // ScriptDataObjectEnd
4298                        value = undefined;
4299                        offset = 1;
4300                        objectEnd = true;
4301                        break;
4302                    case 10:
4303                        {
4304                            // Strict array type
4305                            // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf
4306                            value = [];
4307                            var strictArrayLength = v.getUint32(1, !le);
4308                            offset += 4;
4309                            for (var i = 0; i < strictArrayLength; i++) {
4310                                var val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);
4311                                value.push(val.data);
4312                                offset += val.size;
4313                            }
4314                            break;
4315                        }
4316                    case 11:
4317                        {
4318                            // Date type
4319                            var date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);
4320                            value = date.data;
4321                            offset += date.size;
4322                            break;
4323                        }
4324                    case 12:
4325                        {
4326                            // Long string type
4327                            var amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);
4328                            value = amfLongStr.data;
4329                            offset += amfLongStr.size;
4330                            break;
4331                        }
4332                    default:
4333                        // ignore and skip
4334                        offset = dataSize;
4335                        _logger2.default.w('AMF', 'Unsupported AMF value type ' + type);
4336                }
4337            } catch (e) {
4338                _logger2.default.e('AMF', e.toString());
4339            }
4340
4341            return {
4342                data: value,
4343                size: offset,
4344                objectEnd: objectEnd
4345            };
4346        }
4347    }]);
4348
4349    return AMF;
4350}();
4351
4352exports.default = AMF;
4353
4354},{"../utils/exception.js":40,"../utils/logger.js":41,"../utils/utf8-conv.js":44}],16:[function(_dereq_,module,exports){
4355'use strict';
4356
4357Object.defineProperty(exports, "__esModule", {
4358  value: true
4359});
4360/*
4361 * Copyright (C) 2016 Bilibili. All Rights Reserved.
4362 *
4363 * @author zheng qian <[email protected]>
4364 *
4365 * Licensed under the Apache License, Version 2.0 (the "License");
4366 * you may not use this file except in compliance with the License.
4367 * You may obtain a copy of the License at
4368 *
4369 *     http://www.apache.org/licenses/LICENSE-2.0
4370 *
4371 * Unless required by applicable law or agreed to in writing, software
4372 * distributed under the License is distributed on an "AS IS" BASIS,
4373 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4374 * See the License for the specific language governing permissions and
4375 * limitations under the License.
4376 */
4377
4378var DemuxErrors = {
4379  OK: 'OK',
4380  FORMAT_ERROR: 'FormatError',
4381  FORMAT_UNSUPPORTED: 'FormatUnsupported',
4382  CODEC_UNSUPPORTED: 'CodecUnsupported'
4383};
4384
4385exports.default = DemuxErrors;
4386
4387},{}],17:[function(_dereq_,module,exports){
4388'use strict';
4389
4390Object.defineProperty(exports, "__esModule", {
4391    value: true
4392});
4393
4394var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
4395                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
4396                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4397                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
4398                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4399                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
4400                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
4400not use this file except in compliance with the License.
4401                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
4402                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4403                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
4404                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4405                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
4406                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
4407                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4408                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
4409                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
4410                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
4411
4412var _exception = _dereq_('../utils/exception.js');
4413
4414function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4415
4416// Exponential-Golomb buffer decoder
4417var ExpGolomb = function () {
4418    function ExpGolomb(uint8array) {
4419        _classCallCheck(this, ExpGolomb);
4420
4421        this.TAG = 'ExpGolomb';
4422
4423        this._buffer = uint8array;
4424        this._buffer_index = 0;
4425        this._total_bytes = uint8array.byteLength;
4426        this._total_bits = uint8array.byteLength * 8;
4427        this._current_word = 0;
4428        this._current_word_bits_left = 0;
4429    }
4430
4431    _createClass(ExpGolomb, [{
4432        key: 'destroy',
4433        value: function destroy() {
4434            this._buffer = null;
4435        }
4436    }, {
4437        key: '_fillCurrentWord',
4438        value: function _fillCurrentWord() {
4439            var buffer_bytes_left = this._total_bytes - this._buffer_index;
4440            if (buffer_bytes_left <= 0) throw new _exception.IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');
4441
4442            var bytes_read = Math.min(4, buffer_bytes_left);
4443            var word = new Uint8Array(4);
4444            word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));
4445            this._current_word = new DataView(word.buffer).getUint32(0, false);
4446
4447            this._buffer_index += bytes_read;
4448            this._current_word_bits_left = bytes_read * 8;
4449        }
4450    }, {
4451        key: 'readBits',
4452        value: function readBits(bits) {
4453            if (bits > 32) throw new _exception.InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');
4454
4455            if (bits <= this._current_word_bits_left) {
4456                var _result = this._current_word >>> 32 - bits;
4457                this._current_word <<= bits;
4458                this._current_word_bits_left -= bits;
4459                return _result;
4460            }
4461
4462            var result = this._current_word_bits_left ? this._current_word : 0;
4463            result = result >>> 32 - this._current_word_bits_left;
4464            var bits_need_left = bits - this._current_word_bits_left;
4465
4466            this._fillCurrentWord();
4467            var bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);
4468
4469            var result2 = this._current_word >>> 32 - bits_read_next;
4470            this._current_word <<= bits_read_next;
4471            this._current_word_bits_left -= bits_read_next;
4472
4473            result = result << bits_read_next | result2;
4474            return result;
4475        }
4476    }, {
4477        key: 'readBool',
4478        value: function readBool() {
4479            return this.readBits(1) === 1;
4480        }
4481    }, {
4482        key: 'readByte',
4483        value: function readByte() {
4484            return this.readBits(8);
4485        }
4486    }, {
4487        key: '_skipLeadingZero',
4488        value: function _skipLeadingZero() {
4489            var zero_count = void 0;
4490            for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {
4491                if (0 !== (this._current_word & 0x80000000 >>> zero_count)) {
4492                    this._current_word <<= zero_count;
4493                    this._current_word_bits_left -= zero_count;
4494                    return zero_count;
4495                }
4496            }
4497            this._fillCurrentWord();
4498            return zero_count + this._skipLeadingZero();
4499        }
4500    }, {
4501        key: 'readUEG',
4502        value: function readUEG() {
4503            // unsigned exponential golomb
4504            var leading_zeros = this._skipLeadingZero();
4505            return this.readBits(leading_zeros + 1) - 1;
4506        }
4507    }, {
4508        key: 'readSEG',
4509        value: function readSEG() {
4510            // signed exponential golomb
4511            var value = this.readUEG();
4512            if (value & 0x01) {
4513                return value + 1 >>> 1;
4514            } else {
4515                return -1 * (value >>> 1);
4516            }
4517        }
4518    }]);
4519
4520    return ExpGolomb;
4521}();
4522
4523exports.default = ExpGolomb;
4524
4525},{"../utils/exception.js":40}],18:[function(_dereq_,module,exports){
4526'use strict';
4527
4528Object.defineProperty(exports, "__esModule", {
4529    value: true
4530});
4531
4532var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4533
4534var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
4535                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
4536                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4537                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
4538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
4540                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
4540not use this file except in compliance with the License.
4541                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
4542                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4543                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
4544                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
4545                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
4546                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
4547                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4548                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
4549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
4550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
4551
4552var _logger = _dereq_('../utils/logger.js');
4553
4554var _logger2 = _interopRequireDefault(_logger);
4555
4556var _amfParser = _dereq_('./amf-parser.js');
4557
4558var _amfParser2 = _interopRequireDefault(_amfParser);
4559
4560var _spsParser = _dereq_('./sps-parser.js');
4561
4562var _spsParser2 = _interopRequireDefault(_spsParser);
4563
4564var _demuxErrors = _dereq_('./demux-errors.js');
4565
4566var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
4567
4568var _mediaInfo = _dereq_('../core/media-info.js');
4569
4570var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
4571
4572var _exception = _dereq_('../utils/exception.js');
4573
4574function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
4575
4576function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4577
4578function Swap16(src) {
4579    return src >>> 8 & 0xFF | (src & 0xFF) << 8;
4580}
4581
4582function Swap32(src) {
4583    return (src & 0xFF000000) >>> 24 | (src & 0x00FF0000) >>> 8 | (src & 0x0000FF00) << 8 | (src & 0x000000FF) << 24;
4584}
4585
4586function ReadBig32(array, index) {
4587    return array[index] << 24 | array[index + 1] << 16 | array[index + 2] << 8 | array[index + 3];
4588}
4589
4590var FLVDemuxer = function () {
4591    function FLVDemuxer(probeData, config) {
4592        _classCallCheck(this, FLVDemuxer);
4593
4594        this.TAG = 'FLVDemuxer';
4595
4596        this._config = config;
4597
4598        this._onError = null;
4599        this._onMediaInfo = null;
4600        this._onMetaDataArrived = null;
4601        this._onScriptDataArrived = null;
4602        this._onTrackMetadata = null;
4603        this._onDataAvailable = null;
4604
4605        this._dataOffset = probeData.dataOffset;
4606        this._firstParse = true;
4607        this._dispatch = false;
4608
4609        this._hasAudio = probeData.hasAudioTrack;
4610        this._hasVideo = probeData.hasVideoTrack;
4611
4612        this._hasAudioFlagOverrided = false;
4613        this._hasVideoFlagOverrided = false;
4614
4615        this._audioInitialMetadataDispatched = false;
4616        this._videoInitialMetadataDispatched = false;
4617
4618        this._mediaInfo = new _mediaInfo2.default();
4619        this._mediaInfo.hasAudio = this._hasAudio;
4620        this._mediaInfo.hasVideo = this._hasVideo;
4621        this._metadata = null;
4622        this._audioMetadata = null;
4623        this._videoMetadata = null;
4624
4625        this._naluLengthSize = 4;
4626        this._timestampBase = 0; // int32, in milliseconds
4627        this._timescale = 1000;
4628        this._duration = 0; // int32, in milliseconds
4629        this._durationOverrided = false;
4630        this._referenceFrameRate = {
4631            fixed: true,
4632            fps: 23.976,
4633            fps_num: 23976,
4634            fps_den: 1000
4635        };
4636
4637        this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];
4638
4639        this._mpegSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
4640
4641        this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];
4642        this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];
4643        this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];
4644
4645        this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];
4646        this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];
4647        this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];
4648
4649        this._videoTrack = { type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0 };
4650        this._audioTrack = { type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0 };
4651
4652        this._littleEndian = function () {
4653            var buf = new ArrayBuffer(2);
4654            new DataView(buf).setInt16(0, 256, true); // little-endian write
4655            return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
4656        }();
4657    }
4658
4659    _createClass(FLVDemuxer, [{
4660        key: 'destroy',
4661        value: function destroy() {
4662            this._mediaInfo = null;
4663            this._metadata = null;
4664            this._audioMetadata = null;
4665            this._videoMetadata = null;
4666            this._videoTrack = null;
4667            this._audioTrack = null;
4668
4669            this._onError = null;
4670            this._onMediaInfo = null;
4671            this._onMetaDataArrived = null;
4672            this._onScriptDataArrived = null;
4673            this._onTrackMetadata = null;
4674            this._onDataAvailable = null;
4675        }
4676    }, {
4677        key: 'bindDataSource',
4678        value: function bindDataSource(loader) {
4679            loader.onDataArrival = this.parseChunks.bind(this);
4680            return this;
4681        }
4682
4683        // prototype: function(type: string, metadata: any): void
4684
4685    }, {
4686        key: 'resetMediaInfo',
4687        value: function resetMediaInfo() {
4688            this._mediaInfo = new _mediaInfo2.default();
4689        }
4690    }, {
4691        key: '_isInitialMetadataDispatched',
4692        value: function _isInitialMetadataDispatched() {
4693            if (this._hasAudio && this._hasVideo) {
4694                // both audio & video
4695                return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;
4696            }
4697            if (this._hasAudio && !this._hasVideo) {
4698                // audio only
4699                return this._audioInitialMetadataDispatched;
4700            }
4701            if (!this._hasAudio && this._hasVideo) {
4702                // video only
4703                return this._videoInitialMetadataDispatched;
4704            }
4705            return false;
4706        }
4707
4708        // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;
4709
4710    }, {
4711        key: 'parseChunks',
4712        value: function parseChunks(chunk, byteStart) {
4713            if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {
4714                throw new _exception.IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');
4715            }
4716
4717            var offset = 0;
4718            var le = this._littleEndian;
4719
4720            if (byteStart === 0) {
4721                // buffer with FLV header
4722                if (chunk.byteLength > 13) {
4723                    var probeData = FLVDemuxer.probe(chunk);
4724                    offset = probeData.dataOffset;
4725                } else {
4726                    return 0;
4727                }
4728            }
4729
4730            if (this._firstParse) {
4731                // handle PreviousTagSize0 before Tag1
4732                this._firstParse = false;
vendor: 20,009 bytes, lines 4733-5196
4733                if (byteStart + offset !== this._dataOffset) {
4734                    _logger2.default.w(this.TAG, 'First time parsing but chunk byteStart invalid!');
4735                }
4736
4737                var v = new DataView(chunk, offset);
4738                var prevTagSize0 = v.getUint32(0, !le);
4739                if (prevTagSize0 !== 0) {
4740                    _logger2.default.w(this.TAG, 'PrevTagSize0 !== 0 !!!');
4741                }
4742                offset += 4;
4743            }
4744
4745            while (offset < chunk.byteLength) {
4746                this._dispatch = true;
4747
4748                var _v = new DataView(chunk, offset);
4749
4750                if (offset + 11 + 4 > chunk.byteLength) {
4751                    // data not enough for parsing an flv tag
4752                    break;
4753                }
4754
4755                var tagType = _v.getUint8(0);
4756                var dataSize = _v.getUint32(0, !le) & 0x00FFFFFF;
4757
4758                if (offset + 11 + dataSize + 4 > chunk.byteLength) {
4759                    // data not enough for parsing actual data body
4760                    break;
4761                }
4762
4763                if (tagType !== 8 && tagType !== 9 && tagType !== 18) {
4764                    _logger2.default.w(this.TAG, 'Unsupported tag type ' + tagType + ', skipped');
4765                    // consume the whole tag (skip it)
4766                    offset += 11 + dataSize + 4;
4767                    continue;
4768                }
4769
4770                var ts2 = _v.getUint8(4);
4771                var ts1 = _v.getUint8(5);
4772                var ts0 = _v.getUint8(6);
4773                var ts3 = _v.getUint8(7);
4774
4775                var timestamp = ts0 | ts1 << 8 | ts2 << 16 | ts3 << 24;
4776
4777                var streamId = _v.getUint32(7, !le) & 0x00FFFFFF;
4778                if (streamId !== 0) {
4779                    _logger2.default.w(this.TAG, 'Meet tag which has StreamID != 0!');
4780                }
4781
4782                var dataOffset = offset + 11;
4783
4784                switch (tagType) {
4785                    case 8:
4786                        // Audio
4787                        this._parseAudioData(chunk, dataOffset, dataSize, timestamp);
4788                        break;
4789                    case 9:
4790                        // Video
4791                        this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);
4792                        break;
4793                    case 18:
4794                        // ScriptDataObject
4795                        this._parseScriptData(chunk, dataOffset, dataSize);
4796                        break;
4797                }
4798
4799                var prevTagSize = _v.getUint32(11 + dataSize, !le);
4800                if (prevTagSize !== 11 + dataSize) {
4801                    _logger2.default.w(this.TAG, 'Invalid PrevTagSize ' + prevTagSize);
4802                }
4803
4804                offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize
4805            }
4806
4807            // dispatch parsed frames to consumer (typically, the remuxer)
4808            if (this._isInitialMetadataDispatched()) {
4809                if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
4810                    this._onDataAvailable(this._audioTrack, this._videoTrack);
4811                }
4812            }
4813
4814            return offset; // consumed bytes, just equals latest offset index
4815        }
4816    }, {
4817        key: '_parseScriptData',
4818        value: function _parseScriptData(arrayBuffer, dataOffset, dataSize) {
4819            var scriptData = _amfParser2.default.parseScriptData(arrayBuffer, dataOffset, dataSize);
4820
4821            if (scriptData.hasOwnProperty('onMetaData')) {
4822                if (scriptData.onMetaData == null || _typeof(scriptData.onMetaData) !== 'object') {
4823                    _logger2.default.w(this.TAG, 'Invalid onMetaData structure!');
4824                    return;
4825                }
4826                if (this._metadata) {
4827                    _logger2.default.w(this.TAG, 'Found another onMetaData tag!');
4828                }
4829                this._metadata = scriptData;
4830                var onMetaData = this._metadata.onMetaData;
4831
4832                if (this._onMetaDataArrived) {
4833                    this._onMetaDataArrived(Object.assign({}, onMetaData));
4834                }
4835
4836                if (typeof onMetaData.hasAudio === 'boolean') {
4837                    // hasAudio
4838                    if (this._hasAudioFlagOverrided === false) {
4839                        this._hasAudio = onMetaData.hasAudio;
4840                        this._mediaInfo.hasAudio = this._hasAudio;
4841                    }
4842                }
4843                if (typeof onMetaData.hasVideo === 'boolean') {
4844                    // hasVideo
4845                    if (this._hasVideoFlagOverrided === false) {
4846                        this._hasVideo = onMetaData.hasVideo;
4847                        this._mediaInfo.hasVideo = this._hasVideo;
4848                    }
4849                }
4850                if (typeof onMetaData.audiodatarate === 'number') {
4851                    // audiodatarate
4852                    this._mediaInfo.audioDataRate = onMetaData.audiodatarate;
4853                }
4854                if (typeof onMetaData.videodatarate === 'number') {
4855                    // videodatarate
4856                    this._mediaInfo.videoDataRate = onMetaData.videodatarate;
4857                }
4858                if (typeof onMetaData.width === 'number') {
4859                    // width
4860                    this._mediaInfo.width = onMetaData.width;
4861                }
4862                if (typeof onMetaData.height === 'number') {
4863                    // height
4864                    this._mediaInfo.height = onMetaData.height;
4865                }
4866                if (typeof onMetaData.duration === 'number') {
4867                    // duration
4868                    if (!this._durationOverrided) {
4869                        var duration = Math.floor(onMetaData.duration * this._timescale);
4870                        this._duration = duration;
4871                        this._mediaInfo.duration = duration;
4872                    }
4873                } else {
4874                    this._mediaInfo.duration = 0;
4875                }
4876                if (typeof onMetaData.framerate === 'number') {
4877                    // framerate
4878                    var fps_num = Math.floor(onMetaData.framerate * 1000);
4879                    if (fps_num > 0) {
4880                        var fps = fps_num / 1000;
4881                        this._referenceFrameRate.fixed = true;
4882                        this._referenceFrameRate.fps = fps;
4883                        this._referenceFrameRate.fps_num = fps_num;
4884                        this._referenceFrameRate.fps_den = 1000;
4885                        this._mediaInfo.fps = fps;
4886                    }
4887                }
4888                if (_typeof(onMetaData.keyframes) === 'object') {
4889                    // keyframes
4890                    this._mediaInfo.hasKeyframesIndex = true;
4891                    var keyframes = onMetaData.keyframes;
4892                    this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);
4893                    onMetaData.keyframes = null; // keyframes has been extracted, remove it
4894                } else {
4895                    this._mediaInfo.hasKeyframesIndex = false;
4896                }
4897                this._dispatch = false;
4898                this._mediaInfo.metadata = onMetaData;
4899                _logger2.default.v(this.TAG, 'Parsed onMetaData');
4900                if (this._mediaInfo.isComplete()) {
4901                    this._onMediaInfo(this._mediaInfo);
4902                }
4903            }
4904
4905            if (Object.keys(scriptData).length > 0) {
4906                if (this._onScriptDataArrived) {
4907                    this._onScriptDataArrived(Object.assign({}, scriptData));
4908                }
4909            }
4910        }
4911    }, {
4912        key: '_parseKeyframesIndex',
4913        value: function _parseKeyframesIndex(keyframes) {
4914            var times = [];
4915            var filepositions = [];
4916
4917            // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)
4918            for (var i = 1; i < keyframes.times.length; i++) {
4919                var time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);
4920                times.push(time);
4921                filepositions.push(keyframes.filepositions[i]);
4922            }
4923
4924            return {
4925                times: times,
4926                filepositions: filepositions
4927            };
4928        }
4929    }, {
4930        key: '_parseAudioData',
4931        value: function _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {
4932            if (dataSize <= 1) {
4933                _logger2.default.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');
4934                return;
4935            }
4936
4937            if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {
4938                // If hasAudio: false indicated explicitly in MediaDataSource,
4939                // Ignore all the audio packets
4940                return;
4941            }
4942
4943            var le = this._littleEndian;
4944            var v = new DataView(arrayBuffer, dataOffset, dataSize);
4945
4946            var soundSpec = v.getUint8(0);
4947
4948            var soundFormat = soundSpec >>> 4;
4949            if (soundFormat !== 2 && soundFormat !== 10) {
4950                // MP3 or AAC
4951                this._onError(_demuxErrors2.default.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);
4952                return;
4953            }
4954
4955            var soundRate = 0;
4956            var soundRateIndex = (soundSpec & 12) >>> 2;
4957            if (soundRateIndex >= 0 && soundRateIndex <= 4) {
4958                soundRate = this._flvSoundRateTable[soundRateIndex];
4959            } else {
4960                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);
4961                return;
4962            }
4963
4964            var soundSize = (soundSpec & 2) >>> 1; // unused
4965            var soundType = soundSpec & 1;
4966
4967            var meta = this._audioMetadata;
4968            var track = this._audioTrack;
4969
4970            if (!meta) {
4971                if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {
4972                    this._hasAudio = true;
4973                    this._mediaInfo.hasAudio = true;
4974                }
4975
4976                // initial metadata
4977                meta = this._audioMetadata = {};
4978                meta.type = 'audio';
4979                meta.id = track.id;
4980                meta.timescale = this._timescale;
4981                meta.duration = this._duration;
4982                meta.audioSampleRate = soundRate;
4983                meta.channelCount = soundType === 0 ? 1 : 2;
4984            }
4985
4986            if (soundFormat === 10) {
4987                // AAC
4988                var aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);
4989                if (aacData == undefined) {
4990                    return;
4991                }
4992
4993                if (aacData.packetType === 0) {
4994                    // AAC sequence header (AudioSpecificConfig)
4995                    if (meta.config) {
4996                        _logger2.default.w(this.TAG, 'Found another AudioSpecificConfig!');
4997                    }
4998                    var misc = aacData.data;
4999                    meta.audioSampleRate = misc.samplingRate;
5000                    meta.channelCount = misc.channelCount;
5001                    meta.codec = misc.codec;
5002                    meta.originalCodec = misc.originalCodec;
5003                    meta.config = misc.config;
5004                    // The decode result of an aac sample is 1024 PCM samples
5005                    meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;
5006                    _logger2.default.v(this.TAG, 'Parsed AudioSpecificConfig');
5007
5008                    if (this._isInitialMetadataDispatched()) {
5009                        // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer
5010                        if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
5011                            this._onDataAvailable(this._audioTrack, this._videoTrack);
5012                        }
5013                    } else {
5014                        this._audioInitialMetadataDispatched = true;
5015                    }
5016                    // then notify new metadata
5017                    this._dispatch = false;
5018                    this._onTrackMetadata('audio', meta);
5019
5020                    var mi = this._mediaInfo;
5021                    mi.audioCodec = meta.originalCodec;
5022                    mi.audioSampleRate = meta.audioSampleRate;
5023                    mi.audioChannelCount = meta.channelCount;
5024                    if (mi.hasVideo) {
5025                        if (mi.videoCodec != null) {
5026                            mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
5027                        }
5028                    } else {
5029                        mi.mimeType = 'video/x-flv; codecs="' + mi.audioCodec + '"';
5030                    }
5031                    if (mi.isComplete()) {
5032                        this._onMediaInfo(mi);
5033                    }
5034                } else if (aacData.packetType === 1) {
5035                    // AAC raw frame data
5036                    var dts = this._timestampBase + tagTimestamp;
5037                    var aacSample = { unit: aacData.data, length: aacData.data.byteLength, dts: dts, pts: dts };
5038                    track.samples.push(aacSample);
5039                    track.length += aacData.data.length;
5040                } else {
5041                    _logger2.default.e(this.TAG, 'Flv: Unsupported AAC data type ' + aacData.packetType);
5042                }
5043            } else if (soundFormat === 2) {
5044                // MP3
5045                if (!meta.codec) {
5046                    // We need metadata for mp3 audio track, extract info from frame header
5047                    var _misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);
5048                    if (_misc == undefined) {
5049                        return;
5050                    }
5051                    meta.audioSampleRate = _misc.samplingRate;
5052                    meta.channelCount = _misc.channelCount;
5053                    meta.codec = _misc.codec;
5054                    meta.originalCodec = _misc.originalCodec;
5055                    // The decode result of an mp3 sample is 1152 PCM samples
5056                    meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;
5057                    _logger2.default.v(this.TAG, 'Parsed MPEG Audio Frame Header');
5058
5059                    this._audioInitialMetadataDispatched = true;
5060                    this._onTrackMetadata('audio', meta);
5061
5062                    var _mi = this._mediaInfo;
5063                    _mi.audioCodec = meta.codec;
5064                    _mi.audioSampleRate = meta.audioSampleRate;
5065                    _mi.audioChannelCount = meta.channelCount;
5066                    _mi.audioDataRate = _misc.bitRate;
5067                    if (_mi.hasVideo) {
5068                        if (_mi.videoCodec != null) {
5069                            _mi.mimeType = 'video/x-flv; codecs="' + _mi.videoCodec + ',' + _mi.audioCodec + '"';
5070                        }
5071                    } else {
5072                        _mi.mimeType = 'video/x-flv; codecs="' + _mi.audioCodec + '"';
5073                    }
5074                    if (_mi.isComplete()) {
5075                        this._onMediaInfo(_mi);
5076                    }
5077                }
5078
5079                // This packet is always a valid audio packet, extract it
5080                var data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);
5081                if (data == undefined) {
5082                    return;
5083                }
5084                var _dts = this._timestampBase + tagTimestamp;
5085                var mp3Sample = { unit: data, length: data.byteLength, dts: _dts, pts: _dts };
5086                track.samples.push(mp3Sample);
5087                track.length += data.length;
5088            }
5089        }
5090    }, {
5091        key: '_parseAACAudioData',
5092        value: function _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {
5093            if (dataSize <= 1) {
5094                _logger2.default.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');
5095                return;
5096            }
5097
5098            var result = {};
5099            var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
5100
5101            result.packetType = array[0];
5102
5103            if (array[0] === 0) {
5104                result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);
5105            } else {
5106                result.data = array.subarray(1);
5107            }
5108
5109            return result;
5110        }
5111    }, {
5112        key: '_parseAACAudioSpecificConfig',
5113        value: function _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {
5114            var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
5115            var config = null;
5116
5117            /* Audio Object Type:
5118               0: Null
5119               1: AAC Main
5120               2: AAC LC
5121               3: AAC SSR (Scalable Sample Rate)
5122               4: AAC LTP (Long Term Prediction)
5123               5: HE-AAC / SBR (Spectral Band Replication)
5124               6: AAC Scalable
5125            */
5126
5127            var audioObjectType = 0;
5128            var originalAudioObjectType = 0;
5129            var audioExtensionObjectType = null;
5130            var samplingIndex = 0;
5131            var extensionSamplingIndex = null;
5132
5133            // 5 bits
5134            audioObjectType = originalAudioObjectType = array[0] >>> 3;
5135            // 4 bits
5136            samplingIndex = (array[0] & 0x07) << 1 | array[1] >>> 7;
5137            if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {
5138                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');
5139                return;
5140            }
5141
5142            var samplingFrequence = this._mpegSamplingRates[samplingIndex];
5143
5144            // 4 bits
5145            var channelConfig = (array[1] & 0x78) >>> 3;
5146            if (channelConfig < 0 || channelConfig >= 8) {
5147                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');
5148                return;
5149            }
5150
5151            if (audioObjectType === 5) {
5152                // HE-AAC?
5153                // 4 bits
5154                extensionSamplingIndex = (array[1] & 0x07) << 1 | array[2] >>> 7;
5155                // 5 bits
5156                audioExtensionObjectType = (array[2] & 0x7C) >>> 2;
5157            }
5158
5159            // workarounds for various browsers
5160            var userAgent = self.navigator.userAgent.toLowerCase();
5161
5162            if (userAgent.indexOf('firefox') !== -1) {
5163                // firefox: use SBR (HE-AAC) if freq less than 24kHz
5164                if (samplingIndex >= 6) {
5165                    audioObjectType = 5;
5166                    config = new Array(4);
5167                    extensionSamplingIndex = samplingIndex - 3;
5168                } else {
5169                    // use LC-AAC
5170                    audioObjectType = 2;
5171                    config = new Array(2);
5172                    extensionSamplingIndex = samplingIndex;
5173                }
5174            } else if (userAgent.indexOf('android') !== -1) {
5175                // android: always use LC-AAC
5176                audioObjectType = 2;
5177                config = new Array(2);
5178                extensionSamplingIndex = samplingIndex;
5179            } else {
5180                // for other browsers, e.g. chrome...
5181                // Always use HE-AAC to make it easier to switch aac codec profile
5182                audioObjectType = 5;
5183                extensionSamplingIndex = samplingIndex;
5184                config = new Array(4);
5185
5186                if (samplingIndex >= 6) {
5187                    extensionSamplingIndex = samplingIndex - 3;
5188                } else if (channelConfig === 1) {
5189                    // Mono channel
5190                    audioObjectType = 2;
5191                    config = new Array(2);
5192                    extensionSamplingIndex = samplingIndex;
5193                }
5194            }
5195
5196            config[0] = audioObjectType << 3;
5197            config[0] |= (samplingIndex & 0x0F) >>> 1;
5198            config[1] = (samplingIndex & 0x0F) << 7;
5199            config[1] |= (channelConfig & 0x0F) << 3;
5200            if (audioObjectType === 5) {
5201                config[1] |= (extensionSamplingIndex & 0x0F) >>> 1;
5202                config[2] = (extensionSamplingIndex & 0x01) << 7;
5203                // extended audio object type: force to 2 (LC-AAC)
5204                config[2] |= 2 << 2;
5205                config[3] = 0;
5206            }
5207
5208            return {
5209                config: config,
5210                samplingRate: samplingFrequence,
5211                channelCount: channelConfig,
5212                codec: 'mp4a.40.' + audioObjectType,
5213                originalCodec: 'mp4a.40.' + originalAudioObjectType
5214            };
5215        }
5216    }, {
5217        key: '_parseMP3AudioData',
5218        value: function _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {
5219            if (dataSize < 4) {
5220                _logger2.default.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');
5221                return;
5222            }
5223
5224            var le = this._littleEndian;
5225            var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
5226            var result = null;
5227
5228            if (requestHeader) {
5229                if (array[0] !== 0xFF) {
5230                    return;
5231                }
5232                var ver = array[1] >>> 3 & 0x03;
5233                var layer = (array[1] & 0x06) >> 1;
5234
5235                var bitrate_index = (array[2] & 0xF0) >>> 4;
5236                var sampling_freq_index = (array[2] & 0x0C) >>> 2;
5237
5238                var channel_mode = array[3] >>> 6 & 0x03;
5239                var channel_count = channel_mode !== 3 ? 2 : 1;
5240
5241                var sample_rate = 0;
5242                var bit_rate = 0;
5243                var object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types
5244
5245                var codec = 'mp3';
5246
5247                switch (ver) {
5248                    case 0:
5249                        // MPEG 2.5
5250                        sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];
5251                        break;
5252                    case 2:
5253                        // MPEG 2
5254                        sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];
5255                        break;
5256                    case 3:
5257                        // MPEG 1
5258                        sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];
5259                        break;
5260                }
5261
5262                switch (layer) {
5263                    case 1:
5264                        // Layer 3
5265                        object_type = 34;
5266                        if (bitrate_index < this._mpegAudioL3BitRateTable.length) {
5267                            bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];
5268                        }
5269                        break;
5270                    case 2:
5271                        // Layer 2
5272                        object_type = 33;
5273                        if (bitrate_index < this._mpegAudioL2BitRateTable.length) {
5274                            bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];
5275                        }
5276                        break;
5277                    case 3:
5278                        // Layer 1
5279                        object_type = 32;
5280                        if (bitrate_index < this._mpegAudioL1BitRateTable.length) {
5281                            bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];
5282                        }
5283                        break;
5284                }
5285
5286                result = {
5287                    bitRate: bit_rate,
5288                    samplingRate: sample_rate,
5289                    channelCount: channel_count,
5290                    codec: codec,
5291                    originalCodec: codec
5292                };
5293            } else {
5294                result = array;
5295            }
5296
5297            return result;
5298        }
5299    }, {
5300        key: '_parseVideoData',
5301        value: function _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {
5302            if (dataSize <= 1) {
5303                _logger2.default.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');
5304                return;
5305            }
5306
5307            if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {
5308                // If hasVideo: false indicated explicitly in MediaDataSource,
5309                // Ignore all the video packets
5310                return;
5311            }
5312
5313            var spec = new Uint8Array(arrayBuffer, dataOffset, dataSize)[0];
5314
5315            var frameType = (spec & 240) >>> 4;
5316            var codecId = spec & 15;
5317
5318            if (codecId !== 7) {
5319                this._onError(_demuxErrors2.default.CODEC_UNSUPPORTED, 'Flv: Unsupported codec in video frame: ' + codecId);
5320                return;
5321            }
5322
5323            this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);
5324        }
5325    }, {
vendor: 8,228 bytes, lines 5326-5518
5326        key: '_parseAVCVideoPacket',
5327        value: function _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {
5328            if (dataSize < 4) {
5329                _logger2.default.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');
5330                return;
5331            }
5332
5333            var le = this._littleEndian;
5334            var v = new DataView(arrayBuffer, dataOffset, dataSize);
5335
5336            var packetType = v.getUint8(0);
5337            var cts_unsigned = v.getUint32(0, !le) & 0x00FFFFFF;
5338            var cts = cts_unsigned << 8 >> 8; // convert to 24-bit signed int
5339
5340            if (packetType === 0) {
5341                // AVCDecoderConfigurationRecord
5342                this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);
5343            } else if (packetType === 1) {
5344                // One or more Nalus
5345                this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);
5346            } else if (packetType === 2) {
5347                // empty, AVC end of sequence
5348            } else {
5349                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid video packet type ' + packetType);
5350                return;
5351            }
5352        }
5353    }, {
5354        key: '_parseAVCDecoderConfigurationRecord',
5355        value: function _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {
5356            if (dataSize < 7) {
5357                _logger2.default.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');
5358                return;
5359            }
5360
5361            var meta = this._videoMetadata;
5362            var track = this._videoTrack;
5363            var le = this._littleEndian;
5364            var v = new DataView(arrayBuffer, dataOffset, dataSize);
5365
5366            if (!meta) {
5367                if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {
5368                    this._hasVideo = true;
5369                    this._mediaInfo.hasVideo = true;
5370                }
5371
5372                meta = this._videoMetadata = {};
5373                meta.type = 'video';
5374                meta.id = track.id;
5375                meta.timescale = this._timescale;
5376                meta.duration = this._duration;
5377            } else {
5378                if (typeof meta.avcc !== 'undefined') {
5379                    _logger2.default.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');
5380                }
5381            }
5382
5383            var version = v.getUint8(0); // configurationVersion
5384            var avcProfile = v.getUint8(1); // avcProfileIndication
5385            var profileCompatibility = v.getUint8(2); // profile_compatibility
5386            var avcLevel = v.getUint8(3); // AVCLevelIndication
5387
5388            if (version !== 1 || avcProfile === 0) {
5389                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');
5390                return;
5391            }
5392
5393            this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne
5394            if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) {
5395                // holy shit!!!
5396                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Strange NaluLengthSizeMinusOne: ' + (this._naluLengthSize - 1));
5397                return;
5398            }
5399
5400            var spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets
5401            if (spsCount === 0) {
5402                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');
5403                return;
5404            } else if (spsCount > 1) {
5405                _logger2.default.w(this.TAG, 'Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ' + spsCount);
5406            }
5407
5408            var offset = 6;
5409
5410            for (var i = 0; i < spsCount; i++) {
5411                var len = v.getUint16(offset, !le); // sequenceParameterSetLength
5412                offset += 2;
5413
5414                if (len === 0) {
5415                    continue;
5416                }
5417
5418                // Notice: Nalu without startcode header (00 00 00 01)
5419                var sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);
5420                offset += len;
5421
5422                var config = _spsParser2.default.parseSPS(sps);
5423                if (i !== 0) {
5424                    // ignore other sps's config
5425                    continue;
5426                }
5427
5428                meta.codecWidth = config.codec_size.width;
5429                meta.codecHeight = config.codec_size.height;
5430                meta.presentWidth = config.present_size.width;
5431                meta.presentHeight = config.present_size.height;
5432
5433                meta.profile = config.profile_string;
5434                meta.level = config.level_string;
5435                meta.bitDepth = config.bit_depth;
5436                meta.chromaFormat = config.chroma_format;
5437                meta.sarRatio = config.sar_ratio;
5438                meta.frameRate = config.frame_rate;
5439
5440                if (config.frame_rate.fixed === false || config.frame_rate.fps_num === 0 || config.frame_rate.fps_den === 0) {
5441                    meta.frameRate = this._referenceFrameRate;
5442                }
5443
5444                var fps_den = meta.frameRate.fps_den;
5445                var fps_num = meta.frameRate.fps_num;
5446                meta.refSampleDuration = meta.timescale * (fps_den / fps_num);
5447
5448                var codecArray = sps.subarray(1, 4);
5449                var codecString = 'avc1.';
5450                for (var j = 0; j < 3; j++) {
5451                    var h = codecArray[j].toString(16);
5452                    if (h.length < 2) {
5453                        h = '0' + h;
5454                    }
5455                    codecString += h;
5456                }
5457                meta.codec = codecString;
5458
5459                var mi = this._mediaInfo;
5460                mi.width = meta.codecWidth;
5461                mi.height = meta.codecHeight;
5462                mi.fps = meta.frameRate.fps;
5463                mi.profile = meta.profile;
5464                mi.level = meta.level;
5465                mi.refFrames = config.ref_frames;
5466                mi.chromaFormat = config.chroma_format_string;
5467                mi.sarNum = meta.sarRatio.width;
5468                mi.sarDen = meta.sarRatio.height;
5469                mi.videoCodec = codecString;
5470
5471                if (mi.hasAudio) {
5472                    if (mi.audioCodec != null) {
5473                        mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
5474                    }
5475                } else {
5476                    mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + '"';
5477                }
5478                if (mi.isComplete()) {
5479                    this._onMediaInfo(mi);
5480                }
5481            }
5482
5483            var ppsCount = v.getUint8(offset); // numOfPictureParameterSets
5484            if (ppsCount === 0) {
5485                this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');
5486                return;
5487            } else if (ppsCount > 1) {
5488                _logger2.default.w(this.TAG, 'Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ' + ppsCount);
5489            }
5490
5491            offset++;
5492
5493            for (var _i = 0; _i < ppsCount; _i++) {
5494                var _len = v.getUint16(offset, !le); // pictureParameterSetLength
5495                offset += 2;
5496
5497                if (_len === 0) {
5498                    continue;
5499                }
5500
5501                // pps is useless for extracting video information
5502                offset += _len;
5503            }
5504
5505            meta.avcc = new Uint8Array(dataSize);
5506            meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);
5507            _logger2.default.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');
5508
5509            if (this._isInitialMetadataDispatched()) {
5510                // flush parsed frames
5511                if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
5512                    this._onDataAvailable(this._audioTrack, this._videoTrack);
5513                }
5514            } else {
5515                this._videoInitialMetadataDispatched = true;
5516            }
5517            // notify new metadata
5518            this._dispatch = false;
5519            this._onTrackMetadata('video', meta);
5520        }
5521    }, {
5522        key: '_parseAVCVideoData',
5523        value: function _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {
5524            var le = this._littleEndian;
5525            var v = new DataView(arrayBuffer, dataOffset, dataSize);
5526
5527            var units = [],
5528                length = 0;
5529
5530            var offset = 0;
5531            var lengthSize = this._naluLengthSize;
5532            var dts = this._timestampBase + tagTimestamp;
5533            var keyframe = frameType === 1; // from FLV Frame Type constants
5534
5535            while (offset < dataSize) {
5536                if (offset + 4 >= dataSize) {
5537                    _logger2.default.w(this.TAG, 'Malformed Nalu near timestamp ' + dts + ', offset = ' + offset + ', dataSize = ' + dataSize);
5538                    break; // data not enough for next Nalu
5539                }
5540                // Nalu with length-header (AVC1)
5541                var naluSize = v.getUint32(offset, !le); // Big-Endian read
5542                if (lengthSize === 3) {
5543                    naluSize >>>= 8;
5544                }
5545                if (naluSize > dataSize - lengthSize) {
5546                    _logger2.default.w(this.TAG, 'Malformed Nalus near timestamp ' + dts + ', NaluSize > DataSize!');
5547                    return;
5548                }
5549
5550                var unitType = v.getUint8(offset + lengthSize) & 0x1F;
5551
5552                if (unitType === 5) {
5553                    // IDR
5554                    keyframe = true;
5555                }
5556
5557                var data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);
5558                var unit = { type: unitType, data: data };
5559                units.push(unit);
5560                length += data.byteLength;
5561
5562                offset += lengthSize + naluSize;
5563            }
5564
5565            if (units.length) {
5566                var track = this._videoTrack;
5567                var avcSample = {
5568                    units: units,
5569                    length: length,
5570                    isKeyframe: keyframe,
5571                    dts: dts,
5572                    cts: cts,
5573                    pts: dts + cts
5574                };
5575                if (keyframe) {
5576                    avcSample.fileposition = tagPosition;
5577                }
5578                track.samples.push(avcSample);
5579                track.length += length;
5580            }
5581        }
5582    }, {
5583        key: 'onTrackMetadata',
5584        get: function get() {
5585            return this._onTrackMetadata;
5586        },
5587        set: function set(callback) {
5588            this._onTrackMetadata = callback;
5589        }
5590
5591        // prototype: function(mediaInfo: MediaInfo): void
5592
5593    }, {
5594        key: 'onMediaInfo',
5595        get: function get() {
5596            return this._onMediaInfo;
5597        },
5598        set: function set(callback) {
5599            this._onMediaInfo = callback;
5600        }
5601    }, {
5602        key: 'onMetaDataArrived',
5603        get: function get() {
5604            return this._onMetaDataArrived;
5605        },
5606        set: function set(callback) {
5607            this._onMetaDataArrived = callback;
5608        }
5609    }, {
5610        key: 'onScriptDataArrived',
5611        get: function get() {
5612            return this._onScriptDataArrived;
5613        },
5614        set: function set(callback) {
5615            this._onScriptDataArrived = callback;
5616        }
5617
5618        // prototype: function(type: number, info: string): void
5619
5620    }, {
5621        key: 'onError',
5622        get: function get() {
5623            return this._onError;
5624        },
5625        set: function set(callback) {
5626            this._onError = callback;
5627        }
5628
5629        // prototype: function(videoTrack: any, audioTrack: any): void
5630
5631    }, {
5632        key: 'onDataAvailable',
5633        get: function get() {
5634            return this._onDataAvailable;
5635        },
5636        set: function set(callback) {
5637            this._onDataAvailable = callback;
5638        }
5639
5640        // timestamp base for output samples, must be in milliseconds
5641
5642    }, {
5643        key: 'timestampBase',
5644        get: function get() {
5645            return this._timestampBase;
5646        },
5647        set: function set(base) {
5648            this._timestampBase = base;
5649        }
5650    }, {
5651        key: 'overridedDuration',
5652        get: function get() {
5653            return this._duration;
5654        }
5655
5656        // Force-override media duration. Must be in milliseconds, int32
5657        ,
5658        set: function set(duration) {
5659            this._durationOverrided = true;
5660            this._duration = duration;
5661            this._mediaInfo.duration = duration;
5662        }
5663
5664        // Force-override audio track present flag, boolean
5665
5666    }, {
5667        key: 'overridedHasAudio',
5668        set: function set(hasAudio) {
5669            this._hasAudioFlagOverrided = true;
5670            this._hasAudio = hasAudio;
5671            this._mediaInfo.hasAudio = hasAudio;
5672        }
5673
5674        // Force-override video track present flag, boolean
5675
5676    }, {
5677        key: 'overridedHasVideo',
5678        set: function set(hasVideo) {
5679            this._hasVideoFlagOverrided = true;
5680            this._hasVideo = hasVideo;
5681            this._mediaInfo.hasVideo = hasVideo;
5682        }
5683    }], [{
5684        key: 'probe',
5685        value: function probe(buffer) {
5686            var data = new Uint8Array(buffer);
5687            var mismatch = { match: false };
5688
5689            if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {
5690                return mismatch;
5691            }
5692
5693            var hasAudio = (data[4] & 4) >>> 2 !== 0;
5694            var hasVideo = (data[4] & 1) !== 0;
5695
5696            var offset = ReadBig32(data, 5);
5697
5698            if (offset < 9) {
5699                return mismatch;
5700            }
5701
5702            return {
5703                match: true,
5704                consumed: offset,
5705                dataOffset: offset,
5706                hasAudioTrack: hasAudio,
5707                hasVideoTrack: hasVideo
5708            };
5709        }
5710    }]);
5711
5712    return FLVDemuxer;
5713}();
5714
5715exports.default = FLVDemuxer;
5716
5717},{"../core/media-info.js":7,"../utils/exception.js":40,"../utils/logger.js":41,"./amf-parser.js":15,"./demux-errors.js":16,"./sps-parser.js":19}],19:[function(_dereq_,module,exports){
5718'use strict';
5719
5720Object.defineProperty(exports, "__esModule", {
5721    value: true
5722});
5723
5724var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
5725                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
5726                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
5727                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
5728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
5729                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
5730                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
5730not use this file except in compliance with the License.
5731                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
5732                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
5733                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
5734                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
5735                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
5736                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
5737                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5738                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
5739                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
5740                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
5741
5742var _expGolomb = _dereq_('./exp-golomb.js');
5743
5744var _expGolomb2 = _interopRequireDefault(_expGolomb);
5745
5746function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
5747
5748function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5749
5750var SPSParser = function () {
5751    function SPSParser() {
5752        _classCallCheck(this, SPSParser);
5753    }
5754
5755    _createClass(SPSParser, null, [{
5756        key: '_ebsp2rbsp',
5757        value: function _ebsp2rbsp(uint8array) {
5758            var src = uint8array;
5759            var src_length = src.byteLength;
5760            var dst = new Uint8Array(src_length);
5761            var dst_idx = 0;
5762
5763            for (var i = 0; i < src_length; i++) {
5764                if (i >= 2) {
5765                    // Unescape: Skip 0x03 after 00 00
5766                    if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
5767                        continue;
5768                    }
5769                }
5770                dst[dst_idx] = src[i];
5771                dst_idx++;
5772            }
5773
5774            return new Uint8Array(dst.buffer, 0, dst_idx);
5775        }
5776    }, {
vendor: 6,100 bytes, lines 5777-5906
5777        key: 'parseSPS',
5778        value: function parseSPS(uint8array) {
5779            var rbsp = SPSParser._ebsp2rbsp(uint8array);
5780            var gb = new _expGolomb2.default(rbsp);
5781
5782            gb.readByte();
5783            var profile_idc = gb.readByte(); // profile_idc
5784            gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]
5785            var level_idc = gb.readByte(); // level_idc
5786            gb.readUEG(); // seq_parameter_set_id
5787
5788            var profile_string = SPSParser.getProfileString(profile_idc);
5789            var level_string = SPSParser.getLevelString(level_idc);
5790            var chroma_format_idc = 1;
5791            var chroma_format = 420;
5792            var chroma_format_table = [0, 420, 422, 444];
5793            var bit_depth = 8;
5794
5795            if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 || profile_idc === 244 || profile_idc === 44 || profile_idc === 83 || profile_idc === 86 || profile_idc === 118 || profile_idc === 128 || profile_idc === 138 || profile_idc === 144) {
5796
5797                chroma_format_idc = gb.readUEG();
5798                if (chroma_format_idc === 3) {
5799                    gb.readBits(1); // separate_colour_plane_flag
5800                }
5801                if (chroma_format_idc <= 3) {
5802                    chroma_format = chroma_format_table[chroma_format_idc];
5803                }
5804
5805                bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8
5806                gb.readUEG(); // bit_depth_chroma_minus8
5807                gb.readBits(1); // qpprime_y_zero_transform_bypass_flag
5808                if (gb.readBool()) {
5809                    // seq_scaling_matrix_present_flag
5810                    var scaling_list_count = chroma_format_idc !== 3 ? 8 : 12;
5811                    for (var i = 0; i < scaling_list_count; i++) {
5812                        if (gb.readBool()) {
5813                            // seq_scaling_list_present_flag
5814                            if (i < 6) {
5815                                SPSParser._skipScalingList(gb, 16);
5816                            } else {
5817                                SPSParser._skipScalingList(gb, 64);
5818                            }
5819                        }
5820                    }
5821                }
5822            }
5823            gb.readUEG(); // log2_max_frame_num_minus4
5824            var pic_order_cnt_type = gb.readUEG();
5825            if (pic_order_cnt_type === 0) {
5826                gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4
5827            } else if (pic_order_cnt_type === 1) {
5828                gb.readBits(1); // delta_pic_order_always_zero_flag
5829                gb.readSEG(); // offset_for_non_ref_pic
5830                gb.readSEG(); // offset_for_top_to_bottom_field
5831                var num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();
5832                for (var _i = 0; _i < num_ref_frames_in_pic_order_cnt_cycle; _i++) {
5833                    gb.readSEG(); // offset_for_ref_frame
5834                }
5835            }
5836            var ref_frames = gb.readUEG(); // max_num_ref_frames
5837            gb.readBits(1); // gaps_in_frame_num_value_allowed_flag
5838
5839            var pic_width_in_mbs_minus1 = gb.readUEG();
5840            var pic_height_in_map_units_minus1 = gb.readUEG();
5841
5842            var frame_mbs_only_flag = gb.readBits(1);
5843            if (frame_mbs_only_flag === 0) {
5844                gb.readBits(1); // mb_adaptive_frame_field_flag
5845            }
5846            gb.readBits(1); // direct_8x8_inference_flag
5847
5848            var frame_crop_left_offset = 0;
5849            var frame_crop_right_offset = 0;
5850            var frame_crop_top_offset = 0;
5851            var frame_crop_bottom_offset = 0;
5852
5853            var frame_cropping_flag = gb.readBool();
5854            if (frame_cropping_flag) {
5855                frame_crop_left_offset = gb.readUEG();
5856                frame_crop_right_offset = gb.readUEG();
5857                frame_crop_top_offset = gb.readUEG();
5858                frame_crop_bottom_offset = gb.readUEG();
5859            }
5860
5861            var sar_width = 1,
5862                sar_height = 1;
5863            var fps = 0,
5864                fps_fixed = true,
5865                fps_num = 0,
5866                fps_den = 0;
5867
5868            var vui_parameters_present_flag = gb.readBool();
5869            if (vui_parameters_present_flag) {
5870                if (gb.readBool()) {
5871                    // aspect_ratio_info_present_flag
5872                    var aspect_ratio_idc = gb.readByte();
5873                    var sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
5874                    var sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
5875
5876                    if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
5877                        sar_width = sar_w_table[aspect_ratio_idc - 1];
5878                        sar_height = sar_h_table[aspect_ratio_idc - 1];
5879                    } else if (aspect_ratio_idc === 255) {
5880                        sar_width = gb.readByte() << 8 | gb.readByte();
5881                        sar_height = gb.readByte() << 8 | gb.readByte();
5882                    }
5883                }
5884
5885                if (gb.readBool()) {
5886                    // overscan_info_present_flag
5887                    gb.readBool(); // overscan_appropriate_flag
5888                }
5889                if (gb.readBool()) {
5890                    // video_signal_type_present_flag
5891                    gb.readBits(4); // video_format & video_full_range_flag
5892                    if (gb.readBool()) {
5893                        // colour_description_present_flag
5894                        gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients
5895                    }
5896                }
5897                if (gb.readBool()) {
5898                    // chroma_loc_info_present_flag
5899                    gb.readUEG(); // chroma_sample_loc_type_top_field
5900                    gb.readUEG(); // chroma_sample_loc_type_bottom_field
5901                }
5902                if (gb.readBool()) {
5903                    // timing_info_present_flag
5904                    var num_units_in_tick = gb.readBits(32);
5905                    var time_scale = gb.readBits(32);
5906                    fps_fixed = gb.readBool();
5906 // fixed_frame_rate_flag
5907
5908                    fps_num = time_scale;
5909                    fps_den = num_units_in_tick * 2;
5910                    fps = fps_num / fps_den;
5911                }
5912            }
5913
5914            var sarScale = 1;
5915            if (sar_width !== 1 || sar_height !== 1) {
5916                sarScale = sar_width / sar_height;
5917            }
5918
5919            var crop_unit_x = 0,
5920                crop_unit_y = 0;
5921            if (chroma_format_idc === 0) {
5922                crop_unit_x = 1;
5923                crop_unit_y = 2 - frame_mbs_only_flag;
5924            } else {
5925                var sub_wc = chroma_format_idc === 3 ? 1 : 2;
5926                var sub_hc = chroma_format_idc === 1 ? 2 : 1;
5927                crop_unit_x = sub_wc;
5928                crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);
5929            }
5930
5931            var codec_width = (pic_width_in_mbs_minus1 + 1) * 16;
5932            var codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);
5933
5934            codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;
5935            codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;
5936
5937            var present_width = Math.ceil(codec_width * sarScale);
5938
5939            gb.destroy();
5940            gb = null;
5941
5942            return {
5943                profile_string: profile_string, // baseline, high, high10, ...
5944                level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...
5945                bit_depth: bit_depth, // 8bit, 10bit, ...
5946                ref_frames: ref_frames,
5947                chroma_format: chroma_format, // 4:2:0, 4:2:2, ...
5948                chroma_format_string: SPSParser.getChromaFormatString(chroma_format),
5949
5950                frame_rate: {
5951                    fixed: fps_fixed,
5952                    fps: fps,
5953                    fps_den: fps_den,
5954                    fps_num: fps_num
5955                },
5956
5957                sar_ratio: {
5958                    width: sar_width,
5959                    height: sar_height
5960                },
5961
5962                codec_size: {
5963                    width: codec_width,
5964                    height: codec_height
5965                },
5966
5967                present_size: {
5968                    width: present_width,
5969                    height: codec_height
5970                }
5971            };
5972        }
5973    }, {
5974        key: '_skipScalingList',
5975        value: function _skipScalingList(gb, count) {
5976            var last_scale = 8,
5977                next_scale = 8;
5978            var delta_scale = 0;
5979            for (var i = 0; i < count; i++) {
5980                if (next_scale !== 0) {
5981                    delta_scale = gb.readSEG();
5982                    next_scale = (last_scale + delta_scale + 256) % 256;
5983                }
5984                last_scale = next_scale === 0 ? last_scale : next_scale;
5985            }
5986        }
5987    }, {
5988        key: 'getProfileString',
5989        value: function getProfileString(profile_idc) {
5990            switch (profile_idc) {
5991                case 66:
5992                    return 'Baseline';
5993                case 77:
5994                    return 'Main';
5995                case 88:
5996                    return 'Extended';
5997                case 100:
5998                    return 'High';
5999                case 110:
6000                    return 'High10';
6001                case 122:
6002                    return 'High422';
6003                case 244:
6004                    return 'High444';
6005                default:
6006                    return 'Unknown';
6007            }
6008        }
6009    }, {
6010        key: 'getLevelString',
6011        value: function getLevelString(level_idc) {
6012            return (level_idc / 10).toFixed(1);
6013        }
6014    }, {
6015        key: 'getChromaFormatString',
6016        value: function getChromaFormatString(chroma) {
6017            switch (chroma) {
6018                case 420:
6019                    return '4:2:0';
6020                case 422:
6021                    return '4:2:2';
6022                case 444:
6023                    return '4:4:4';
6024                default:
6025                    return 'Unknown';
6026            }
6027        }
6028    }]);
6029
6030    return SPSParser;
6031}();
6032
6033exports.default = SPSParser;
6034
6035},{"./exp-golomb.js":17}],20:[function(_dereq_,module,exports){
6036'use strict';
6037
6038Object.defineProperty(exports, "__esModule", {
6039    value: true
6040});
6041
6042var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /*
6043                                                                                                                                                                                                                                                                               * Copyright (C) 2016 Bilibili. All Rights Reserved.
6044                                                                                                                                                                                                                                                                               *
6045                                                                                                                                                                                                                                                                               * @author zheng qian <[email protected]>
6046                                                                                                                                                                                                                                                                               *
6047                                                                                                                                                                                                                                                                               * Licensed under the Apache License, Version 2.0 (the "License");
6048                                                                                                                                                                                                                                                                               * you may 
6048not use this file except in compliance with the License.
6049                                                                                                                                                                                                                                                                               * You may obtain a copy of the License at
6050                                                                                                                                                                                                                                                                               *
6051                                                                                                                                                                                                                                                                               *     http://www.apache.org/licenses/LICENSE-2.0
6052                                                                                                                                                                                                                                                                               *
6053                                                                                                                                                                                                                                                                               * Unless required by applicable law or agreed to in writing, software
6054                                                                                                                                                                                                                                                                               * distributed under the License is distributed on an "AS IS" BASIS,
6055                                                                                                                                                                                                                                                                               * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6056                                                                                                                                                                                                                                                                               * See the License for the specific language governing permissions and
6057                                                                                                                                                                                                                                                                               * limitations under the License.
6058                                                                                                                                                                                                                                                                               */
6059
6060var _polyfill = _dereq_('./utils/polyfill.js');
6061
6062var _polyfill2 = _interopRequireDefault(_polyfill);
6063
6064var _features = _dereq_('./core/features.js');
6065
6066var _features2 = _interopRequireDefault(_features);
6067
6068var _loader = _dereq_('./io/loader.js');
6069
6070var _flvPlayer = _dereq_('./player/flv-player.js');
6071
6072var _flvPlayer2 = _interopRequireDefault(_flvPlayer);
6073
6074var _nativePlayer = _dereq_('./player/native-player.js');
6075
6076var _nativePlayer2 = _interopRequireDefault(_nativePlayer);
6077
6078var _playerEvents = _dereq_('./player/player-events.js');
6079
6080var _playerEvents2 = _interopRequireDefault(_playerEvents);
6081
6082var _playerErrors = _dereq_('./player/player-errors.js');
6083
6084var _loggingControl = _dereq_('./utils/logging-control.js');
6085
6086var _loggingControl2 = _interopRequireDefault(_loggingControl);
6087
6088var _exception = _dereq_('./utils/exception.js');
6089
6090function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6091
6092// here are all the interfaces
6093
6094// install polyfills
6095_polyfill2.default.install();
6096
6097// factory method
6098function createPlayer(mediaDataSource, optionalConfig) {
6099    var mds = mediaDataSource;
6100    if (mds == null || (typeof mds === 'undefined' ? 'undefined' : _typeof(mds)) !== 'object') {
6101        throw new _exception.InvalidArgumentException('MediaDataSource must be an javascript object!');
6102    }
6103
6104    if (!mds.hasOwnProperty('type')) {
6105        throw new _exception.InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');
6106    }
6107
6108    switch (mds.type) {
6109        case 'flv':
6110            return new _flvPlayer2.default(mds, optionalConfig);
6111        default:
6112            return new _nativePlayer2.default(mds, optionalConfig);
6113    }
6114}
6115
6116// feature detection
6117function isSupported() {
6118    return _features2.default.supportMSEH264Playback();
6119}
6120
6121function getFeatureList() {
6122    return _features2.default.getFeatureList();
6123}
6124
6125// interfaces
6126var flvjs = {};
6127
6128flvjs.createPlayer = createPlayer;
6129flvjs.isSupported = isSupported;
6130flvjs.getFeatureList = getFeatureList;
6131
6132flvjs.BaseLoader = _loader.BaseLoader;
6133flvjs.LoaderStatus = _loader.LoaderStatus;
6134flvjs.LoaderErrors = _loader.LoaderErrors;
6135
6136flvjs.Events = _playerEvents2.default;
6137flvjs.ErrorTypes = _playerErrors.ErrorTypes;
6138flvjs.ErrorDetails = _playerErrors.ErrorDetails;
6139
6140flvjs.FlvPlayer = _flvPlayer2.default;
6141flvjs.NativePlayer = _nativePlayer2.default;
6142flvjs.LoggingControl = _loggingControl2.default;
6143
6144Object.defineProperty(flvjs, 'version', {
6145    enumerable: true,
6146    get: function get() {
6147        // replaced by browserify-versionify transform
6148        return '1.5.0';
6149    }
6150});
6151
6152exports.default = flvjs;
6153
6154},{"./core/features.js":6,"./io/loader.js":24,"./player/flv-player.js":32,"./player/native-player.js":33,"./player/player-errors.js":34,"./player/player-events.js":35,"./utils/exception.js":40,"./utils/logging-control.js":42,"./utils/polyfill.js":43}],21:[function(_dereq_,module,exports){
6155'use strict';
6156
6157// entry/index file
6158
6159// make it compatible with browserify's umd wrapper
6160module.exports = _dereq_('./flv.js').default;
6161
6162},{"./flv.js":20}],22:[function(_dereq_,module,exports){
6163'use strict';
6164
6165Object.defineProperty(exports, "__esModule", {
6166    value: true
6167});
6168
6169var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
6170
6171var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
6172
6173var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
6174
6175var _logger = _dereq_('../utils/logger.js');
6176
6177var _logger2 = _interopRequireDefault(_logger);
6178
6179var _browser = _dereq_('../utils/browser.js');
6180
6181var _browser2 = _interopRequireDefault(_browser);
6182
6183var _loader = _dereq_('./loader.js');
6184
6185var _exception = _dereq_('../utils/exception.js');
6186
6187function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6188
6189function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6190
6191function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6192
6193function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
6193onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
6194                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (C) 2016 Bilibili. All Rights Reserved.
6195                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
6196                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * @author zheng qian <[email protected]>
6197                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
6198                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Licensed under the Apache License, Version 2.0 (the "License");
6199                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * you may not use this file except in compliance with the License.
6200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * You may obtain a copy of the License at
6201                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
6202                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *     http://www.apache.org/licenses/LICENSE-2.0
6203                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
6204                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Unless required by applicable law or agreed to in writing, softw
6204are
6205                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * distributed under the License is distributed on an "AS IS" BASIS,
6206                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6207                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * See the License for the specific language governing permissions and
6208                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * limitations under the License.
6209                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */
6210
6211/* fetch + stream IO loader. Currently working on chrome 43+.
6212 * fetch provides a better alternative http API to XMLHttpRequest
6213 *
6214 * fetch spec   https://fetch.spec.whatwg.org/
6215 * stream spec  https://streams.spec.whatwg.org/
6216 */
6217var FetchStreamLoader = function (_BaseLoader) {
6218    _inherits(FetchStreamLoader, _BaseLoader);
6219
6220    _createClass(FetchStreamLoader, null, [{
6221        key: 'isSupported',
6222        value: function isSupported() {
6223            try {
6224                // fetch + stream is broken on Microsoft Edge. Disable before build 15048.
6225                // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/
6226                // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.
6227                var isWorkWellEdge = _browser2.default.msedge && _browser2.default.version.minor >= 15048;
6228                var browserNotBlacklisted = _browser2.default.msedge ? isWorkWellEdge : true;
6229                return self.fetch && self.ReadableStream && browserNotBlacklisted;
6230            } catch (e) {
6231                return false;
6232            }
6233        }
6234    }]);
6235
6236    function FetchStreamLoader(seekHandler, config) {
6237        _classCallCheck(this, FetchStreamLoader);
6238
6239        var _this = _possibleConstructorReturn(this, (FetchStreamLoader.__proto__ || Object.getPrototypeOf(FetchStreamLoader)).call(this, 'fetch-stream-loader'));
6240
6241        _this.TAG = 'FetchStreamLoader';
6242
6243        _this._seekHandler = seekHandler;
6244        _this._config = config;
6245        _this._needStash = true;
6246
6247        _this._requestAbort = false;
6248        _this._contentLength = null;
6249        _this._receivedLength = 0;
6250        return _this;
6251    }
6252
6253    _createClass(FetchStreamLoader, [{
6254        key: 'destroy',
6255        value: function destroy() {
6256            if (this.isWorking()) {
6257                this.abort();
6258            }
6259            _get(FetchStreamLoader.prototype.__proto__ || Object.getPrototypeOf(FetchStreamLoader.prototype), 'destroy', this).call(this);
6260        }
6261    }, {
6262        key: 'open',
6263        value: function open(dataSource, range) {
6264            var _this2 = this;
6265
6266            this._dataSource = dataSource;
6267            this._range = range;
6268
6269            var sourceURL = dataSource.url;
6270            if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {
6271                sourceURL = dataSource.redirectedURL;
6272            }
6273
6274            var seekConfig = this._seekHandler.getConfig(sourceURL, range);
6275
6276            var headers = new self.Headers();
6277
6278            if (_typeof(seekConfig.headers) === 'object') {
6279                var configHeaders = seekConfig.headers;
6280                for (var key in configHeaders) {
6281                    if (configHeaders.hasOwnProperty(key)) {
6282                        headers.append(key, configHeaders[key]);
6283                    }
6284                }
6285            }
6286
6287            var params = {
6288                method: 'GET',
6289                headers: headers,
6290                mode: 'cors',
6291                cache: 'default',
6292                // The default policy of Fetch API in the whatwg standard
6293                // Safari incorrectly indicates 'no-referrer' as default policy, fuck it
6294                referrerPolicy: 'no-referrer-when-downgrade'
6295            };
6296
6297            // add additional headers
6298            if (_typeof(this._config.headers) === 'object') {
6299                for (var _key in this._config.headers) {
6300                    headers.append(_key, this._config.headers[_key]);
6301                }
6302            }
6303
6304            // cors is enabled by default
6305            if (dataSource.cors === false) {
6306                // no-cors means 'disregard cors policy', which can only be used in ServiceWorker
6307                params.mode = 'same-origin';
6308            }
6309
6310            // withCredentials is disabled by default
6311            if (dataSource.withCredentials) {
6312                params.credentials = 'include';
6313            }
6314
6315            // referrerPolicy from config
6316            if (dataSource.referrerPolicy) {
6317                params.referrerPolicy = dataSource.referrerPolicy;
6318            }
6319
6320            this._status = _loader.LoaderStatus.kConnecting;
6321            self.fetch(seekConfig.url, params).then(function (res) {
6322                if (_this2._requestAbort) {
6323                    _this2._requestAbort = false;
6324                    _this2._status = _loader.LoaderStatus.kIdle;
6325                    return;
6326                }
6327                if (res.ok && res.status >= 200 && res.status <= 299) {
6328                    if (res.url !== seekConfig.url) {
6329                        if (_this2._onURLRedirect) {
6330                            var redirectedURL = _this2._seekHandler.removeURLParameters(res.url);
6331                            _this2._onURLRedirect(redirectedURL);
6332                        }
6333                    }
6334
6335                    var lengthHeader = res.headers.get('Content-Length');
6336                    if (lengthHeader != null) {
6337                        _this2._contentLength = parseInt(lengthHeader);
6338                        if (_this2._contentLength !== 0) {
6339                            if (_this2._onContentLengthKnown) {
6340                                _this2._onContentLengthKnown(_this2._contentLength);
6341                            }
6342                        }
6343                    }
6344
6345                    return _this2._pump.call(_this2, res.body.getReader());
6346                } else {
6347                    _this2._status = _loader.LoaderStatus.kError;
6348                    if (_this2._onError) {
6349                        _this2._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: res.status, msg: res.statusText });
6350                    } else {
6351                        throw new _exception.RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);
6352                    }
6353                }
6354            }).catch(function (e) {
6355                _this2._status = _loader.LoaderStatus.kError;
6356                if (_this2._onError) {
6357                    _this2._onError(_loader.LoaderErrors.EXCEPTION, { code: -1, msg: e.message });
6358                } else {
6359                    throw e;
6360                }
6361            });
6362        }
6363    }, {
6364        key: 'abort',
6365        value: function abort() {
6366            this._requestAbort = true;
6367        }
6368    }, {
6369        key: '_pump',
6370        value: function _pump(reader) {
6371            var _this3 = this;
6372
6373            // ReadableStreamReader
6374            return reader.read().then(function (result) {
6375                if (result.done) {
6376                    // First check received length
6377                    if (_this3._contentLength !== null && _this3._receivedLength < _this3._contentLength) {
6378                        // Report Early-EOF
6379                        _this3._status = _loader.LoaderStatus.kError;
6380                        var type = _loader.LoaderErrors.EARLY_EOF;
6381                        var info = { code: -1, msg: 'Fetch stream meet Early-EOF' };
6382                        if (_this3._onError) {
6383                            _this3._onError(type, info);
6384                        } else {
6385                            throw new _exception.RuntimeException(info.msg);
6386                        }
6387                    } else {
6388                        // OK. Download complete
6389                        _this3._status = _loader.LoaderStatus.kComplete;
6390                        if (_this3._onComplete) {
6391                            _this3._onComplete(_this3._range.from, _this3._range.from + _this3._receivedLength - 1);
6392                        }
6393                    }
6394                } else {
6395                    if (_this3._requestAbort === true) {
6396                        _this3._requestAbort = false;
6397                        _this3._status = _loader.LoaderStatus.kComplete;
6398                        return reader.cancel();
6399                    }
6400
6401                    _this3._status = _loader.LoaderStatus.kBuffering;
6402
6403                    var chunk = result.value.buffer;
6404                    var byteStart = _this3._range.from + _this3._receivedLength;
6405                    _this3._receivedLength += chunk.byteLength;
6406
6407                    if (_this3._onDataArrival) {
6408                        _this3._onDataArrival(chunk, byteStart, _this3._receivedLength);
6409                    }
6410
6411                    _this3._pump(reader);
6412                }
6413            }).catch(function (e) {
6414                if (e.code === 11 && _browser2.default.msedge) {
6415                    // InvalidStateError on Microsoft Edge
6416                    // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call
6417                    // Ignore the unknown exception.
6418                    // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/
6419                    return;
6420                }
6421
6422                _this3._status = _loader.LoaderStatus.kError;
6423                var type = 0;
6424                var info = null;
6425
6426                if ((e.code === 19 || e.message === 'network error') && ( // NETWORK_ERR
6427                _this3._contentLength === null || _this3._contentLength !== null && _this3._receivedLength < _this3._contentLength)) {
6428                    type = _loader.LoaderErrors.EARLY_EOF;
6429                    info = { code: e.code, msg: 'Fetch stream meet Early-EOF' };
6430                } else {
6431                    type = _loader.LoaderErrors.EXCEPTION;
6432                    info = { code: e.code, msg: e.message };
6433                }
6434
6435                if (_this3._onError) {
6436                    _this3._onError(type, info);
6437                } else {
6438                    throw new _exception.RuntimeException(info.msg);
6439                }
6440            });
6441        }
6442    }]);
6443
6444    return FetchStreamLoader;
6445}(_loader.BaseLoader);
6446
6447exports.default = FetchStreamLoader;
6448
6449},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],23:[function(_dereq_,module,exports){
6450'use strict';
6451
6452Object.defineProperty(exports, "__esModule", {
6453    value: true
6454});
6455
6456var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
6457                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
6458                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
6459                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
6460                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
6461                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
6462                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
6462not use this file except in compliance with the License.
6463                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
6464                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
6465                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
6466                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
6467                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
6468                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
6469                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6470                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
6471                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
6472                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
6473
6474var _logger = _dereq_('../utils/logger.js');
6475
6476var _logger2 = _interopRequireDefault(_logger);
6477
vendor: 4,348 bytes, lines 6478-6613
6478var _speedSampler = _dereq_('./speed-sampler.js');
6479
6480var _speedSampler2 = _interopRequireDefault(_speedSampler);
6481
6482var _loader = _dereq_('./loader.js');
6483
6484var _fetchStreamLoader = _dereq_('./fetch-stream-loader.js');
6485
6486var _fetchStreamLoader2 = _interopRequireDefault(_fetchStreamLoader);
6487
6488var _xhrMozChunkedLoader = _dereq_('./xhr-moz-chunked-loader.js');
6489
6490var _xhrMozChunkedLoader2 = _interopRequireDefault(_xhrMozChunkedLoader);
6491
6492var _xhrMsstreamLoader = _dereq_('./xhr-msstream-loader.js');
6493
6494var _xhrMsstreamLoader2 = _interopRequireDefault(_xhrMsstreamLoader);
6495
6496var _xhrRangeLoader = _dereq_('./xhr-range-loader.js');
6497
6498var _xhrRangeLoader2 = _interopRequireDefault(_xhrRangeLoader);
6499
6500var _websocketLoader = _dereq_('./websocket-loader.js');
6501
6502var _websocketLoader2 = _interopRequireDefault(_websocketLoader);
6503
6504var _rangeSeekHandler = _dereq_('./range-seek-handler.js');
6505
6506var _rangeSeekHandler2 = _interopRequireDefault(_rangeSeekHandler);
6507
6508var _paramSeekHandler = _dereq_('./param-seek-handler.js');
6509
6510var _paramSeekHandler2 = _interopRequireDefault(_paramSeekHandler);
6511
6512var _exception = _dereq_('../utils/exception.js');
6513
6514function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6515
6516function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6517
6518/**
6519 * DataSource: {
6520 *     url: string,
6521 *     filesize: number,
6522 *     cors: boolean,
6523 *     withCredentials: boolean
6524 * }
6525 * 
6526 */
6527
6528// Manage IO Loaders
6529var IOController = function () {
6530    function IOController(dataSource, config, extraData) {
6531        _classCallCheck(this, IOController);
6532
6533        this.TAG = 'IOController';
6534
6535        this._config = config;
6536        this._extraData = extraData;
6537
6538        this._stashInitialSize = 1024 * 384; // default initial size: 384KB
6539        if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {
6540            // apply from config
6541            this._stashInitialSize = config.stashInitialSize;
6542        }
6543
6544        this._stashUsed = 0;
6545        this._stashSize = this._stashInitialSize;
6546        this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB
6547        this._stashBuffer = new ArrayBuffer(this._bufferSize);
6548        this._stashByteStart = 0;
6549        this._enableStash = true;
6550        if (config.enableStashBuffer === false) {
6551            this._enableStash = false;
6552        }
6553
6554        this._loader = null;
6555        this._loaderClass = null;
6556        this._seekHandler = null;
6557
6558        this._dataSource = dataSource;
6559        this._isWebSocketURL = /wss?:\/\/(.+?)/.test(dataSource.url);
6560        this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;
6561        this._totalLength = this._refTotalLength;
6562        this._fullRequestFlag = false;
6563        this._currentRange = null;
6564        this._redirectedURL = null;
6565
6566        this._speedNormalized = 0;
6567        this._speedSampler = new _speedSampler2.default();
6568        this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];
6569
6570        this._isEarlyEofReconnecting = false;
6571
6572        this._paused = false;
6573        this._resumeFrom = 0;
6574
6575        this._onDataArrival = null;
6576        this._onSeeked = null;
6577        this._onError = null;
6578        this._onComplete = null;
6579        this._onRedirect = null;
6580        this._onRecoveredEarlyEof = null;
6581
6582        this._selectSeekHandler();
6583        this._selectLoader();
6584        this._createLoader();
6585    }
6586
6587    _createClass(IOController, [{
6588        key: 'destroy',
6589        value: function destroy() {
6590            if (this._loader.isWorking()) {
6591                this._loader.abort();
6592            }
6593            this._loader.destroy();
6594            this._loader = null;
6595            this._loaderClass = null;
6596            this._dataSource = null;
6597            this._stashBuffer = null;
6598            this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;
6599            this._currentRange = null;
6600            this._speedSampler = null;
6601
6602            this._isEarlyEofReconnecting = false;
6603
6604            this._onDataArrival = null;
6605            this._onSeeked = null;
6606            this._onError = null;
6607            this._onComplete = null;
6608            this._onRedirect = null;
6609            this._onRecoveredEarlyEof = null;
6610
6611            this._extraData = null;
6612        }
6613    }, {
6614        key: 'isWorking',
6615        value: function isWorking() {
6616            return this._loader && this._loader.isWorking() && !this._paused;
6617        }
6618    }, {
6619        key: 'isPaused',
6620        value: function isPaused() {
6621            return this._paused;
6622        }
6623    }, {
6624        key: '_selectSeekHandler',
6625        value: function _selectSeekHandler() {
6626            var config = this._config;
6627
6628            if (config.seekType === 'range') {
6629                this._seekHandler = new _rangeSeekHandler2.default(this._config.rangeLoadZeroStart);
6630            } else if (config.seekType === 'param') {
6631                var paramStart = config.seekParamStart || 'bstart';
6632                var paramEnd = config.seekParamEnd || 'bend';
6633
6634                this._seekHandler = new _paramSeekHandler2.default(paramStart, paramEnd);
6635            } else if (config.seekType === 'custom') {
6636                if (typeof config.customSeekHandler !== 'function') {
6637                    throw new _exception.InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');
6638                }
6639                this._seekHandler = new config.customSeekHandler();
6640            } else {
6641                throw new _exception.InvalidArgumentException('Invalid seekType in config: ' + config.seekType);
6642            }
6643        }
6644    }, {
6645        key: '_selectLoader',
6646        value: function _selectLoader() {
6647            if (this._config.customLoader != null) {
6648                this._loaderClass = this._config.customLoader;
6649            } else if (this._isWebSocketURL) {
6650                this._loaderClass = _websocketLoader2.default;
6651            } else if (_fetchStreamLoader2.default.isSupported()) {
6652                this._loaderClass = _fetchStreamLoader2.default;
6653            } else if (_xhrMozChunkedLoader2.default.isSupported()) {
6654                this._loaderClass = _xhrMozChunkedLoader2.default;
6655            } else if (_xhrRangeLoader2.default.isSupported()) {
6656                this._loaderClass = _xhrRangeLoader2.default;
6657            } else {
6658                throw new _exception.RuntimeException('Your browser doesn\'t support xhr with arraybuffer responseType!');
6659            }
6660        }
6661    }, {
6662        key: '_createLoader',
6663        value: function _createLoader() {
6664            this._loader = new this._loaderClass(this._seekHandler, this._config);
6665            if (this._loader.needStashBuffer === false) {
6666                this._enableStash = false;
6667            }
6668            this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);
6669            this._loader.onURLRedirect = this._onURLRedirect.bind(this);
6670            this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);
6671            this._loader.onComplete = this._onLoaderComplete.bind(this);
6672            this._loader.onError = this._onLoaderError.bind(this);
6673        }
6674    }, {
6675        key: 'open',
6676        value: function open(optionalFrom) {
6677            this._currentRange = { from: 0, to: -1 };
6678            if (optionalFrom) {
6679                this._currentRange.from = optionalFrom;
6680            }
6681
6682            this._speedSampler.reset();
6683            if (!optionalFrom) {
6684                this._fullRequestFlag = true;
6685            }
6686
6687            this._loader.open(this._dataSource, Object.assign({}, this._currentRange));
6688        }
6689    }, {
6690        key: 'abort',
6691        value: function abort() {
6692            this._loader.abort();
6693
6694            if (this._paused) {
6695                this._paused = false;
6696                this._resumeFrom = 0;
6697            }
6698        }
6699    }, {
6700        key: 'pause',
6701        value: function pause() {
6702            if (this.isWorking()) {
6703                this._loader.abort();
6704
6705                if (this._stashUsed !== 0) {
6706                    this._resumeFrom = this._stashByteStart;
6707                    this._currentRange.to = this._stashByteStart - 1;
6708                } else {
6709                    this._resumeFrom = this._currentRange.to + 1;
6710                }
6711                this._stashUsed = 0;
6712                this._stashByteStart = 0;
6713                this._paused = true;
6714            }
6715        }
6716    }, {
6717        key: 'resume',
6718        value: function resume() {
6719            if (this._paused) {
6720                this._paused = false;
6721                var bytes = this._resumeFrom;
6722                this._resumeFrom = 0;
6723                this._internalSeek(bytes, true);
6724            }
6725        }
6726    }, {
6727        key: 'seek',
6728        value: function seek(bytes) {
6729            this._paused = false;
6730            this._stashUsed = 0;
6731            this._stashByteStart = 0;
6732            this._internalSeek(bytes, true);
6733        }
6734
6735        /**
6736         * When seeking request is from media seeking, unconsumed stash data should be dropped
6737         * However, stash data shouldn't be dropped if seeking requested from http reconnection
6738         *
6739         * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer
6740         */
6741
6742    }, {
6743        key: '_internalSeek',
6744        value: function _internalSeek(bytes, dropUnconsumed) {
6745            if (this._loader.isWorking()) {
6746                this._loader.abort();
6747            }
6748
6749            // dispatch & flush stash buffer before seek
6750            this._flushStashBuffer(dropUnconsumed);
6751
6752            this._loader.destroy();
6753            this._loader = null;
6754
6755            var requestRange = { from: bytes, to: -1 };
6756            this._currentRange = { from: requestRange.from, to: -1 };
6757
6758            this._speedSampler.reset();
6759            this._stashSize = this._stashInitialSize;
6760            this._createLoader();
6761            this._loader.open(this._dataSource, requestRange);
6762
6763            if (this._onSeeked) {
6764                this._onSeeked();
6765            }
6766        }
6767    }, {
6768        key: 'updateUrl',
6769        value: function updateUrl(url) {
6770            if (!url || typeof url !== 'string' || url.length === 0) {
6771                throw new _exception.InvalidArgumentException('Url must be a non-empty string!');
6772            }
6773
6774            this._dataSource.url = url;
6775
6776            // TODO: replace with new url
6777        }
6778    }, {
6779        key: '_expandBuffer',
6780        value: function _expandBuffer(expectedBytes) {
6781            var bufferNewSize = this._stashSize;
6782            while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {
6783                bufferNewSize *= 2;
6784            }
6785
6786            bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB
6787            if (bufferNewSize === this._bufferSize) {
6788                return;
6789            }
6790
6791            var newBuffer = new ArrayBuffer(bufferNewSize);
6792
6793            if (this._stashUsed > 0) {
6794                // copy existing data into new buffer
6795                var stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);
6796                var stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);
6797                stashNewArray.set(stashOldArray, 0);
6798            }
6799
6800            this._stashBuffer = newBuffer;
6801            this._bufferSize = bufferNewSize;
6802        }
6803    }, {
6804        key: '_normalizeSpeed',
6805        value: function _normalizeSpeed(input) {
6806            var list = this._speedNormalizeList;
6807            var last = list.length - 1;
6808            var mid = 0;
6809            var lbound = 0;
6810            var ubound = last;
6811
6812            if (input < list[0]) {
6813                return list[0];
6814            }
6815
6816            // binary search
6817            while (lbound <= ubound) {
6818                mid = lbound + Math.floor((ubound - lbound) / 2);
6819                if (mid === last || input >= list[mid] && input < list[mid + 1]) {
6820                    return list[mid];
6821                } else if (list[mid] < input) {
6822                    lbound = mid + 1;
6823                } else {
6824                    ubound = mid - 1;
6825                }
6826            }
6827        }
6828    }, {
6829        key: '_adjustStashSize',
6830        value: function _adjustStashSize(normalized) {
6831            var stashSizeKB = 0;
6832
6833            if (this._config.isLive) {
6834                // live stream: always use single normalized speed for size of stashSizeKB
6835                stashSizeKB = normalized;
6836            } else {
6837                if (normalized < 512) {
6838                    stashSizeKB = normalized;
6839                } else if (normalized >= 512 && normalized <= 1024) {
6840                    stashSizeKB = Math.floor(normalized * 1.5);
6841                } else {
6842                    stashSizeKB = normalized * 2;
6843                }
6844            }
6845
6846            if (stashSizeKB > 8192) {
6847                stashSizeKB = 8192;
6848            }
6849
6850            var bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB
6851            if (this._bufferSize < bufferSize) {
6852                this._expandBuffer(bufferSize);
6853            }
6854            this._stashSize = stashSizeKB * 1024;
6855        }
6856    }, {
vendor: 11,052 bytes, lines 6857-7081
6857        key: '_dispatchChunks',
6858        value: function _dispatchChunks(chunks, byteStart) {
6859            this._currentRange.to = byteStart + chunks.byteLength - 1;
6860            return this._onDataArrival(chunks, byteStart);
6861        }
6862    }, {
6863        key: '_onURLRedirect',
6864        value: function _onURLRedirect(redirectedURL) {
6865            this._redirectedURL = redirectedURL;
6866            if (this._onRedirect) {
6867                this._onRedirect(redirectedURL);
6868            }
6869        }
6870    }, {
6871        key: '_onContentLengthKnown',
6872        value: function _onContentLengthKnown(contentLength) {
6873            if (contentLength && this._fullRequestFlag) {
6874                this._totalLength = contentLength;
6875                this._fullRequestFlag = false;
6876            }
6877        }
6878    }, {
6879        key: '_onLoaderChunkArrival',
6880        value: function _onLoaderChunkArrival(chunk, byteStart, receivedLength) {
6881            if (!this._onDataArrival) {
6882                throw new _exception.IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');
6883            }
6884            if (this._paused) {
6885                return;
6886            }
6887            if (this._isEarlyEofReconnecting) {
6888                // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback
6889                this._isEarlyEofReconnecting = false;
6890                if (this._onRecoveredEarlyEof) {
6891                    this._onRecoveredEarlyEof();
6892                }
6893            }
6894
6895            this._speedSampler.addBytes(chunk.byteLength);
6896
6897            // adjust stash buffer size according to network speed dynamically
6898            var KBps = this._speedSampler.lastSecondKBps;
6899            if (KBps !== 0) {
6900                var normalized = this._normalizeSpeed(KBps);
6901                if (this._speedNormalized !== normalized) {
6902                    this._speedNormalized = normalized;
6903                    this._adjustStashSize(normalized);
6904                }
6905            }
6906
6907            if (!this._enableStash) {
6908                // disable stash
6909                if (this._stashUsed === 0) {
6910                    // dispatch chunk directly to consumer;
6911                    // check ret value (consumed bytes) and stash unconsumed to stashBuffer
6912                    var consumed = this._dispatchChunks(chunk, byteStart);
6913                    if (consumed < chunk.byteLength) {
6914                        // unconsumed data remain.
6915                        var remain = chunk.byteLength - consumed;
6916                        if (remain > this._bufferSize) {
6917                            this._expandBuffer(remain);
6918                        }
6919                        var stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
6920                        stashArray.set(new Uint8Array(chunk, consumed), 0);
6921                        this._stashUsed += remain;
6922                        this._stashByteStart = byteStart + consumed;
6923                    }
6924                } else {
6925                    // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.
6926                    if (this._stashUsed + chunk.byteLength > this._bufferSize) {
6927                        this._expandBuffer(this._stashUsed + chunk.byteLength);
6928                    }
6929                    var _stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
6930                    _stashArray.set(new Uint8Array(chunk), this._stashUsed);
6931                    this._stashUsed += chunk.byteLength;
6932                    var _consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);
6933                    if (_consumed < this._stashUsed && _consumed > 0) {
6934                        // unconsumed data remain
6935                        var remainArray = new Uint8Array(this._stashBuffer, _consumed);
6936                        _stashArray.set(remainArray, 0);
6937                    }
6938                    this._stashUsed -= _consumed;
6939                    this._stashByteStart += _consumed;
6940                }
6941            } else {
6942                // enable stash
6943                if (this._stashUsed === 0 && this._stashByteStart === 0) {
6944                    // seeked? or init chunk?
6945                    // This is the first chunk after seek action
6946                    this._stashByteStart = byteStart;
6947                }
6948                if (this._stashUsed + chunk.byteLength <= this._stashSize) {
6949                    // just stash
6950                    var _stashArray2 = new Uint8Array(this._stashBuffer, 0, this._stashSize);
6951                    _stashArray2.set(new Uint8Array(chunk), this._stashUsed);
6952                    this._stashUsed += chunk.byteLength;
6953                } else {
6954                    // stashUsed + chunkSize > stashSize, size limit exceeded
6955                    var _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
6956                    if (this._stashUsed > 0) {
6957                        // There're stash datas in buffer
6958                        // dispatch the whole stashBuffer, and stash remain data
6959                        // then append chunk to stashBuffer (stash)
6960                        var buffer = this._stashBuffer.slice(0, this._stashUsed);
6961                        var _consumed2 = this._dispatchChunks(buffer, this._stashByteStart);
6962                        if (_consumed2 < buffer.byteLength) {
6963                            if (_consumed2 > 0) {
6964                                var _remainArray = new Uint8Array(buffer, _consumed2);
6965                                _stashArray3.set(_remainArray, 0);
6966                                this._stashUsed = _remainArray.byteLength;
6967                                this._stashByteStart += _consumed2;
6968                            }
6969                        } else {
6970                            this._stashUsed = 0;
6971                            this._stashByteStart += _consumed2;
6972                        }
6973                        if (this._stashUsed + chunk.byteLength > this._bufferSize) {
6974                            this._expandBuffer(this._stashUsed + chunk.byteLength);
6975                            _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
6976                        }
6977                        _stashArray3.set(new Uint8Array(chunk), this._stashUsed);
6978                        this._stashUsed += chunk.byteLength;
6979                    } else {
6980                        // stash buffer empty, but chunkSize > stashSize (oh, holy shit)
6981                        // dispatch chunk directly and stash remain data
6982                        var _consumed3 = this._dispatchChunks(chunk, byteStart);
6983                        if (_consumed3 < chunk.byteLength) {
6984                            var _remain = chunk.byteLength - _consumed3;
6985                            if (_remain > this._bufferSize) {
6986                                this._expandBuffer(_remain);
6987                                _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
6988                            }
6989                            _stashArray3.set(new Uint8Array(chunk, _consumed3), 0);
6990                            this._stashUsed += _remain;
6991                            this._stashByteStart = byteStart + _consumed3;
6992                        }
6993                    }
6994                }
6995            }
6996        }
6997    }, {
6998        key: '_flushStashBuffer',
6999        value: function _flushStashBuffer(dropUnconsumed) {
7000            if (this._stashUsed > 0) {
7001                var buffer = this._stashBuffer.slice(0, this._stashUsed);
7002                var consumed = this._dispatchChunks(buffer, this._stashByteStart);
7003                var remain = buffer.byteLength - consumed;
7004
7005                if (consumed < buffer.byteLength) {
7006                    if (dropUnconsumed) {
7007                        _logger2.default.w(this.TAG, remain + ' bytes unconsumed data remain when flush buffer, dropped');
7008                    } else {
7009                        if (consumed > 0) {
7010                            var stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
7011                            var remainArray = new Uint8Array(buffer, consumed);
7012                            stashArray.set(remainArray, 0);
7013                            this._stashUsed = remainArray.byteLength;
7014                            this._stashByteStart += consumed;
7015                        }
7016                        return 0;
7017                    }
7018                }
7019                this._stashUsed = 0;
7020                this._stashByteStart = 0;
7021                return remain;
7022            }
7023            return 0;
7024        }
7025    }, {
7026        key: '_onLoaderComplete',
7027        value: function _onLoaderComplete(from, to) {
7028            // Force-flush stash buffer, and drop unconsumed data
7029            this._flushStashBuffer(true);
7030
7031            if (this._onComplete) {
7032                this._onComplete(this._extraData);
7033            }
7034        }
7035    }, {
7036        key: '_onLoaderError',
7037        value: function _onLoaderError(type, data) {
7038            _logger2.default.e(this.TAG, 'Loader error, code = ' + data.code + ', msg = ' + data.msg);
7039
7040            this._flushStashBuffer(false);
7041
7042            if (this._isEarlyEofReconnecting) {
7043                // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer
7044                this._isEarlyEofReconnecting = false;
7045                type = _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF;
7046            }
7047
7048            switch (type) {
7049                case _loader.LoaderErrors.EARLY_EOF:
7050                    {
7051                        if (!this._config.isLive) {
7052                            // Do internal http reconnect if not live stream
7053                            if (this._totalLength) {
7054                                var nextFrom = this._currentRange.to + 1;
7055                                if (nextFrom < this._totalLength) {
7056                                    _logger2.default.w(this.TAG, 'Connection lost, trying reconnect...');
7057                                    this._isEarlyEofReconnecting = true;
7058                                    this._internalSeek(nextFrom, false);
7059                                }
7060                                return;
7061                            }
7062                            // else: We don't know totalLength, throw UnrecoverableEarlyEof
7063                        }
7064                        // live stream: throw UnrecoverableEarlyEof error to upper-layer
7065                        type = _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF;
7066                        break;
7067                    }
7068                case _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF:
7069                case _loader.LoaderErrors.CONNECTING_TIMEOUT:
7070                case _loader.LoaderErrors.HTTP_STATUS_CODE_INVALID:
7071                case _loader.LoaderErrors.EXCEPTION:
7072                    break;
7073            }
7074
7075            if (this._onError) {
7076                this._onError(type, data);
7077            } else {
7078                throw new _exception.RuntimeException('IOException: ' + data.msg);
7079            }
7080        }
7081    }, {
7082        key: 'status',
7083        get: function get() {
7084            return this._loader.status;
7085        }
7086    }, {
7087        key: 'extraData',
7088        get: function get() {
7089            return this._extraData;
7090        },
7091        set: function set(data) {
7092            this._extraData = data;
7093        }
7094
7095        // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number
7096
7097    }, {
7098        key: 'onDataArrival',
7099        get: function get() {
7100            return this._onDataArrival;
7101        },
7102        set: function set(callback) {
7103            this._onDataArrival = callback;
7104        }
7105    }, {
7106        key: 'onSeeked',
7107        get: function get() {
7108            return this._onSeeked;
7109        },
7110        set: function set(callback) {
7111            this._onSeeked = callback;
7112        }
7113
7114        // prototype: function onError(type: number, info: {code: number, msg: string}): void
7115
7116    }, {
7117        key: 'onError',
7118        get: function get() {
7119            return this._onError;
7120        },
7121        set: function set(callback) {
7122            this._onError = callback;
7123        }
7124    }, {
7125        key: 'onComplete',
7126        get: function get() {
7127            return this._onComplete;
7128        },
7129        set: function set(callback) {
7130            this._onComplete = callback;
7131        }
7132    }, {
7133        key: 'onRedirect',
7134        get: function get() {
7135            return this._onRedirect;
7136        },
7137        set: function set(callback) {
7138            this._onRedirect = callback;
7139        }
7140    }, {
7141        key: 'onRecoveredEarlyEof',
7142        get: function get() {
7143            return this._onRecoveredEarlyEof;
7144        },
7145        set: function set(callback) {
7146            this._onRecoveredEarlyEof = callback;
7147        }
7148    }, {
7149        key: 'currentURL',
7150        get: function get() {
7151            return this._dataSource.url;
7152        }
7153    }, {
7154        key: 'hasRedirect',
7155        get: function get() {
7156            return this._redirectedURL != null || this._dataSource.redirectedURL != undefined;
7157        }
7158    }, {
7159        key: 'currentRedirectedURL',
7160        get: function get() {
7161            return this._redirectedURL || this._dataSource.redirectedURL;
7162        }
7163
7164        // in KB/s
7165
7166    }, {
7167        key: 'currentSpeed',
7168        get: function get() {
7169            if (this._loaderClass === _xhrRangeLoader2.default) {
7170                // SpeedSampler is inaccuracy if loader is RangeLoader
7171                return this._loader.currentSpeed;
7172            }
7173            return this._speedSampler.lastSecondKBps;
7174        }
7175    }, {
7176        key: 'loaderType',
7177        get: function get() {
7178            return this._loader.type;
7179        }
7180    }]);
7181
7182    return IOController;
7183}();
7184
7185exports.default = IOController;
7186
7187},{"../utils/exception.js":40,"../utils/logger.js":41,"./fetch-stream-loader.js":22,"./loader.js":24,"./param-seek-handler.js":25,"./range-seek-handler.js":26,"./speed-sampler.js":27,"./websocket-loader.js":28,"./xhr-moz-chunked-loader.js":29,"./xhr-msstream-loader.js":30,"./xhr-range-loader.js":31}],24:[function(_dereq_,module,exports){
7188'use strict';
7189
7190Object.defineProperty(exports, "__esModule", {
7191    value: true
7192});
7193exports.BaseLoader = exports.LoaderErrors = exports.LoaderStatus = undefined;
7194
7195var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
7196                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
7197                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
7198                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
7199                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
7200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
7201                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
7201not use this file except in compliance with the License.
7202                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
7203                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
7204                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
7205                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
7206                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
7207                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
7208                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7209                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
7210                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
7211                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
7212
7213var _exception = _dereq_('../utils/exception.js');
7214
7215function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7216
7217var LoaderStatus = exports.LoaderStatus = {
7218    kIdle: 0,
7219    kConnecting: 1,
7220    kBuffering: 2,
7221    kError: 3,
7222    kComplete: 4
7223};
7224
7225var LoaderErrors = exports.LoaderErrors = {
7226    OK: 'OK',
7227    EXCEPTION: 'Exception',
7228    HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',
7229    CONNECTING_TIMEOUT: 'ConnectingTimeout',
7230    EARLY_EOF: 'EarlyEof',
7231    UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'
7232};
7233
7234/* Loader has callbacks which have following prototypes:
7235 *     function onContentLengthKnown(contentLength: number): void
7236 *     function onURLRedirect(url: string): void
7237 *     function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void
7238 *     function onError(errorType: number, errorInfo: {code: number, msg: string}): void
7239 *     function onComplete(rangeFrom: number, rangeTo: number): void
7240 */
7241
7242var BaseLoader = exports.BaseLoader = function () {
7243    function BaseLoader(typeName) {
7244        _classCallCheck(this, BaseLoader);
7245
7246        this._type = typeName || 'undefined';
7247        this._status = LoaderStatus.kIdle;
7248        this._needStash = false;
7249        // callbacks
7250        this._onContentLengthKnown = null;
7251        this._onURLRedirect = null;
7252        this._onDataArrival = null;
7253        this._onError = null;
7254        this._onComplete = null;
7255    }
7256
7257    _createClass(BaseLoader, [{
7258        key: 'destroy',
7259        value: function destroy() {
7260            this._status = LoaderStatus.kIdle;
7261            this._onContentLengthKnown = null;
7262            this._onURLRedirect = null;
7263            this._onDataArrival = null;
7264            this._onError = null;
7265            this._onComplete = null;
7266        }
7267    }, {
7268        key: 'isWorking',
7269        value: function isWorking() {
7270            return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;
7271        }
7272    }, {
7273        key: 'open',
7274
7275
7276        // pure virtual
7277        value: function open(dataSource, range) {
7278            throw new _exception.NotImplementedException('Unimplemented abstract function!');
7279        }
7280    }, {
7281        key: 'abort',
7282        value: function abort() {
7283            throw new _exception.NotImplementedException('Unimplemented abstract function!');
7284        }
7285    }, {
7286        key: 'type',
7287        get: function get() {
7288            return this._type;
7289        }
7290    }, {
7291        key: 'status',
7292        get: function get() {
7293            return this._status;
7294        }
7295    }, {
7296        key: 'needStashBuffer',
7297        get: function get() {
7298            return this._needStash;
7299        }
7300    }, {
7301        key: 'onContentLengthKnown',
7302        get: function get() {
7303            return this._onContentLengthKnown;
7304        },
7305        set: function set(callback) {
7306            this._onContentLengthKnown = callback;
7307        }
7308    }, {
7309        key: 'onURLRedirect',
7310        get: function get() {
7311            return this._onURLRedirect;
7312        },
7313        set: function set(callback) {
7314            this._onURLRedirect = callback;
7315        }
7316    }, {
7317        key: 'onDataArrival',
7318        get: function get() {
7319            return this._onDataArrival;
7320        },
7321        set: function set(callback) {
7322            this._onDataArrival = callback;
7323        }
7324    }, {
7325        key: 'onError',
7326        get: function get() {
7327            return this._onError;
7328        },
7329        set: function set(callback) {
7330            this._onError = callback;
7331        }
7332    }, {
7333        key: 'onComplete',
7334        get: function get() {
7335            return this._onComplete;
7336        },
7337        set: function set(callback) {
7338            this._onComplete = callback;
7339        }
7340    }]);
7341
7342    return BaseLoader;
7343}();
7344
7345},{"../utils/exception.js":40}],25:[function(_dereq_,module,exports){
7346'use strict';
7347
7348Object.defineProperty(exports, "__esModule", {
7349    value: true
7350});
7351
7352var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7353
7354function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7355
7356/*
7357 * Copyright (C) 2016 Bilibili. All Rights Reserved.
7358 *
7359 * @author zheng qian <[email protected]>
7360 *
7361 * Licensed under the Apache License, Version 2.0 (the "License");
7362 * you may not use this file except in compliance with the License.
7363 * You may obtain a copy of the License at
7364 *
7365 *     http://www.apache.org/licenses/LICENSE-2.0
7366 *
7367 * Unless required by applicable law or agreed to in writing, software
7368 * distributed under the License is distributed on an "AS IS" BASIS,
7369 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7370 * See the License for the specific language governing permissions and
7371 * limitations under the License.
7372 */
7373
7374var ParamSeekHandler = function () {
7375    function ParamSeekHandler(paramStart, paramEnd) {
7376        _classCallCheck(this, ParamSeekHandler);
7377
7378        this._startName = paramStart;
7379        this._endName = paramEnd;
7380    }
7381
7382    _createClass(ParamSeekHandler, [{
7383        key: 'getConfig',
7384        value: function getConfig(baseUrl, range) {
7385            var url = baseUrl;
7386
7387            if (range.from !== 0 || range.to !== -1) {
7388                var needAnd = true;
7389                if (url.indexOf('?') === -1) {
7390                    url += '?';
7391                    needAnd = false;
7392                }
7393
7394                if (needAnd) {
7395                    url += '&';
7396                }
7397
7398                url += this._startName + '=' + range.from.toString();
7399
7400                if (range.to !== -1) {
7401                    url += '&' + this._endName + '=' + range.to.toString();
7402                }
7403            }
7404
7405            return {
7406                url: url,
7407                headers: {}
7408            };
7409        }
7410    }, {
7411        key: 'removeURLParameters',
7412        value: function removeURLParameters(seekedURL) {
7413            var baseURL = seekedURL.split('?')[0];
7414            var params = undefined;
7415
7416            var queryIndex = seekedURL.indexOf('?');
7417            if (queryIndex !== -1) {
7418                params = seekedURL.substring(queryIndex + 1);
7419            }
7420
7421            var resultParams = '';
7422
7423            if (params != undefined && params.length > 0) {
7424                var pairs = params.split('&');
7425
7426                for (var i = 0; i < pairs.length; i++) {
7427                    var pair = pairs[i].split('=');
7428                    var requireAnd = i > 0;
7429
7430                    if (pair[0] !== this._startName && pair[0] !== this._endName) {
7431                        if (requireAnd) {
7432                            resultParams += '&';
7433                        }
7434                        resultParams += pairs[i];
7435                    }
7436                }
7437            }
7438
7439            return resultParams.length === 0 ? baseURL : baseURL + '?' + resultParams;
7440        }
7441    }]);
7442
7443    return ParamSeekHandler;
7444}();
7445
7446exports.default = ParamSeekHandler;
7447
7448},{}],26:[function(_dereq_,module,exports){
7449'use strict';
7450
7451Object.defineProperty(exports, "__esModule", {
7452    value: true
7453});
7454
7455var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7456
7457function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7458
7459/*
7460 * Copyright (C) 2016 Bilibili. All Rights Reserved.
7461 *
7462 * @author zheng qian <[email protected]>
7463 *
7464 * Licensed under the Apache License, Version 2.0 (the "License");
7465 * you may not use this file except in compliance with the License.
7466 * You may obtain a copy of the License at
7467 *
7468 *     http://www.apache.org/licenses/LICENSE-2.0
7469 *
7470 * Unless required by applicable law or agreed to in writing, software
7471 * distributed under the License is distributed on an "AS IS" BASIS,
7472 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7473 * See the License for the specific language governing permissions and
7474 * limitations under the License.
7475 */
7476
7477var RangeSeekHandler = function () {
7478    function RangeSeekHandler(zeroStart) {
7479        _classCallCheck(this, RangeSeekHandler);
7480
7481        this._zeroStart = zeroStart || false;
7482    }
7483
7484    _createClass(RangeSeekHandler, [{
7485        key: 'getConfig',
7486        value: function getConfig(url, range) {
7487            var headers = {};
7488
7489            if (range.from !== 0 || range.to !== -1) {
7490                var param = void 0;
7491                if (range.to !== -1) {
7492                    param = 'bytes=' + range.from.toString() + '-' + range.to.toString();
7493                } else {
7494                    param = 'bytes=' + range.from.toString() + '-';
7495                }
7496                headers['Range'] = param;
7497            } else if (this._zeroStart) {
7498                headers['Range'] = 'bytes=0-';
7499            }
7500
7501            return {
7502                url: url,
7503                headers: headers
7504            };
7505        }
7506    }, {
7507        key: 'removeURLParameters',
7508        value: function removeURLParameters(seekedURL) {
7509            return seekedURL;
7510        }
7511    }]);
7512
7513    return RangeSeekHandler;
7514}();
7515
7516exports.default = RangeSeekHandler;
7517
7518},{}],27:[function(_dereq_,module,exports){
7519"use strict";
7520
7521Object.defineProperty(exports, "__esModule", {
7522    value: true
7523});
7524
7525var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7526
7527function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7528
7529/*
7530 * Copyright (C) 2016 Bilibili. All Rights Reserved.
7531 *
7532 * @author zheng qian <[email protected]>
7533 *
7534 * Licensed under the Apache License, Version 2.0 (the "License");
7535 * you may not use this file except in compliance with the License.
7536 * You may obtain a copy of the License at
7537 *
7538 *     http://www.apache.org/licenses/LICENSE-2.0
7539 *
7540 * Unless required by applicable law or agreed to in writing, software
7541 * distributed under the License is distributed on an "AS IS" BASIS,
7542 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7543 * See the License for the specific language governing permissions and
7544 * limitations under the License.
7545 */
7546
7547// Utility class to calculate realtime network I/O speed
7548var SpeedSampler = function () {
7549    function SpeedSampler() {
7550        _classCallCheck(this, SpeedSampler);
7551
7552        // milliseconds
7553        this._firstCheckpoint = 0;
7554        this._lastCheckpoint = 0;
7555        this._intervalBytes = 0;
7556        this._totalBytes = 0;
7557        this._lastSecondBytes = 0;
7558
7559        // compatibility detection
7560        if (self.performance && self.performance.now) {
7561            this._now = self.performance.now.bind(self.performance);
7562        } else {
7563            this._now = Date.now;
7564        }
7565    }
7566
7567    _createClass(SpeedSampler, [{
7568        key: "reset",
7569        value: function reset() {
7570            this._firstCheckpoint = this._lastCheckpoint = 0;
7571            this._totalBytes = this._intervalBytes = 0;
7572            this._lastSecondBytes = 0;
7573        }
7574    }, {
7575        key: "addBytes",
7576        value: function addBytes(bytes) {
7577            if (this._firstCheckpoint === 0) {
7578                this._firstCheckpoint = this._now();
7579                this._lastCheckpoint = this._firstCheckpoint;
7580                this._intervalBytes += bytes;
7581                this._totalBytes += bytes;
7582            } else if (this._now() - this._lastCheckpoint < 1000) {
7583                this._intervalBytes += bytes;
7584                this._totalBytes += bytes;
7585            } else {
7586                // duration >= 1000
7587                this._lastSecondBytes = this._intervalBytes;
7588                this._intervalBytes = bytes;
7589                this._totalBytes += bytes;
7590                this._lastCheckpoint = this._now();
7591            }
7592        }
7593    }, {
7594        key: "currentKBps",
7595        get: function get() {
7596            this.addBytes(0);
7597
7598            var durationSeconds = (this._now() - this._lastCheckpoint) / 1000;
7599            if (durationSeconds == 0) durationSeconds = 1;
7600            return this._intervalBytes / durationSeconds / 1024;
7601        }
7602    }, {
7603        key: "lastSecondKBps",
7604        get: function get() {
7605            this.addBytes(0);
7606
7607            if (this._lastSecondBytes !== 0) {
7608                return this._lastSecondBytes / 1024;
7609            } else {
7610                // lastSecondBytes === 0
7611                if (this._now() - this._lastCheckpoint >= 500) {
7612                    // if time interval since last checkpoint has exceeded 500ms
7613                    // the speed is nearly accurate
7614                    return this.currentKBps;
7615                } else {
7616                    // We don't know
7617                    return 0;
7618                }
7619            }
7620        }
7621    }, {
vendor: 5,790 bytes, lines 7622-7665
7622        key: "averageKBps",
7623        get: function get() {
7624            var durationSeconds = (this._now() - this._firstCheckpoint) / 1000;
7625            return this._totalBytes / durationSeconds / 1024;
7626        }
7627    }]);
7628
7629    return SpeedSampler;
7630}();
7631
7632exports.default = SpeedSampler;
7633
7634},{}],28:[function(_dereq_,module,exports){
7635'use strict';
7636
7637Object.defineProperty(exports, "__esModule", {
7638    value: true
7639});
7640
7641var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
7642
7643var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7644
7645var _logger = _dereq_('../utils/logger.js');
7646
7647var _logger2 = _interopRequireDefault(_logger);
7648
7649var _loader = _dereq_('./loader.js');
7650
7651var _exception = _dereq_('../utils/exception.js');
7652
7653function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7654
7655function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7656
7657function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7658
7659function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
7660                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (C) 2016 Bilibili. All Rights Reserved.
7661                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7662                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * @author zheng qian <[email protected]>
7663                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7664                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Licensed under the Apache License, Version 2.0 (the "License");
7665                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * you may 
7665not use this file except in compliance with the License.
7666                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * You may obtain a copy of the License at
7667                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7668                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *     http://www.apache.org/licenses/LICENSE-2.0
7669                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7670                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Unless required by applicable law or agreed to in writing, software
7671                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * distributed under the License is distributed on an "AS IS" BASIS,
7672                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7673                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * See the License for the specific language governing permissions and
7674                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * limitations under the License.
7675                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */
7676
7677// For FLV over WebSocket live stream
7678var WebSocketLoader = function (_BaseLoader) {
7679    _inherits(WebSocketLoader, _BaseLoader);
7680
7681    _createClass(WebSocketLoader, null, [{
7682        key: 'isSupported',
7683        value: function isSupported() {
7684            try {
7685                return typeof self.WebSocket !== 'undefined';
7686            } catch (e) {
7687                return false;
7688            }
7689        }
7690    }]);
7691
7692    function WebSocketLoader() {
7693        _classCallCheck(this, WebSocketLoader);
7694
7695        var _this = _possibleConstructorReturn(this, (WebSocketLoader.__proto__ || Object.getPrototypeOf(WebSocketLoader)).call(this, 'websocket-loader'));
7696
7697        _this.TAG = 'WebSocketLoader';
7698
7699        _this._needStash = true;
7700
7701        _this._ws = null;
7702        _this._requestAbort = false;
7703        _this._receivedLength = 0;
7704        return _this;
7705    }
7706
7707    _createClass(WebSocketLoader, [{
7708        key: 'destroy',
7709        value: function destroy() {
7710            if (this._ws) {
7711                this.abort();
7712            }
7713            _get(WebSocketLoader.prototype.__proto__ || Object.getPrototypeOf(WebSocketLoader.prototype), 'destroy', this).call(this);
7714        }
7715    }, {
7716        key: 'open',
7717        value: function open(dataSource) {
7718            try {
7719                var ws = this._ws = new self.WebSocket(dataSource.url);
7720                ws.binaryType = 'arraybuffer';
7721                ws.onopen = this._onWebSocketOpen.bind(this);
7722                ws.onclose = this._onWebSocketClose.bind(this);
7723                ws.onmessage = this._onWebSocketMessage.bind(this);
7724                ws.onerror = this._onWebSocketError.bind(this);
7725
7726                this._status = _loader.LoaderStatus.kConnecting;
7727            } catch (e) {
7728                this._status = _loader.LoaderStatus.kError;
7729
7730                var info = { code: e.code, msg: e.message };
7731
7732                if (this._onError) {
7733                    this._onError(_loader.LoaderErrors.EXCEPTION, info);
7734                } else {
7735                    throw new _exception.RuntimeException(info.msg);
7736                }
7737            }
7738        }
7739    }, {
7740        key: 'abort',
7741        value: function abort() {
7742            var ws = this._ws;
7743            if (ws && (ws.readyState === 0 || ws.readyState === 1)) {
7744                // CONNECTING || OPEN
7745                this._requestAbort = true;
7746                ws.close();
7747            }
7748
7749            this._ws = null;
7750            this._status = _loader.LoaderStatus.kComplete;
7751        }
7752    }, {
7753        key: '_onWebSocketOpen',
7754        value: function _onWebSocketOpen(e) {
7755            this._status = _loader.LoaderStatus.kBuffering;
7756        }
7757    }, {
7758        key: '_onWebSocketClose',
7759        value: function _onWebSocketClose(e) {
7760            if (this._requestAbort === true) {
7761                this._requestAbort = false;
7762                return;
7763            }
7764
7765            this._status = _loader.LoaderStatus.kComplete;
7766
7767            if (this._onComplete) {
7768                this._onComplete(0, this._receivedLength - 1);
7769            }
7770        }
7771    }, {
7772        key: '_onWebSocketMessage',
7773        value: function _onWebSocketMessage(e) {
7774            var _this2 = this;
7775
7776            if (e.data instanceof ArrayBuffer) {
7777                this._dispatchArrayBuffer(e.data);
7778            } else if (e.data instanceof Blob) {
7779                var reader = new FileReader();
7780                reader.onload = function () {
7781                    _this2._dispatchArrayBuffer(reader.result);
7782                };
7783                reader.readAsArrayBuffer(e.data);
7784            } else {
7785                this._status = _loader.LoaderStatus.kError;
7786                var info = { code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name };
7787
7788                if (this._onError) {
7789                    this._onError(_loader.LoaderErrors.EXCEPTION, info);
7790                } else {
7791                    throw new _exception.RuntimeException(info.msg);
7792                }
7793            }
7794        }
7795    }, {
7796        key: '_dispatchArrayBuffer',
7797        value: function _dispatchArrayBuffer(arraybuffer) {
7798            var chunk = arraybuffer;
7799            var byteStart = this._receivedLength;
7800            this._receivedLength += chunk.byteLength;
7801
7802            if (this._onDataArrival) {
7803                this._onDataArrival(chunk, byteStart, this._receivedLength);
7804            }
7805        }
7806    }, {
7807        key: '_onWebSocketError',
7808        value: function _onWebSocketError(e) {
7809            this._status = _loader.LoaderStatus.kError;
7810
7811            var info = {
7812                code: e.code,
7813                msg: e.message
7814            };
7815
7816            if (this._onError) {
7817                this._onError(_loader.LoaderErrors.EXCEPTION, info);
7818            } else {
7819                throw new _exception.RuntimeException(info.msg);
7820            }
7821        }
7822    }]);
7823
7824    return WebSocketLoader;
7825}(_loader.BaseLoader);
7826
7827exports.default = WebSocketLoader;
7828
7829},{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],29:[function(_dereq_,module,exports){
7830'use strict';
7831
7832Object.defineProperty(exports, "__esModule", {
7833    value: true
7834});
7835
7836var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
7837
7838var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
7839
7840var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7841
7842var _logger = _dereq_('../utils/logger.js');
7843
7844var _logger2 = _interopRequireDefault(_logger);
7845
7846var _loader = _dereq_('./loader.js');
7847
7848var _exception = _dereq_('../utils/exception.js');
7849
7850function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7851
7852function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7853
7854function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7855
7856function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
7856onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
7857                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (C) 2016 Bilibili. All Rights Reserved.
7858                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7859                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * @author zheng qian <[email protected]>
7860                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7861                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Licensed under the Apache License, Version 2.0 (the "License");
7862                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * you may not use this file except in compliance with the License.
7863                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * You may obtain a copy of the License at
7864                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7865                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *     http://www.apache.org/licenses/LICENSE-2.0
7866                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
7867                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Unless required by applicable law or agreed to in writing, softw
7867are
7868                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * distributed under the License is distributed on an "AS IS" BASIS,
7869                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7870                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * See the License for the specific language governing permissions and
7871                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * limitations under the License.
7872                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */
7873
7874// For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`
7875var MozChunkedLoader = function (_BaseLoader) {
7876    _inherits(MozChunkedLoader, _BaseLoader);
7877
7878    _createClass(MozChunkedLoader, null, [{
7879        key: 'isSupported',
7880        value: function isSupported() {
7881            try {
7882                var xhr = new XMLHttpRequest();
7883                // Firefox 37- requires .open() to be called before setting responseType
7884                xhr.open('GET', 'https://example.com', true);
7885                xhr.responseType = 'moz-chunked-arraybuffer';
7886                return xhr.responseType === 'moz-chunked-arraybuffer';
7887            } catch (e) {
7888                _logger2.default.w('MozChunkedLoader', e.message);
7889                return false;
7890            }
7891        }
7892    }]);
7893
7894    function MozChunkedLoader(seekHandler, config) {
7895        _classCallCheck(this, MozChunkedLoader);
7896
7897        var _this = _possibleConstructorReturn(this, (MozChunkedLoader.__proto__ || Object.getPrototypeOf(MozChunkedLoader)).call(this, 'xhr-moz-chunked-loader'));
7898
7899        _this.TAG = 'MozChunkedLoader';
7900
7901        _this._seekHandler = seekHandler;
7902        _this._config = config;
7903        _this._needStash = true;
7904
7905        _this._xhr = null;
7906        _this._requestAbort = false;
7907        _this._contentLength = null;
7908        _this._receivedLength = 0;
7909        return _this;
7910    }
7911
7912    _createClass(MozChunkedLoader, [{
7913        key: 'destroy',
7914        value: function destroy() {
7915            if (this.isWorking()) {
7916                this.abort();
7917            }
7918            if (this._xhr) {
7919                this._xhr.onreadystatechange = null;
7920                this._xhr.onprogress = null;
7921                this._xhr.onloadend = null;
7922                this._xhr.onerror = null;
7923                this._xhr = null;
7924            }
7925            _get(MozChunkedLoader.prototype.__proto__ || Object.getPrototypeOf(MozChunkedLoader.prototype), 'destroy', this).call(this);
7926        }
7927    }, {
7928        key: 'open',
7929        value: function open(dataSource, range) {
7930            this._dataSource = dataSource;
7931            this._range = range;
7932
7933            var sourceURL = dataSource.url;
7934            if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {
7935                sourceURL = dataSource.redirectedURL;
7936            }
7937
7938            var seekConfig = this._seekHandler.getConfig(sourceURL, range);
7939            this._requestURL = seekConfig.url;
7940
7941            var xhr = this._xhr = new XMLHttpRequest();
7942            xhr.open('GET', seekConfig.url, true);
7943            xhr.responseType = 'moz-chunked-arraybuffer';
7944            xhr.onreadystatechange = this._onReadyStateChange.bind(this);
7945            xhr.onprogress = this._onProgress.bind(this);
7946            xhr.onloadend = this._onLoadEnd.bind(this);
7947            xhr.onerror = this._onXhrError.bind(this);
7948
7949            // cors is auto detected and enabled by xhr
7950
7951            // withCredentials is disabled by default
7952            if (dataSource.withCredentials) {
7953                xhr.withCredentials = true;
7954            }
7955
7956            if (_typeof(seekConfig.headers) === 'object') {
7957                var headers = seekConfig.headers;
7958
7959                for (var key in headers) {
7960                    if (headers.hasOwnProperty(key)) {
7961                        xhr.setRequestHeader(key, headers[key]);
7962                    }
7963                }
7964            }
7965
7966            // add additional headers
7967            if (_typeof(this._config.headers) === 'object') {
7968                var _headers = this._config.headers;
7969
7970                for (var _key in _headers) {
7971                    if (_headers.hasOwnProperty(_key)) {
7972                        xhr.setRequestHeader(_key, _headers[_key]);
7973                    }
7974                }
7975            }
7976
7977            this._status = _loader.LoaderStatus.kConnecting;
7978            xhr.send();
7979        }
7980    }, {
7981        key: 'abort',
7982        value: function abort() {
7983            this._requestAbort = true;
7984            if (this._xhr) {
7985                this._xhr.abort();
7986            }
7987            this._status = _loader.LoaderStatus.kComplete;
7988        }
7989    }, {
7990        key: '_onReadyStateChange',
7991        value: function _onReadyStateChange(e) {
7992            var xhr = e.target;
7993
7994            if (xhr.readyState === 2) {
7995                // HEADERS_RECEIVED
7996                if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {
7997                    if (this._onURLRedirect) {
7998                        var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
7999                        this._onURLRedirect(redirectedURL);
8000                    }
8001                }
8002
8003                if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {
8004                    this._status = _loader.LoaderStatus.kError;
8005                    if (this._onError) {
8006                        this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
8007                    } else {
8008                        throw new _exception.RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
8009                    }
8010                } else {
8011                    this._status = _loader.LoaderStatus.kBuffering;
8012                }
8013            }
8014        }
8015    }, {
8016        key: '_onProgress',
8017        value: function _onProgress(e) {
8018            if (this._status === _loader.LoaderStatus.kError) {
8019                // Ignore error response
8020                return;
8021            }
8022
8023            if (this._contentLength === null) {
8024                if (e.total !== null && e.total !== 0) {
8025                    this._contentLength = e.total;
8026                    if (this._onContentLengthKnown) {
8027                        this._onContentLengthKnown(this._contentLength);
8028                    }
8029                }
8030            }
8031
8032            var chunk = e.target.response;
8033            var byteStart = this._range.from + this._receivedLength;
8034            this._receivedLength += chunk.byteLength;
8035
8036            if (this._onDataArrival) {
8037                this._onDataArrival(chunk, byteStart, this._receivedLength);
8038            }
8039        }
8040    }, {
8041        key: '_onLoadEnd',
8042        value: function _onLoadEnd(e) {
8043            if (this._requestAbort === true) {
8044                this._requestAbort = false;
8045                return;
8046            } else if (this._status === _loader.LoaderStatus.kError) {
8047                return;
8048            }
8049
8050            this._status = _loader.LoaderStatus.kComplete;
8051            if (this._onComplete) {
8052                this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
8053            }
8054        }
8055    }, {
8056        key: '_onXhrError',
8057        value: function _onXhrError(e) {
8058            this._status = _loader.LoaderStatus.kError;
8059            var type = 0;
8060            var info = null;
8061
8062            if (this._contentLength && e.loaded < this._contentLength) {
8063                type = _loader.LoaderErrors.EARLY_EOF;
8064                info = { code: -1, msg: 'Moz-Chunked stream meet Early-Eof' };
8065            } else {
8066                type = _loader.LoaderErrors.EXCEPTION;
8067                info = { code: -1, msg: e.constructor.name + ' ' + e.type };
8068            }
8069
8070            if (this._onError) {
8071                this._onError(type, info);
8072            } else {
8073                throw new _exception.RuntimeException(info.msg);
8074            }
8075        }
8076    }]);
8077
8078    return MozChunkedLoader;
8079}(_loader.BaseLoader);
8080
8081exports.default = MozChunkedLoader;
8082
8083},{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],30:[function(_dereq_,module,exports){
8084'use strict';
8085
8086Object.defineProperty(exports, "__esModule", {
8087    value: true
8088});
8089
8090var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
8091
8092var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
8093
8094var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8095
8096var _logger = _dereq_('../utils/logger.js');
8097
8098var _logger2 = _interopRequireDefault(_logger);
8099
8100var _loader = _dereq_('./loader.js');
8101
8102var _exception = _dereq_('../utils/exception.js');
8103
8104function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8105
8106function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8107
8108function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8109
8110function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
8111                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (C) 2016 Bilibili. All Rights Reserved.
8112                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8113                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * @author zheng qian <[email protected]>
8114                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8115                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Licensed under the Apache License, Version 2.0 (the "License");
8116                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * you may 
8116not use this file except in compliance with the License.
8117                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * You may obtain a copy of the License at
8118                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8119                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *     http://www.apache.org/licenses/LICENSE-2.0
8120                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8121                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Unless required by applicable law or agreed to in writing, software
8122                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * distributed under the License is distributed on an "AS IS" BASIS,
8123                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8124                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * See the License for the specific language governing permissions and
8125                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * limitations under the License.
8126                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */
8127
8128/* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!
8129 * The browser may crash in wininet.dll. Disable for now.
8130 *
8131 * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`
8132 * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.
8133 *
8134 * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.
8135 * in order to release previous ArrayBuffer to avoid memory leak
8136 *
8137 * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.
8138 */
8139var MSStreamLoader = function (_BaseLoader) {
8140    _inherits(MSStreamLoader, _BaseLoader);
8141
8142    _createClass(MSStreamLoader, null, [{
8143        key: 'isSupported',
8144        value: function isSupported() {
8145            try {
8146                if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {
8147                    return false;
8148                }
8149
8150                var xhr = new XMLHttpRequest();
8151                xhr.open('GET', 'https://example.com', true);
8152                xhr.responseType = 'ms-stream';
8153                return xhr.responseType === 'ms-stream';
8154            } catch (e) {
8155                _logger2.default.w('MSStreamLoader', e.message);
8156                return false;
8157            }
8158        }
8159    }]);
8160
8161    function MSStreamLoader(seekHandler, config) {
8162        _classCallCheck(this, MSStreamLoader);
8163
8164        var _this = _possibleConstructorReturn(this, (MSStreamLoader.__proto__ || Object.getPrototypeOf(MSStreamLoader)).call(this, 'xhr-msstream-loader'));
8165
8166        _this.TAG = 'MSStreamLoader';
8167
8168        _this._seekHandler = seekHandler;
8169        _this._config = config;
8170        _this._needStash = true;
8171
8172        _this._xhr = null;
8173        _this._reader = null; // MSStreamReader
8174
8175        _this._totalRange = null;
8176        _this._currentRange = null;
8177
8178        _this._currentRequestURL = null;
8179        _this._currentRedirectedURL = null;
8180
8181        _this._contentLength = null;
8182        _this._receivedLength = 0;
8183
8184        _this._bufferLimit = 16 * 1024 * 1024; // 16MB
8185        _this._lastTimeBufferSize = 0;
8186        _this._isReconnecting = false;
8187        return _this;
8188    }
8189
8190    _createClass(MSStreamLoader, [{
8191        key: 'destroy',
8192        value: function destroy() {
8193            if (this.isWorking()) {
8194                this.abort();
8195            }
8196            if (this._reader) {
8197                this._reader.onprogress = null;
8198                this._reader.onload = null;
8199                this._reader.onerror = null;
8200                this._reader = null;
8201            }
8202            if (this._xhr) {
8203                this._xhr.onreadystatechange = null;
8204                this._xhr = null;
8205            }
8206            _get(MSStreamLoader.prototype.__proto__ || Object.getPrototypeOf(MSStreamLoader.prototype), 'destroy', this).call(this);
8207        }
8208    }, {
8209        key: 'open',
8210        value: function open(dataSource, range) {
8211            this._internalOpen(dataSource, range, false);
8212        }
8213    }, {
8214        key: '_internalOpen',
8215        value: function _internalOpen(dataSource, range, isSubrange) {
8216            this._dataSource = dataSource;
8217
8218            if (!isSubrange) {
8219                this._totalRange = range;
8220            } else {
8221                this._currentRange = range;
8222            }
8223
8224            var sourceURL = dataSource.url;
8225            if (this._config.reuseRedirectedURL) {
8226                if (this._currentRedirectedURL != undefined) {
8227                    sourceURL = this._currentRedirectedURL;
8228                } else if (dataSource.redirectedURL != undefined) {
8229                    sourceURL = dataSource.redirectedURL;
8230                }
8231            }
8232
8233            var seekConfig = this._seekHandler.getConfig(sourceURL, range);
8234            this._currentRequestURL = seekConfig.url;
8235
8236            var reader = this._reader = new self.MSStreamReader();
8237            reader.onprogress = this._msrOnProgress.bind(this);
8238            reader.onload = this._msrOnLoad.bind(this);
8239            reader.onerror = this._msrOnError.bind(this);
8240
8241            var xhr = this._xhr = new XMLHttpRequest();
8242            xhr.open('GET', seekConfig.url, true);
8243            xhr.responseType = 'ms-stream';
8244            xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);
8245            xhr.onerror = this._xhrOnError.bind(this);
8246
8247            if (dataSource.withCredentials) {
8248                xhr.withCredentials = true;
8249            }
8250
8251            if (_typeof(seekConfig.headers) === 'object') {
8252                var headers = seekConfig.headers;
8253
8254                for (var key in headers) {
8255                    if (headers.hasOwnProperty(key)) {
8256                        xhr.setRequestHeader(key, headers[key]);
8257                    }
8258                }
8259            }
8260
8261            // add additional headers
8262            if (_typeof(this._config.headers) === 'object') {
8263                var _headers = this._config.headers;
8264
8265                for (var _key in _headers) {
8266                    if (_headers.hasOwnProperty(_key)) {
8267                        xhr.setRequestHeader(_key, _headers[_key]);
8268                    }
8269                }
8270            }
8271
8272            if (this._isReconnecting) {
8273                this._isReconnecting = false;
8274            } else {
8275                this._status = _loader.LoaderStatus.kConnecting;
8276            }
8277            xhr.send();
8278        }
8279    }, {
8280        key: 'abort',
8281        value: function abort() {
8282            this._internalAbort();
8283            this._status = _loader.LoaderStatus.kComplete;
8284        }
8285    }, {
8286        key: '_internalAbort',
8287        value: function _internalAbort() {
8288            if (this._reader) {
8289                if (this._reader.readyState === 1) {
8290                    // LOADING
8291                    this._reader.abort();
8292                }
8293                this._reader.onprogress = null;
8294                this._reader.onload = null;
8295                this._reader.onerror = null;
8296                this._reader = null;
8297            }
8298            if (this._xhr) {
8299                this._xhr.abort();
8300                this._xhr.onreadystatechange = null;
8301                this._xhr = null;
8302            }
8303        }
8304    }, {
8305        key: '_xhrOnReadyStateChange',
8306        value: function _xhrOnReadyStateChange(e) {
8307            var xhr = e.target;
8308
8309            if (xhr.readyState === 2) {
8310                // HEADERS_RECEIVED
8311                if (xhr.status >= 200 && xhr.status <= 299) {
8312                    this._status = _loader.LoaderStatus.kBuffering;
8313
8314                    if (xhr.responseURL != undefined) {
8315                        var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
8316                        if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {
8317                            this._currentRedirectedURL = redirectedURL;
8318                            if (this._onURLRedirect) {
8319                                this._onURLRedirect(redirectedURL);
8320                            }
8321                        }
8322                    }
8323
8324                    var lengthHeader = xhr.getResponseHeader('Content-Length');
8325                    if (lengthHeader != null && this._contentLength == null) {
8326                        var length = parseInt(lengthHeader);
8327                        if (length > 0) {
8328                            this._contentLength = length;
8329                            if (this._onContentLengthKnown) {
8330                                this._onContentLengthKnown(this._contentLength);
8331                            }
8332                        }
8333                    }
8334                } else {
8335                    this._status = _loader.LoaderStatus.kError;
8336                    if (this._onError) {
8337                        this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
8338                    } else {
8339                        throw new _exception.RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
8340                    }
8341                }
8342            } else if (xhr.readyState === 3) {
8343                // LOADING
8344                if (xhr.status >= 200 && xhr.status <= 299) {
8345                    this._status = _loader.LoaderStatus.kBuffering;
8346
8347                    var msstream = xhr.response;
8348                    this._reader.readAsArrayBuffer(msstream);
8349                }
8350            }
8351        }
8352    }, {
8353        key: '_xhrOnError',
8354        value: function _xhrOnError(e) {
8355            this._status = _loader.LoaderStatus.kError;
8356            var type = _loader.LoaderErrors.EXCEPTION;
8357            var info = { code: -1, msg: e.constructor.name + ' ' + e.type };
8358
8359            if (this._onError) {
8360                this._onError(type, info);
8361            } else {
8362                throw new _exception.RuntimeException(info.msg);
8363            }
8364        }
8365    }, {
8366        key: '_msrOnProgress',
8367        value: function _msrOnProgress(e) {
8368            var reader = e.target;
8369            var bigbuffer = reader.result;
8370            if (bigbuffer == null) {
8371                // result may be null, workaround for buggy M$
8372                this._doReconnectIfNeeded();
8373                return;
8374            }
8375
8376            var slice = bigbuffer.slice(this._lastTimeBufferSize);
8377            this._lastTimeBufferSize = bigbuffer.byteLength;
8378            var byteStart = this._totalRange.from + this._receivedLength;
8379            this._receivedLength += slice.byteLength;
8380
8381            if (this._onDataArrival) {
8382                this._onDataArrival(slice, byteStart, this._receivedLength);
8383            }
8384
8385            if (bigbuffer.byteLength >= this._bufferLimit) {
8386                _logger2.default.v(this.TAG, 'MSStream buffer exceeded max size near ' + (byteStart + slice.byteLength) + ', reconnecting...');
8387                this._doReconnectIfNeeded();
8388            }
8389        }
8390    }, {
8391        key: '_doReconnectIfNeeded',
8392        value: function _doReconnectIfNeeded() {
8393            if (this._contentLength == null || this._receivedLength < this._contentLength) {
8394                this._isReconnecting = true;
8395                this._lastTimeBufferSize = 0;
8396                this._internalAbort();
8397
8398                var range = {
8399                    from: this._totalRange.from + this._receivedLength,
8400                    to: -1
8401                };
8402                this._internalOpen(this._dataSource, range, true);
8403            }
8404        }
8405    }, {
8406        key: '_msrOnLoad',
8407        value: function _msrOnLoad(e) {
8408            // actually it is onComplete event
8409            this._status = _loader.LoaderStatus.kComplete;
8410            if (this._onComplete) {
8411                this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);
8412            }
8413        }
8414    }, {
8415        key: '_msrOnError',
8416        value: function _msrOnError(e) {
8417            this._status = _loader.LoaderStatus.kError;
8418            var type = 0;
8419            var info = null;
8420
8421            if (this._contentLength && this._receivedLength < this._contentLength) {
8422                type = _loader.LoaderErrors.EARLY_EOF;
8423                info = { code: -1, msg: 'MSStream meet Early-Eof' };
8424            } else {
8425                type = _loader.LoaderErrors.EARLY_EOF;
8426                info = { code: -1, msg: e.constructor.name + ' ' + e.type };
8427            }
8428
8429            if (this._onError) {
8430                this._onError(type, info);
8431            } else {
8432                throw new _exception.RuntimeException(info.msg);
8433            }
8434        }
8435    }]);
8436
8437    return MSStreamLoader;
8438}(_loader.BaseLoader);
8439
8440exports.default = MSStreamLoader;
8441
8442},{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],31:[function(_dereq_,module,exports){
8443'use strict';
8444
8445Object.defineProperty(exports, "__esModule", {
8446    value: true
8447});
8448
8449var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
8450
8451var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
8452
8453var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8454
8455var _logger = _dereq_('../utils/logger.js');
8456
8457var _logger2 = _interopRequireDefault(_logger);
8458
8459var _speedSampler = _dereq_('./speed-sampler.js');
8460
8461var _speedSampler2 = _interopRequireDefault(_speedSampler);
8462
8463var _loader = _dereq_('./loader.js');
8464
8465var _exception = _dereq_('../utils/exception.js');
8466
8467function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8468
8469function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8470
8471function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8472
8473function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
8473onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
8474                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (C) 2016 Bilibili. All Rights Reserved.
8475                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8476                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * @author zheng qian <[email protected]>
8477                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8478                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Licensed under the Apache License, Version 2.0 (the "License");
8479                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * you may not use this file except in compliance with the License.
8480                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * You may obtain a copy of the License at
8481                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8482                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *     http://www.apache.org/licenses/LICENSE-2.0
8483                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *
8484                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Unless required by applicable law or agreed to in writing, softw
8484are
8485                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * distributed under the License is distributed on an "AS IS" BASIS,
8486                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8487                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * See the License for the specific language governing permissions and
8488                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * limitations under the License.
8489                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */
8490
8491// Universal IO Loader, implemented by adding Range header in xhr's request header
8492var RangeLoader = function (_BaseLoader) {
8493    _inherits(RangeLoader, _BaseLoader);
8494
8495    _createClass(RangeLoader, null, [{
8496        key: 'isSupported',
8497        value: function isSupported() {
8498            try {
8499                var xhr = new XMLHttpRequest();
8500                xhr.open('GET', 'https://example.com', true);
8501                xhr.responseType = 'arraybuffer';
8502                return xhr.responseType === 'arraybuffer';
8503            } catch (e) {
8504                _logger2.default.w('RangeLoader', e.message);
8505                return false;
8506            }
8507        }
8508    }]);
8509
8510    function RangeLoader(seekHandler, config) {
8511        _classCallCheck(this, RangeLoader);
8512
8513        var _this = _possibleConstructorReturn(this, (RangeLoader.__proto__ || Object.getPrototypeOf(RangeLoader)).call(this, 'xhr-range-loader'));
8514
8515        _this.TAG = 'RangeLoader';
8516
8517        _this._seekHandler = seekHandler;
8518        _this._config = config;
8519        _this._needStash = false;
8520
8521        _this._chunkSizeKBList = [128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192];
8522        _this._currentChunkSizeKB = 384;
8523        _this._currentSpeedNormalized = 0;
8524        _this._zeroSpeedChunkCount = 0;
8525
8526        _this._xhr = null;
8527        _this._speedSampler = new _speedSampler2.default();
8528
8529        _this._requestAbort = false;
8530        _this._waitForTotalLength = false;
8531        _this._totalLengthReceived = false;
8532
8533        _this._currentRequestURL = null;
8534        _this._currentRedirectedURL = null;
8535        _this._currentRequestRange = null;
8536        _this._totalLength = null; // size of the entire file
8537        _this._contentLength = null; // Content-Length of entire request range
8538        _this._receivedLength = 0; // total received bytes
8539        _this._lastTimeLoaded = 0; // received bytes of current request sub-range
8540        return _this;
8541    }
8542
8543    _createClass(RangeLoader, [{
8544        key: 'destroy',
8545        value: function destroy() {
8546            if (this.isWorking()) {
8547                this.abort();
8548            }
8549            if (this._xhr) {
8550                this._xhr.onreadystatechange = null;
8551                this._xhr.onprogress = null;
8552                this._xhr.onload = null;
8553                this._xhr.onerror = null;
8554                this._xhr = null;
8555            }
8556            _get(RangeLoader.prototype.__proto__ || Object.getPrototypeOf(RangeLoader.prototype), 'destroy', this).call(this);
8557        }
8558    }, {
8559        key: 'open',
8560        value: function open(dataSource, range) {
8561            this._dataSource = dataSource;
8562            this._range = range;
8563            this._status = _loader.LoaderStatus.kConnecting;
8564
8565            var useRefTotalLength = false;
8566            if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {
8567                useRefTotalLength = true;
8568                this._totalLength = this._dataSource.filesize;
8569            }
8570
8571            if (!this._totalLengthReceived && !useRefTotalLength) {
8572                // We need total filesize
8573                this._waitForTotalLength = true;
8574                this._internalOpen(this._dataSource, { from: 0, to: -1 });
8575            } else {
8576                // We have filesize, start loading
8577                this._openSubRange();
8578            }
8579        }
8580    }, {
8581        key: '_openSubRange',
8582        value: function _openSubRange() {
8583            var chunkSize = this._currentChunkSizeKB * 1024;
8584
8585            var from = this._range.from + this._receivedLength;
8586            var to = from + chunkSize;
8587
8588            if (this._contentLength != null) {
8589                if (to - this._range.from >= this._contentLength) {
8590                    to = this._range.from + this._contentLength - 1;
8591                }
8592            }
8593
8594            this._currentRequestRange = { from: from, to: to };
8595            this._internalOpen(this._dataSource, this._currentRequestRange);
8596        }
8597    }, {
8598        key: '_internalOpen',
8599        value: function _internalOpen(dataSource, range) {
8600            this._lastTimeLoaded = 0;
8601
8602            var sourceURL = dataSource.url;
8603            if (this._config.reuseRedirectedURL) {
8604                if (this._currentRedirectedURL != undefined) {
8605                    sourceURL = this._currentRedirectedURL;
8606                } else if (dataSource.redirectedURL != undefined) {
8607                    sourceURL = dataSource.redirectedURL;
8608                }
8609            }
8610
8611            var seekConfig = this._seekHandler.getConfig(sourceURL, range);
8612            this._currentRequestURL = seekConfig.url;
8613
8614            var xhr = this._xhr = new XMLHttpRequest();
8615            xhr.open('GET', seekConfig.url, true);
8616            xhr.responseType = 'arraybuffer';
8617            xhr.onreadystatechange = this._onReadyStateChange.bind(this);
8618            xhr.onprogress = this._onProgress.bind(this);
8619            xhr.onload = this._onLoad.bind(this);
8620            xhr.onerror = this._onXhrError.bind(this);
8621
8622            if (dataSource.withCredentials) {
8623                xhr.withCredentials = true;
8624            }
8625
8626            if (_typeof(seekConfig.headers) === 'object') {
8627                var headers = seekConfig.headers;
8628
8629                for (var key in headers) {
8630                    if (headers.hasOwnProperty(key)) {
8631                        xhr.setRequestHeader(key, headers[key]);
8632                    }
8633                }
8634            }
8635
8636            // add additional headers
8637            if (_typeof(this._config.headers) === 'object') {
8638                var _headers = this._config.headers;
8639
8640                for (var _key in _headers) {
8641                    if (_headers.hasOwnProperty(_key)) {
8642                        xhr.setRequestHeader(_key, _headers[_key]);
8643                    }
8644                }
8645            }
8646
8647            xhr.send();
8648        }
8649    }, {
8650        key: 'abort',
8651        value: function abort() {
8652            this._requestAbort = true;
8653            this._internalAbort();
8654            this._status = _loader.LoaderStatus.kComplete;
8655        }
8656    }, {
8657        key: '_internalAbort',
8658        value: function _internalAbort() {
8659            if (this._xhr) {
8660                this._xhr.onreadystatechange = null;
8661                this._xhr.onprogress = null;
8662                this._xhr.onload = null;
8663                this._xhr.onerror = null;
8664                this._xhr.abort();
8665                this._xhr = null;
8666            }
8667        }
8668    }, {
8669        key: '_onReadyStateChange',
8670        value: function _onReadyStateChange(e) {
8671            var xhr = e.target;
8672
8673            if (xhr.readyState === 2) {
8674                // HEADERS_RECEIVED
8675                if (xhr.responseURL != undefined) {
8676                    // if the browser support this property
8677                    var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
8678                    if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {
8679                        this._currentRedirectedURL = redirectedURL;
8680                        if (this._onURLRedirect) {
8681                            this._onURLRedirect(redirectedURL);
8682                        }
8683                    }
8684                }
8685
8686                if (xhr.status >= 200 && xhr.status <= 299) {
8687                    if (this._waitForTotalLength) {
8688                        return;
8689                    }
8690                    this._status = _loader.LoaderStatus.kBuffering;
8691                } else {
8692                    this._status = _loader.LoaderStatus.kError;
8693                    if (this._onError) {
8694                        this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
8695                    } else {
8696                        throw new _exception.RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
8697                    }
8698                }
8699            }
8700        }
8701    }, {
8702        key: '_onProgress',
8703        value: function _onProgress(e) {
8704            if (this._status === _loader.LoaderStatus.kError) {
8705                // Ignore error response
8706                return;
8707            }
8708
8709            if (this._contentLength === null) {
8710                var openNextRange = false;
8711
8712                if (this._waitForTotalLength) {
8713                    this._waitForTotalLength = false;
8714                    this._totalLengthReceived = true;
8715                    openNextRange = true;
8716
8717                    var total = e.total;
8718                    this._internalAbort();
8719                    if (total != null & total !== 0) {
8720                        this._totalLength = total;
8721                    }
8722                }
8723
8724                // calculate currrent request range's contentLength
8725                if (this._range.to === -1) {
8726                    this._contentLength = this._totalLength - this._range.from;
8727                } else {
8728                    // to !== -1
8729                    this._contentLength = this._range.to - this._range.from + 1;
8730                }
8731
8732                if (openNextRange) {
8733                    this._openSubRange();
8734                    return;
8735                }
8736                if (this._onContentLengthKnown) {
8737                    this._onContentLengthKnown(this._contentLength);
8738                }
8739            }
8740
8741            var delta = e.loaded - this._lastTimeLoaded;
8742            this._lastTimeLoaded = e.loaded;
8743            this._speedSampler.addBytes(delta);
8744        }
8745    }, {
8746        key: '_normalizeSpeed',
8747        value: function _normalizeSpeed(input) {
8748            var list = this._chunkSizeKBList;
8749            var last = list.length - 1;
8750            var mid = 0;
8751            var lbound = 0;
8752            var ubound = last;
8753
8754            if (input < list[0]) {
8755                return list[0];
8756            }
8757
8758            while (lbound <= ubound) {
8759                mid = lbound + Math.floor((ubound - lbound) / 2);
8760                if (mid === last || input >= list[mid] && input < list[mid + 1]) {
8761                    return list[mid];
8762                } else if (list[mid] < input) {
8763                    lbound = mid + 1;
8764                } else {
8765                    ubound = mid - 1;
8766                }
8767            }
8768        }
8769    }, {
8770        key: '_onLoad',
8771        value: function _onLoad(e) {
8772            if (this._status === _loader.LoaderStatus.kError) {
8773                // Ignore error response
8774                return;
8775            }
8776
8777            if (this._waitForTotalLength) {
8778                this._waitForTotalLength = false;
8779                return;
8780            }
8781
8782            this._lastTimeLoaded = 0;
8783            var KBps = this._speedSampler.lastSecondKBps;
8784            if (KBps === 0) {
8785                this._zeroSpeedChunkCount++;
8786                if (this._zeroSpeedChunkCount >= 3) {
8787                    // Try get currentKBps after 3 chunks
8788                    KBps = this._speedSampler.currentKBps;
8789                }
8790            }
8791
8792            if (KBps !== 0) {
8793                var normalized = this._normalizeSpeed(KBps);
8794                if (this._currentSpeedNormalized !== normalized) {
8795                    this._currentSpeedNormalized = normalized;
8796                    this._currentChunkSizeKB = normalized;
8797                }
8798            }
8799
8800            var chunk = e.target.response;
8801            var byteStart = this._range.from + this._receivedLength;
8802            this._receivedLength += chunk.byteLength;
8803
8804            var reportComplete = false;
8805
8806            if (this._contentLength != null && this._receivedLength < this._contentLength) {
8807                // continue load next chunk
8808                this._openSubRange();
8809            } else {
8810                reportComplete = true;
8811            }
8812
8813            // dispatch received chunk
8814            if (this._onDataArrival) {
8815                this._onDataArrival(chunk, byteStart, this._receivedLength);
8816            }
8817
8818            if (reportComplete) {
8819                this._status = _loader.LoaderStatus.kComplete;
8820                if (this._onComplete) {
8821                    this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
8822                }
8823            }
8824        }
8825    }, {
8826        key: '_onXhrError',
8827        value: function _onXhrError(e) {
8828            this._status = _loader.LoaderStatus.kError;
8829            var type = 0;
8830            var info = null;
8831
8832            if (this._contentLength && this._receivedLength > 0 && this._receivedLength < this._contentLength) {
8833                type = _loader.LoaderErrors.EARLY_EOF;
8834                info = { code: -1, msg: 'RangeLoader meet Early-Eof' };
8835            } else {
8836                type = _loader.LoaderErrors.EXCEPTION;
8837                info = { code: -1, msg: e.constructor.name + ' ' + e.type };
8838            }
8839
8840            if (this._onError) {
8841                this._onError(type, info);
8842            } else {
8843                throw new _exception.RuntimeException(info.msg);
8844            }
8845        }
8846    }, {
8847        key: 'currentSpeed',
8848        get: function get() {
8849            return this._speedSampler.lastSecondKBps;
8850        }
8851    }]);
8852
8853    return RangeLoader;
8854}(_loader.BaseLoader);
8855
8856exports.default = RangeLoader;
8857
8858},{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24,"./speed-sampler.js":27}],32:[function(_dereq_,module,exports){
8859'use strict';
8860
8861Object.defineProperty(exports, "__esModule", {
8862    value: true
8863});
8864
8865var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
8866
8867var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
8868                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
8869                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
8870                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
8871                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
8872                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
8873                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
8873not use this file except in compliance with the License.
8874                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
8875                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
8876                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
8877                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
8878                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
8879                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
8880                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8881                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
8882                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
8883                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
8884
8885var _events = _dereq_('events');
8886
8887var _events2 = _interopRequireDefault(_events);
8888
8889var _logger = _dereq_('../utils/logger.js');
8890
8891var _logger2 = _interopRequireDefault(_logger);
8892
8893var _browser = _dereq_('../utils/browser.js');
8894
8895var _browser2 = _interopRequireDefault(_browser);
8896
8897var _playerEvents = _dereq_('./player-events.js');
8898
8899var _playerEvents2 = _interopRequireDefault(_playerEvents);
8900
8901var _transmuxer = _dereq_('../core/transmuxer.js');
8902
8903var _transmuxer2 = _interopRequireDefault(_transmuxer);
8904
8905var _transmuxingEvents = _dereq_('../core/transmuxing-events.js');
8906
8907var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
8908
8909var _mseController = _dereq_('../core/mse-controller.js');
8910
8911var _mseController2 = _interopRequireDefault(_mseController);
8912
8913var _mseEvents = _dereq_('../core/mse-events.js');
8914
8915var _mseEvents2 = _interopRequireDefault(_mseEvents);
8916
8917var _playerErrors = _dereq_('./player-errors.js');
8918
8919var _config = _dereq_('../config.js');
8920
8921var _exception = _dereq_('../utils/exception.js');
8922
8923function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8924
8925function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8926
8927var FlvPlayer = function () {
8928    function FlvPlayer(mediaDataSource, config) {
8929        _classCallCheck(this, FlvPlayer);
8930
8931        this.TAG = 'FlvPlayer';
8932        this._type = 'FlvPlayer';
8933        this._emitter = new _events2.default();
8934
8935        this._config = (0, _config.createDefaultConfig)();
8936        if ((typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object') {
8937            Object.assign(this._config, config);
8938        }
8939
8940        if (mediaDataSource.type.toLowerCase() !== 'flv') {
8941            throw new _exception.InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');
8942        }
8943
8944        if (mediaDataSource.isLive === true) {
8945            this._config.isLive = true;
8946        }
8947
8948        this.e = {
8949            onvLoadedMetadata: this._onvLoadedMetadata.bind(this),
8950            onvSeeking: this._onvSeeking.bind(this),
8951            onvCanPlay: this._onvCanPlay.bind(this),
8952            onvStalled: this._onvStalled.bind(this),
8953            onvProgress: this._onvProgress.bind(this)
8954        };
8955
8956        if (self.performance && self.performance.now) {
8957            this._now = self.performance.now.bind(self.performance);
8958        } else {
8959            this._now = Date.now;
8960        }
8961
8962        this._pendingSeekTime = null; // in seconds
8963        this._requestSetTime = false;
8964        this._seekpointRecord = null;
8965        this._progressChecker = null;
8966
8967        this._mediaDataSource = mediaDataSource;
8968        this._mediaElement = null;
8969        this._msectl = null;
8970        this._transmuxer = null;
8971
8972        this._mseSourceOpened = false;
8973        this._hasPendingLoad = false;
8974        this._receivedCanPlay = false;
8975
8976        this._mediaInfo = null;
8977        this._statisticsInfo = null;
8978
8979        var chromeNeedIDRFix = _browser2.default.chrome && (_browser2.default.version.major < 50 || _browser2.default.version.major === 50 && _browser2.default.version.build < 2661);
8980        this._alwaysSeekKeyframe = chromeNeedIDRFix || _browser2.default.msedge || _browser2.default.msie ? true : false;
8981
8982        if (this._alwaysSeekKeyframe) {
8983            this._config.accurateSeek = false;
8984        }
8985    }
8986
8987    _createClass(FlvPlayer, [{
8988        key: 'destroy',
8989        value: function destroy() {
8990            if (this._progressChecker != null) {
8991                window.clearInterval(this._progressChecker);
8992                this._progressChecker = null;
8993            }
8994            if (this._transmuxer) {
8995                this.unload();
8996            }
8997            if (this._mediaElement) {
8998                this.detachMediaElement();
8999            }
9000            this.e = null;
9001            this._mediaDataSource = null;
9002
9003            this._emitter.removeAllListeners();
9004            this._emitter = null;
9005        }
9006    }, {
9007        key: 'on',
9008        value: function on(event, listener) {
9009            var _this = this;
9010
9011            if (event === _playerEvents2.default.MEDIA_INFO) {
9012                if (this._mediaInfo != null) {
9013                    Promise.resolve().then(function () {
9014                        _this._emitter.emit(_playerEvents2.default.MEDIA_INFO, _this.mediaInfo);
9015                    });
9016                }
9017            } else if (event === _playerEvents2.default.STATISTICS_INFO) {
9018                if (this._statisticsInfo != null) {
9019                    Promise.resolve().then(function () {
9020                        _this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, _this.statisticsInfo);
9021                    });
9022                }
9023            }
9024            this._emitter.addListener(event, listener);
9025        }
9026    }, {
9027        key: 'off',
9028        value: function off(event, listener) {
9029            this._emitter.removeListener(event, listener);
9030        }
9031    }, {
9032        key: 'attachMediaElement',
9033        value: function attachMediaElement(mediaElement) {
9034            var _this2 = this;
9035
9036            this._mediaElement = mediaElement;
9037            mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);
9038            mediaElement.addEventListener('seeking', this.e.onvSeeking);
9039            mediaElement.addEventListener('canplay', this.e.onvCanPlay);
9040            mediaElement.addEventListener('stalled', this.e.onvStalled);
9041            mediaElement.addEventListener('progress', this.e.onvProgress);
9042
9043            this._msectl = new _mseController2.default(this._config);
9044
9045            this._msectl.on(_mseEvents2.default.UPDATE_END, this._onmseUpdateEnd.bind(this));
9046            this._msectl.on(_mseEvents2.default.BUFFER_FULL, this._onmseBufferFull.bind(this));
9047            this._msectl.on(_mseEvents2.default.SOURCE_OPEN, function () {
9048                _this2._mseSourceOpened = true;
9049                if (_this2._hasPendingLoad) {
9050                    _this2._hasPendingLoad = false;
9051                    _this2.load();
9052                }
9053            });
9054            this._msectl.on(_mseEvents2.default.ERROR, function (info) {
9055                _this2._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.MEDIA_ERROR, _playerErrors.ErrorDetails.MEDIA_MSE_ERROR, info);
9056            });
9057
9058            this._msectl.attachMediaElement(mediaElement);
9059
9060            if (this._pendingSeekTime != null) {
9061                try {
9062                    mediaElement.currentTime = this._pendingSeekTime;
9063                    this._pendingSeekTime = null;
9064                } catch (e) {
9065                    // IE11 may throw InvalidStateError if readyState === 0
9066                    // We can defer set currentTime operation after loadedmetadata
9067                }
9068            }
9069        }
9070    }, {
vendor: 5,054 bytes, lines 9071-9168
9071        key: 'detachMediaElement',
9072        value: function detachMediaElement() {
9073            if (this._mediaElement) {
9074                this._msectl.detachMediaElement();
9075                this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);
9076                this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);
9077                this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);
9078                this._mediaElement.removeEventListener('stalled', this.e.onvStalled);
9079                this._mediaElement.removeEventListener('progress', this.e.onvProgress);
9080                this._mediaElement = null;
9081            }
9082            if (this._msectl) {
9083                this._msectl.destroy();
9084                this._msectl = null;
9085            }
9086        }
9087    }, {
9088        key: 'load',
9089        value: function load() {
9090            var _this3 = this;
9091
9092            if (!this._mediaElement) {
9093                throw new _exception.IllegalStateException('HTMLMediaElement must be attached before load()!');
9094            }
9095            if (this._transmuxer) {
9096                throw new _exception.IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');
9097            }
9098            if (this._hasPendingLoad) {
9099                return;
9100            }
9101
9102            if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {
9103                this._hasPendingLoad = true;
9104                return;
9105            }
9106
9107            if (this._mediaElement.readyState > 0) {
9108                this._requestSetTime = true;
9109                // IE11 may throw InvalidStateError if readyState === 0
9110                this._mediaElement.currentTime = 0;
9111            }
9112
9113            this._transmuxer = new _transmuxer2.default(this._mediaDataSource, this._config);
9114
9115            this._transmuxer.on(_transmuxingEvents2.default.INIT_SEGMENT, function (type, is) {
9116                _this3._msectl.appendInitSegment(is);
9117            });
9118            this._transmuxer.on(_transmuxingEvents2.default.MEDIA_SEGMENT, function (type, ms) {
9119                _this3._msectl.appendMediaSegment(ms);
9120
9121                // lazyLoad check
9122                if (_this3._config.lazyLoad && !_this3._config.isLive) {
9123                    var currentTime = _this3._mediaElement.currentTime;
9124                    if (ms.info.endDts >= (currentTime + _this3._config.lazyLoadMaxDuration) * 1000) {
9125                        if (_this3._progressChecker == null) {
9126                            _logger2.default.v(_this3.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');
9127                            _this3._suspendTransmuxer();
9128                        }
9129                    }
9130                }
9131            });
9132            this._transmuxer.on(_transmuxingEvents2.default.LOADING_COMPLETE, function () {
9133                _this3._msectl.endOfStream();
9134                _this3._emitter.emit(_playerEvents2.default.LOADING_COMPLETE);
9135            });
9136            this._transmuxer.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, function () {
9137                _this3._emitter.emit(_playerEvents2.default.RECOVERED_EARLY_EOF);
9138            });
9139            this._transmuxer.on(_transmuxingEvents2.default.IO_ERROR, function (detail, info) {
9140                _this3._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.NETWORK_ERROR, detail, info);
9141            });
9142            this._transmuxer.on(_transmuxingEvents2.default.DEMUX_ERROR, function (detail, info) {
9143                _this3._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.MEDIA_ERROR, detail, { code: -1, msg: info });
9144            });
9145            this._transmuxer.on(_transmuxingEvents2.default.MEDIA_INFO, function (mediaInfo) {
9146                _this3._mediaInfo = mediaInfo;
9147                _this3._emitter.emit(_playerEvents2.default.MEDIA_INFO, Object.assign({}, mediaInfo));
9148            });
9149            this._transmuxer.on(_transmuxingEvents2.default.METADATA_ARRIVED, function (metadata) {
9150                _this3._emitter.emit(_playerEvents2.default.METADATA_ARRIVED, metadata);
9151            });
9152            this._transmuxer.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, function (data) {
9153                _this3._emitter.emit(_playerEvents2.default.SCRIPTDATA_ARRIVED, data);
9154            });
9155            this._transmuxer.on(_transmuxingEvents2.default.STATISTICS_INFO, function (statInfo) {
9156                _this3._statisticsInfo = _this3._fillStatisticsInfo(statInfo);
9157                _this3._emitter.emit(_playerEvents2.default.STATISTICS_INFO, Object.assign({}, _this3._statisticsInfo));
9158            });
9159            this._transmuxer.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, function (milliseconds) {
9160                if (_this3._mediaElement && !_this3._config.accurateSeek) {
9161                    _this3._requestSetTime = true;
9162                    _this3._mediaElement.currentTime = milliseconds / 1000;
9163                }
9164            });
9165
9166            this._transmuxer.open();
9167        }
9168    }, {
9169        key: 'unload',
9170        value: function unload() {
9171            if (this._mediaElement) {
9172                this._mediaElement.pause();
9173            }
9174            if (this._msectl) {
9175                this._msectl.seek(0);
9176            }
9177            if (this._transmuxer) {
9178                this._transmuxer.close();
9179                this._transmuxer.destroy();
9180                this._transmuxer = null;
9181            }
9182        }
9183    }, {
9184        key: 'play',
9185        value: function play() {
9186            return this._mediaElement.play();
9187        }
9188    }, {
9189        key: 'pause',
9190        value: function pause() {
9191            this._mediaElement.pause();
9192        }
9193    }, {
9194        key: '_fillStatisticsInfo',
9195        value: function _fillStatisticsInfo(statInfo) {
9196            statInfo.playerType = this._type;
9197
9198            if (!(this._mediaElement instanceof HTMLVideoElement)) {
9199                return statInfo;
9200            }
9201
9202            var hasQualityInfo = true;
9203            var decoded = 0;
9204            var dropped = 0;
9205
9206            if (this._mediaElement.getVideoPlaybackQuality) {
9207                var quality = this._mediaElement.getVideoPlaybackQuality();
9208                decoded = quality.totalVideoFrames;
9209                dropped = quality.droppedVideoFrames;
9210            } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {
9211                decoded = this._mediaElement.webkitDecodedFrameCount;
9212                dropped = this._mediaElement.webkitDroppedFrameCount;
9213            } else {
9214                hasQualityInfo = false;
9215            }
9216
9217            if (hasQualityInfo) {
9218                statInfo.decodedFrames = decoded;
9219                statInfo.droppedFrames = dropped;
9220            }
9221
9222            return statInfo;
9223        }
9224    }, {
9225        key: '_onmseUpdateEnd',
9226        value: function _onmseUpdateEnd() {
9227            if (!this._config.lazyLoad || this._config.isLive) {
9228                return;
9229            }
9230
9231            var buffered = this._mediaElement.buffered;
9232            var currentTime = this._mediaElement.currentTime;
9233            var currentRangeStart = 0;
9234            var currentRangeEnd = 0;
9235
9236            for (var i = 0; i < buffered.length; i++) {
9237                var start = buffered.start(i);
9238                var end = buffered.end(i);
9239                if (start <= currentTime && currentTime < end) {
9240                    currentRangeStart = start;
9241                    currentRangeEnd = end;
9242                    break;
9243                }
9244            }
9245
9246            if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {
9247                _logger2.default.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');
9248                this._suspendTransmuxer();
9249            }
9250        }
9251    }, {
9252        key: '_onmseBufferFull',
9253        value: function _onmseBufferFull() {
9254            _logger2.default.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');
9255            if (this._progressChecker == null) {
9256                this._suspendTransmuxer();
9257            }
9258        }
9259    }, {
9260        key: '_suspendTransmuxer',
9261        value: function _suspendTransmuxer() {
9262            if (this._transmuxer) {
9263                this._transmuxer.pause();
9264
9265                if (this._progressChecker == null) {
9266                    this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);
9267                }
9268            }
9269        }
9270    }, {
9271        key: '_checkProgressAndResume',
9272        value: function _checkProgressAndResume() {
9273            var currentTime = this._mediaElement.currentTime;
9274            var buffered = this._mediaElement.buffered;
9275
9276            var needResume = false;
9277
9278            for (var i = 0; i < buffered.length; i++) {
9279                var from = buffered.start(i);
9280                var to = buffered.end(i);
9281                if (currentTime >= from && currentTime < to) {
9282                    if (currentTime >= to - this._config.lazyLoadRecoverDuration) {
9283                        needResume = true;
9284                    }
9285                    break;
9286                }
9287            }
9288
9289            if (needResume) {
9290                window.clearInterval(this._progressChecker);
9291                this._progressChecker = null;
9292                if (needResume) {
9293                    _logger2.default.v(this.TAG, 'Continue loading from paused position');
9294                    this._transmuxer.resume();
9295                }
9296            }
9297        }
9298    }, {
vendor: 4,310 bytes, lines 9299-9392
9299        key: '_isTimepointBuffered',
9300        value: function _isTimepointBuffered(seconds) {
9301            var buffered = this._mediaElement.buffered;
9302
9303            for (var i = 0; i < buffered.length; i++) {
9304                var from = buffered.start(i);
9305                var to = buffered.end(i);
9306                if (seconds >= from && seconds < to) {
9307                    return true;
9308                }
9309            }
9310            return false;
9311        }
9312    }, {
9313        key: '_internalSeek',
9314        value: function _internalSeek(seconds) {
9315            var directSeek = this._isTimepointBuffered(seconds);
9316
9317            var directSeekBegin = false;
9318            var directSeekBeginTime = 0;
9319
9320            if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {
9321                var videoBeginTime = this._mediaElement.buffered.start(0);
9322                if (videoBeginTime < 1.0 && seconds < videoBeginTime || _browser2.default.safari) {
9323                    directSeekBegin = true;
9324                    // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid
9325                    directSeekBeginTime = _browser2.default.safari ? 0.1 : videoBeginTime;
9326                }
9327            }
9328
9329            if (directSeekBegin) {
9330                // seek to video begin, set currentTime directly if beginPTS buffered
9331                this._requestSetTime = true;
9332                this._mediaElement.currentTime = directSeekBeginTime;
9333            } else if (directSeek) {
9334                // buffered position
9335                if (!this._alwaysSeekKeyframe) {
9336                    this._requestSetTime = true;
9337                    this._mediaElement.currentTime = seconds;
9338                } else {
9339                    var idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));
9340                    this._requestSetTime = true;
9341                    if (idr != null) {
9342                        this._mediaElement.currentTime = idr.dts / 1000;
9343                    } else {
9344                        this._mediaElement.currentTime = seconds;
9345                    }
9346                }
9347                if (this._progressChecker != null) {
9348                    this._checkProgressAndResume();
9349                }
9350            } else {
9351                if (this._progressChecker != null) {
9352                    window.clearInterval(this._progressChecker);
9353                    this._progressChecker = null;
9354                }
9355                this._msectl.seek(seconds);
9356                this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds
9357                // no need to set mediaElement.currentTime if non-accurateSeek,
9358                // just wait for the recommend_seekpoint callback
9359                if (this._config.accurateSeek) {
9360                    this._requestSetTime = true;
9361                    this._mediaElement.currentTime = seconds;
9362                }
9363            }
9364        }
9365    }, {
9366        key: '_checkAndApplyUnbufferedSeekpoint',
9367        value: function _checkAndApplyUnbufferedSeekpoint() {
9368            if (this._seekpointRecord) {
9369                if (this._seekpointRecord.recordTime <= this._now() - 100) {
9370                    var target = this._mediaElement.currentTime;
9371                    this._seekpointRecord = null;
9372                    if (!this._isTimepointBuffered(target)) {
9373                        if (this._progressChecker != null) {
9374                            window.clearTimeout(this._progressChecker);
9375                            this._progressChecker = null;
9376                        }
9377                        // .currentTime is consists with .buffered timestamp
9378                        // Chrome/Edge use DTS, while FireFox/Safari use PTS
9379                        this._msectl.seek(target);
9380                        this._transmuxer.seek(Math.floor(target * 1000));
9381                        // set currentTime if accurateSeek, or wait for recommend_seekpoint callback
9382                        if (this._config.accurateSeek) {
9383                            this._requestSetTime = true;
9384                            this._mediaElement.currentTime = target;
9385                        }
9386                    }
9387                } else {
9388                    window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);
9389                }
9390            }
9391        }
9392    }, {
9393        key: '_checkAndResumeStuckPlayback',
9394        value: function _checkAndResumeStuckPlayback(stalled) {
9395            var media = this._mediaElement;
9396            if (stalled || !this._receivedCanPlay || media.readyState < 2) {
9397                // HAVE_CURRENT_DATA
9398                var buffered = media.buffered;
9399                if (buffered.length > 0 && media.currentTime < buffered.start(0)) {
9400                    _logger2.default.w(this.TAG, 'Playback seems stuck at ' + media.currentTime + ', seek to ' + buffered.start(0));
9401                    this._requestSetTime = true;
9402                    this._mediaElement.currentTime = buffered.start(0);
9403                    this._mediaElement.removeEventListener('progress', this.e.onvProgress);
9404                }
9405            } else {
9406                // Playback didn't stuck, remove progress event listener
9407                this._mediaElement.removeEventListener('progress', this.e.onvProgress);
9408            }
9409        }
9410    }, {
9411        key: '_onvLoadedMetadata',
9412        value: function _onvLoadedMetadata(e) {
9413            if (this._pendingSeekTime != null) {
9414                this._mediaElement.currentTime = this._pendingSeekTime;
9415                this._pendingSeekTime = null;
9416            }
9417        }
9418    }, {
9419        key: '_onvSeeking',
9420        value: function _onvSeeking(e) {
9421            // handle seeking request from browser's progress bar
9422            var target = this._mediaElement.currentTime;
9423            var buffered = this._mediaElement.buffered;
9424
9425            if (this._requestSetTime) {
9426                this._requestSetTime = false;
9427                return;
9428            }
9429
9430            if (target < 1.0 && buffered.length > 0) {
9431                // seek to video begin, set currentTime directly if beginPTS buffered
9432                var videoBeginTime = buffered.start(0);
9433                if (videoBeginTime < 1.0 && target < videoBeginTime || _browser2.default.safari) {
9434                    this._requestSetTime = true;
9435                    // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid
9436                    this._mediaElement.currentTime = _browser2.default.safari ? 0.1 : videoBeginTime;
9437                    return;
9438                }
9439            }
9440
9441            if (this._isTimepointBuffered(target)) {
9442                if (this._alwaysSeekKeyframe) {
9443                    var idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));
9444                    if (idr != null) {
9445                        this._requestSetTime = true;
9446                        this._mediaElement.currentTime = idr.dts / 1000;
9447                    }
9448                }
9449                if (this._progressChecker != null) {
9450                    this._checkProgressAndResume();
9451                }
9452                return;
9453            }
9454
9455            this._seekpointRecord = {
9456                seekPoint: target,
9457                recordTime: this._now()
9458            };
9459            window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);
9460        }
9461    }, {
9462        key: '_onvCanPlay',
9463        value: function _onvCanPlay(e) {
9464            this._receivedCanPlay = true;
9465            this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);
9466        }
9467    }, {
9468        key: '_onvStalled',
9469        value: function _onvStalled(e) {
9470            this._checkAndResumeStuckPlayback(true);
9471        }
9472    }, {
9473        key: '_onvProgress',
9474        value: function _onvProgress(e) {
9475            this._checkAndResumeStuckPlayback();
9476        }
9477    }, {
9478        key: 'type',
9479        get: function get() {
9480            return this._type;
9481        }
9482    }, {
9483        key: 'buffered',
9484        get: function get() {
9485            return this._mediaElement.buffered;
9486        }
9487    }, {
9488        key: 'duration',
9489        get: function get() {
9490            return this._mediaElement.duration;
9491        }
9492    }, {
9493        key: 'volume',
9494        get: function get() {
9495            return this._mediaElement.volume;
9496        },
9497        set: function set(value) {
9498            this._mediaElement.volume = value;
9499        }
9500    }, {
9501        key: 'muted',
9502        get: function get() {
9503            return this._mediaElement.muted;
9504        },
9505        set: function set(muted) {
9506            this._mediaElement.muted = muted;
9507        }
9508    }, {
9509        key: 'currentTime',
9510        get: function get() {
9511            if (this._mediaElement) {
9512                return this._mediaElement.currentTime;
9513            }
9514            return 0;
9515        },
9516        set: function set(seconds) {
9517            if (this._mediaElement) {
9518                this._internalSeek(seconds);
9519            } else {
9520                this._pendingSeekTime = seconds;
9521            }
9522        }
9523    }, {
9524        key: 'mediaInfo',
9525        get: function get() {
9526            return Object.assign({}, this._mediaInfo);
9527        }
9528    }, {
9529        key: 'statisticsInfo',
9530        get: function get() {
9531            if (this._statisticsInfo == null) {
9532                this._statisticsInfo = {};
9533            }
9534            this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);
9535            return Object.assign({}, this._statisticsInfo);
9536        }
9537    }]);
9538
9539    return FlvPlayer;
9540}();
9541
9542exports.default = FlvPlayer;
9543
9544},{"../config.js":5,"../core/mse-controller.js":9,"../core/mse-events.js":10,"../core/transmuxer.js":11,"../core/transmuxing-events.js":13,"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./player-errors.js":34,"./player-events.js":35,"events":2}],33:[function(_dereq_,module,exports){
9545'use strict';
9546
9547Object.defineProperty(exports, "__esModule", {
9548    value: true
9549});
9550
9551var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
9552
9553var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
9554                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
9555                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
9556                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
9557                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
9558                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
9559                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
9559not use this file except in compliance with the License.
9560                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
9561                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
9562                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
9563                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
9564                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
9565                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
9566                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9567                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
9568                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
9569                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
9570
9571var _events = _dereq_('events');
9572
9573var _events2 = _interopRequireDefault(_events);
9574
9575var _playerEvents = _dereq_('./player-events.js');
9576
9577var _playerEvents2 = _interopRequireDefault(_playerEvents);
9578
9579var _config = _dereq_('../config.js');
9580
9581var _exception = _dereq_('../utils/exception.js');
9582
9583function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9584
9585function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9586
9587// Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. 
9588var NativePlayer = function () {
9589    function NativePlayer(mediaDataSource, config) {
9590        _classCallCheck(this, NativePlayer);
9591
9592        this.TAG = 'NativePlayer';
9593        this._type = 'NativePlayer';
9594        this._emitter = new _events2.default();
9595
9596        this._config = (0, _config.createDefaultConfig)();
9597        if ((typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object') {
9598            Object.assign(this._config, config);
9599        }
9600
9601        if (mediaDataSource.type.toLowerCase() === 'flv') {
9602            throw new _exception.InvalidArgumentException('NativePlayer does\'t support flv MediaDataSource input!');
9603        }
9604        if (mediaDataSource.hasOwnProperty('segments')) {
9605            throw new _exception.InvalidArgumentException('NativePlayer(' + mediaDataSource.type + ') doesn\'t support multipart playback!');
9606        }
9607
9608        this.e = {
9609            onvLoadedMetadata: this._onvLoadedMetadata.bind(this)
9610        };
9611
9612        this._pendingSeekTime = null;
9613        this._statisticsReporter = null;
9614
9615        this._mediaDataSource = mediaDataSource;
9616        this._mediaElement = null;
9617    }
9618
9619    _createClass(NativePlayer, [{
9620        key: 'destroy',
9621        value: function destroy() {
9622            if (this._mediaElement) {
9623                this.unload();
9624                this.detachMediaElement();
9625            }
9626            this.e = null;
9627            this._mediaDataSource = null;
9628            this._emitter.removeAllListeners();
9629            this._emitter = null;
9630        }
9631    }, {
9632        key: 'on',
9633        value: function on(event, listener) {
9634            var _this = this;
9635
9636            if (event === _playerEvents2.default.MEDIA_INFO) {
9637                if (this._mediaElement != null && this._mediaElement.readyState !== 0) {
9638                    // HAVE_NOTHING
9639                    Promise.resolve().then(function () {
9640                        _this._emitter.emit(_playerEvents2.default.MEDIA_INFO, _this.mediaInfo);
9641                    });
9642                }
9643            } else if (event === _playerEvents2.default.STATISTICS_INFO) {
9644                if (this._mediaElement != null && this._mediaElement.readyState !== 0) {
9645                    Promise.resolve().then(function () {
9646                        _this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, _this.statisticsInfo);
9647                    });
9648                }
9649            }
9650            this._emitter.addListener(event, listener);
9651        }
9652    }, {
9653        key: 'off',
9654        value: function off(event, listener) {
9655            this._emitter.removeListener(event, listener);
9656        }
9657    }, {
9658        key: 'attachMediaElement',
9659        value: function attachMediaElement(mediaElement) {
9660            this._mediaElement = mediaElement;
9661            mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);
9662
9663            if (this._pendingSeekTime != null) {
9664                try {
9665                    mediaElement.currentTime = this._pendingSeekTime;
9666                    this._pendingSeekTime = null;
9667                } catch (e) {
9668                    // IE11 may throw InvalidStateError if readyState === 0
9669                    // Defer set currentTime operation after loadedmetadata
9670                }
9671            }
9672        }
9673    }, {
9674        key: 'detachMediaElement',
9675        value: function detachMediaElement() {
9676            if (this._mediaElement) {
9677                this._mediaElement.src = '';
9678                this._mediaElement.removeAttribute('src');
9679                this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);
9680                this._mediaElement = null;
9681            }
9682            if (this._statisticsReporter != null) {
9683                window.clearInterval(this._statisticsReporter);
9684                this._statisticsReporter = null;
9685            }
9686        }
9687    }, {
9688        key: 'load',
9689        value: function load() {
9690            if (!this._mediaElement) {
9691                throw new _exception.IllegalStateException('HTMLMediaElement must be attached before load()!');
9692            }
9693            this._mediaElement.src = this._mediaDataSource.url;
9694
9695            if (this._mediaElement.readyState > 0) {
9696                this._mediaElement.currentTime = 0;
9697            }
9698
9699            this._mediaElement.preload = 'auto';
9700            this._mediaElement.load();
9701            this._statisticsReporter = window.setInterval(this._reportStatisticsInfo.bind(this), this._config.statisticsInfoReportInterval);
9702        }
9703    }, {
9704        key: 'unload',
9705        value: function unload() {
9706            if (this._mediaElement) {
9707                this._mediaElement.src = '';
9708                this._mediaElement.removeAttribute('src');
9709            }
9710            if (this._statisticsReporter != null) {
9711                window.clearInterval(this._statisticsReporter);
9712                this._statisticsReporter = null;
9713            }
9714        }
9715    }, {
9716        key: 'play',
9717        value: function play() {
9718            return this._mediaElement.play();
9719        }
9720    }, {
9721        key: 'pause',
9722        value: function pause() {
9723            this._mediaElement.pause();
9724        }
9725    }, {
9726        key: '_onvLoadedMetadata',
9727        value: function _onvLoadedMetadata(e) {
9728            if (this._pendingSeekTime != null) {
9729                this._mediaElement.currentTime = this._pendingSeekTime;
9730                this._pendingSeekTime = null;
9731            }
9732            this._emitter.emit(_playerEvents2.default.MEDIA_INFO, this.mediaInfo);
9733        }
9734    }, {
9735        key: '_reportStatisticsInfo',
9736        value: function _reportStatisticsInfo() {
9737            this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, this.statisticsInfo);
9738        }
9739    }, {
9740        key: 'type',
9741        get: function get() {
9742            return this._type;
9743        }
9744    }, {
9745        key: 'buffered',
9746        get: function get() {
9747            return this._mediaElement.buffered;
9748        }
9749    }, {
9750        key: 'duration',
9751        get: function get() {
9752            return this._mediaElement.duration;
9753        }
9754    }, {
9755        key: 'volume',
9756        get: function get() {
9757            return this._mediaElement.volume;
9758        },
9759        set: function set(value) {
9760            this._mediaElement.volume = value;
9761        }
9762    }, {
9763        key: 'muted',
9764        get: function get() {
9765            return this._mediaElement.muted;
9766        },
9767        set: function set(muted) {
9768            this._mediaElement.muted = muted;
9769        }
9770    }, {
9771        key: 'currentTime',
9772        get: function get() {
9773            if (this._mediaElement) {
9774                return this._mediaElement.currentTime;
9775            }
9776            return 0;
9777        },
9778        set: function set(seconds) {
9779            if (this._mediaElement) {
9780                this._mediaElement.currentTime = seconds;
9781            } else {
9782                this._pendingSeekTime = seconds;
9783            }
9784        }
9785    }, {
9786        key: 'mediaInfo',
9787        get: function get() {
9788            var mediaPrefix = this._mediaElement instanceof HTMLAudioElement ? 'audio/' : 'video/';
9789            var info = {
9790                mimeType: mediaPrefix + this._mediaDataSource.type
9791            };
9792            if (this._mediaElement) {
9793                info.duration = Math.floor(this._mediaElement.duration * 1000);
9794                if (this._mediaElement instanceof HTMLVideoElement) {
9795                    info.width = this._mediaElement.videoWidth;
9796                    info.height = this._mediaElement.videoHeight;
9797                }
9798            }
9799            return info;
9800        }
9801    }, {
9802        key: 'statisticsInfo',
9803        get: function get() {
9804            var info = {
9805                playerType: this._type,
9806                url: this._mediaDataSource.url
9807            };
9808
9809            if (!(this._mediaElement instanceof HTMLVideoElement)) {
9810                return info;
9811            }
9812
9813            var hasQualityInfo = true;
9814            var decoded = 0;
9815            var dropped = 0;
9816
9817            if (this._mediaElement.getVideoPlaybackQuality) {
9818                var quality = this._mediaElement.getVideoPlaybackQuality();
9819                decoded = quality.totalVideoFrames;
9820                dropped = quality.droppedVideoFrames;
9821            } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {
9822                decoded = this._mediaElement.webkitDecodedFrameCount;
9823                dropped = this._mediaElement.webkitDroppedFrameCount;
9824            } else {
9825                hasQualityInfo = false;
9826            }
9827
9828            if (hasQualityInfo) {
9829                info.decodedFrames = decoded;
9830                info.droppedFrames = dropped;
9831            }
9832
9833            return info;
9834        }
9835    }]);
9836
9837    return NativePlayer;
9838}();
9839
9840exports.default = NativePlayer;
9841
9842},{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,"events":2}],34:[function(_dereq_,module,exports){
9843'use strict';
9844
9845Object.defineProperty(exports, "__esModule", {
9846    value: true
9847});
9848exports.ErrorDetails = exports.ErrorTypes = undefined;
9849
9850var _loader = _dereq_('../io/loader.js');
9851
9852var _demuxErrors = _dereq_('../demux/demux-errors.js');
9853
9854var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
9855
9856function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9857
9858/*
9859 * Copyright (C) 2016 Bilibili. All Rights Reserved.
9860 *
9861 * @author zheng qian <[email protected]>
9862 *
9863 * Licensed under the Apache License, Version 2.0 (the "License");
9864 * you may not use this file except in compliance with the License.
9865 * You may obtain a copy of the License at
9866 *
9867 *     http://www.apache.org/licenses/LICENSE-2.0
9868 *
9869 * Unless required by applicable law or agreed to in writing, software
9870 * distributed under the License is distributed on an "AS IS" BASIS,
9871 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9872 * See the License for the specific language governing permissions and
9873 * limitations under the License.
9874 */
9875
9876var ErrorTypes = exports.ErrorTypes = {
9877    NETWORK_ERROR: 'NetworkError',
9878    MEDIA_ERROR: 'MediaError',
9879    OTHER_ERROR: 'OtherError'
9880};
9881
9882var ErrorDetails = exports.ErrorDetails = {
9883    NETWORK_EXCEPTION: _loader.LoaderErrors.EXCEPTION,
9884    NETWORK_STATUS_CODE_INVALID: _loader.LoaderErrors.HTTP_STATUS_CODE_INVALID,
9885    NETWORK_TIMEOUT: _loader.LoaderErrors.CONNECTING_TIMEOUT,
9886    NETWORK_UNRECOVERABLE_EARLY_EOF: _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF,
9887
9888    MEDIA_MSE_ERROR: 'MediaMSEError',
9889
9890    MEDIA_FORMAT_ERROR: _demuxErrors2.default.FORMAT_ERROR,
9891    MEDIA_FORMAT_UNSUPPORTED: _demuxErrors2.default.FORMAT_UNSUPPORTED,
9892    MEDIA_CODEC_UNSUPPORTED: _demuxErrors2.default.CODEC_UNSUPPORTED
9893};
9894
9895},{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(_dereq_,module,exports){
9896'use strict';
9897
9898Object.defineProperty(exports, "__esModule", {
9899  value: true
9900});
9901/*
9902 * Copyright (C) 2016 Bilibili. All Rights Reserved.
9903 *
9904 * @author zheng qian <[email protected]>
9905 *
9906 * Licensed under the Apache License, Version 2.0 (the "License");
9907 * you may not use this file except in compliance with the License.
9908 * You may obtain a copy of the License at
9909 *
9910 *     http://www.apache.org/licenses/LICENSE-2.0
9911 *
9912 * Unless required by applicable law or agreed to in writing, software
9913 * distributed under the License is distributed on an "AS IS" BASIS,
9914 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9915 * See the License for the specific language governing permissions and
9916 * limitations under the License.
9917 */
9918
9919var PlayerEvents = {
9920  ERROR: 'error',
9921  LOADING_COMPLETE: 'loading_complete',
9922  RECOVERED_EARLY_EOF: 'recovered_early_eof',
9923  MEDIA_INFO: 'media_info',
9924  METADATA_ARRIVED: 'metadata_arrived',
9925  SCRIPTDATA_ARRIVED: 'scriptdata_arrived',
9926  STATISTICS_INFO: 'statistics_info'
9927};
9928
9929exports.default = PlayerEvents;
9930
9931},{}],36:[function(_dereq_,module,exports){
9932'use strict';
9933
9934Object.defineProperty(exports, "__esModule", {
9935    value: true
9936});
9937
9938var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9939
9940function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9941
9942/*
9943 * Copyright (C) 2016 Bilibili. All Rights Reserved.
9944 *
9945 * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)
9946 * @author zheng qian <[email protected]>
9947 *
9948 * Licensed under the Apache License, Version 2.0 (the "License");
9949 * you may not use this file except in compliance with the License.
9950 * You may obtain a copy of the License at
9951 *
9952 *     http://www.apache.org/licenses/LICENSE-2.0
9953 *
9954 * Unless required by applicable law or agreed to in writing, software
9955 * distributed under the License is distributed on an "AS IS" BASIS,
9956 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9957 * See the License for the specific language governing permissions and
9958 * limitations under the License.
9959 */
9960
9961var AAC = function () {
9962    function AAC() {
9963        _classCallCheck(this, AAC);
9964    }
9965
9966    _createClass(AAC, null, [{
9967        key: 'getSilentFrame',
9968        value: function getSilentFrame(codec, channelCount) {
9969            if (codec === 'mp4a.40.2') {
9970                // handle LC-AAC
9971                if (channelCount === 1) {
9972                    return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
9973                } else if (channelCount === 2) {
9974                    return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
9975                } else if (channelCount === 3) {
9976                    return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
9977                } else if (channelCount === 4) {
9978                    return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
9979                } else if (channelCount === 5) {
9980                    return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
9981                } else if (channelCount === 6) {
9982                    return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
9983                }
9984            } else {
9985                // handle HE-AAC (mp4a.40.5 / mp4a.40.29)
9986                if (channelCount === 1) {
9987                    // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
9988                    return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
9989                } else if (channelCount === 2) {
9990                    // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
9991                    return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
9992                } else if (channelCount === 3) {
9993                    // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
9994                    return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
9995                }
9996            }
9997            return null;
9998        }
9999    }]);
10000
10001    return AAC;
10002}();
10003
10004exports.default = AAC;
10005
10006},{}],37:[function(_dereq_,module,exports){
10007'use strict';
10008
10009Object.defineProperty(exports, "__esModule", {
10010    value: true
10011});
10012
10013var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10014
10015function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10016
10017/*
10018 * Copyright (C) 2016 Bilibili. All Rights Reserved.
10019 *
10020 * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)
10021 * @author zheng qian <[email protected]>
10022 *
10023 * Licensed under the Apache License, Version 2.0 (the "License");
10024 * you may not use this file except in compliance with the License.
10025 * You may obtain a copy of the License at
10026 *
10027 *     http://www.apache.org/licenses/LICENSE-2.0
10028 *
10029 * Unless required by applicable law or agreed to in writing, software
10030 * distributed under the License is distributed on an "AS IS" BASIS,
10031 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10032 * See the License for the specific language governing permissions and
10033 * limitations under the License.
10034 */
10035
10036//  MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)
10037var MP4 = function () {
10038    function MP4() {
10039        _classCallCheck(this, MP4);
10040    }
10041
10042    _createClass(MP4, null, [{
10043        key: 'init',
10044        value: function init() {
10045            MP4.types = {
10046                avc1: [], avcC: [], btrt: [], dinf: [],
10047                dref: [], esds: [], ftyp: [], hdlr: [],
10048                mdat: [], mdhd: [], mdia: [], mfhd: [],
10049                minf: [], moof: [], moov: [], mp4a: [],
10050                mvex: [], mvhd: [], sdtp: [], stbl: [],
10051                stco: [], stsc: [], stsd: [], stsz: [],
10052                stts: [], tfdt: [], tfhd: [], traf: [],
10053                trak: [], trun: [], trex: [], tkhd: [],
10054                vmhd: [], smhd: [], '.mp3': []
10055            };
10056
10057            for (var name in MP4.types) {
10058                if (MP4.types.hasOwnProperty(name)) {
10059                    MP4.types[name] = [name.charCodeAt(0), name.charCodeAt(1), name.charCodeAt(2), name.charCodeAt(3)];
10060                }
10061            }
10062
10063            var constants = MP4.constants = {};
10064
10065            constants.FTYP = new Uint8Array([0x69, 0x73, 0x6F, 0x6D, // major_brand: isom
10066            0x0, 0x0, 0x0, 0x1, // minor_version: 0x01
10067            0x69, 0x73, 0x6F, 0x6D, // isom
10068            0x61, 0x76, 0x63, 0x31 // avc1
10069            ]);
10070
10071            constants.STSD_PREFIX = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10072            0x00, 0x00, 0x00, 0x01 // entry_count
10073            ]);
10074
10075            constants.STTS = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10076            0x00, 0x00, 0x00, 0x00 // entry_count
10077            ]);
10078
10079            constants.STSC = constants.STCO = constants.STTS;
10080
10081            constants.STSZ = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10082            0x00, 0x00, 0x00, 0x00, // sample_size
10083            0x00, 0x00, 0x00, 0x00 // sample_count
10084            ]);
10085
10086            constants.HDLR_VIDEO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10087            0x00, 0x00, 0x00, 0x00, // pre_defined
10088            0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
10089            0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
10090            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x69, 0x64, 0x65, 0x6F, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler
10091            ]);
10092
10093            constants.HDLR_AUDIO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10094            0x00, 0x00, 0x00, 0x00, // pre_defined
10095            0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'
10096            0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
10097            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x6F, 0x75, 0x6E, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler
10098            ]);
10099
10100            constants.DREF = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10101            0x00, 0x00, 0x00, 0x01, // entry_count
10102            0x00, 0x00, 0x00, 0x0C, // entry_size
10103            0x75, 0x72, 0x6C, 0x20, // type 'url '
10104            0x00, 0x00, 0x00, 0x01 // version(0) + flags
10105            ]);
10106
10107            // Sound media header
10108            constants.SMHD = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10109            0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)
10110            ]);
10111
10112            // video media header
10113            constants.VMHD = new Uint8Array([0x00, 0x00, 0x00, 0x01, // version(0) + flags
10114            0x00, 0x00, // graphicsmode: 2 bytes
10115            0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes
10116            0x00, 0x00]);
10117        }
10118
10119        // Generate a box
10120
10121    }, {
10122        key: 'box',
10123        value: function box(type) {
10124            var size = 8;
10125            var result = null;
10126            var datas = Array.prototype.slice.call(arguments, 1);
10127            var arrayCount = datas.length;
10128
10129            for (var i = 0; i < arrayCount; i++) {
10130                size += datas[i].byteLength;
10131            }
10132
10133            result = new Uint8Array(size);
10134            result[0] = size >>> 24 & 0xFF; // size
10135            result[1] = size >>> 16 & 0xFF;
10136            result[2] = size >>> 8 & 0xFF;
10137            result[3] = size & 0xFF;
10138
10139            result.set(type, 4); // type
10140
10141            var offset = 8;
10142            for (var _i = 0; _i < arrayCount; _i++) {
10143                // data body
10144                result.set(datas[_i], offset);
10145                offset += datas[_i].byteLength;
10146            }
10147
10148            return result;
10149        }
10150
10151        // emit ftyp & moov
10152
10153    }, {
10154        key: 'generateInitSegment',
10155        value: function generateInitSegment(meta) {
10156            var ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);
10157            var moov = MP4.moov(meta);
10158
10159            var result = new Uint8Array(ftyp.byteLength + moov.byteLength);
10160            result.set(ftyp, 0);
10161            result.set(moov, ftyp.byteLength);
10162            return result;
10163        }
10164
10165        // Movie metadata box
10166
10167    }, {
10168        key: 'moov',
10169        value: function moov(meta) {
10170            var mvhd = MP4.mvhd(meta.timescale, meta.duration);
10171            var trak = MP4.trak(meta);
10172            var mvex = MP4.mvex(meta);
10173            return MP4.box(MP4.types.moov, mvhd, trak, mvex);
10174        }
10175
10176        // Movie header box
10177
10178    }, {
10179        key: 'mvhd',
10180        value: function mvhd(timescale, duration) {
10181            return MP4.box(MP4.types.mvhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10182            0x00, 0x00, 0x00, 0x00, // creation_time
10183            0x00, 0x00, 0x00, 0x00, // modification_time
10184            timescale >>> 24 & 0xFF, // timescale: 4 bytes
10185            timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes
10186            duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0
10187            0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)
10188            0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes
10189            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
10190            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, // ----end composition matrix----
10191            0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----
10192            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----
10193            0xFF, 0xFF, 0xFF, 0xFF // next_track_ID
10194            ]));
10195        }
10196
10197        // Track box
10198
10199    }, {
10200        key: 'trak',
10201        value: function trak(meta) {
10202            return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));
10203        }
10204
10205        // Track header box
10206
10207    }, {
10208        key: 'tkhd',
10209        value: function tkhd(meta) {
10210            var trackId = meta.id,
10211                duration = meta.duration;
10212            var width = meta.presentWidth,
10213                height = meta.presentHeight;
10214
10215            return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, 0x00, 0x00, 0x07, // version(0) + flags
10216            0x00, 0x00, 0x00, 0x00, // creation_time
10217            0x00, 0x00, 0x00, 0x00, // modification_time
10218            trackId >>> 24 & 0xFF, // track_ID: 4 bytes
10219            trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
10220            duration >>> 24 & 0xFF, // duration: 4 bytes
10221            duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
10222            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)
10223            0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)
10224            0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
10225            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, // ----end composition matrix----
10226            width >>> 8 & 0xFF, // width and height
10227            width & 0xFF, 0x00, 0x00, height >>> 8 & 0xFF, height & 0xFF, 0x00, 0x00]));
10228        }
10229
10230        // Media Box
10231
10232    }, {
10233        key: 'mdia',
10234        value: function mdia(meta) {
10235            return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));
10236        }
10237
10238        // Media header box
10239
10240    }, {
10241        key: 'mdhd',
10242        value: function mdhd(meta) {
10243            var timescale = meta.timescale;
10244            var duration = meta.duration;
10245            return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10246            0x00, 0x00, 0x00, 0x00, // creation_time
10247            0x00, 0x00, 0x00, 0x00, // modification_time
10248            timescale >>> 24 & 0xFF, // timescale: 4 bytes
10249            timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes
10250            duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x55, 0xC4, // language: und (undetermined)
10251            0x00, 0x00 // pre_defined = 0
10252            ]));
10253        }
10254
10255        // Media handler reference box
10256
10257    }, {
10258        key: 'hdlr',
10259        value: function hdlr(meta) {
10260            var data = null;
10261            if (meta.type === 'audio') {
10262                data = MP4.constants.HDLR_AUDIO;
10263            } else {
10264                data = MP4.constants.HDLR_VIDEO;
10265            }
10266            return MP4.box(MP4.types.hdlr, data);
10267        }
10268
10269        // Media infomation box
10270
10271    }, {
10272        key: 'minf',
10273        value: function minf(meta) {
10274            var xmhd = null;
10275            if (meta.type === 'audio') {
10276                xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);
10277            } else {
10278                xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);
10279            }
10280            return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));
10281        }
10282
10283        // Data infomation box
10284
10285    }, {
10286        key: 'dinf',
10287        value: function dinf() {
10288            var result = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, MP4.constants.DREF));
10289            return result;
10290        }
10291
10292        // Sample table box
10293
10294    }, {
10295        key: 'stbl',
10296        value: function stbl(meta) {
10297            var result = MP4.box(MP4.types.stbl, // type: stbl
10298            MP4.stsd(meta), // Sample Description Table
10299            MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample
10300            MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk
10301            MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size
10302            MP4.box(MP4.types.stco, MP4.constants.STCO // Chunk offset
10303            ));
10304            return result;
10305        }
10306
10307        // Sample description box
10308
10309    }, {
10310        key: 'stsd',
10311        value: function stsd(meta) {
10312            if (meta.type === 'audio') {
10313                if (meta.codec === 'mp3') {
10314                    return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));
10315                }
10316                // else: aac -> mp4a
10317                return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));
10318            } else {
10319                return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));
10320            }
10321        }
10322    }, {
10323        key: 'mp3',
10324        value: function mp3(meta) {
10325            var channelCount = meta.channelCount;
10326            var sampleRate = meta.audioSampleRate;
10327
10328            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
10329            0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
10330            0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
10331            0x00, 0x00, 0x00, 0x00, 0x00, channelCount, // channelCount(2)
10332            0x00, 0x10, // sampleSize(2)
10333            0x00, 0x00, 0x00, 0x00, // reserved(4)
10334            sampleRate >>> 8 & 0xFF, // Audio sample rate
10335            sampleRate & 0xFF, 0x00, 0x00]);
10336
10337            return MP4.box(MP4.types['.mp3'], data);
10338        }
10339    }, {
10340        key: 'mp4a',
10341        value: function mp4a(meta) {
10342            var channelCount = meta.channelCount;
10343            var sampleRate = meta.audioSampleRate;
10344
10345            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
10346            0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
10347            0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
10348            0x00, 0x00, 0x00, 0x00, 0x00, channelCount, // channelCount(2)
10349            0x00, 0x10, // sampleSize(2)
10350            0x00, 0x00, 0x00, 0x00, // reserved(4)
10351            sampleRate >>> 8 & 0xFF, // Audio sample rate
10352            sampleRate & 0xFF, 0x00, 0x00]);
10353
10354            return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));
10355        }
10356    }, {
10357        key: 'esds',
10358        value: function esds(meta) {
10359            var config = meta.config || [];
10360            var configSize = config.length;
10361            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version 0 + flags
10362
10363            0x03, // descriptor_type
10364            0x17 + configSize, // length3
10365            0x00, 0x01, // es_id
10366            0x00, // stream_priority
10367
10368            0x04, // descriptor_type
10369            0x0F + configSize, // length
10370            0x40, // codec: mpeg4_audio
10371            0x15, // stream_type: Audio
10372            0x00, 0x00, 0x00, // buffer_size
10373            0x00, 0x00, 0x00, 0x00, // maxBitrate
10374            0x00, 0x00, 0x00, 0x00, // avgBitrate
10375
10376            0x05 // descriptor_type
10377            ].concat([configSize]).concat(config).concat([0x06, 0x01, 0x02 // GASpecificConfig
10378            ]));
10379            return MP4.box(MP4.types.esds, data);
10380        }
10381    }, {
10382        key: 'avc1',
10383        value: function avc1(meta) {
10384            var avcc = meta.avcc;
10385            var width = meta.codecWidth,
10386                height = meta.codecHeight;
10387
10388            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
10389            0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
10390            0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)
10391            0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes
10392            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, width >>> 8 & 0xFF, // width: 2 bytes
10393            width & 0xFF, height >>> 8 & 0xFF, // height: 2 bytes
10394            height & 0xFF, 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes
10395            0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes
10396            0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
10397            0x00, 0x01, // frame_count
10398            0x0A, // strlen
10399            0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes
10400            0x66, 0x6C, 0x76, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, // depth
10401            0xFF, 0xFF // pre_defined = -1
10402            ]);
10403            return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));
10404        }
10405
10406        // Movie Extends box
10407
10408    }, {
10409        key: 'mvex',
10410        value: function mvex(meta) {
10411            return MP4.box(MP4.types.mvex, MP4.trex(meta));
10412        }
10413
10414        // Track Extends box
10415
10416    }, {
10417        key: 'trex',
10418        value: function trex(meta) {
10419            var trackId = meta.id;
10420            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
10421            trackId >>> 24 & 0xFF, // track_ID
10422            trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
10423            0x00, 0x00, 0x00, 0x00, // default_sample_duration
10424            0x00, 0x00, 0x00, 0x00, // default_sample_size
10425            0x00, 0x01, 0x00, 0x01 // default_sample_flags
10426            ]);
10427            return MP4.box(MP4.types.trex, data);
10428        }
10429
10430        // Movie fragment box
10431
10432    }, {
10433        key: 'moof',
10434        value: function moof(track, baseMediaDecodeTime) {
10435            return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));
10436        }
10437    }, {
10438        key: 'mfhd',
10439        value: function mfhd(sequenceNumber) {
10440            var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, sequenceNumber >>> 24 & 0xFF, // sequence_number: int32
10441            sequenceNumber >>> 16 & 0xFF, sequenceNumber >>> 8 & 0xFF, sequenceNumber & 0xFF]);
10442            return MP4.box(MP4.types.mfhd, data);
10443        }
10444
10445        // Track fragment box
10446
10447    }, {
10448        key: 'traf',
10449        value: function traf(track, baseMediaDecodeTime) {
10450            var trackId = track.id;
10451
10452            // Track fragment header box
10453            var tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
10454            trackId >>> 24 & 0xFF, // track_ID
10455            trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF]));
10456            // Track Fragment Decode Time
10457            var tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
10458            baseMediaDecodeTime >>> 24 & 0xFF, // baseMediaDecodeTime: int32
10459            baseMediaDecodeTime >>> 16 & 0xFF, baseMediaDecodeTime >>> 8 & 0xFF, baseMediaDecodeTime & 0xFF]));
10460            var sdtp = MP4.sdtp(track);
10461            var trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);
10462
10463            return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);
10464        }
10465
10466        // Sample Dependency Type box
10467
10468    }, {
10469        key: 'sdtp',
10470        value: function sdtp(track) {
10471            var samples = track.samples || [];
10472            var sampleCount = samples.length;
10473            var data = new Uint8Array(4 + sampleCount);
10474            // 0~4 bytes: version(0) & flags
10475            for (var i = 0; i < sampleCount; i++) {
10476                var flags = samples[i].flags;
10477                data[i + 4] = flags.isLeading << 6 | // is_leading: 2 (bit)
10478                flags.dependsOn << 4 // sample_depends_on
10479                | flags.isDependedOn << 2 // sample_is_depended_on
10480                | flags.hasRedundancy; // sample_has_redundancy
10481            }
10482            return MP4.box(MP4.types.sdtp, data);
10483        }
10484
10485        // Track fragment run box
10486
10487    }, {
10488        key: 'trun',
10489        value: function trun(track, offset) {
10490            var samples = track.samples || [];
10491            var sampleCount = samples.length;
10492            var dataSize = 12 + 16 * sampleCount;
10493            var data = new Uint8Array(dataSize);
10494            offset += 8 + dataSize;
10495
10496            data.set([0x00, 0x00, 0x0F, 0x01, // version(0) & flags
10497            sampleCount >>> 24 & 0xFF, // sample_count
10498            sampleCount >>> 16 & 0xFF, sampleCount >>> 8 & 0xFF, sampleCount & 0xFF, offset >>> 24 & 0xFF, // data_offset
10499            offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF], 0);
10500
10501            for (var i = 0; i < sampleCount; i++) {
10502                var duration = samples[i].duration;
10503                var size = samples[i].size;
10504                var flags = samples[i].flags;
10505                var cts = samples[i].cts;
10506                data.set([duration >>> 24 & 0xFF, // sample_duration
10507                duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, size >>> 24 & 0xFF, // sample_size
10508                size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, flags.isLeading << 2 | flags.dependsOn, // sample_flags
10509                flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.isNonSync, 0x00, 0x00, // sample_degradation_priority
10510                cts >>> 24 & 0xFF, // sample_composition_time_offset
10511                cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF], 12 + 16 * i);
10512            }
10513            return MP4.box(MP4.types.trun, data);
10514        }
10515    }, {
10516        key: 'mdat',
10517        value: function mdat(data) {
10518            return MP4.box(MP4.types.mdat, data);
10519        }
10520    }]);
10521
10522    return MP4;
10523}();
10524
10525MP4.init();
10526
10527exports.default = MP4;
10528
10529},{}],38:[function(_dereq_,module,exports){
10530'use strict';
10531
10532Object.defineProperty(exports, "__esModule", {
10533    value: true
10534});
10535
10536var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
10537                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
10538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
10539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
10540                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
10541                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
10542                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
10542not use this file except in compliance with the License.
10543                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
10544                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
10545                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
10546                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
10547                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
10548                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
10549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
10551                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
10552                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
10553
10554var _logger = _dereq_('../utils/logger.js');
10555
10556var _logger2 = _interopRequireDefault(_logger);
10557
10558var _mp4Generator = _dereq_('./mp4-generator.js');
10559
10560var _mp4Generator2 = _interopRequireDefault(_mp4Generator);
10561
10562var _aacSilent = _dereq_('./aac-silent.js');
10563
10564var _aacSilent2 = _interopRequireDefault(_aacSilent);
10565
10566var _browser = _dereq_('../utils/browser.js');
10567
10568var _browser2 = _interopRequireDefault(_browser);
10569
10570var _mediaSegmentInfo = _dereq_('../core/media-segment-info.js');
10571
10572var _exception = _dereq_('../utils/exception.js');
10573
10574function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10575
10576function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10577
10578// Fragmented mp4 remuxer
10579var MP4Remuxer = function () {
10580    function MP4Remuxer(config) {
10581        _classCallCheck(this, MP4Remuxer);
10582
10583        this.TAG = 'MP4Remuxer';
10584
10585        this._config = config;
10586        this._isLive = config.isLive === true ? true : false;
10587
10588        this._dtsBase = -1;
10589        this._dtsBaseInited = false;
10590        this._audioDtsBase = Infinity;
10591        this._videoDtsBase = Infinity;
10592        this._audioNextDts = undefined;
10593        this._videoNextDts = undefined;
10594        this._audioStashedLastSample = null;
10595        this._videoStashedLastSample = null;
10596
10597        this._audioMeta = null;
10598        this._videoMeta = null;
10599
10600        this._audioSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('audio');
10601        this._videoSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('video');
10602
10603        this._onInitSegment = null;
10604        this._onMediaSegment = null;
10605
10606        // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment
10607        // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
10608        this._forceFirstIDR = _browser2.default.chrome && (_browser2.default.version.major < 50 || _browser2.default.version.major === 50 && _browser2.default.version.build < 2661) ? true : false;
10609
10610        // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking
10611        // Make audio beginDts equals with video beginDts, in order to fix seek freeze
10612        this._fillSilentAfterSeek = _browser2.default.msedge || _browser2.default.msie;
10613
10614        // While only FireFox supports 'audio/mp4, codecs="mp3"', use 'audio/mpeg' for chrome, safari, ...
10615        this._mp3UseMpegAudio = !_browser2.default.firefox;
10616
10617        this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;
10618    }
10619
10620    _createClass(MP4Remuxer, [{
10621        key: 'destroy',
10622        value: function destroy() {
10623            this._dtsBase = -1;
10624            this._dtsBaseInited = false;
10625            this._audioMeta = null;
10626            this._videoMeta = null;
10627            this._audioSegmentInfoList.clear();
10628            this._audioSegmentInfoList = null;
10629            this._videoSegmentInfoList.clear();
10630            this._videoSegmentInfoList = null;
10631            this._onInitSegment = null;
10632            this._onMediaSegment = null;
10633        }
10634    }, {
10635        key: 'bindDataSource',
10636        value: function bindDataSource(producer) {
10637            producer.onDataAvailable = this.remux.bind(this);
10638            producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);
10639            return this;
10640        }
10641
10642        /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void
10643           InitSegment: {
10644               type: string,
10645               data: ArrayBuffer,
10646               codec: string,
10647               container: string
10648           }
10649        */
10650
10651    }, {
10652        key: 'insertDiscontinuity',
10653        value: function insertDiscontinuity() {
10654            this._audioNextDts = this._videoNextDts = undefined;
10655        }
10656    }, {
10657        key: 'seek',
10658        value: function seek(originalDts) {
10659            this._audioStashedLastSample = null;
10660            this._videoStashedLastSample = null;
10661            this._videoSegmentInfoList.clear();
10662            this._audioSegmentInfoList.clear();
10663        }
10664    }, {
10665        key: 'remux',
10666        value: function remux(audioTrack, videoTrack) {
10667            if (!this._onMediaSegment) {
10668                throw new _exception.IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');
10669            }
10670            if (!this._dtsBaseInited) {
10671                this._calculateDtsBase(audioTrack, videoTrack);
10672            }
10673            this._remuxVideo(videoTrack);
10674            this._remuxAudio(audioTrack);
10675        }
10676    }, {
10677        key: '_onTrackMetadataReceived',
10678        value: function _onTrackMetadataReceived(type, metadata) {
10679            var metabox = null;
10680
10681            var container = 'mp4';
10682            var codec = metadata.codec;
10683
10684            if (type === 'audio') {
10685                this._audioMeta = metadata;
10686                if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {
10687                    // 'audio/mpeg' for MP3 audio track
10688                    container = 'mpeg';
10689                    codec = '';
10690                    metabox = new Uint8Array();
10691                } else {
10692                    // 'audio/mp4, codecs="codec"'
10693                    metabox = _mp4Generator2.default.generateInitSegment(metadata);
10694                }
10695            } else if (type === 'video') {
10696                this._videoMeta = metadata;
10697                metabox = _mp4Generator2.default.generateInitSegment(metadata);
10698            } else {
10699                return;
10700            }
10701
10702            // dispatch metabox (Initialization Segment)
10703            if (!this._onInitSegment) {
10704                throw new _exception.IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');
10705            }
10706            this._onInitSegment(type, {
10707                type: type,
10708                data: metabox.buffer,
10709                codec: codec,
10710                container: type + '/' + container,
10711                mediaDuration: metadata.duration // in timescale 1000 (milliseconds)
10712            });
10713        }
10714    }, {
vendor: 4,837 bytes, lines 10715-10850
10715        key: '_calculateDtsBase',
10716        value: function _calculateDtsBase(audioTrack, videoTrack) {
10717            if (this._dtsBaseInited) {
10718                return;
10719            }
10720
10721            if (audioTrack.samples && audioTrack.samples.length) {
10722                this._audioDtsBase = audioTrack.samples[0].dts;
10723            }
10724            if (videoTrack.samples && videoTrack.samples.length) {
10725                this._videoDtsBase = videoTrack.samples[0].dts;
10726            }
10727
10728            this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);
10729            this._dtsBaseInited = true;
10730        }
10731    }, {
10732        key: 'flushStashedSamples',
10733        value: function flushStashedSamples() {
10734            var videoSample = this._videoStashedLastSample;
10735            var audioSample = this._audioStashedLastSample;
10736
10737            var videoTrack = {
10738                type: 'video',
10739                id: 1,
10740                sequenceNumber: 0,
10741                samples: [],
10742                length: 0
10743            };
10744
10745            if (videoSample != null) {
10746                videoTrack.samples.push(videoSample);
10747                videoTrack.length = videoSample.length;
10748            }
10749
10750            var audioTrack = {
10751                type: 'audio',
10752                id: 2,
10753                sequenceNumber: 0,
10754                samples: [],
10755                length: 0
10756            };
10757
10758            if (audioSample != null) {
10759                audioTrack.samples.push(audioSample);
10760                audioTrack.length = audioSample.length;
10761            }
10762
10763            this._videoStashedLastSample = null;
10764            this._audioStashedLastSample = null;
10765
10766            this._remuxVideo(videoTrack, true);
10767            this._remuxAudio(audioTrack, true);
10768        }
10769    }, {
10770        key: '_remuxAudio',
10771        value: function _remuxAudio(audioTrack, force) {
10772            if (this._audioMeta == null) {
10773                return;
10774            }
10775
10776            var track = audioTrack;
10777            var samples = track.samples;
10778            var dtsCorrection = undefined;
10779            var firstDts = -1,
10780                lastDts = -1,
10781                lastPts = -1;
10782            var refSampleDuration = this._audioMeta.refSampleDuration;
10783
10784            var mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;
10785            var firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;
10786
10787            var insertPrefixSilentFrame = false;
10788
10789            if (!samples || samples.length === 0) {
10790                return;
10791            }
10792            if (samples.length === 1 && !force) {
10793                // If [sample count in current batch] === 1 && (force != true)
10794                // Ignore and keep in demuxer's queue
10795                return;
10796            } // else if (force === true) do remux
10797
10798            var offset = 0;
10799            var mdatbox = null;
10800            var mdatBytes = 0;
10801
10802            // calculate initial mdat size
10803            if (mpegRawTrack) {
10804                // for raw mpeg buffer
10805                offset = 0;
10806                mdatBytes = track.length;
10807            } else {
10808                // for fmp4 mdat box
10809                offset = 8; // size + type
10810                mdatBytes = 8 + track.length;
10811            }
10812
10813            var lastSample = null;
10814
10815            // Pop the lastSample and waiting for stash
10816            if (samples.length > 1) {
10817                lastSample = samples.pop();
10818                mdatBytes -= lastSample.length;
10819            }
10820
10821            // Insert [stashed lastSample in the previous batch] to the front
10822            if (this._audioStashedLastSample != null) {
10823                var sample = this._audioStashedLastSample;
10824                this._audioStashedLastSample = null;
10825                samples.unshift(sample);
10826                mdatBytes += sample.length;
10827            }
10828
10829            // Stash the lastSample of current batch, waiting for next batch
10830            if (lastSample != null) {
10831                this._audioStashedLastSample = lastSample;
10832            }
10833
10834            var firstSampleOriginalDts = samples[0].dts - this._dtsBase;
10835
10836            // calculate dtsCorrection
10837            if (this._audioNextDts) {
10838                dtsCorrection = firstSampleOriginalDts - this._audioNextDts;
10839            } else {
10840                // this._audioNextDts == undefined
10841                if (this._audioSegmentInfoList.isEmpty()) {
10842                    dtsCorrection = 0;
10843                    if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {
10844                        if (this._audioMeta.originalCodec !== 'mp3') {
10845                            insertPrefixSilentFrame = true;
10846                        }
10847                    }
10848                } else {
10849                    var _lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);
10850                    if (_lastSample != null) {
10851                        var distance = firstSampleOriginalDts - (_lastSample.originalDts + _lastSample.duration);
10852                        if (distance <= 3) {
10853                            distance = 0;
10854                        }
10855                        var expectedDts = _lastSample.dts + _lastSample.duration + distance;
10856                        dtsCorrection = firstSampleOriginalDts - expectedDts;
10857                    } else {
10858                        // lastSample == null, cannot found
10859                        dtsCorrection = 0;
10860                    }
10861                }
10862            }
10863
10864            if (insertPrefixSilentFrame) {
10865                // align audio segment beginDts to match with current video segment's beginDts
10866                var firstSampleDts = firstSampleOriginalDts - dtsCorrection;
10867                var videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);
10868                if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {
10869                    var silentUnit = _aacSilent2.default.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);
10870                    if (silentUnit) {
10871                        var dts = videoSegment.beginDts;
10872                        var silentFrameDuration = firstSampleDts - videoSegment.beginDts;
10873                        _logger2.default.v(this.TAG, 'InsertPrefixSilentAudio: dts: ' + dts + ', duration: ' + silentFrameDuration);
10874                        samples.unshift({ unit: silentUnit, dts: dts, pts: dts });
10875                        mdatBytes += silentUnit.byteLength;
10876                    } // silentUnit == null: Cannot generate, skip
10877                } else {
10878                    insertPrefixSilentFrame = false;
10879                }
10880            }
10881
10882            var mp4Samples = [];
10883
10884            // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples
10885            for (var i = 0; i < samples.length; i++) {
10886                var _sample = samples[i];
10887                var unit = _sample.unit;
10888                var originalDts = _sample.dts - this._dtsBase;
10889                var _dts = originalDts - dtsCorrection;
10890
10891                if (firstDts === -1) {
10892                    firstDts = _dts;
10893                }
10894
10895                var sampleDuration = 0;
10896
10897                if (i !== samples.length - 1) {
10898                    var nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;
10899                    sampleDuration = nextDts - _dts;
10900                } else {
10901                    // the last sample
10902                    if (lastSample != null) {
10903                        // use stashed sample's dts to calculate sample duration
10904                        var _nextDts = lastSample.dts - this._dtsBase - dtsCorrection;
10905                        sampleDuration = _nextDts - _dts;
10906                    } else if (mp4Samples.length >= 1) {
10907                        // use second last sample duration
10908                        sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
10909                    } else {
10910                        // the only one sample, use reference sample duration
10911                        sampleDuration = Math.floor(refSampleDuration);
10912                    }
10913                }
10914
10915                var needFillSilentFrames = false;
10916                var silentFrames = null;
10917
10918                // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap
10919                if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !_browser2.default.safari) {
10920                    // We need to insert silent frames to fill timestamp gap
10921                    needFillSilentFrames = true;
10922                    var delta = Math.abs(sampleDuration - refSampleDuration);
10923                    var frameCount = Math.ceil(delta / refSampleDuration);
10924                    var currentDts = _dts + refSampleDuration; // Notice: in float
10925
10926                    _logger2.default.w(this.TAG, 'Large audio timestamp gap detected, may cause AV sync to drift. ' + 'Silent frames will be generated to avoid unsync.\n' + ('dts: ' + (_dts + sampleDuration) + ' ms, expected: ' + (_dts + Math.round(refSampleDuration)) + ' ms, ') + ('delta: ' + Math.round(delta) + ' ms, generate: ' + frameCount + ' frames'));
10927
10928                    var _silentUnit = _aacSilent2.default.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);
10929                    if (_silentUnit == null) {
10930                        _logger2.default.w(this.TAG, 'Unable to generate silent frame for ' + (this._audioMeta.originalCodec + ' with ' + this._audioMeta.channelCount + ' channels, repeat last frame'));
10931                        // Repeat last frame
10932                        _silentUnit = unit;
10933                    }
10934                    silentFrames = [];
10935
10936                    for (var j = 0; j < frameCount; j++) {
10937                        var intDts = Math.round(currentDts); // round to integer
10938                        if (silentFrames.length > 0) {
10939                            // Set previous frame sample duration
10940                            var previousFrame = silentFrames[silentFrames.length - 1];
10941                            previousFrame.duration = intDts - previousFrame.dts;
10942                        }
10943                        var frame = {
10944                            dts: intDts,
10945                            pts: intDts,
10946                            cts: 0,
10947                            unit: _silentUnit,
10948                            size: _silentUnit.byteLength,
10949                            duration: 0, // wait for next sample
10950                            originalDts: originalDts,
10951                            flags: {
10952                                isLeading: 0,
10953                                dependsOn: 1,
10954                                isDependedOn: 0,
10955                                hasRedundancy: 0
10956                            }
10957                        };
10958                        silentFrames.push(frame);
10959                        mdatBytes += frame.size;
10960                        currentDts += refSampleDuration;
10961                    }
10962
10963                    // last frame: align end time to next frame dts
10964                    var lastFrame = silentFrames[silentFrames.length - 1];
10965                    lastFrame.duration = _dts + sampleDuration - lastFrame.dts;
10966
10967                    // silentFrames.forEach((frame) => {
10968                    //     Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);
10969                    // });
10970
10971                    // Set correct sample duration for current frame
10972                    sampleDuration = Math.round(refSampleDuration);
10973                }
10974
10975                mp4Samples.push({
10976                    dts: _dts,
10977                    pts: _dts,
10978                    cts: 0,
10979                    unit: _sample.unit,
10980                    size: _sample.unit.byteLength,
10981                    duration: sampleDuration,
10982                    originalDts: originalDts,
10983                    flags: {
10984                        isLeading: 0,
10985                        dependsOn: 1,
10986                        isDependedOn: 0,
10987                        hasRedundancy: 0
10988                    }
10989                });
10990
10991                if (needFillSilentFrames) {
10992                    // Silent frames should be inserted after wrong-duration frame
10993                    mp4Samples.push.apply(mp4Samples, silentFrames);
10994                }
10995            }
10996
10997            // allocate mdatbox
10998            if (mpegRawTrack) {
10999                // allocate for raw mpeg buffer
11000                mdatbox = new Uint8Array(mdatBytes);
11001            } else {
11002                // allocate for fmp4 mdat box
11003                mdatbox = new Uint8Array(mdatBytes);
11004                // size field
11005                mdatbox[0] = mdatBytes >>> 24 & 0xFF;
11006                mdatbox[1] = mdatBytes >>> 16 & 0xFF;
11007                mdatbox[2] = mdatBytes >>> 8 & 0xFF;
11008                mdatbox[3] = mdatBytes & 0xFF;
11009                // type field (fourCC)
11010                mdatbox.set(_mp4Generator2.default.types.mdat, 4);
11011            }
11012
11013            // Write samples into mdatbox
11014            for (var _i = 0; _i < mp4Samples.length; _i++) {
11015                var _unit = mp4Samples[_i].unit;
11016                mdatbox.set(_unit, offset);
11017                offset += _unit.byteLength;
11018            }
11019
11020            var latest = mp4Samples[mp4Samples.length - 1];
11021            lastDts = latest.dts + latest.duration;
11022            this._audioNextDts = lastDts;
11023
11024            // fill media segment info & add to info list
11025            var info = new _mediaSegmentInfo.MediaSegmentInfo();
11026            info.beginDts = firstDts;
11027            info.endDts = lastDts;
11028            info.beginPts = firstDts;
11029            info.endPts = lastDts;
11030            info.originalBeginDts = mp4Samples[0].originalDts;
11031            info.originalEndDts = latest.originalDts + latest.duration;
11032            info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, false);
11033            info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, false);
11034            if (!this._isLive) {
11035                this._audioSegmentInfoList.append(info);
11036            }
11037
11038            track.samples = mp4Samples;
11039            track.sequenceNumber++;
11040
11041            var moofbox = null;
11042
11043            if (mpegRawTrack) {
11044                // Generate empty buffer, because useless for raw mpeg
11045                moofbox = new Uint8Array();
11046            } else {
11047                // Generate moof for fmp4 segment
11048                moofbox = _mp4Generator2.default.moof(track, firstDts);
11049            }
11050
11051            track.samples = [];
11052            track.length = 0;
11053
11054            var segment = {
11055                type: 'audio',
11056                data: this._mergeBoxes(moofbox, mdatbox).buffer,
11057                sampleCount: mp4Samples.length,
11058                info: info
11059            };
11060
11061            if (mpegRawTrack && firstSegmentAfterSeek) {
11062                // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer
11063                // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.
11064                segment.timestampOffset = firstDts;
11065            }
11066
11067            this._onMediaSegment('audio', segment);
11068        }
11069    }, {
11070        key: '_remuxVideo',
11071        value: function _remuxVideo(videoTrack, force) {
11072            if (this._videoMeta == null) {
11073                return;
11074            }
11075
11076            var track = videoTrack;
11077            var samples = track.samples;
11078            var dtsCorrection = undefined;
11079            var firstDts = -1,
vendor: 7,675 bytes, lines 11080-11264
11080                lastDts = -1;
11081            var firstPts = -1,
11082                lastPts = -1;
11083
11084            if (!samples || samples.length === 0) {
11085                return;
11086            }
11087            if (samples.length === 1 && !force) {
11088                // If [sample count in current batch] === 1 && (force != true)
11089                // Ignore and keep in demuxer's queue
11090                return;
11091            } // else if (force === true) do remux
11092
11093            var offset = 8;
11094            var mdatbox = null;
11095            var mdatBytes = 8 + videoTrack.length;
11096
11097            var lastSample = null;
11098
11099            // Pop the lastSample and waiting for stash
11100            if (samples.length > 1) {
11101                lastSample = samples.pop();
11102                mdatBytes -= lastSample.length;
11103            }
11104
11105            // Insert [stashed lastSample in the previous batch] to the front
11106            if (this._videoStashedLastSample != null) {
11107                var sample = this._videoStashedLastSample;
11108                this._videoStashedLastSample = null;
11109                samples.unshift(sample);
11110                mdatBytes += sample.length;
11111            }
11112
11113            // Stash the lastSample of current batch, waiting for next batch
11114            if (lastSample != null) {
11115                this._videoStashedLastSample = lastSample;
11116            }
11117
11118            var firstSampleOriginalDts = samples[0].dts - this._dtsBase;
11119
11120            // calculate dtsCorrection
11121            if (this._videoNextDts) {
11122                dtsCorrection = firstSampleOriginalDts - this._videoNextDts;
11123            } else {
11124                // this._videoNextDts == undefined
11125                if (this._videoSegmentInfoList.isEmpty()) {
11126                    dtsCorrection = 0;
11127                } else {
11128                    var _lastSample2 = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);
11129                    if (_lastSample2 != null) {
11130                        var distance = firstSampleOriginalDts - (_lastSample2.originalDts + _lastSample2.duration);
11131                        if (distance <= 3) {
11132                            distance = 0;
11133                        }
11134                        var expectedDts = _lastSample2.dts + _lastSample2.duration + distance;
11135                        dtsCorrection = firstSampleOriginalDts - expectedDts;
11136                    } else {
11137                        // lastSample == null, cannot found
11138                        dtsCorrection = 0;
11139                    }
11140                }
11141            }
11142
11143            var info = new _mediaSegmentInfo.MediaSegmentInfo();
11144            var mp4Samples = [];
11145
11146            // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples
11147            for (var i = 0; i < samples.length; i++) {
11148                var _sample2 = samples[i];
11149                var originalDts = _sample2.dts - this._dtsBase;
11150                var isKeyframe = _sample2.isKeyframe;
11151                var dts = originalDts - dtsCorrection;
11152                var cts = _sample2.cts;
11153                var pts = dts + cts;
11154
11155                if (firstDts === -1) {
11156                    firstDts = dts;
11157                    firstPts = pts;
11158                }
11159
11160                var sampleDuration = 0;
11161
11162                if (i !== samples.length - 1) {
11163                    var nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;
11164                    sampleDuration = nextDts - dts;
11165                } else {
11166                    // the last sample
11167                    if (lastSample != null) {
11168                        // use stashed sample's dts to calculate sample duration
11169                        var _nextDts2 = lastSample.dts - this._dtsBase - dtsCorrection;
11170                        sampleDuration = _nextDts2 - dts;
11171                    } else if (mp4Samples.length >= 1) {
11172                        // use second last sample duration
11173                        sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
11174                    } else {
11175                        // the only one sample, use reference sample duration
11176                        sampleDuration = Math.floor(this._videoMeta.refSampleDuration);
11177                    }
11178                }
11179
11180                if (isKeyframe) {
11181                    var syncPoint = new _mediaSegmentInfo.SampleInfo(dts, pts, sampleDuration, _sample2.dts, true);
11182                    syncPoint.fileposition = _sample2.fileposition;
11183                    info.appendSyncPoint(syncPoint);
11184                }
11185
11186                mp4Samples.push({
11187                    dts: dts,
11188                    pts: pts,
11189                    cts: cts,
11190                    units: _sample2.units,
11191                    size: _sample2.length,
11192                    isKeyframe: isKeyframe,
11193                    duration: sampleDuration,
11194                    originalDts: originalDts,
11195                    flags: {
11196                        isLeading: 0,
11197                        dependsOn: isKeyframe ? 2 : 1,
11198                        isDependedOn: isKeyframe ? 1 : 0,
11199                        hasRedundancy: 0,
11200                        isNonSync: isKeyframe ? 0 : 1
11201                    }
11202                });
11203            }
11204
11205            // allocate mdatbox
11206            mdatbox = new Uint8Array(mdatBytes);
11207            mdatbox[0] = mdatBytes >>> 24 & 0xFF;
11208            mdatbox[1] = mdatBytes >>> 16 & 0xFF;
11209            mdatbox[2] = mdatBytes >>> 8 & 0xFF;
11210            mdatbox[3] = mdatBytes & 0xFF;
11211            mdatbox.set(_mp4Generator2.default.types.mdat, 4);
11212
11213            // Write samples into mdatbox
11214            for (var _i2 = 0; _i2 < mp4Samples.length; _i2++) {
11215                var units = mp4Samples[_i2].units;
11216                while (units.length) {
11217                    var unit = units.shift();
11218                    var data = unit.data;
11219                    mdatbox.set(data, offset);
11220                    offset += data.byteLength;
11221                }
11222            }
11223
11224            var latest = mp4Samples[mp4Samples.length - 1];
11225            lastDts = latest.dts + latest.duration;
11226            lastPts = latest.pts + latest.duration;
11227            this._videoNextDts = lastDts;
11228
11229            // fill media segment info & add to info list
11230            info.beginDts = firstDts;
11231            info.endDts = lastDts;
11232            info.beginPts = firstPts;
11233            info.endPts = lastPts;
11234            info.originalBeginDts = mp4Samples[0].originalDts;
11235            info.originalEndDts = latest.originalDts + latest.duration;
11236            info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, mp4Samples[0].isKeyframe);
11237            info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, latest.isKeyframe);
11238            if (!this._isLive) {
11239                this._videoSegmentInfoList.append(info);
11240            }
11241
11242            track.samples = mp4Samples;
11243            track.sequenceNumber++;
11244
11245            // workaround for chrome < 50: force first sample as a random access point
11246            // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
11247            if (this._forceFirstIDR) {
11248                var flags = mp4Samples[0].flags;
11249                flags.dependsOn = 2;
11250                flags.isNonSync = 0;
11251            }
11252
11253            var moofbox = _mp4Generator2.default.moof(track, firstDts);
11254            track.samples = [];
11255            track.length = 0;
11256
11257            this._onMediaSegment('video', {
11258                type: 'video',
11259                data: this._mergeBoxes(moofbox, mdatbox).buffer,
11260                sampleCount: mp4Samples.length,
11261                info: info
11262            });
11263        }
11264    }, {
11265        key: '_mergeBoxes',
11266        value: function _mergeBoxes(moof, mdat) {
11267            var result = new Uint8Array(moof.byteLength + mdat.byteLength);
11268            result.set(moof, 0);
11269            result.set(mdat, moof.byteLength);
11270            return result;
11271        }
11272    }, {
11273        key: 'onInitSegment',
11274        get: function get() {
11275            return this._onInitSegment;
11276        },
11277        set: function set(callback) {
11278            this._onInitSegment = callback;
11279        }
11280
11281        /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void
11282           MediaSegment: {
11283               type: string,
11284               data: ArrayBuffer,
11285               sampleCount: int32
11286               info: MediaSegmentInfo
11287           }
11288        */
11289
11290    }, {
11291        key: 'onMediaSegment',
11292        get: function get() {
11293            return this._onMediaSegment;
11294        },
11295        set: function set(callback) {
11296            this._onMediaSegment = callback;
11297        }
11298    }]);
11299
11300    return MP4Remuxer;
11301}();
11302
11303exports.default = MP4Remuxer;
11304
11305},{"../core/media-segment-info.js":8,"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./aac-silent.js":36,"./mp4-generator.js":37}],39:[function(_dereq_,module,exports){
11306'use strict';
11307
11308Object.defineProperty(exports, "__esModule", {
11309    value: true
11310});
11311/*
11312 * Copyright (C) 2016 Bilibili. All Rights Reserved.
11313 *
11314 * @author zheng qian <[email protected]>
11315 *
11316 * Licensed under the Apache License, Version 2.0 (the "License");
11317 * you may not use this file except in compliance with the License.
11318 * You may obtain a copy of the License at
11319 *
11320 *     http://www.apache.org/licenses/LICENSE-2.0
11321 *
11322 * Unless required by applicable law or agreed to in writing, software
11323 * distributed under the License is distributed on an "AS IS" BASIS,
11324 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11325 * See the License for the specific language governing permissions and
11326 * limitations under the License.
11327 */
11328
11329var Browser = {};
11330
11331function detect() {
11332    // modified from jquery-browser-plugin
11333
11334    var ua = self.navigator.userAgent.toLowerCase();
11335
11336    var match = /(edge)\/([\w.]+)/.exec(ua) || /(opr)[\/]([\w.]+)/.exec(ua) || /(chrome)[ \/]([\w.]+)/.exec(ua) || /(iemobile)[\/]([\w.]+)/.exec(ua) || /(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua) || ua.indexOf('compatible') < 0 && /(firefox)[ \/]([\w.]+)/.exec(ua) || [];
11337
11338    var platform_match = /(ipad)/.exec(ua) || /(ipod)/.exec(ua) || /(windows phone)/.exec(ua) || /(iphone)/.exec(ua) || /(kindle)/.exec(ua) || /(android)/.exec(ua) || /(windows)/.exec(ua) || /(mac)/.exec(ua) || /(linux)/.exec(ua) || /(cros)/.exec(ua) || [];
11339
11340    var matched = {
11341        browser: match[5] || match[3] || match[1] || '',
11342        version: match[2] || match[4] || '0',
11343        majorVersion: match[4] || match[2] || '0',
11344        platform: platform_match[0] || ''
11345    };
11346
11347    var browser = {};
11348    if (matched.browser) {
11349        browser[matched.browser] = true;
11350
11351        var versionArray = matched.majorVersion.split('.');
11352        browser.version = {
11353            major: parseInt(matched.majorVersion, 10),
11354            string: matched.version
11355        };
11356        if (versionArray.length > 1) {
11357            browser.version.minor = parseInt(versionArray[1], 10);
11358        }
11359        if (versionArray.length > 2) {
11360            browser.version.build = parseInt(versionArray[2], 10);
11361        }
11362    }
11363
11364    if (matched.platform) {
11365        browser[matched.platform] = true;
11366    }
11367
11368    if (browser.chrome || browser.opr || browser.safari) {
11369        browser.webkit = true;
11370    }
11371
11372    // MSIE. IE11 has 'rv' identifer
11373    if (browser.rv || browser.iemobile) {
11374        if (browser.rv) {
11375            delete browser.rv;
11376        }
11377        var msie = 'msie';
11378        matched.browser = msie;
11379        browser[msie] = true;
11380    }
11381
11382    // Microsoft Edge
11383    if (browser.edge) {
11384        delete browser.edge;
11385        var msedge = 'msedge';
11386        matched.browser = msedge;
11387        browser[msedge] = true;
11388    }
11389
11390    // Opera 15+
11391    if (browser.opr) {
11392        var opera = 'opera';
11393        matched.browser = opera;
11394        browser[opera] = true;
11395    }
11396
11397    // Stock android browsers are marked as Safari
11398    if (browser.safari && browser.android) {
11399        var android = 'android';
11400        matched.browser = android;
11401        browser[android] = true;
11402    }
11403
11404    browser.name = matched.browser;
11405    browser.platform = matched.platform;
11406
11407    for (var key in Browser) {
11408        if (Browser.hasOwnProperty(key)) {
11409            delete Browser[key];
11410        }
11411    }
11412    Object.assign(Browser, browser);
11413}
11414
11415detect();
11416
11417exports.default = Browser;
11418
11419},{}],40:[function(_dereq_,module,exports){
11420'use strict';
11421
11422Object.defineProperty(exports, "__esModule", {
11423    value: true
11424});
11425
11426var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
11427
11428function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
11429
11430function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
11430onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
11431
11432function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11433
11434/*
11435 * Copyright (C) 2016 Bilibili. All Rights Reserved.
11436 *
11437 * @author zheng qian <[email protected]>
11438 *
11439 * Licensed under the Apache License, Version 2.0 (the "License");
11440 * you may not use this file except in compliance with the License.
11441 * You may obtain a copy of the License at
11442 *
11443 *     http://www.apache.org/licenses/LICENSE-2.0
11444 *
11445 * Unless required by applicable law or agreed to in writing, software
11446 * distributed under the License is distributed on an "AS IS" BASIS,
11447 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11448 * See the License for the specific language governing permissions and
11449 * limitations under the License.
11450 */
11451
11452var RuntimeException = exports.RuntimeException = function () {
11453    function RuntimeException(message) {
11454        _classCallCheck(this, RuntimeException);
11455
11456        this._message = message;
11457    }
11458
11459    _createClass(RuntimeException, [{
11460        key: 'toString',
11461        value: function toString() {
11462            return this.name + ': ' + this.message;
11463        }
11464    }, {
11465        key: 'name',
11466        get: function get() {
11467            return 'RuntimeException';
11468        }
11469    }, {
11470        key: 'message',
11471        get: function get() {
11472            return this._message;
11473        }
11474    }]);
11475
11476    return RuntimeException;
11477}();
11478
11479var IllegalStateException = exports.IllegalStateException = function (_RuntimeException) {
11480    _inherits(IllegalStateException, _RuntimeException);
11481
11482    function IllegalStateException(message) {
11483        _classCallCheck(this, IllegalStateException);
11484
11485        return _possibleConstructorReturn(this, (IllegalStateException.__proto__ || Object.getPrototypeOf(IllegalStateException)).call(this, message));
11486    }
11487
11488    _createClass(IllegalStateException, [{
11489        key: 'name',
11490        get: function get() {
11491            return 'IllegalStateException';
11492        }
11493    }]);
11494
11495    return IllegalStateException;
11496}(RuntimeException);
11497
11498var InvalidArgumentException = exports.InvalidArgumentException = function (_RuntimeException2) {
11499    _inherits(InvalidArgumentException, _RuntimeException2);
11500
11501    function InvalidArgumentException(message) {
11502        _classCallCheck(this, InvalidArgumentException);
11503
11504        return _possibleConstructorReturn(this, (InvalidArgumentException.__proto__ || Object.getPrototypeOf(InvalidArgumentException)).call(this, message));
11505    }
11506
11507    _createClass(InvalidArgumentException, [{
11508        key: 'name',
11509        get: function get() {
11510            return 'InvalidArgumentException';
11511        }
11512    }]);
11513
11514    return InvalidArgumentException;
11515}(RuntimeException);
11516
11517var NotImplementedException = exports.NotImplementedException = function (_RuntimeException3) {
11518    _inherits(NotImplementedException, _RuntimeException3);
11519
11520    function NotImplementedException(message) {
11521        _classCallCheck(this, NotImplementedException);
11522
11523        return _possibleConstructorReturn(this, (NotImplementedException.__proto__ || Object.getPrototypeOf(NotImplementedException)).call(this, message));
11524    }
11525
11526    _createClass(NotImplementedException, [{
11527        key: 'name',
11528        get: function get() {
11529            return 'NotImplementedException';
11530        }
11531    }]);
11532
11533    return NotImplementedException;
11534}(RuntimeException);
11535
11536},{}],41:[function(_dereq_,module,exports){
11537'use strict';
11538
11539Object.defineProperty(exports, "__esModule", {
11540    value: true
11541});
11542
11543var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
11544                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
11545                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11546                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
11547                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11548                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
11549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
11549not use this file except in compliance with the License.
11550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
11551                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11552                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
11553                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11554                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
11555                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
11556                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11557                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
11558                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
11559                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
11560
11561var _events = _dereq_('events');
11562
11563var _events2 = _interopRequireDefault(_events);
11564
11565function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11566
11567function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11568
11569var Log = function () {
11570    function Log() {
11571        _classCallCheck(this, Log);
11572    }
11573
11574    _createClass(Log, null, [{
11575        key: 'e',
11576        value: function e(tag, msg) {
11577            if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
11578
11579            var str = '[' + tag + '] > ' + msg;
11580
11581            if (Log.ENABLE_CALLBACK) {
11582                Log.emitter.emit('log', 'error', str);
11583            }
11584
11585            if (!Log.ENABLE_ERROR) {
11586                return;
11587            }
11588
11589            if (console.error) {
11590                console.error(str);
11591            } else if (console.warn) {
11592                console.warn(str);
11593            } else {
11594                console.log(str);
11595            }
11596        }
11597    }, {
11598        key: 'i',
11599        value: function i(tag, msg) {
11600            if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
11601
11602            var str = '[' + tag + '] > ' + msg;
11603
11604            if (Log.ENABLE_CALLBACK) {
11605                Log.emitter.emit('log', 'info', str);
11606            }
11607
11608            if (!Log.ENABLE_INFO) {
11609                return;
11610            }
11611
11612            if (console.info) {
11613                console.info(str);
11614            } else {
11615                console.log(str);
11616            }
11617        }
11618    }, {
11619        key: 'w',
11620        value: function w(tag, msg) {
11621            if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
11622
11623            var str = '[' + tag + '] > ' + msg;
11624
11625            if (Log.ENABLE_CALLBACK) {
11626                Log.emitter.emit('log', 'warn', str);
11627            }
11628
11629            if (!Log.ENABLE_WARN) {
11630                return;
11631            }
11632
11633            if (console.warn) {
11634                console.warn(str);
11635            } else {
11636                console.log(str);
11637            }
11638        }
11639    }, {
11640        key: 'd',
11641        value: function d(tag, msg) {
11642            if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
11643
11644            var str = '[' + tag + '] > ' + msg;
11645
11646            if (Log.ENABLE_CALLBACK) {
11647                Log.emitter.emit('log', 'debug', str);
11648            }
11649
11650            if (!Log.ENABLE_DEBUG) {
11651                return;
11652            }
11653
11654            if (console.debug) {
11655                console.debug(str);
11656            } else {
11657                console.log(str);
11658            }
11659        }
11660    }, {
11661        key: 'v',
11662        value: function v(tag, msg) {
11663            if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
11664
11665            var str = '[' + tag + '] > ' + msg;
11666
11667            if (Log.ENABLE_CALLBACK) {
11668                Log.emitter.emit('log', 'verbose', str);
11669            }
11670
11671            if (!Log.ENABLE_VERBOSE) {
11672                return;
11673            }
11674
11675            console.log(str);
11676        }
11677    }]);
11678
11679    return Log;
11680}();
11681
11682Log.GLOBAL_TAG = 'flv.js';
11683Log.FORCE_GLOBAL_TAG = false;
11684Log.ENABLE_ERROR = false; //Edited By BuddyBoss
11685Log.ENABLE_INFO = false; //Edited By BuddyBoss
11686Log.ENABLE_WARN = false; //Edited By BuddyBoss
11687Log.ENABLE_DEBUG = false; //Edited By BuddyBoss
11688Log.ENABLE_VERBOSE = false; //Edited By BuddyBoss
11689
11690Log.ENABLE_CALLBACK = false;
11691
11692Log.emitter = new _events2.default();
11693
11694exports.default = Log;
11695
11696},{"events":2}],42:[function(_dereq_,module,exports){
11697'use strict';
11698
11699Object.defineProperty(exports, "__esModule", {
11700    value: true
11701});
11702
11703var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
11704                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright (C) 2016 Bilibili. All Rights Reserved.
11705                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11706                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * @author zheng qian <[email protected]>
11707                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11708                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the "License");
11709                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may 
11709not use this file except in compliance with the License.
11710                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at
11711                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11712                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0
11713                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *
11714                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software
11715                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an "AS IS" BASIS,
11716                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11717                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and
11718                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.
11719                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
11720
11721var _events = _dereq_('events');
11722
11723var _events2 = _interopRequireDefault(_events);
11724
11725var _logger = _dereq_('./logger.js');
11726
11727var _logger2 = _interopRequireDefault(_logger);
11728
11729function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11730
11731function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11732
11733var LoggingControl = function () {
11734    function LoggingControl() {
11735        _classCallCheck(this, LoggingControl);
11736    }
11737
11738    _createClass(LoggingControl, null, [{
11739        key: 'getConfig',
11740        value: function getConfig() {
11741            return {
11742                globalTag: _logger2.default.GLOBAL_TAG,
11743                forceGlobalTag: _logger2.default.FORCE_GLOBAL_TAG,
11744                enableVerbose: _logger2.default.ENABLE_VERBOSE,
11745                enableDebug: _logger2.default.ENABLE_DEBUG,
11746                enableInfo: _logger2.default.ENABLE_INFO,
11747                enableWarn: _logger2.default.ENABLE_WARN,
11748                enableError: _logger2.default.ENABLE_ERROR,
11749                enableCallback: _logger2.default.ENABLE_CALLBACK
11750            };
11751        }
11752    }, {
11753        key: 'applyConfig',
11754        value: function applyConfig(config) {
11755            _logger2.default.GLOBAL_TAG = config.globalTag;
11756            _logger2.default.FORCE_GLOBAL_TAG = config.forceGlobalTag;
11757            _logger2.default.ENABLE_VERBOSE = config.enableVerbose;
11758            _logger2.default.ENABLE_DEBUG = config.enableDebug;
11759            _logger2.default.ENABLE_INFO = config.enableInfo;
11760            _logger2.default.ENABLE_WARN = config.enableWarn;
11761            _logger2.default.ENABLE_ERROR = config.enableError;
11762            _logger2.default.ENABLE_CALLBACK = config.enableCallback;
11763        }
11764    }, {
11765        key: '_notifyChange',
11766        value: function _notifyChange() {
11767            var emitter = LoggingControl.emitter;
11768
11769            if (emitter.listenerCount('change') > 0) {
11770                var config = LoggingControl.getConfig();
11771                emitter.emit('change', config);
11772            }
11773        }
11774    }, {
11775        key: 'registerListener',
11776        value: function registerListener(listener) {
11777            LoggingControl.emitter.addListener('change', listener);
11778        }
11779    }, {
11780        key: 'removeListener',
11781        value: function removeListener(listener) {
11782            LoggingControl.emitter.removeListener('change', listener);
11783        }
11784    }, {
11785        key: 'addLogListener',
11786        value: function addLogListener(listener) {
11787            _logger2.default.emitter.addListener('log', listener);
11788            if (_logger2.default.emitter.listenerCount('log') > 0) {
11789                _logger2.default.ENABLE_CALLBACK = true;
11790                LoggingControl._notifyChange();
11791            }
11792        }
11793    }, {
11794        key: 'removeLogListener',
11795        value: function removeLogListener(listener) {
11796            _logger2.default.emitter.removeListener('log', listener);
11797            if (_logger2.default.emitter.listenerCount('log') === 0) {
11798                _logger2.default.ENABLE_CALLBACK = false;
11799                LoggingControl._notifyChange();
11800            }
11801        }
11802    }, {
11803        key: 'forceGlobalTag',
11804        get: function get() {
11805            return _logger2.default.FORCE_GLOBAL_TAG;
11806        },
11807        set: function set(enable) {
11808            _logger2.default.FORCE_GLOBAL_TAG = enable;
11809            LoggingControl._notifyChange();
11810        }
11811    }, {
11812        key: 'globalTag',
11813        get: function get() {
11814            return _logger2.default.GLOBAL_TAG;
11815        },
11816        set: function set(tag) {
11817            _logger2.default.GLOBAL_TAG = tag;
11818            LoggingControl._notifyChange();
11819        }
11820    }, {
11821        key: 'enableAll',
11822        get: function get() {
11823            return _logger2.default.ENABLE_VERBOSE && _logger2.default.ENABLE_DEBUG && _logger2.default.ENABLE_INFO && _logger2.default.ENABLE_WARN && _logger2.default.ENABLE_ERROR;
11824        },
11825        set: function set(enable) {
11826            _logger2.default.ENABLE_VERBOSE = enable;
11827            _logger2.default.ENABLE_DEBUG = enable;
11828            _logger2.default.ENABLE_INFO = enable;
11829            _logger2.default.ENABLE_WARN = enable;
11830            _logger2.default.ENABLE_ERROR = enable;
11831            LoggingControl._notifyChange();
11832        }
11833    }, {
11834        key: 'enableDebug',
11835        get: function get() {
11836            return _logger2.default.ENABLE_DEBUG;
11837        },
11838        set: function set(enable) {
11839            _logger2.default.ENABLE_DEBUG = enable;
11840            LoggingControl._notifyChange();
11841        }
11842    }, {
11843        key: 'enableVerbose',
11844        get: function get() {
11845            return _logger2.default.ENABLE_VERBOSE;
11846        },
11847        set: function set(enable) {
11848            _logger2.default.ENABLE_VERBOSE = enable;
11849            LoggingControl._notifyChange();
11850        }
11851    }, {
11852        key: 'enableInfo',
11853        get: function get() {
11854            return _logger2.default.ENABLE_INFO;
11855        },
11856        set: function set(enable) {
11857            _logger2.default.ENABLE_INFO = enable;
11858            LoggingControl._notifyChange();
11859        }
11860    }, {
11861        key: 'enableWarn',
11862        get: function get() {
11863            return _logger2.default.ENABLE_WARN;
11864        },
11865        set: function set(enable) {
11866            _logger2.default.ENABLE_WARN = enable;
11867            LoggingControl._notifyChange();
11868        }
11869    }, {
11870        key: 'enableError',
11871        get: function get() {
11872            return _logger2.default.ENABLE_ERROR;
11873        },
11874        set: function set(enable) {
11875            _logger2.default.ENABLE_ERROR = enable;
11876            LoggingControl._notifyChange();
11877        }
11878    }]);
11879
11880    return LoggingControl;
11881}();
11882
11883LoggingControl.emitter = new _events2.default();
11884
11885exports.default = LoggingControl;
11886
11887},{"./logger.js":41,"events":2}],43:[function(_dereq_,module,exports){
11888'use strict';
11889
11890Object.defineProperty(exports, "__esModule", {
11891    value: true
11892});
11893
11894var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
11895
11896function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11897
11898/*
11899 * Copyright (C) 2016 Bilibili. All Rights Reserved.
11900 *
11901 * @author zheng qian <[email protected]>
11902 *
11903 * Licensed under the Apache License, Version 2.0 (the "License");
11904 * you may not use this file except in compliance with the License.
11905 * You may obtain a copy of the License at
11906 *
11907 *     http://www.apache.org/licenses/LICENSE-2.0
11908 *
11909 * Unless required by applicable law or agreed to in writing, software
11910 * distributed under the License is distributed on an "AS IS" BASIS,
11911 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11912 * See the License for the specific language governing permissions and
11913 * limitations under the License.
11914 */
11915
11916var Polyfill = function () {
11917    function Polyfill() {
11918        _classCallCheck(this, Polyfill);
11919    }
11920
11921    _createClass(Polyfill, null, [{
11922        key: 'install',
11923        value: function install() {
11924            // ES6 Object.setPrototypeOf
11925            Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
11926                obj.__proto__ = proto;
11927                return obj;
11928            };
11929
11930            // ES6 Object.assign
11931            Object.assign = Object.assign || function (target) {
11932                if (target === undefined || target === null) {
11933                    throw new TypeError('Cannot convert undefined or null to object');
11934                }
11935
11936                var output = Object(target);
11937                for (var i = 1; i < arguments.length; i++) {
11938                    var source = arguments[i];
11939                    if (source !== undefined && source !== null) {
11940                        for (var key in source) {
11941                            if (source.hasOwnProperty(key)) {
11942                                output[key] = source[key];
11943                            }
11944                        }
11945                    }
11946                }
11947                return output;
11948            };
11949
11950            // ES6 Promise (missing support in IE11)
11951            if (typeof self.Promise !== 'function') {
11952                _dereq_('es6-promise').polyfill();
11953            }
11954        }
11955    }]);
11956
11957    return Polyfill;
11958}();
11959
11960Polyfill.install();
11961
11962exports.default = Polyfill;
11963
11964},{"es6-promise":1}],44:[function(_dereq_,module,exports){
11965'use strict';
11966
11967Object.defineProperty(exports, "__esModule", {
11968    value: true
11969});
11970/*
11971 * Copyright (C) 2016 Bilibili. All Rights Reserved.
11972 *
11973 * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)
11974 * @author zheng qian <[email protected]>
11975 *
11976 * Licensed under the Apache License, Version 2.0 (the "License");
11977 * you may not use this file except in compliance with the License.
11978 * You may obtain a copy of the License at
11979 *
11980 *     http://www.apache.org/licenses/LICENSE-2.0
11981 *
11982 * Unless required by applicable law or agreed to in writing, software
11983 * distributed under the License is distributed on an "AS IS" BASIS,
11984 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11985 * See the License for the specific language governing permissions and
11986 * limitations under the License.
11987 */
11988
11989function checkContinuation(uint8array, start, checkLength) {
11990    var array = uint8array;
11991    if (start + checkLength < array.length) {
11992        while (checkLength--) {
11993            if ((array[++start] & 0xC0) !== 0x80) return false;
11994        }
11995        return true;
11996    } else {
11997        return false;
11998    }
11999}
12000
12001function decodeUTF8(uint8array) {
12002    var out = [];
12003    var input = uint8array;
12004    var i = 0;
12005    var length = uint8array.length;
12006
12007    while (i < length) {
12008        if (input[i] < 0x80) {
12009            out.push(String.fromCharCode(input[i]));
12010            ++i;
12011            continue;
12012        } else if (input[i] < 0xC0) {
12013            // fallthrough
12014        } else if (input[i] < 0xE0) {
12015            if (checkContinuation(input, i, 1)) {
12016                var ucs4 = (input[i] & 0x1F) << 6 | input[i + 1] & 0x3F;
12017                if (ucs4 >= 0x80) {
12018                    out.push(String.fromCharCode(ucs4 & 0xFFFF));
12019                    i += 2;
12020                    continue;
12021                }
12022            }
12023        } else if (input[i] < 0xF0) {
12024            if (checkContinuation(input, i, 2)) {
12025                var _ucs = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;
12026                if (_ucs >= 0x800 && (_ucs & 0xF800) !== 0xD800) {
12027                    out.push(String.fromCharCode(_ucs & 0xFFFF));
12028                    i += 3;
12029                    continue;
12030                }
12031            }
12032        } else if (input[i] < 0xF8) {
12033            if (checkContinuation(input, i, 3)) {
12034                var _ucs2 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12 | (input[i + 2] & 0x3F) << 6 | input[i + 3] & 0x3F;
12035                if (_ucs2 > 0x10000 && _ucs2 < 0x110000) {
12036                    _ucs2 -= 0x10000;
12037                    out.push(String.fromCharCode(_ucs2 >>> 10 | 0xD800));
12038                    out.push(String.fromCharCode(_ucs2 & 0x3FF | 0xDC00));
12039                    i += 4;
12040                    continue;
12041                }
12042            }
12043        }
12044        out.push(String.fromCharCode(0xFFFD));
12045        ++i;
12046    }
12047
12048    return out.join('');
12049}
12050
12051exports.default = decodeUTF8;
12052
12053},{}]},{},[21])(21)
12054});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.