github.com/cnotch/ipchub@v1.1.0/demos/flv/flv.js (about)

     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(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({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.8+1e68dce6
     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  
    17  function objectOrFunction(x) {
    18    var type = typeof x;
    19    return x !== null && (type === 'object' || type === 'function');
    20  }
    21  
    22  function isFunction(x) {
    23    return typeof x === 'function';
    24  }
    25  
    26  
    27  
    28  var _isArray = void 0;
    29  if (Array.isArray) {
    30    _isArray = Array.isArray;
    31  } else {
    32    _isArray = function (x) {
    33      return Object.prototype.toString.call(x) === '[object Array]';
    34    };
    35  }
    36  
    37  var isArray = _isArray;
    38  
    39  var len = 0;
    40  var vertxNext = void 0;
    41  var customSchedulerFn = void 0;
    42  
    43  var 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  
    59  function setScheduler(scheduleFn) {
    60    customSchedulerFn = scheduleFn;
    61  }
    62  
    63  function setAsap(asapFn) {
    64    asap = asapFn;
    65  }
    66  
    67  var browserWindow = typeof window !== 'undefined' ? window : undefined;
    68  var browserGlobal = browserWindow || {};
    69  var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
    70  var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
    71  
    72  // test for web worker but not in IE10
    73  var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
    74  
    75  // node
    76  function 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
    85  function useVertxTimer() {
    86    if (typeof vertxNext !== 'undefined') {
    87      return function () {
    88        vertxNext(flush);
    89      };
    90    }
    91  
    92    return useSetTimeout();
    93  }
    94  
    95  function 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
   107  function useMessageChannel() {
   108    var channel = new MessageChannel();
   109    channel.port1.onmessage = flush;
   110    return function () {
   111      return channel.port2.postMessage(0);
   112    };
   113  }
   114  
   115  function 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  
   124  var queue = new Array(1000);
   125  function 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  
   139  function 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  
   149  var scheduleFlush = void 0;
   150  // Decide what async method to use to triggering processing of queued callbacks:
   151  if (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_ === 'function') {
   158    scheduleFlush = attemptVertx();
   159  } else {
   160    scheduleFlush = useSetTimeout();
   161  }
   162  
   163  function 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  */
   218  function 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  
   231  var PROMISE_ID = Math.random().toString(36).substring(2);
   232  
   233  function noop() {}
   234  
   235  var PENDING = void 0;
   236  var FULFILLED = 1;
   237  var REJECTED = 2;
   238  
   239  function selfFulfillment() {
   240    return new TypeError("You cannot resolve a promise with itself");
   241  }
   242  
   243  function cannotReturnOwn() {
   244    return new TypeError('A promises callback cannot return that same promise.');
   245  }
   246  
   247  function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
   248    try {
   249      then$$1.call(value, fulfillmentHandler, rejectionHandler);
   250    } catch (e) {
   251      return e;
   252    }
   253  }
   254  
   255  function handleForeignThenable(promise, thenable, then$$1) {
   256    asap(function (promise) {
   257      var sealed = false;
   258      var error = tryThen(then$$1, thenable, function (value) {
   259        if (sealed) {
   260          return;
   261        }
   262        sealed = true;
   263        if (thenable !== value) {
   264          resolve(promise, value);
   265        } else {
   266          fulfill(promise, value);
   267        }
   268      }, function (reason) {
   269        if (sealed) {
   270          return;
   271        }
   272        sealed = true;
   273  
   274        reject(promise, reason);
   275      }, 'Settle: ' + (promise._label || ' unknown promise'));
   276  
   277      if (!sealed && error) {
   278        sealed = true;
   279        reject(promise, error);
   280      }
   281    }, promise);
   282  }
   283  
   284  function handleOwnThenable(promise, thenable) {
   285    if (thenable._state === FULFILLED) {
   286      fulfill(promise, thenable._result);
   287    } else if (thenable._state === REJECTED) {
   288      reject(promise, thenable._result);
   289    } else {
   290      subscribe(thenable, undefined, function (value) {
   291        return resolve(promise, value);
   292      }, function (reason) {
   293        return reject(promise, reason);
   294      });
   295    }
   296  }
   297  
   298  function handleMaybeThenable(promise, maybeThenable, then$$1) {
   299    if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
   300      handleOwnThenable(promise, maybeThenable);
   301    } else {
   302      if (then$$1 === undefined) {
   303        fulfill(promise, maybeThenable);
   304      } else if (isFunction(then$$1)) {
   305        handleForeignThenable(promise, maybeThenable, then$$1);
   306      } else {
   307        fulfill(promise, maybeThenable);
   308      }
   309    }
   310  }
   311  
   312  function resolve(promise, value) {
   313    if (promise === value) {
   314      reject(promise, selfFulfillment());
   315    } else if (objectOrFunction(value)) {
   316      var then$$1 = void 0;
   317      try {
   318        then$$1 = value.then;
   319      } catch (error) {
   320        reject(promise, error);
   321        return;
   322      }
   323      handleMaybeThenable(promise, value, then$$1);
   324    } else {
   325      fulfill(promise, value);
   326    }
   327  }
   328  
   329  function publishRejection(promise) {
   330    if (promise._onerror) {
   331      promise._onerror(promise._result);
   332    }
   333  
   334    publish(promise);
   335  }
   336  
   337  function fulfill(promise, value) {
   338    if (promise._state !== PENDING) {
   339      return;
   340    }
   341  
   342    promise._result = value;
   343    promise._state = FULFILLED;
   344  
   345    if (promise._subscribers.length !== 0) {
   346      asap(publish, promise);
   347    }
   348  }
   349  
   350  function reject(promise, reason) {
   351    if (promise._state !== PENDING) {
   352      return;
   353    }
   354    promise._state = REJECTED;
   355    promise._result = reason;
   356  
   357    asap(publishRejection, promise);
   358  }
   359  
   360  function subscribe(parent, child, onFulfillment, onRejection) {
   361    var _subscribers = parent._subscribers;
   362    var length = _subscribers.length;
   363  
   364  
   365    parent._onerror = null;
   366  
   367    _subscribers[length] = child;
   368    _subscribers[length + FULFILLED] = onFulfillment;
   369    _subscribers[length + REJECTED] = onRejection;
   370  
   371    if (length === 0 && parent._state) {
   372      asap(publish, parent);
   373    }
   374  }
   375  
   376  function publish(promise) {
   377    var subscribers = promise._subscribers;
   378    var settled = promise._state;
   379  
   380    if (subscribers.length === 0) {
   381      return;
   382    }
   383  
   384    var child = void 0,
   385        callback = void 0,
   386        detail = promise._result;
   387  
   388    for (var i = 0; i < subscribers.length; i += 3) {
   389      child = subscribers[i];
   390      callback = subscribers[i + settled];
   391  
   392      if (child) {
   393        invokeCallback(settled, child, callback, detail);
   394      } else {
   395        callback(detail);
   396      }
   397    }
   398  
   399    promise._subscribers.length = 0;
   400  }
   401  
   402  function invokeCallback(settled, promise, callback, detail) {
   403    var hasCallback = isFunction(callback),
   404        value = void 0,
   405        error = void 0,
   406        succeeded = true;
   407  
   408    if (hasCallback) {
   409      try {
   410        value = callback(detail);
   411      } catch (e) {
   412        succeeded = false;
   413        error = e;
   414      }
   415  
   416      if (promise === value) {
   417        reject(promise, cannotReturnOwn());
   418        return;
   419      }
   420    } else {
   421      value = detail;
   422    }
   423  
   424    if (promise._state !== PENDING) {
   425      // noop
   426    } else if (hasCallback && succeeded) {
   427      resolve(promise, value);
   428    } else if (succeeded === false) {
   429      reject(promise, error);
   430    } else if (settled === FULFILLED) {
   431      fulfill(promise, value);
   432    } else if (settled === REJECTED) {
   433      reject(promise, value);
   434    }
   435  }
   436  
   437  function initializePromise(promise, resolver) {
   438    try {
   439      resolver(function resolvePromise(value) {
   440        resolve(promise, value);
   441      }, function rejectPromise(reason) {
   442        reject(promise, reason);
   443      });
   444    } catch (e) {
   445      reject(promise, e);
   446    }
   447  }
   448  
   449  var id = 0;
   450  function nextId() {
   451    return id++;
   452  }
   453  
   454  function makePromise(promise) {
   455    promise[PROMISE_ID] = id++;
   456    promise._state = undefined;
   457    promise._result = undefined;
   458    promise._subscribers = [];
   459  }
   460  
   461  function validationError() {
   462    return new Error('Array Methods must be provided an Array');
   463  }
   464  
   465  var Enumerator = function () {
   466    function Enumerator(Constructor, input) {
   467      this._instanceConstructor = Constructor;
   468      this.promise = new Constructor(noop);
   469  
   470      if (!this.promise[PROMISE_ID]) {
   471        makePromise(this.promise);
   472      }
   473  
   474      if (isArray(input)) {
   475        this.length = input.length;
   476        this._remaining = input.length;
   477  
   478        this._result = new Array(this.length);
   479  
   480        if (this.length === 0) {
   481          fulfill(this.promise, this._result);
   482        } else {
   483          this.length = this.length || 0;
   484          this._enumerate(input);
   485          if (this._remaining === 0) {
   486            fulfill(this.promise, this._result);
   487          }
   488        }
   489      } else {
   490        reject(this.promise, validationError());
   491      }
   492    }
   493  
   494    Enumerator.prototype._enumerate = function _enumerate(input) {
   495      for (var i = 0; this._state === PENDING && i < input.length; i++) {
   496        this._eachEntry(input[i], i);
   497      }
   498    };
   499  
   500    Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
   501      var c = this._instanceConstructor;
   502      var resolve$$1 = c.resolve;
   503  
   504  
   505      if (resolve$$1 === resolve$1) {
   506        var _then = void 0;
   507        var error = void 0;
   508        var didError = false;
   509        try {
   510          _then = entry.then;
   511        } catch (e) {
   512          didError = true;
   513          error = e;
   514        }
   515  
   516        if (_then === then && entry._state !== PENDING) {
   517          this._settledAt(entry._state, i, entry._result);
   518        } else if (typeof _then !== 'function') {
   519          this._remaining--;
   520          this._result[i] = entry;
   521        } else if (c === Promise$1) {
   522          var promise = new c(noop);
   523          if (didError) {
   524            reject(promise, error);
   525          } else {
   526            handleMaybeThenable(promise, entry, _then);
   527          }
   528          this._willSettleAt(promise, i);
   529        } else {
   530          this._willSettleAt(new c(function (resolve$$1) {
   531            return resolve$$1(entry);
   532          }), i);
   533        }
   534      } else {
   535        this._willSettleAt(resolve$$1(entry), i);
   536      }
   537    };
   538  
   539    Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
   540      var promise = this.promise;
   541  
   542  
   543      if (promise._state === PENDING) {
   544        this._remaining--;
   545  
   546        if (state === REJECTED) {
   547          reject(promise, value);
   548        } else {
   549          this._result[i] = value;
   550        }
   551      }
   552  
   553      if (this._remaining === 0) {
   554        fulfill(promise, this._result);
   555      }
   556    };
   557  
   558    Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
   559      var enumerator = this;
   560  
   561      subscribe(promise, undefined, function (value) {
   562        return enumerator._settledAt(FULFILLED, i, value);
   563      }, function (reason) {
   564        return enumerator._settledAt(REJECTED, i, reason);
   565      });
   566    };
   567  
   568    return Enumerator;
   569  }();
   570  
   571  /**
   572    `Promise.all` accepts an array of promises, and returns a new promise which
   573    is fulfilled with an array of fulfillment values for the passed promises, or
   574    rejected with the reason of the first passed promise to be rejected. It casts all
   575    elements of the passed iterable to promises as it runs this algorithm.
   576  
   577    Example:
   578  
   579    ```javascript
   580    let promise1 = resolve(1);
   581    let promise2 = resolve(2);
   582    let promise3 = resolve(3);
   583    let promises = [ promise1, promise2, promise3 ];
   584  
   585    Promise.all(promises).then(function(array){
   586      // The array here would be [ 1, 2, 3 ];
   587    });
   588    ```
   589  
   590    If any of the `promises` given to `all` are rejected, the first promise
   591    that is rejected will be given as an argument to the returned promises's
   592    rejection handler. For example:
   593  
   594    Example:
   595  
   596    ```javascript
   597    let promise1 = resolve(1);
   598    let promise2 = reject(new Error("2"));
   599    let promise3 = reject(new Error("3"));
   600    let promises = [ promise1, promise2, promise3 ];
   601  
   602    Promise.all(promises).then(function(array){
   603      // Code here never runs because there are rejected promises!
   604    }, function(error) {
   605      // error.message === "2"
   606    });
   607    ```
   608  
   609    @method all
   610    @static
   611    @param {Array} entries array of promises
   612    @param {String} label optional string for labeling the promise.
   613    Useful for tooling.
   614    @return {Promise} promise that is fulfilled when all `promises` have been
   615    fulfilled, or rejected if any of them become rejected.
   616    @static
   617  */
   618  function all(entries) {
   619    return new Enumerator(this, entries).promise;
   620  }
   621  
   622  /**
   623    `Promise.race` returns a new promise which is settled in the same way as the
   624    first passed promise to settle.
   625  
   626    Example:
   627  
   628    ```javascript
   629    let promise1 = new Promise(function(resolve, reject){
   630      setTimeout(function(){
   631        resolve('promise 1');
   632      }, 200);
   633    });
   634  
   635    let promise2 = new Promise(function(resolve, reject){
   636      setTimeout(function(){
   637        resolve('promise 2');
   638      }, 100);
   639    });
   640  
   641    Promise.race([promise1, promise2]).then(function(result){
   642      // result === 'promise 2' because it was resolved before promise1
   643      // was resolved.
   644    });
   645    ```
   646  
   647    `Promise.race` is deterministic in that only the state of the first
   648    settled promise matters. For example, even if other promises given to the
   649    `promises` array argument are resolved, but the first settled promise has
   650    become rejected before the other promises became fulfilled, the returned
   651    promise will become rejected:
   652  
   653    ```javascript
   654    let promise1 = new Promise(function(resolve, reject){
   655      setTimeout(function(){
   656        resolve('promise 1');
   657      }, 200);
   658    });
   659  
   660    let promise2 = new Promise(function(resolve, reject){
   661      setTimeout(function(){
   662        reject(new Error('promise 2'));
   663      }, 100);
   664    });
   665  
   666    Promise.race([promise1, promise2]).then(function(result){
   667      // Code here never runs
   668    }, function(reason){
   669      // reason.message === 'promise 2' because promise 2 became rejected before
   670      // promise 1 became fulfilled
   671    });
   672    ```
   673  
   674    An example real-world use case is implementing timeouts:
   675  
   676    ```javascript
   677    Promise.race([ajax('foo.json'), timeout(5000)])
   678    ```
   679  
   680    @method race
   681    @static
   682    @param {Array} promises array of promises to observe
   683    Useful for tooling.
   684    @return {Promise} a promise which settles in the same way as the first passed
   685    promise to settle.
   686  */
   687  function race(entries) {
   688    /*jshint validthis:true */
   689    var Constructor = this;
   690  
   691    if (!isArray(entries)) {
   692      return new Constructor(function (_, reject) {
   693        return reject(new TypeError('You must pass an array to race.'));
   694      });
   695    } else {
   696      return new Constructor(function (resolve, reject) {
   697        var length = entries.length;
   698        for (var i = 0; i < length; i++) {
   699          Constructor.resolve(entries[i]).then(resolve, reject);
   700        }
   701      });
   702    }
   703  }
   704  
   705  /**
   706    `Promise.reject` returns a promise rejected with the passed `reason`.
   707    It is shorthand for the following:
   708  
   709    ```javascript
   710    let promise = new Promise(function(resolve, reject){
   711      reject(new Error('WHOOPS'));
   712    });
   713  
   714    promise.then(function(value){
   715      // Code here doesn't run because the promise is rejected!
   716    }, function(reason){
   717      // reason.message === 'WHOOPS'
   718    });
   719    ```
   720  
   721    Instead of writing the above, your code now simply becomes the following:
   722  
   723    ```javascript
   724    let promise = Promise.reject(new Error('WHOOPS'));
   725  
   726    promise.then(function(value){
   727      // Code here doesn't run because the promise is rejected!
   728    }, function(reason){
   729      // reason.message === 'WHOOPS'
   730    });
   731    ```
   732  
   733    @method reject
   734    @static
   735    @param {Any} reason value that the returned promise will be rejected with.
   736    Useful for tooling.
   737    @return {Promise} a promise rejected with the given `reason`.
   738  */
   739  function reject$1(reason) {
   740    /*jshint validthis:true */
   741    var Constructor = this;
   742    var promise = new Constructor(noop);
   743    reject(promise, reason);
   744    return promise;
   745  }
   746  
   747  function needsResolver() {
   748    throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
   749  }
   750  
   751  function needsNew() {
   752    throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
   753  }
   754  
   755  /**
   756    Promise objects represent the eventual result of an asynchronous operation. The
   757    primary way of interacting with a promise is through its `then` method, which
   758    registers callbacks to receive either a promise's eventual value or the reason
   759    why the promise cannot be fulfilled.
   760  
   761    Terminology
   762    -----------
   763  
   764    - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
   765    - `thenable` is an object or function that defines a `then` method.
   766    - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
   767    - `exception` is a value that is thrown using the throw statement.
   768    - `reason` is a value that indicates why a promise was rejected.
   769    - `settled` the final resting state of a promise, fulfilled or rejected.
   770  
   771    A promise can be in one of three states: pending, fulfilled, or rejected.
   772  
   773    Promises that are fulfilled have a fulfillment value and are in the fulfilled
   774    state.  Promises that are rejected have a rejection reason and are in the
   775    rejected state.  A fulfillment value is never a thenable.
   776  
   777    Promises can also be said to *resolve* a value.  If this value is also a
   778    promise, then the original promise's settled state will match the value's
   779    settled state.  So a promise that *resolves* a promise that rejects will
   780    itself reject, and a promise that *resolves* a promise that fulfills will
   781    itself fulfill.
   782  
   783  
   784    Basic Usage:
   785    ------------
   786  
   787    ```js
   788    let promise = new Promise(function(resolve, reject) {
   789      // on success
   790      resolve(value);
   791  
   792      // on failure
   793      reject(reason);
   794    });
   795  
   796    promise.then(function(value) {
   797      // on fulfillment
   798    }, function(reason) {
   799      // on rejection
   800    });
   801    ```
   802  
   803    Advanced Usage:
   804    ---------------
   805  
   806    Promises shine when abstracting away asynchronous interactions such as
   807    `XMLHttpRequest`s.
   808  
   809    ```js
   810    function getJSON(url) {
   811      return new Promise(function(resolve, reject){
   812        let xhr = new XMLHttpRequest();
   813  
   814        xhr.open('GET', url);
   815        xhr.onreadystatechange = handler;
   816        xhr.responseType = 'json';
   817        xhr.setRequestHeader('Accept', 'application/json');
   818        xhr.send();
   819  
   820        function handler() {
   821          if (this.readyState === this.DONE) {
   822            if (this.status === 200) {
   823              resolve(this.response);
   824            } else {
   825              reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
   826            }
   827          }
   828        };
   829      });
   830    }
   831  
   832    getJSON('/posts.json').then(function(json) {
   833      // on fulfillment
   834    }, function(reason) {
   835      // on rejection
   836    });
   837    ```
   838  
   839    Unlike callbacks, promises are great composable primitives.
   840  
   841    ```js
   842    Promise.all([
   843      getJSON('/posts'),
   844      getJSON('/comments')
   845    ]).then(function(values){
   846      values[0] // => postsJSON
   847      values[1] // => commentsJSON
   848  
   849      return values;
   850    });
   851    ```
   852  
   853    @class Promise
   854    @param {Function} resolver
   855    Useful for tooling.
   856    @constructor
   857  */
   858  
   859  var Promise$1 = function () {
   860    function Promise(resolver) {
   861      this[PROMISE_ID] = nextId();
   862      this._result = this._state = undefined;
   863      this._subscribers = [];
   864  
   865      if (noop !== resolver) {
   866        typeof resolver !== 'function' && needsResolver();
   867        this instanceof Promise ? initializePromise(this, resolver) : needsNew();
   868      }
   869    }
   870  
   871    /**
   872    The primary way of interacting with a promise is through its `then` method,
   873    which registers callbacks to receive either a promise's eventual value or the
   874    reason why the promise cannot be fulfilled.
   875     ```js
   876    findUser().then(function(user){
   877      // user is available
   878    }, function(reason){
   879      // user is unavailable, and you are given the reason why
   880    });
   881    ```
   882     Chaining
   883    --------
   884     The return value of `then` is itself a promise.  This second, 'downstream'
   885    promise is resolved with the return value of the first promise's fulfillment
   886    or rejection handler, or rejected if the handler throws an exception.
   887     ```js
   888    findUser().then(function (user) {
   889      return user.name;
   890    }, function (reason) {
   891      return 'default name';
   892    }).then(function (userName) {
   893      // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
   894      // will be `'default name'`
   895    });
   896     findUser().then(function (user) {
   897      throw new Error('Found user, but still unhappy');
   898    }, function (reason) {
   899      throw new Error('`findUser` rejected and we're unhappy');
   900    }).then(function (value) {
   901      // never reached
   902    }, function (reason) {
   903      // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
   904      // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
   905    });
   906    ```
   907    If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
   908     ```js
   909    findUser().then(function (user) {
   910      throw new PedagogicalException('Upstream error');
   911    }).then(function (value) {
   912      // never reached
   913    }).then(function (value) {
   914      // never reached
   915    }, function (reason) {
   916      // The `PedgagocialException` is propagated all the way down to here
   917    });
   918    ```
   919     Assimilation
   920    ------------
   921     Sometimes the value you want to propagate to a downstream promise can only be
   922    retrieved asynchronously. This can be achieved by returning a promise in the
   923    fulfillment or rejection handler. The downstream promise will then be pending
   924    until the returned promise is settled. This is called *assimilation*.
   925     ```js
   926    findUser().then(function (user) {
   927      return findCommentsByAuthor(user);
   928    }).then(function (comments) {
   929      // The user's comments are now available
   930    });
   931    ```
   932     If the assimliated promise rejects, then the downstream promise will also reject.
   933     ```js
   934    findUser().then(function (user) {
   935      return findCommentsByAuthor(user);
   936    }).then(function (comments) {
   937      // If `findCommentsByAuthor` fulfills, we'll have the value here
   938    }, function (reason) {
   939      // If `findCommentsByAuthor` rejects, we'll have the reason here
   940    });
   941    ```
   942     Simple Example
   943    --------------
   944     Synchronous Example
   945     ```javascript
   946    let result;
   947     try {
   948      result = findResult();
   949      // success
   950    } catch(reason) {
   951      // failure
   952    }
   953    ```
   954     Errback Example
   955     ```js
   956    findResult(function(result, err){
   957      if (err) {
   958        // failure
   959      } else {
   960        // success
   961      }
   962    });
   963    ```
   964     Promise Example;
   965     ```javascript
   966    findResult().then(function(result){
   967      // success
   968    }, function(reason){
   969      // failure
   970    });
   971    ```
   972     Advanced Example
   973    --------------
   974     Synchronous Example
   975     ```javascript
   976    let author, books;
   977     try {
   978      author = findAuthor();
   979      books  = findBooksByAuthor(author);
   980      // success
   981    } catch(reason) {
   982      // failure
   983    }
   984    ```
   985     Errback Example
   986     ```js
   987     function foundBooks(books) {
   988     }
   989     function failure(reason) {
   990     }
   991     findAuthor(function(author, err){
   992      if (err) {
   993        failure(err);
   994        // failure
   995      } else {
   996        try {
   997          findBoooksByAuthor(author, function(books, err) {
   998            if (err) {
   999              failure(err);
  1000            } else {
  1001              try {
  1002                foundBooks(books);
  1003              } catch(reason) {
  1004                failure(reason);
  1005              }
  1006            }
  1007          });
  1008        } catch(error) {
  1009          failure(err);
  1010        }
  1011        // success
  1012      }
  1013    });
  1014    ```
  1015     Promise Example;
  1016     ```javascript
  1017    findAuthor().
  1018      then(findBooksByAuthor).
  1019      then(function(books){
  1020        // found books
  1021    }).catch(function(reason){
  1022      // something went wrong
  1023    });
  1024    ```
  1025     @method then
  1026    @param {Function} onFulfilled
  1027    @param {Function} onRejected
  1028    Useful for tooling.
  1029    @return {Promise}
  1030    */
  1031  
  1032    /**
  1033    `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
  1034    as the catch block of a try/catch statement.
  1035    ```js
  1036    function findAuthor(){
  1037    throw new Error('couldn't find that author');
  1038    }
  1039    // synchronous
  1040    try {
  1041    findAuthor();
  1042    } catch(reason) {
  1043    // something went wrong
  1044    }
  1045    // async with promises
  1046    findAuthor().catch(function(reason){
  1047    // something went wrong
  1048    });
  1049    ```
  1050    @method catch
  1051    @param {Function} onRejection
  1052    Useful for tooling.
  1053    @return {Promise}
  1054    */
  1055  
  1056  
  1057    Promise.prototype.catch = function _catch(onRejection) {
  1058      return this.then(null, onRejection);
  1059    };
  1060  
  1061    /**
  1062      `finally` will be invoked regardless of the promise's fate just as native
  1063      try/catch/finally behaves
  1064    
  1065      Synchronous example:
  1066    
  1067      ```js
  1068      findAuthor() {
  1069        if (Math.random() > 0.5) {
  1070          throw new Error();
  1071        }
  1072        return new Author();
  1073      }
  1074    
  1075      try {
  1076        return findAuthor(); // succeed or fail
  1077      } catch(error) {
  1078        return findOtherAuther();
  1079      } finally {
  1080        // always runs
  1081        // doesn't affect the return value
  1082      }
  1083      ```
  1084    
  1085      Asynchronous example:
  1086    
  1087      ```js
  1088      findAuthor().catch(function(reason){
  1089        return findOtherAuther();
  1090      }).finally(function(){
  1091        // author was either found, or not
  1092      });
  1093      ```
  1094    
  1095      @method finally
  1096      @param {Function} callback
  1097      @return {Promise}
  1098    */
  1099  
  1100  
  1101    Promise.prototype.finally = function _finally(callback) {
  1102      var promise = this;
  1103      var constructor = promise.constructor;
  1104  
  1105      if (isFunction(callback)) {
  1106        return promise.then(function (value) {
  1107          return constructor.resolve(callback()).then(function () {
  1108            return value;
  1109          });
  1110        }, function (reason) {
  1111          return constructor.resolve(callback()).then(function () {
  1112            throw reason;
  1113          });
  1114        });
  1115      }
  1116  
  1117      return promise.then(callback, callback);
  1118    };
  1119  
  1120    return Promise;
  1121  }();
  1122  
  1123  Promise$1.prototype.then = then;
  1124  Promise$1.all = all;
  1125  Promise$1.race = race;
  1126  Promise$1.resolve = resolve$1;
  1127  Promise$1.reject = reject$1;
  1128  Promise$1._setScheduler = setScheduler;
  1129  Promise$1._setAsap = setAsap;
  1130  Promise$1._asap = asap;
  1131  
  1132  /*global self*/
  1133  function polyfill() {
  1134    var local = void 0;
  1135  
  1136    if (typeof global !== 'undefined') {
  1137      local = global;
  1138    } else if (typeof self !== 'undefined') {
  1139      local = self;
  1140    } else {
  1141      try {
  1142        local = Function('return this')();
  1143      } catch (e) {
  1144        throw new Error('polyfill failed because global object is unavailable in this environment');
  1145      }
  1146    }
  1147  
  1148    var P = local.Promise;
  1149  
  1150    if (P) {
  1151      var promiseToString = null;
  1152      try {
  1153        promiseToString = Object.prototype.toString.call(P.resolve());
  1154      } catch (e) {
  1155        // silently ignored
  1156      }
  1157  
  1158      if (promiseToString === '[object Promise]' && !P.cast) {
  1159        return;
  1160      }
  1161    }
  1162  
  1163    local.Promise = Promise$1;
  1164  }
  1165  
  1166  // Strange compat..
  1167  Promise$1.polyfill = polyfill;
  1168  Promise$1.Promise = Promise$1;
  1169  
  1170  return Promise$1;
  1171  
  1172  })));
  1173  
  1174  
  1175  
  1176  
  1177  
  1178  }).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  1179  
  1180  },{"_process":3}],2:[function(_dereq_,module,exports){
  1181  // Copyright Joyent, Inc. and other Node contributors.
  1182  //
  1183  // Permission is hereby granted, free of charge, to any person obtaining a
  1184  // copy of this software and associated documentation files (the
  1185  // "Software"), to deal in the Software without restriction, including
  1186  // without limitation the rights to use, copy, modify, merge, publish,
  1187  // distribute, sublicense, and/or sell copies of the Software, and to permit
  1188  // persons to whom the Software is furnished to do so, subject to the
  1189  // following conditions:
  1190  //
  1191  // The above copyright notice and this permission notice shall be included
  1192  // in all copies or substantial portions of the Software.
  1193  //
  1194  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  1195  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  1196  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  1197  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  1198  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  1199  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  1200  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  1201  
  1202  function EventEmitter() {
  1203    this._events = this._events || {};
  1204    this._maxListeners = this._maxListeners || undefined;
  1205  }
  1206  module.exports = EventEmitter;
  1207  
  1208  // Backwards-compat with node 0.10.x
  1209  EventEmitter.EventEmitter = EventEmitter;
  1210  
  1211  EventEmitter.prototype._events = undefined;
  1212  EventEmitter.prototype._maxListeners = undefined;
  1213  
  1214  // By default EventEmitters will print a warning if more than 10 listeners are
  1215  // added to it. This is a useful default which helps finding memory leaks.
  1216  EventEmitter.defaultMaxListeners = 10;
  1217  
  1218  // Obviously not all Emitters should be limited to 10. This function allows
  1219  // that to be increased. Set to zero for unlimited.
  1220  EventEmitter.prototype.setMaxListeners = function(n) {
  1221    if (!isNumber(n) || n < 0 || isNaN(n))
  1222      throw TypeError('n must be a positive number');
  1223    this._maxListeners = n;
  1224    return this;
  1225  };
  1226  
  1227  EventEmitter.prototype.emit = function(type) {
  1228    var er, handler, len, args, i, listeners;
  1229  
  1230    if (!this._events)
  1231      this._events = {};
  1232  
  1233    // If there is no 'error' event listener then throw.
  1234    if (type === 'error') {
  1235      if (!this._events.error ||
  1236          (isObject(this._events.error) && !this._events.error.length)) {
  1237        er = arguments[1];
  1238        if (er instanceof Error) {
  1239          throw er; // Unhandled 'error' event
  1240        } else {
  1241          // At least give some kind of context to the user
  1242          var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
  1243          err.context = er;
  1244          throw err;
  1245        }
  1246      }
  1247    }
  1248  
  1249    handler = this._events[type];
  1250  
  1251    if (isUndefined(handler))
  1252      return false;
  1253  
  1254    if (isFunction(handler)) {
  1255      switch (arguments.length) {
  1256        // fast cases
  1257        case 1:
  1258          handler.call(this);
  1259          break;
  1260        case 2:
  1261          handler.call(this, arguments[1]);
  1262          break;
  1263        case 3:
  1264          handler.call(this, arguments[1], arguments[2]);
  1265          break;
  1266        // slower
  1267        default:
  1268          args = Array.prototype.slice.call(arguments, 1);
  1269          handler.apply(this, args);
  1270      }
  1271    } else if (isObject(handler)) {
  1272      args = Array.prototype.slice.call(arguments, 1);
  1273      listeners = handler.slice();
  1274      len = listeners.length;
  1275      for (i = 0; i < len; i++)
  1276        listeners[i].apply(this, args);
  1277    }
  1278  
  1279    return true;
  1280  };
  1281  
  1282  EventEmitter.prototype.addListener = function(type, listener) {
  1283    var m;
  1284  
  1285    if (!isFunction(listener))
  1286      throw TypeError('listener must be a function');
  1287  
  1288    if (!this._events)
  1289      this._events = {};
  1290  
  1291    // To avoid recursion in the case that type === "newListener"! Before
  1292    // adding it to the listeners, first emit "newListener".
  1293    if (this._events.newListener)
  1294      this.emit('newListener', type,
  1295                isFunction(listener.listener) ?
  1296                listener.listener : listener);
  1297  
  1298    if (!this._events[type])
  1299      // Optimize the case of one listener. Don't need the extra array object.
  1300      this._events[type] = listener;
  1301    else if (isObject(this._events[type]))
  1302      // If we've already got an array, just append.
  1303      this._events[type].push(listener);
  1304    else
  1305      // Adding the second element, need to change to array.
  1306      this._events[type] = [this._events[type], listener];
  1307  
  1308    // Check for listener leak
  1309    if (isObject(this._events[type]) && !this._events[type].warned) {
  1310      if (!isUndefined(this._maxListeners)) {
  1311        m = this._maxListeners;
  1312      } else {
  1313        m = EventEmitter.defaultMaxListeners;
  1314      }
  1315  
  1316      if (m && m > 0 && this._events[type].length > m) {
  1317        this._events[type].warned = true;
  1318        console.error('(node) warning: possible EventEmitter memory ' +
  1319                      'leak detected. %d listeners added. ' +
  1320                      'Use emitter.setMaxListeners() to increase limit.',
  1321                      this._events[type].length);
  1322        if (typeof console.trace === 'function') {
  1323          // not supported in IE 10
  1324          console.trace();
  1325        }
  1326      }
  1327    }
  1328  
  1329    return this;
  1330  };
  1331  
  1332  EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  1333  
  1334  EventEmitter.prototype.once = function(type, listener) {
  1335    if (!isFunction(listener))
  1336      throw TypeError('listener must be a function');
  1337  
  1338    var fired = false;
  1339  
  1340    function g() {
  1341      this.removeListener(type, g);
  1342  
  1343      if (!fired) {
  1344        fired = true;
  1345        listener.apply(this, arguments);
  1346      }
  1347    }
  1348  
  1349    g.listener = listener;
  1350    this.on(type, g);
  1351  
  1352    return this;
  1353  };
  1354  
  1355  // emits a 'removeListener' event iff the listener was removed
  1356  EventEmitter.prototype.removeListener = function(type, listener) {
  1357    var list, position, length, i;
  1358  
  1359    if (!isFunction(listener))
  1360      throw TypeError('listener must be a function');
  1361  
  1362    if (!this._events || !this._events[type])
  1363      return this;
  1364  
  1365    list = this._events[type];
  1366    length = list.length;
  1367    position = -1;
  1368  
  1369    if (list === listener ||
  1370        (isFunction(list.listener) && list.listener === listener)) {
  1371      delete this._events[type];
  1372      if (this._events.removeListener)
  1373        this.emit('removeListener', type, listener);
  1374  
  1375    } else if (isObject(list)) {
  1376      for (i = length; i-- > 0;) {
  1377        if (list[i] === listener ||
  1378            (list[i].listener && list[i].listener === listener)) {
  1379          position = i;
  1380          break;
  1381        }
  1382      }
  1383  
  1384      if (position < 0)
  1385        return this;
  1386  
  1387      if (list.length === 1) {
  1388        list.length = 0;
  1389        delete this._events[type];
  1390      } else {
  1391        list.splice(position, 1);
  1392      }
  1393  
  1394      if (this._events.removeListener)
  1395        this.emit('removeListener', type, listener);
  1396    }
  1397  
  1398    return this;
  1399  };
  1400  
  1401  EventEmitter.prototype.removeAllListeners = function(type) {
  1402    var key, listeners;
  1403  
  1404    if (!this._events)
  1405      return this;
  1406  
  1407    // not listening for removeListener, no need to emit
  1408    if (!this._events.removeListener) {
  1409      if (arguments.length === 0)
  1410        this._events = {};
  1411      else if (this._events[type])
  1412        delete this._events[type];
  1413      return this;
  1414    }
  1415  
  1416    // emit removeListener for all listeners on all events
  1417    if (arguments.length === 0) {
  1418      for (key in this._events) {
  1419        if (key === 'removeListener') continue;
  1420        this.removeAllListeners(key);
  1421      }
  1422      this.removeAllListeners('removeListener');
  1423      this._events = {};
  1424      return this;
  1425    }
  1426  
  1427    listeners = this._events[type];
  1428  
  1429    if (isFunction(listeners)) {
  1430      this.removeListener(type, listeners);
  1431    } else if (listeners) {
  1432      // LIFO order
  1433      while (listeners.length)
  1434        this.removeListener(type, listeners[listeners.length - 1]);
  1435    }
  1436    delete this._events[type];
  1437  
  1438    return this;
  1439  };
  1440  
  1441  EventEmitter.prototype.listeners = function(type) {
  1442    var ret;
  1443    if (!this._events || !this._events[type])
  1444      ret = [];
  1445    else if (isFunction(this._events[type]))
  1446      ret = [this._events[type]];
  1447    else
  1448      ret = this._events[type].slice();
  1449    return ret;
  1450  };
  1451  
  1452  EventEmitter.prototype.listenerCount = function(type) {
  1453    if (this._events) {
  1454      var evlistener = this._events[type];
  1455  
  1456      if (isFunction(evlistener))
  1457        return 1;
  1458      else if (evlistener)
  1459        return evlistener.length;
  1460    }
  1461    return 0;
  1462  };
  1463  
  1464  EventEmitter.listenerCount = function(emitter, type) {
  1465    return emitter.listenerCount(type);
  1466  };
  1467  
  1468  function isFunction(arg) {
  1469    return typeof arg === 'function';
  1470  }
  1471  
  1472  function isNumber(arg) {
  1473    return typeof arg === 'number';
  1474  }
  1475  
  1476  function isObject(arg) {
  1477    return typeof arg === 'object' && arg !== null;
  1478  }
  1479  
  1480  function isUndefined(arg) {
  1481    return arg === void 0;
  1482  }
  1483  
  1484  },{}],3:[function(_dereq_,module,exports){
  1485  // shim for using process in browser
  1486  var process = module.exports = {};
  1487  
  1488  // cached from whatever global is present so that test runners that stub it
  1489  // don't break things.  But we need to wrap it in a try catch in case it is
  1490  // wrapped in strict mode code which doesn't define any globals.  It's inside a
  1491  // function because try/catches deoptimize in certain engines.
  1492  
  1493  var cachedSetTimeout;
  1494  var cachedClearTimeout;
  1495  
  1496  function defaultSetTimout() {
  1497      throw new Error('setTimeout has not been defined');
  1498  }
  1499  function defaultClearTimeout () {
  1500      throw new Error('clearTimeout has not been defined');
  1501  }
  1502  (function () {
  1503      try {
  1504          if (typeof setTimeout === 'function') {
  1505              cachedSetTimeout = setTimeout;
  1506          } else {
  1507              cachedSetTimeout = defaultSetTimout;
  1508          }
  1509      } catch (e) {
  1510          cachedSetTimeout = defaultSetTimout;
  1511      }
  1512      try {
  1513          if (typeof clearTimeout === 'function') {
  1514              cachedClearTimeout = clearTimeout;
  1515          } else {
  1516              cachedClearTimeout = defaultClearTimeout;
  1517          }
  1518      } catch (e) {
  1519          cachedClearTimeout = defaultClearTimeout;
  1520      }
  1521  } ())
  1522  function runTimeout(fun) {
  1523      if (cachedSetTimeout === setTimeout) {
  1524          //normal enviroments in sane situations
  1525          return setTimeout(fun, 0);
  1526      }
  1527      // if setTimeout wasn't available but was latter defined
  1528      if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
  1529          cachedSetTimeout = setTimeout;
  1530          return setTimeout(fun, 0);
  1531      }
  1532      try {
  1533          // when when somebody has screwed with setTimeout but no I.E. maddness
  1534          return cachedSetTimeout(fun, 0);
  1535      } catch(e){
  1536          try {
  1537              // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  1538              return cachedSetTimeout.call(null, fun, 0);
  1539          } catch(e){
  1540              // 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
  1541              return cachedSetTimeout.call(this, fun, 0);
  1542          }
  1543      }
  1544  
  1545  
  1546  }
  1547  function runClearTimeout(marker) {
  1548      if (cachedClearTimeout === clearTimeout) {
  1549          //normal enviroments in sane situations
  1550          return clearTimeout(marker);
  1551      }
  1552      // if clearTimeout wasn't available but was latter defined
  1553      if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
  1554          cachedClearTimeout = clearTimeout;
  1555          return clearTimeout(marker);
  1556      }
  1557      try {
  1558          // when when somebody has screwed with setTimeout but no I.E. maddness
  1559          return cachedClearTimeout(marker);
  1560      } catch (e){
  1561          try {
  1562              // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
  1563              return cachedClearTimeout.call(null, marker);
  1564          } catch (e){
  1565              // 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.
  1566              // Some versions of I.E. have different rules for clearTimeout vs setTimeout
  1567              return cachedClearTimeout.call(this, marker);
  1568          }
  1569      }
  1570  
  1571  
  1572  
  1573  }
  1574  var queue = [];
  1575  var draining = false;
  1576  var currentQueue;
  1577  var queueIndex = -1;
  1578  
  1579  function cleanUpNextTick() {
  1580      if (!draining || !currentQueue) {
  1581          return;
  1582      }
  1583      draining = false;
  1584      if (currentQueue.length) {
  1585          queue = currentQueue.concat(queue);
  1586      } else {
  1587          queueIndex = -1;
  1588      }
  1589      if (queue.length) {
  1590          drainQueue();
  1591      }
  1592  }
  1593  
  1594  function drainQueue() {
  1595      if (draining) {
  1596          return;
  1597      }
  1598      var timeout = runTimeout(cleanUpNextTick);
  1599      draining = true;
  1600  
  1601      var len = queue.length;
  1602      while(len) {
  1603          currentQueue = queue;
  1604          queue = [];
  1605          while (++queueIndex < len) {
  1606              if (currentQueue) {
  1607                  currentQueue[queueIndex].run();
  1608              }
  1609          }
  1610          queueIndex = -1;
  1611          len = queue.length;
  1612      }
  1613      currentQueue = null;
  1614      draining = false;
  1615      runClearTimeout(timeout);
  1616  }
  1617  
  1618  process.nextTick = function (fun) {
  1619      var args = new Array(arguments.length - 1);
  1620      if (arguments.length > 1) {
  1621          for (var i = 1; i < arguments.length; i++) {
  1622              args[i - 1] = arguments[i];
  1623          }
  1624      }
  1625      queue.push(new Item(fun, args));
  1626      if (queue.length === 1 && !draining) {
  1627          runTimeout(drainQueue);
  1628      }
  1629  };
  1630  
  1631  // v8 likes predictible objects
  1632  function Item(fun, array) {
  1633      this.fun = fun;
  1634      this.array = array;
  1635  }
  1636  Item.prototype.run = function () {
  1637      this.fun.apply(null, this.array);
  1638  };
  1639  process.title = 'browser';
  1640  process.browser = true;
  1641  process.env = {};
  1642  process.argv = [];
  1643  process.version = ''; // empty string to avoid regexp issues
  1644  process.versions = {};
  1645  
  1646  function noop() {}
  1647  
  1648  process.on = noop;
  1649  process.addListener = noop;
  1650  process.once = noop;
  1651  process.off = noop;
  1652  process.removeListener = noop;
  1653  process.removeAllListeners = noop;
  1654  process.emit = noop;
  1655  process.prependListener = noop;
  1656  process.prependOnceListener = noop;
  1657  
  1658  process.listeners = function (name) { return [] }
  1659  
  1660  process.binding = function (name) {
  1661      throw new Error('process.binding is not supported');
  1662  };
  1663  
  1664  process.cwd = function () { return '/' };
  1665  process.chdir = function (dir) {
  1666      throw new Error('process.chdir is not supported');
  1667  };
  1668  process.umask = function() { return 0; };
  1669  
  1670  },{}],4:[function(_dereq_,module,exports){
  1671  var bundleFn = arguments[3];
  1672  var sources = arguments[4];
  1673  var cache = arguments[5];
  1674  
  1675  var stringify = JSON.stringify;
  1676  
  1677  module.exports = function (fn, options) {
  1678      var wkey;
  1679      var cacheKeys = Object.keys(cache);
  1680  
  1681      for (var i = 0, l = cacheKeys.length; i < l; i++) {
  1682          var key = cacheKeys[i];
  1683          var exp = cache[key].exports;
  1684          // Using babel as a transpiler to use esmodule, the export will always
  1685          // be an object with the default export as a property of it. To ensure
  1686          // the existing api and babel esmodule exports are both supported we
  1687          // check for both
  1688          if (exp === fn || exp && exp.default === fn) {
  1689              wkey = key;
  1690              break;
  1691          }
  1692      }
  1693  
  1694      if (!wkey) {
  1695          wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
  1696          var wcache = {};
  1697          for (var i = 0, l = cacheKeys.length; i < l; i++) {
  1698              var key = cacheKeys[i];
  1699              wcache[key] = key;
  1700          }
  1701          sources[wkey] = [
  1702              'function(require,module,exports){' + fn + '(self); }',
  1703              wcache
  1704          ];
  1705      }
  1706      var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
  1707  
  1708      var scache = {}; scache[wkey] = wkey;
  1709      sources[skey] = [
  1710          'function(require,module,exports){' +
  1711              // try to call default if defined to also support babel esmodule exports
  1712              'var f = require(' + stringify(wkey) + ');' +
  1713              '(f.default ? f.default : f)(self);' +
  1714          '}',
  1715          scache
  1716      ];
  1717  
  1718      var workerSources = {};
  1719      resolveSources(skey);
  1720  
  1721      function resolveSources(key) {
  1722          workerSources[key] = true;
  1723  
  1724          for (var depPath in sources[key][1]) {
  1725              var depKey = sources[key][1][depPath];
  1726              if (!workerSources[depKey]) {
  1727                  resolveSources(depKey);
  1728              }
  1729          }
  1730      }
  1731  
  1732      var src = '(' + bundleFn + ')({'
  1733          + Object.keys(workerSources).map(function (key) {
  1734              return stringify(key) + ':['
  1735                  + sources[key][0]
  1736                  + ',' + stringify(sources[key][1]) + ']'
  1737              ;
  1738          }).join(',')
  1739          + '},{},[' + stringify(skey) + '])'
  1740      ;
  1741  
  1742      var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
  1743  
  1744      var blob = new Blob([src], { type: 'text/javascript' });
  1745      if (options && options.bare) { return blob; }
  1746      var workerUrl = URL.createObjectURL(blob);
  1747      var worker = new Worker(workerUrl);
  1748      worker.objectURL = workerUrl;
  1749      return worker;
  1750  };
  1751  
  1752  },{}],5:[function(_dereq_,module,exports){
  1753  'use strict';
  1754  
  1755  Object.defineProperty(exports, "__esModule", {
  1756      value: true
  1757  });
  1758  exports.createDefaultConfig = createDefaultConfig;
  1759  /*
  1760   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  1761   *
  1762   * @author zheng qian <xqq@xqq.im>
  1763   *
  1764   * Licensed under the Apache License, Version 2.0 (the "License");
  1765   * you may not use this file except in compliance with the License.
  1766   * You may obtain a copy of the License at
  1767   *
  1768   *     http://www.apache.org/licenses/LICENSE-2.0
  1769   *
  1770   * Unless required by applicable law or agreed to in writing, software
  1771   * distributed under the License is distributed on an "AS IS" BASIS,
  1772   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1773   * See the License for the specific language governing permissions and
  1774   * limitations under the License.
  1775   */
  1776  
  1777  var defaultConfig = exports.defaultConfig = {
  1778      enableWorker: false,
  1779      enableStashBuffer: true,
  1780      stashInitialSize: undefined,
  1781  
  1782      isLive: false,
  1783  
  1784      lazyLoad: true,
  1785      lazyLoadMaxDuration: 3 * 60,
  1786      lazyLoadRecoverDuration: 30,
  1787      deferLoadAfterSourceOpen: true,
  1788  
  1789      // autoCleanupSourceBuffer: default as false, leave unspecified
  1790      autoCleanupMaxBackwardDuration: 3 * 60,
  1791      autoCleanupMinBackwardDuration: 2 * 60,
  1792  
  1793      statisticsInfoReportInterval: 600,
  1794  
  1795      fixAudioTimestampGap: true,
  1796  
  1797      accurateSeek: false,
  1798      seekType: 'range', // [range, param, custom]
  1799      seekParamStart: 'bstart',
  1800      seekParamEnd: 'bend',
  1801      rangeLoadZeroStart: false,
  1802      customSeekHandler: undefined,
  1803      reuseRedirectedURL: false,
  1804      // referrerPolicy: leave as unspecified
  1805  
  1806      headers: undefined,
  1807      customLoader: undefined
  1808  };
  1809  
  1810  function createDefaultConfig() {
  1811      return Object.assign({}, defaultConfig);
  1812  }
  1813  
  1814  },{}],6:[function(_dereq_,module,exports){
  1815  'use strict';
  1816  
  1817  Object.defineProperty(exports, "__esModule", {
  1818      value: true
  1819  });
  1820  
  1821  var _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; }; }(); /*
  1822                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  1823                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  1824                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  1825                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  1826                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  1827                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  1828                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  1829                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  1830                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  1831                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  1832                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  1833                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  1834                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1835                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  1836                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  1837                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  1838  
  1839  var _ioController = _dereq_('../io/io-controller.js');
  1840  
  1841  var _ioController2 = _interopRequireDefault(_ioController);
  1842  
  1843  var _config = _dereq_('../config.js');
  1844  
  1845  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  1846  
  1847  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1848  
  1849  var Features = function () {
  1850      function Features() {
  1851          _classCallCheck(this, Features);
  1852      }
  1853  
  1854      _createClass(Features, null, [{
  1855          key: 'supportMSEH264Playback',
  1856          value: function supportMSEH264Playback() {
  1857              return window.MediaSource && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
  1858          }
  1859      }, {
  1860          key: 'supportNetworkStreamIO',
  1861          value: function supportNetworkStreamIO() {
  1862              var ioctl = new _ioController2.default({}, (0, _config.createDefaultConfig)());
  1863              var loaderType = ioctl.loaderType;
  1864              ioctl.destroy();
  1865              return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';
  1866          }
  1867      }, {
  1868          key: 'getNetworkLoaderTypeName',
  1869          value: function getNetworkLoaderTypeName() {
  1870              var ioctl = new _ioController2.default({}, (0, _config.createDefaultConfig)());
  1871              var loaderType = ioctl.loaderType;
  1872              ioctl.destroy();
  1873              return loaderType;
  1874          }
  1875      }, {
  1876          key: 'supportNativeMediaPlayback',
  1877          value: function supportNativeMediaPlayback(mimeType) {
  1878              if (Features.videoElement == undefined) {
  1879                  Features.videoElement = window.document.createElement('video');
  1880              }
  1881              var canPlay = Features.videoElement.canPlayType(mimeType);
  1882              return canPlay === 'probably' || canPlay == 'maybe';
  1883          }
  1884      }, {
  1885          key: 'getFeatureList',
  1886          value: function getFeatureList() {
  1887              var features = {
  1888                  mseFlvPlayback: false,
  1889                  mseLiveFlvPlayback: false,
  1890                  networkStreamIO: false,
  1891                  networkLoaderName: '',
  1892                  nativeMP4H264Playback: false,
  1893                  nativeWebmVP8Playback: false,
  1894                  nativeWebmVP9Playback: false
  1895              };
  1896  
  1897              features.mseFlvPlayback = Features.supportMSEH264Playback();
  1898              features.networkStreamIO = Features.supportNetworkStreamIO();
  1899              features.networkLoaderName = Features.getNetworkLoaderTypeName();
  1900              features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;
  1901              features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs="avc1.42001E, mp4a.40.2"');
  1902              features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs="vp8.0, vorbis"');
  1903              features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs="vp9"');
  1904  
  1905              return features;
  1906          }
  1907      }]);
  1908  
  1909      return Features;
  1910  }();
  1911  
  1912  exports.default = Features;
  1913  
  1914  },{"../config.js":5,"../io/io-controller.js":23}],7:[function(_dereq_,module,exports){
  1915  "use strict";
  1916  
  1917  Object.defineProperty(exports, "__esModule", {
  1918      value: true
  1919  });
  1920  
  1921  var _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; }; }();
  1922  
  1923  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1924  
  1925  /*
  1926   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  1927   *
  1928   * @author zheng qian <xqq@xqq.im>
  1929   *
  1930   * Licensed under the Apache License, Version 2.0 (the "License");
  1931   * you may not use this file except in compliance with the License.
  1932   * You may obtain a copy of the License at
  1933   *
  1934   *     http://www.apache.org/licenses/LICENSE-2.0
  1935   *
  1936   * Unless required by applicable law or agreed to in writing, software
  1937   * distributed under the License is distributed on an "AS IS" BASIS,
  1938   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1939   * See the License for the specific language governing permissions and
  1940   * limitations under the License.
  1941   */
  1942  
  1943  var MediaInfo = function () {
  1944      function MediaInfo() {
  1945          _classCallCheck(this, MediaInfo);
  1946  
  1947          this.mimeType = null;
  1948          this.duration = null;
  1949  
  1950          this.hasAudio = null;
  1951          this.hasVideo = null;
  1952          this.audioCodec = null;
  1953          this.videoCodec = null;
  1954          this.audioDataRate = null;
  1955          this.videoDataRate = null;
  1956  
  1957          this.audioSampleRate = null;
  1958          this.audioChannelCount = null;
  1959  
  1960          this.width = null;
  1961          this.height = null;
  1962          this.fps = null;
  1963          this.profile = null;
  1964          this.level = null;
  1965          this.refFrames = null;
  1966          this.chromaFormat = null;
  1967          this.sarNum = null;
  1968          this.sarDen = null;
  1969  
  1970          this.metadata = null;
  1971          this.segments = null; // MediaInfo[]
  1972          this.segmentCount = null;
  1973          this.hasKeyframesIndex = null;
  1974          this.keyframesIndex = null;
  1975      }
  1976  
  1977      _createClass(MediaInfo, [{
  1978          key: "isComplete",
  1979          value: function isComplete() {
  1980              var audioInfoComplete = this.hasAudio === false || this.hasAudio === true && this.audioCodec != null && this.audioSampleRate != null && this.audioChannelCount != null;
  1981  
  1982              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;
  1983  
  1984              // keyframesIndex may not be present
  1985              return this.mimeType != null && this.duration != null && this.metadata != null && this.hasKeyframesIndex != null && audioInfoComplete && videoInfoComplete;
  1986          }
  1987      }, {
  1988          key: "isSeekable",
  1989          value: function isSeekable() {
  1990              return this.hasKeyframesIndex === true;
  1991          }
  1992      }, {
  1993          key: "getNearestKeyframe",
  1994          value: function getNearestKeyframe(milliseconds) {
  1995              if (this.keyframesIndex == null) {
  1996                  return null;
  1997              }
  1998  
  1999              var table = this.keyframesIndex;
  2000              var keyframeIdx = this._search(table.times, milliseconds);
  2001  
  2002              return {
  2003                  index: keyframeIdx,
  2004                  milliseconds: table.times[keyframeIdx],
  2005                  fileposition: table.filepositions[keyframeIdx]
  2006              };
  2007          }
  2008      }, {
  2009          key: "_search",
  2010          value: function _search(list, value) {
  2011              var idx = 0;
  2012  
  2013              var last = list.length - 1;
  2014              var mid = 0;
  2015              var lbound = 0;
  2016              var ubound = last;
  2017  
  2018              if (value < list[0]) {
  2019                  idx = 0;
  2020                  lbound = ubound + 1; // skip search
  2021              }
  2022  
  2023              while (lbound <= ubound) {
  2024                  mid = lbound + Math.floor((ubound - lbound) / 2);
  2025                  if (mid === last || value >= list[mid] && value < list[mid + 1]) {
  2026                      idx = mid;
  2027                      break;
  2028                  } else if (list[mid] < value) {
  2029                      lbound = mid + 1;
  2030                  } else {
  2031                      ubound = mid - 1;
  2032                  }
  2033              }
  2034  
  2035              return idx;
  2036          }
  2037      }]);
  2038  
  2039      return MediaInfo;
  2040  }();
  2041  
  2042  exports.default = MediaInfo;
  2043  
  2044  },{}],8:[function(_dereq_,module,exports){
  2045  "use strict";
  2046  
  2047  Object.defineProperty(exports, "__esModule", {
  2048      value: true
  2049  });
  2050  
  2051  var _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; }; }();
  2052  
  2053  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2054  
  2055  /*
  2056   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  2057   *
  2058   * @author zheng qian <xqq@xqq.im>
  2059   *
  2060   * Licensed under the Apache License, Version 2.0 (the "License");
  2061   * you may not use this file except in compliance with the License.
  2062   * You may obtain a copy of the License at
  2063   *
  2064   *     http://www.apache.org/licenses/LICENSE-2.0
  2065   *
  2066   * Unless required by applicable law or agreed to in writing, software
  2067   * distributed under the License is distributed on an "AS IS" BASIS,
  2068   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2069   * See the License for the specific language governing permissions and
  2070   * limitations under the License.
  2071   */
  2072  
  2073  // Represents an media sample (audio / video)
  2074  var SampleInfo = exports.SampleInfo = function SampleInfo(dts, pts, duration, originalDts, isSync) {
  2075      _classCallCheck(this, SampleInfo);
  2076  
  2077      this.dts = dts;
  2078      this.pts = pts;
  2079      this.duration = duration;
  2080      this.originalDts = originalDts;
  2081      this.isSyncPoint = isSync;
  2082      this.fileposition = null;
  2083  };
  2084  
  2085  // Media Segment concept is defined in Media Source Extensions spec.
  2086  // Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.
  2087  
  2088  
  2089  var MediaSegmentInfo = exports.MediaSegmentInfo = function () {
  2090      function MediaSegmentInfo() {
  2091          _classCallCheck(this, MediaSegmentInfo);
  2092  
  2093          this.beginDts = 0;
  2094          this.endDts = 0;
  2095          this.beginPts = 0;
  2096          this.endPts = 0;
  2097          this.originalBeginDts = 0;
  2098          this.originalEndDts = 0;
  2099          this.syncPoints = []; // SampleInfo[n], for video IDR frames only
  2100          this.firstSample = null; // SampleInfo
  2101          this.lastSample = null; // SampleInfo
  2102      }
  2103  
  2104      _createClass(MediaSegmentInfo, [{
  2105          key: "appendSyncPoint",
  2106          value: function appendSyncPoint(sampleInfo) {
  2107              // also called Random Access Point
  2108              sampleInfo.isSyncPoint = true;
  2109              this.syncPoints.push(sampleInfo);
  2110          }
  2111      }]);
  2112  
  2113      return MediaSegmentInfo;
  2114  }();
  2115  
  2116  // Ordered list for recording video IDR frames, sorted by originalDts
  2117  
  2118  
  2119  var IDRSampleList = exports.IDRSampleList = function () {
  2120      function IDRSampleList() {
  2121          _classCallCheck(this, IDRSampleList);
  2122  
  2123          this._list = [];
  2124      }
  2125  
  2126      _createClass(IDRSampleList, [{
  2127          key: "clear",
  2128          value: function clear() {
  2129              this._list = [];
  2130          }
  2131      }, {
  2132          key: "appendArray",
  2133          value: function appendArray(syncPoints) {
  2134              var list = this._list;
  2135  
  2136              if (syncPoints.length === 0) {
  2137                  return;
  2138              }
  2139  
  2140              if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {
  2141                  this.clear();
  2142              }
  2143  
  2144              Array.prototype.push.apply(list, syncPoints);
  2145          }
  2146      }, {
  2147          key: "getLastSyncPointBeforeDts",
  2148          value: function getLastSyncPointBeforeDts(dts) {
  2149              if (this._list.length == 0) {
  2150                  return null;
  2151              }
  2152  
  2153              var list = this._list;
  2154              var idx = 0;
  2155              var last = list.length - 1;
  2156              var mid = 0;
  2157              var lbound = 0;
  2158              var ubound = last;
  2159  
  2160              if (dts < list[0].dts) {
  2161                  idx = 0;
  2162                  lbound = ubound + 1;
  2163              }
  2164  
  2165              while (lbound <= ubound) {
  2166                  mid = lbound + Math.floor((ubound - lbound) / 2);
  2167                  if (mid === last || dts >= list[mid].dts && dts < list[mid + 1].dts) {
  2168                      idx = mid;
  2169                      break;
  2170                  } else if (list[mid].dts < dts) {
  2171                      lbound = mid + 1;
  2172                  } else {
  2173                      ubound = mid - 1;
  2174                  }
  2175              }
  2176              return this._list[idx];
  2177          }
  2178      }]);
  2179  
  2180      return IDRSampleList;
  2181  }();
  2182  
  2183  // Data structure for recording information of media segments in single track.
  2184  
  2185  
  2186  var MediaSegmentInfoList = exports.MediaSegmentInfoList = function () {
  2187      function MediaSegmentInfoList(type) {
  2188          _classCallCheck(this, MediaSegmentInfoList);
  2189  
  2190          this._type = type;
  2191          this._list = [];
  2192          this._lastAppendLocation = -1; // cached last insert location
  2193      }
  2194  
  2195      _createClass(MediaSegmentInfoList, [{
  2196          key: "isEmpty",
  2197          value: function isEmpty() {
  2198              return this._list.length === 0;
  2199          }
  2200      }, {
  2201          key: "clear",
  2202          value: function clear() {
  2203              this._list = [];
  2204              this._lastAppendLocation = -1;
  2205          }
  2206      }, {
  2207          key: "_searchNearestSegmentBefore",
  2208          value: function _searchNearestSegmentBefore(originalBeginDts) {
  2209              var list = this._list;
  2210              if (list.length === 0) {
  2211                  return -2;
  2212              }
  2213              var last = list.length - 1;
  2214              var mid = 0;
  2215              var lbound = 0;
  2216              var ubound = last;
  2217  
  2218              var idx = 0;
  2219  
  2220              if (originalBeginDts < list[0].originalBeginDts) {
  2221                  idx = -1;
  2222                  return idx;
  2223              }
  2224  
  2225              while (lbound <= ubound) {
  2226                  mid = lbound + Math.floor((ubound - lbound) / 2);
  2227                  if (mid === last || originalBeginDts > list[mid].lastSample.originalDts && originalBeginDts < list[mid + 1].originalBeginDts) {
  2228                      idx = mid;
  2229                      break;
  2230                  } else if (list[mid].originalBeginDts < originalBeginDts) {
  2231                      lbound = mid + 1;
  2232                  } else {
  2233                      ubound = mid - 1;
  2234                  }
  2235              }
  2236              return idx;
  2237          }
  2238      }, {
  2239          key: "_searchNearestSegmentAfter",
  2240          value: function _searchNearestSegmentAfter(originalBeginDts) {
  2241              return this._searchNearestSegmentBefore(originalBeginDts) + 1;
  2242          }
  2243      }, {
  2244          key: "append",
  2245          value: function append(mediaSegmentInfo) {
  2246              var list = this._list;
  2247              var msi = mediaSegmentInfo;
  2248              var lastAppendIdx = this._lastAppendLocation;
  2249              var insertIdx = 0;
  2250  
  2251              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)) {
  2252                  insertIdx = lastAppendIdx + 1; // use cached location idx
  2253              } else {
  2254                  if (list.length > 0) {
  2255                      insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;
  2256                  }
  2257              }
  2258  
  2259              this._lastAppendLocation = insertIdx;
  2260              this._list.splice(insertIdx, 0, msi);
  2261          }
  2262      }, {
  2263          key: "getLastSegmentBefore",
  2264          value: function getLastSegmentBefore(originalBeginDts) {
  2265              var idx = this._searchNearestSegmentBefore(originalBeginDts);
  2266              if (idx >= 0) {
  2267                  return this._list[idx];
  2268              } else {
  2269                  // -1
  2270                  return null;
  2271              }
  2272          }
  2273      }, {
  2274          key: "getLastSampleBefore",
  2275          value: function getLastSampleBefore(originalBeginDts) {
  2276              var segment = this.getLastSegmentBefore(originalBeginDts);
  2277              if (segment != null) {
  2278                  return segment.lastSample;
  2279              } else {
  2280                  return null;
  2281              }
  2282          }
  2283      }, {
  2284          key: "getLastSyncPointBefore",
  2285          value: function getLastSyncPointBefore(originalBeginDts) {
  2286              var segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);
  2287              var syncPoints = this._list[segmentIdx].syncPoints;
  2288              while (syncPoints.length === 0 && segmentIdx > 0) {
  2289                  segmentIdx--;
  2290                  syncPoints = this._list[segmentIdx].syncPoints;
  2291              }
  2292              if (syncPoints.length > 0) {
  2293                  return syncPoints[syncPoints.length - 1];
  2294              } else {
  2295                  return null;
  2296              }
  2297          }
  2298      }, {
  2299          key: "type",
  2300          get: function get() {
  2301              return this._type;
  2302          }
  2303      }, {
  2304          key: "length",
  2305          get: function get() {
  2306              return this._list.length;
  2307          }
  2308      }]);
  2309  
  2310      return MediaSegmentInfoList;
  2311  }();
  2312  
  2313  },{}],9:[function(_dereq_,module,exports){
  2314  'use strict';
  2315  
  2316  Object.defineProperty(exports, "__esModule", {
  2317      value: true
  2318  });
  2319  
  2320  var _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; }; }(); /*
  2321                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  2322                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2323                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  2324                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2325                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  2326                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  2327                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  2328                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2329                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  2330                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2331                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  2332                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  2333                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2334                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  2335                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  2336                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  2337  
  2338  var _events = _dereq_('events');
  2339  
  2340  var _events2 = _interopRequireDefault(_events);
  2341  
  2342  var _logger = _dereq_('../utils/logger.js');
  2343  
  2344  var _logger2 = _interopRequireDefault(_logger);
  2345  
  2346  var _browser = _dereq_('../utils/browser.js');
  2347  
  2348  var _browser2 = _interopRequireDefault(_browser);
  2349  
  2350  var _mseEvents = _dereq_('./mse-events.js');
  2351  
  2352  var _mseEvents2 = _interopRequireDefault(_mseEvents);
  2353  
  2354  var _mediaSegmentInfo = _dereq_('./media-segment-info.js');
  2355  
  2356  var _exception = _dereq_('../utils/exception.js');
  2357  
  2358  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  2359  
  2360  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2361  
  2362  // Media Source Extensions controller
  2363  var MSEController = function () {
  2364      function MSEController(config) {
  2365          _classCallCheck(this, MSEController);
  2366  
  2367          this.TAG = 'MSEController';
  2368  
  2369          this._config = config;
  2370          this._emitter = new _events2.default();
  2371  
  2372          if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {
  2373              // For live stream, do auto cleanup by default
  2374              this._config.autoCleanupSourceBuffer = true;
  2375          }
  2376  
  2377          this.e = {
  2378              onSourceOpen: this._onSourceOpen.bind(this),
  2379              onSourceEnded: this._onSourceEnded.bind(this),
  2380              onSourceClose: this._onSourceClose.bind(this),
  2381              onSourceBufferError: this._onSourceBufferError.bind(this),
  2382              onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)
  2383          };
  2384  
  2385          this._mediaSource = null;
  2386          this._mediaSourceObjectURL = null;
  2387          this._mediaElement = null;
  2388  
  2389          this._isBufferFull = false;
  2390          this._hasPendingEos = false;
  2391  
  2392          this._requireSetMediaDuration = false;
  2393          this._pendingMediaDuration = 0;
  2394  
  2395          this._pendingSourceBufferInit = [];
  2396          this._mimeTypes = {
  2397              video: null,
  2398              audio: null
  2399          };
  2400          this._sourceBuffers = {
  2401              video: null,
  2402              audio: null
  2403          };
  2404          this._lastInitSegments = {
  2405              video: null,
  2406              audio: null
  2407          };
  2408          this._pendingSegments = {
  2409              video: [],
  2410              audio: []
  2411          };
  2412          this._pendingRemoveRanges = {
  2413              video: [],
  2414              audio: []
  2415          };
  2416          this._idrList = new _mediaSegmentInfo.IDRSampleList();
  2417      }
  2418  
  2419      _createClass(MSEController, [{
  2420          key: 'destroy',
  2421          value: function destroy() {
  2422              if (this._mediaElement || this._mediaSource) {
  2423                  this.detachMediaElement();
  2424              }
  2425              this.e = null;
  2426              this._emitter.removeAllListeners();
  2427              this._emitter = null;
  2428          }
  2429      }, {
  2430          key: 'on',
  2431          value: function on(event, listener) {
  2432              this._emitter.addListener(event, listener);
  2433          }
  2434      }, {
  2435          key: 'off',
  2436          value: function off(event, listener) {
  2437              this._emitter.removeListener(event, listener);
  2438          }
  2439      }, {
  2440          key: 'attachMediaElement',
  2441          value: function attachMediaElement(mediaElement) {
  2442              if (this._mediaSource) {
  2443                  throw new _exception.IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');
  2444              }
  2445              var ms = this._mediaSource = new window.MediaSource();
  2446              ms.addEventListener('sourceopen', this.e.onSourceOpen);
  2447              ms.addEventListener('sourceended', this.e.onSourceEnded);
  2448              ms.addEventListener('sourceclose', this.e.onSourceClose);
  2449  
  2450              this._mediaElement = mediaElement;
  2451              this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);
  2452              mediaElement.src = this._mediaSourceObjectURL;
  2453          }
  2454      }, {
  2455          key: 'detachMediaElement',
  2456          value: function detachMediaElement() {
  2457              if (this._mediaSource) {
  2458                  var ms = this._mediaSource;
  2459                  for (var type in this._sourceBuffers) {
  2460                      // pending segments should be discard
  2461                      var ps = this._pendingSegments[type];
  2462                      ps.splice(0, ps.length);
  2463                      this._pendingSegments[type] = null;
  2464                      this._pendingRemoveRanges[type] = null;
  2465                      this._lastInitSegments[type] = null;
  2466  
  2467                      // remove all sourcebuffers
  2468                      var sb = this._sourceBuffers[type];
  2469                      if (sb) {
  2470                          if (ms.readyState !== 'closed') {
  2471                              // ms edge can throw an error: Unexpected call to method or property access
  2472                              try {
  2473                                  ms.removeSourceBuffer(sb);
  2474                              } catch (error) {
  2475                                  _logger2.default.e(this.TAG, error.message);
  2476                              }
  2477                              sb.removeEventListener('error', this.e.onSourceBufferError);
  2478                              sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);
  2479                          }
  2480                          this._mimeTypes[type] = null;
  2481                          this._sourceBuffers[type] = null;
  2482                      }
  2483                  }
  2484                  if (ms.readyState === 'open') {
  2485                      try {
  2486                          ms.endOfStream();
  2487                      } catch (error) {
  2488                          _logger2.default.e(this.TAG, error.message);
  2489                      }
  2490                  }
  2491                  ms.removeEventListener('sourceopen', this.e.onSourceOpen);
  2492                  ms.removeEventListener('sourceended', this.e.onSourceEnded);
  2493                  ms.removeEventListener('sourceclose', this.e.onSourceClose);
  2494                  this._pendingSourceBufferInit = [];
  2495                  this._isBufferFull = false;
  2496                  this._idrList.clear();
  2497                  this._mediaSource = null;
  2498              }
  2499  
  2500              if (this._mediaElement) {
  2501                  this._mediaElement.src = '';
  2502                  this._mediaElement.removeAttribute('src');
  2503                  this._mediaElement = null;
  2504              }
  2505              if (this._mediaSourceObjectURL) {
  2506                  window.URL.revokeObjectURL(this._mediaSourceObjectURL);
  2507                  this._mediaSourceObjectURL = null;
  2508              }
  2509          }
  2510      }, {
  2511          key: 'appendInitSegment',
  2512          value: function appendInitSegment(initSegment, deferred) {
  2513              if (!this._mediaSource || this._mediaSource.readyState !== 'open') {
  2514                  // sourcebuffer creation requires mediaSource.readyState === 'open'
  2515                  // so we defer the sourcebuffer creation, until sourceopen event triggered
  2516                  this._pendingSourceBufferInit.push(initSegment);
  2517                  // make sure that this InitSegment is in the front of pending segments queue
  2518                  this._pendingSegments[initSegment.type].push(initSegment);
  2519                  return;
  2520              }
  2521  
  2522              var is = initSegment;
  2523              var mimeType = '' + is.container;
  2524              if (is.codec && is.codec.length > 0) {
  2525                  mimeType += ';codecs=' + is.codec;
  2526              }
  2527  
  2528              var firstInitSegment = false;
  2529  
  2530              _logger2.default.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);
  2531              this._lastInitSegments[is.type] = is;
  2532  
  2533              if (mimeType !== this._mimeTypes[is.type]) {
  2534                  if (!this._mimeTypes[is.type]) {
  2535                      // empty, first chance create sourcebuffer
  2536                      firstInitSegment = true;
  2537                      try {
  2538                          var sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);
  2539                          sb.addEventListener('error', this.e.onSourceBufferError);
  2540                          sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);
  2541                      } catch (error) {
  2542                          _logger2.default.e(this.TAG, error.message);
  2543                          this._emitter.emit(_mseEvents2.default.ERROR, { code: error.code, msg: error.message });
  2544                          return;
  2545                      }
  2546                  } else {
  2547                      _logger2.default.v(this.TAG, 'Notice: ' + is.type + ' mimeType changed, origin: ' + this._mimeTypes[is.type] + ', target: ' + mimeType);
  2548                  }
  2549                  this._mimeTypes[is.type] = mimeType;
  2550              }
  2551  
  2552              if (!deferred) {
  2553                  // deferred means this InitSegment has been pushed to pendingSegments queue
  2554                  this._pendingSegments[is.type].push(is);
  2555              }
  2556              if (!firstInitSegment) {
  2557                  // append immediately only if init segment in subsequence
  2558                  if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {
  2559                      this._doAppendSegments();
  2560                  }
  2561              }
  2562              if (_browser2.default.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {
  2563                  // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN
  2564                  // Manually correct MediaSource.duration to make progress bar seekable, and report right duration
  2565                  this._requireSetMediaDuration = true;
  2566                  this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds
  2567                  this._updateMediaSourceDuration();
  2568              }
  2569          }
  2570      }, {
  2571          key: 'appendMediaSegment',
  2572          value: function appendMediaSegment(mediaSegment) {
  2573              var ms = mediaSegment;
  2574              this._pendingSegments[ms.type].push(ms);
  2575  
  2576              if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {
  2577                  this._doCleanupSourceBuffer();
  2578              }
  2579  
  2580              var sb = this._sourceBuffers[ms.type];
  2581              if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {
  2582                  this._doAppendSegments();
  2583              }
  2584          }
  2585      }, {
  2586          key: 'seek',
  2587          value: function seek(seconds) {
  2588              // remove all appended buffers
  2589              for (var type in this._sourceBuffers) {
  2590                  if (!this._sourceBuffers[type]) {
  2591                      continue;
  2592                  }
  2593  
  2594                  // abort current buffer append algorithm
  2595                  var sb = this._sourceBuffers[type];
  2596                  if (this._mediaSource.readyState === 'open') {
  2597                      try {
  2598                          // If range removal algorithm is running, InvalidStateError will be throwed
  2599                          // Ignore it.
  2600                          sb.abort();
  2601                      } catch (error) {
  2602                          _logger2.default.e(this.TAG, error.message);
  2603                      }
  2604                  }
  2605  
  2606                  // IDRList should be clear
  2607                  this._idrList.clear();
  2608  
  2609                  // pending segments should be discard
  2610                  var ps = this._pendingSegments[type];
  2611                  ps.splice(0, ps.length);
  2612  
  2613                  if (this._mediaSource.readyState === 'closed') {
  2614                      // Parent MediaSource object has been detached from HTMLMediaElement
  2615                      continue;
  2616                  }
  2617  
  2618                  // record ranges to be remove from SourceBuffer
  2619                  for (var i = 0; i < sb.buffered.length; i++) {
  2620                      var start = sb.buffered.start(i);
  2621                      var end = sb.buffered.end(i);
  2622                      this._pendingRemoveRanges[type].push({ start: start, end: end });
  2623                  }
  2624  
  2625                  // if sb is not updating, let's remove ranges now!
  2626                  if (!sb.updating) {
  2627                      this._doRemoveRanges();
  2628                  }
  2629  
  2630                  // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call
  2631                  // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.
  2632                  // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230
  2633                  if (_browser2.default.safari) {
  2634                      var lastInitSegment = this._lastInitSegments[type];
  2635                      if (lastInitSegment) {
  2636                          this._pendingSegments[type].push(lastInitSegment);
  2637                          if (!sb.updating) {
  2638                              this._doAppendSegments();
  2639                          }
  2640                      }
  2641                  }
  2642              }
  2643          }
  2644      }, {
  2645          key: 'endOfStream',
  2646          value: function endOfStream() {
  2647              var ms = this._mediaSource;
  2648              var sb = this._sourceBuffers;
  2649              if (!ms || ms.readyState !== 'open') {
  2650                  if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {
  2651                      // If MediaSource hasn't turned into open state, and there're pending segments
  2652                      // Mark pending endOfStream, defer call until all pending segments appended complete
  2653                      this._hasPendingEos = true;
  2654                  }
  2655                  return;
  2656              }
  2657              if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {
  2658                  // If any sourcebuffer is updating, defer endOfStream operation
  2659                  // See _onSourceBufferUpdateEnd()
  2660                  this._hasPendingEos = true;
  2661              } else {
  2662                  this._hasPendingEos = false;
  2663                  // Notify media data loading complete
  2664                  // This is helpful for correcting total duration to match last media segment
  2665                  // Otherwise MediaElement's ended event may not be triggered
  2666                  ms.endOfStream();
  2667              }
  2668          }
  2669      }, {
  2670          key: 'getNearestKeyframe',
  2671          value: function getNearestKeyframe(dts) {
  2672              return this._idrList.getLastSyncPointBeforeDts(dts);
  2673          }
  2674      }, {
  2675          key: '_needCleanupSourceBuffer',
  2676          value: function _needCleanupSourceBuffer() {
  2677              if (!this._config.autoCleanupSourceBuffer) {
  2678                  return false;
  2679              }
  2680  
  2681              var currentTime = this._mediaElement.currentTime;
  2682  
  2683              for (var type in this._sourceBuffers) {
  2684                  var sb = this._sourceBuffers[type];
  2685                  if (sb) {
  2686                      var buffered = sb.buffered;
  2687                      if (buffered.length >= 1) {
  2688                          if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {
  2689                              return true;
  2690                          }
  2691                      }
  2692                  }
  2693              }
  2694  
  2695              return false;
  2696          }
  2697      }, {
  2698          key: '_doCleanupSourceBuffer',
  2699          value: function _doCleanupSourceBuffer() {
  2700              var currentTime = this._mediaElement.currentTime;
  2701  
  2702              for (var type in this._sourceBuffers) {
  2703                  var sb = this._sourceBuffers[type];
  2704                  if (sb) {
  2705                      var buffered = sb.buffered;
  2706                      var doRemove = false;
  2707  
  2708                      for (var i = 0; i < buffered.length; i++) {
  2709                          var start = buffered.start(i);
  2710                          var end = buffered.end(i);
  2711  
  2712                          if (start <= currentTime && currentTime < end + 3) {
  2713                              // padding 3 seconds
  2714                              if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {
  2715                                  doRemove = true;
  2716                                  var removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;
  2717                                  this._pendingRemoveRanges[type].push({ start: start, end: removeEnd });
  2718                              }
  2719                          } else if (end < currentTime) {
  2720                              doRemove = true;
  2721                              this._pendingRemoveRanges[type].push({ start: start, end: end });
  2722                          }
  2723                      }
  2724  
  2725                      if (doRemove && !sb.updating) {
  2726                          this._doRemoveRanges();
  2727                      }
  2728                  }
  2729              }
  2730          }
  2731      }, {
  2732          key: '_updateMediaSourceDuration',
  2733          value: function _updateMediaSourceDuration() {
  2734              var sb = this._sourceBuffers;
  2735              if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {
  2736                  return;
  2737              }
  2738              if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {
  2739                  return;
  2740              }
  2741  
  2742              var current = this._mediaSource.duration;
  2743              var target = this._pendingMediaDuration;
  2744  
  2745              if (target > 0 && (isNaN(current) || target > current)) {
  2746                  _logger2.default.v(this.TAG, 'Update MediaSource duration from ' + current + ' to ' + target);
  2747                  this._mediaSource.duration = target;
  2748              }
  2749  
  2750              this._requireSetMediaDuration = false;
  2751              this._pendingMediaDuration = 0;
  2752          }
  2753      }, {
  2754          key: '_doRemoveRanges',
  2755          value: function _doRemoveRanges() {
  2756              for (var type in this._pendingRemoveRanges) {
  2757                  if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {
  2758                      continue;
  2759                  }
  2760                  var sb = this._sourceBuffers[type];
  2761                  var ranges = this._pendingRemoveRanges[type];
  2762                  while (ranges.length && !sb.updating) {
  2763                      var range = ranges.shift();
  2764                      sb.remove(range.start, range.end);
  2765                  }
  2766              }
  2767          }
  2768      }, {
  2769          key: '_doAppendSegments',
  2770          value: function _doAppendSegments() {
  2771              var pendingSegments = this._pendingSegments;
  2772  
  2773              for (var type in pendingSegments) {
  2774                  if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {
  2775                      continue;
  2776                  }
  2777  
  2778                  if (pendingSegments[type].length > 0) {
  2779                      var segment = pendingSegments[type].shift();
  2780  
  2781                      if (segment.timestampOffset) {
  2782                          // For MPEG audio stream in MSE, if unbuffered-seeking occurred
  2783                          // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.
  2784                          var currentOffset = this._sourceBuffers[type].timestampOffset;
  2785                          var targetOffset = segment.timestampOffset / 1000; // in seconds
  2786  
  2787                          var delta = Math.abs(currentOffset - targetOffset);
  2788                          if (delta > 0.1) {
  2789                              // If time delta > 100ms
  2790                              _logger2.default.v(this.TAG, 'Update MPEG audio timestampOffset from ' + currentOffset + ' to ' + targetOffset);
  2791                              this._sourceBuffers[type].timestampOffset = targetOffset;
  2792                          }
  2793                          delete segment.timestampOffset;
  2794                      }
  2795  
  2796                      if (!segment.data || segment.data.byteLength === 0) {
  2797                          // Ignore empty buffer
  2798                          continue;
  2799                      }
  2800  
  2801                      try {
  2802                          this._sourceBuffers[type].appendBuffer(segment.data);
  2803                          this._isBufferFull = false;
  2804                          if (type === 'video' && segment.hasOwnProperty('info')) {
  2805                              this._idrList.appendArray(segment.info.syncPoints);
  2806                          }
  2807                      } catch (error) {
  2808                          this._pendingSegments[type].unshift(segment);
  2809                          if (error.code === 22) {
  2810                              // QuotaExceededError
  2811                              /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full
  2812                               * Currently we can only do lazy-load to avoid SourceBuffer become scattered.
  2813                               * SourceBuffer eviction policy may be changed in future version of FireFox.
  2814                               *
  2815                               * Related issues:
  2816                               * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885
  2817                               * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023
  2818                               */
  2819  
  2820                              // report buffer full, abort network IO
  2821                              if (!this._isBufferFull) {
  2822                                  this._emitter.emit(_mseEvents2.default.BUFFER_FULL);
  2823                              }
  2824                              this._isBufferFull = true;
  2825                          } else {
  2826                              _logger2.default.e(this.TAG, error.message);
  2827                              this._emitter.emit(_mseEvents2.default.ERROR, { code: error.code, msg: error.message });
  2828                          }
  2829                      }
  2830                  }
  2831              }
  2832          }
  2833      }, {
  2834          key: '_onSourceOpen',
  2835          value: function _onSourceOpen() {
  2836              _logger2.default.v(this.TAG, 'MediaSource onSourceOpen');
  2837              this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);
  2838              // deferred sourcebuffer creation / initialization
  2839              if (this._pendingSourceBufferInit.length > 0) {
  2840                  var pendings = this._pendingSourceBufferInit;
  2841                  while (pendings.length) {
  2842                      var segment = pendings.shift();
  2843                      this.appendInitSegment(segment, true);
  2844                  }
  2845              }
  2846              // there may be some pending media segments, append them
  2847              if (this._hasPendingSegments()) {
  2848                  this._doAppendSegments();
  2849              }
  2850              this._emitter.emit(_mseEvents2.default.SOURCE_OPEN);
  2851          }
  2852      }, {
  2853          key: '_onSourceEnded',
  2854          value: function _onSourceEnded() {
  2855              // fired on endOfStream
  2856              _logger2.default.v(this.TAG, 'MediaSource onSourceEnded');
  2857          }
  2858      }, {
  2859          key: '_onSourceClose',
  2860          value: function _onSourceClose() {
  2861              // fired on detaching from media element
  2862              _logger2.default.v(this.TAG, 'MediaSource onSourceClose');
  2863              if (this._mediaSource && this.e != null) {
  2864                  this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);
  2865                  this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);
  2866                  this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);
  2867              }
  2868          }
  2869      }, {
  2870          key: '_hasPendingSegments',
  2871          value: function _hasPendingSegments() {
  2872              var ps = this._pendingSegments;
  2873              return ps.video.length > 0 || ps.audio.length > 0;
  2874          }
  2875      }, {
  2876          key: '_hasPendingRemoveRanges',
  2877          value: function _hasPendingRemoveRanges() {
  2878              var prr = this._pendingRemoveRanges;
  2879              return prr.video.length > 0 || prr.audio.length > 0;
  2880          }
  2881      }, {
  2882          key: '_onSourceBufferUpdateEnd',
  2883          value: function _onSourceBufferUpdateEnd() {
  2884              if (this._requireSetMediaDuration) {
  2885                  this._updateMediaSourceDuration();
  2886              } else if (this._hasPendingRemoveRanges()) {
  2887                  this._doRemoveRanges();
  2888              } else if (this._hasPendingSegments()) {
  2889                  this._doAppendSegments();
  2890              } else if (this._hasPendingEos) {
  2891                  this.endOfStream();
  2892              }
  2893              this._emitter.emit(_mseEvents2.default.UPDATE_END);
  2894          }
  2895      }, {
  2896          key: '_onSourceBufferError',
  2897          value: function _onSourceBufferError(e) {
  2898              _logger2.default.e(this.TAG, 'SourceBuffer Error: ' + e);
  2899              // this error might not always be fatal, just ignore it
  2900          }
  2901      }]);
  2902  
  2903      return MSEController;
  2904  }();
  2905  
  2906  exports.default = MSEController;
  2907  
  2908  },{"../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){
  2909  'use strict';
  2910  
  2911  Object.defineProperty(exports, "__esModule", {
  2912    value: true
  2913  });
  2914  /*
  2915   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  2916   *
  2917   * @author zheng qian <xqq@xqq.im>
  2918   *
  2919   * Licensed under the Apache License, Version 2.0 (the "License");
  2920   * you may not use this file except in compliance with the License.
  2921   * You may obtain a copy of the License at
  2922   *
  2923   *     http://www.apache.org/licenses/LICENSE-2.0
  2924   *
  2925   * Unless required by applicable law or agreed to in writing, software
  2926   * distributed under the License is distributed on an "AS IS" BASIS,
  2927   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2928   * See the License for the specific language governing permissions and
  2929   * limitations under the License.
  2930   */
  2931  
  2932  var MSEEvents = {
  2933    ERROR: 'error',
  2934    SOURCE_OPEN: 'source_open',
  2935    UPDATE_END: 'update_end',
  2936    BUFFER_FULL: 'buffer_full'
  2937  };
  2938  
  2939  exports.default = MSEEvents;
  2940  
  2941  },{}],11:[function(_dereq_,module,exports){
  2942  'use strict';
  2943  
  2944  Object.defineProperty(exports, "__esModule", {
  2945      value: true
  2946  });
  2947  
  2948  var _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; }; }(); /*
  2949                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  2950                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2951                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  2952                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2953                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  2954                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  2955                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  2956                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2957                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  2958                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  2959                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  2960                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  2961                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2962                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  2963                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  2964                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  2965  
  2966  var _events = _dereq_('events');
  2967  
  2968  var _events2 = _interopRequireDefault(_events);
  2969  
  2970  var _logger = _dereq_('../utils/logger.js');
  2971  
  2972  var _logger2 = _interopRequireDefault(_logger);
  2973  
  2974  var _loggingControl = _dereq_('../utils/logging-control.js');
  2975  
  2976  var _loggingControl2 = _interopRequireDefault(_loggingControl);
  2977  
  2978  var _transmuxingController = _dereq_('./transmuxing-controller.js');
  2979  
  2980  var _transmuxingController2 = _interopRequireDefault(_transmuxingController);
  2981  
  2982  var _transmuxingEvents = _dereq_('./transmuxing-events.js');
  2983  
  2984  var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
  2985  
  2986  var _transmuxingWorker = _dereq_('./transmuxing-worker.js');
  2987  
  2988  var _transmuxingWorker2 = _interopRequireDefault(_transmuxingWorker);
  2989  
  2990  var _mediaInfo = _dereq_('./media-info.js');
  2991  
  2992  var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
  2993  
  2994  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  2995  
  2996  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2997  
  2998  var Transmuxer = function () {
  2999      function Transmuxer(mediaDataSource, config) {
  3000          _classCallCheck(this, Transmuxer);
  3001  
  3002          this.TAG = 'Transmuxer';
  3003          this._emitter = new _events2.default();
  3004  
  3005          if (config.enableWorker && typeof Worker !== 'undefined') {
  3006              try {
  3007                  var work = _dereq_('webworkify');
  3008                  this._worker = work(_transmuxingWorker2.default);
  3009                  this._workerDestroying = false;
  3010                  this._worker.addEventListener('message', this._onWorkerMessage.bind(this));
  3011                  this._worker.postMessage({ cmd: 'init', param: [mediaDataSource, config] });
  3012                  this.e = {
  3013                      onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)
  3014                  };
  3015                  _loggingControl2.default.registerListener(this.e.onLoggingConfigChanged);
  3016                  this._worker.postMessage({ cmd: 'logging_config', param: _loggingControl2.default.getConfig() });
  3017              } catch (error) {
  3018                  _logger2.default.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');
  3019                  this._worker = null;
  3020                  this._controller = new _transmuxingController2.default(mediaDataSource, config);
  3021              }
  3022          } else {
  3023              this._controller = new _transmuxingController2.default(mediaDataSource, config);
  3024          }
  3025  
  3026          if (this._controller) {
  3027              var ctl = this._controller;
  3028              ctl.on(_transmuxingEvents2.default.IO_ERROR, this._onIOError.bind(this));
  3029              ctl.on(_transmuxingEvents2.default.DEMUX_ERROR, this._onDemuxError.bind(this));
  3030              ctl.on(_transmuxingEvents2.default.INIT_SEGMENT, this._onInitSegment.bind(this));
  3031              ctl.on(_transmuxingEvents2.default.MEDIA_SEGMENT, this._onMediaSegment.bind(this));
  3032              ctl.on(_transmuxingEvents2.default.LOADING_COMPLETE, this._onLoadingComplete.bind(this));
  3033              ctl.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));
  3034              ctl.on(_transmuxingEvents2.default.MEDIA_INFO, this._onMediaInfo.bind(this));
  3035              ctl.on(_transmuxingEvents2.default.METADATA_ARRIVED, this._onMetaDataArrived.bind(this));
  3036              ctl.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, this._onScriptDataArrived.bind(this));
  3037              ctl.on(_transmuxingEvents2.default.STATISTICS_INFO, this._onStatisticsInfo.bind(this));
  3038              ctl.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));
  3039          }
  3040      }
  3041  
  3042      _createClass(Transmuxer, [{
  3043          key: 'destroy',
  3044          value: function destroy() {
  3045              if (this._worker) {
  3046                  if (!this._workerDestroying) {
  3047                      this._workerDestroying = true;
  3048                      this._worker.postMessage({ cmd: 'destroy' });
  3049                      _loggingControl2.default.removeListener(this.e.onLoggingConfigChanged);
  3050                      this.e = null;
  3051                  }
  3052              } else {
  3053                  this._controller.destroy();
  3054                  this._controller = null;
  3055              }
  3056              this._emitter.removeAllListeners();
  3057              this._emitter = null;
  3058          }
  3059      }, {
  3060          key: 'on',
  3061          value: function on(event, listener) {
  3062              this._emitter.addListener(event, listener);
  3063          }
  3064      }, {
  3065          key: 'off',
  3066          value: function off(event, listener) {
  3067              this._emitter.removeListener(event, listener);
  3068          }
  3069      }, {
  3070          key: 'hasWorker',
  3071          value: function hasWorker() {
  3072              return this._worker != null;
  3073          }
  3074      }, {
  3075          key: 'open',
  3076          value: function open() {
  3077              if (this._worker) {
  3078                  this._worker.postMessage({ cmd: 'start' });
  3079              } else {
  3080                  this._controller.start();
  3081              }
  3082          }
  3083      }, {
  3084          key: 'close',
  3085          value: function close() {
  3086              if (this._worker) {
  3087                  this._worker.postMessage({ cmd: 'stop' });
  3088              } else {
  3089                  this._controller.stop();
  3090              }
  3091          }
  3092      }, {
  3093          key: 'seek',
  3094          value: function seek(milliseconds) {
  3095              if (this._worker) {
  3096                  this._worker.postMessage({ cmd: 'seek', param: milliseconds });
  3097              } else {
  3098                  this._controller.seek(milliseconds);
  3099              }
  3100          }
  3101      }, {
  3102          key: 'pause',
  3103          value: function pause() {
  3104              if (this._worker) {
  3105                  this._worker.postMessage({ cmd: 'pause' });
  3106              } else {
  3107                  this._controller.pause();
  3108              }
  3109          }
  3110      }, {
  3111          key: 'resume',
  3112          value: function resume() {
  3113              if (this._worker) {
  3114                  this._worker.postMessage({ cmd: 'resume' });
  3115              } else {
  3116                  this._controller.resume();
  3117              }
  3118          }
  3119      }, {
  3120          key: '_onInitSegment',
  3121          value: function _onInitSegment(type, initSegment) {
  3122              var _this = this;
  3123  
  3124              // do async invoke
  3125              Promise.resolve().then(function () {
  3126                  _this._emitter.emit(_transmuxingEvents2.default.INIT_SEGMENT, type, initSegment);
  3127              });
  3128          }
  3129      }, {
  3130          key: '_onMediaSegment',
  3131          value: function _onMediaSegment(type, mediaSegment) {
  3132              var _this2 = this;
  3133  
  3134              Promise.resolve().then(function () {
  3135                  _this2._emitter.emit(_transmuxingEvents2.default.MEDIA_SEGMENT, type, mediaSegment);
  3136              });
  3137          }
  3138      }, {
  3139          key: '_onLoadingComplete',
  3140          value: function _onLoadingComplete() {
  3141              var _this3 = this;
  3142  
  3143              Promise.resolve().then(function () {
  3144                  _this3._emitter.emit(_transmuxingEvents2.default.LOADING_COMPLETE);
  3145              });
  3146          }
  3147      }, {
  3148          key: '_onRecoveredEarlyEof',
  3149          value: function _onRecoveredEarlyEof() {
  3150              var _this4 = this;
  3151  
  3152              Promise.resolve().then(function () {
  3153                  _this4._emitter.emit(_transmuxingEvents2.default.RECOVERED_EARLY_EOF);
  3154              });
  3155          }
  3156      }, {
  3157          key: '_onMediaInfo',
  3158          value: function _onMediaInfo(mediaInfo) {
  3159              var _this5 = this;
  3160  
  3161              Promise.resolve().then(function () {
  3162                  _this5._emitter.emit(_transmuxingEvents2.default.MEDIA_INFO, mediaInfo);
  3163              });
  3164          }
  3165      }, {
  3166          key: '_onMetaDataArrived',
  3167          value: function _onMetaDataArrived(metadata) {
  3168              var _this6 = this;
  3169  
  3170              Promise.resolve().then(function () {
  3171                  _this6._emitter.emit(_transmuxingEvents2.default.METADATA_ARRIVED, metadata);
  3172              });
  3173          }
  3174      }, {
  3175          key: '_onScriptDataArrived',
  3176          value: function _onScriptDataArrived(data) {
  3177              var _this7 = this;
  3178  
  3179              Promise.resolve().then(function () {
  3180                  _this7._emitter.emit(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, data);
  3181              });
  3182          }
  3183      }, {
  3184          key: '_onStatisticsInfo',
  3185          value: function _onStatisticsInfo(statisticsInfo) {
  3186              var _this8 = this;
  3187  
  3188              Promise.resolve().then(function () {
  3189                  _this8._emitter.emit(_transmuxingEvents2.default.STATISTICS_INFO, statisticsInfo);
  3190              });
  3191          }
  3192      }, {
  3193          key: '_onIOError',
  3194          value: function _onIOError(type, info) {
  3195              var _this9 = this;
  3196  
  3197              Promise.resolve().then(function () {
  3198                  _this9._emitter.emit(_transmuxingEvents2.default.IO_ERROR, type, info);
  3199              });
  3200          }
  3201      }, {
  3202          key: '_onDemuxError',
  3203          value: function _onDemuxError(type, info) {
  3204              var _this10 = this;
  3205  
  3206              Promise.resolve().then(function () {
  3207                  _this10._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, type, info);
  3208              });
  3209          }
  3210      }, {
  3211          key: '_onRecommendSeekpoint',
  3212          value: function _onRecommendSeekpoint(milliseconds) {
  3213              var _this11 = this;
  3214  
  3215              Promise.resolve().then(function () {
  3216                  _this11._emitter.emit(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, milliseconds);
  3217              });
  3218          }
  3219      }, {
  3220          key: '_onLoggingConfigChanged',
  3221          value: function _onLoggingConfigChanged(config) {
  3222              if (this._worker) {
  3223                  this._worker.postMessage({ cmd: 'logging_config', param: config });
  3224              }
  3225          }
  3226      }, {
  3227          key: '_onWorkerMessage',
  3228          value: function _onWorkerMessage(e) {
  3229              var message = e.data;
  3230              var data = message.data;
  3231  
  3232              if (message.msg === 'destroyed' || this._workerDestroying) {
  3233                  this._workerDestroying = false;
  3234                  this._worker.terminate();
  3235                  this._worker = null;
  3236                  return;
  3237              }
  3238  
  3239              switch (message.msg) {
  3240                  case _transmuxingEvents2.default.INIT_SEGMENT:
  3241                  case _transmuxingEvents2.default.MEDIA_SEGMENT:
  3242                      this._emitter.emit(message.msg, data.type, data.data);
  3243                      break;
  3244                  case _transmuxingEvents2.default.LOADING_COMPLETE:
  3245                  case _transmuxingEvents2.default.RECOVERED_EARLY_EOF:
  3246                      this._emitter.emit(message.msg);
  3247                      break;
  3248                  case _transmuxingEvents2.default.MEDIA_INFO:
  3249                      Object.setPrototypeOf(data, _mediaInfo2.default.prototype);
  3250                      this._emitter.emit(message.msg, data);
  3251                      break;
  3252                  case _transmuxingEvents2.default.METADATA_ARRIVED:
  3253                  case _transmuxingEvents2.default.SCRIPTDATA_ARRIVED:
  3254                  case _transmuxingEvents2.default.STATISTICS_INFO:
  3255                      this._emitter.emit(message.msg, data);
  3256                      break;
  3257                  case _transmuxingEvents2.default.IO_ERROR:
  3258                  case _transmuxingEvents2.default.DEMUX_ERROR:
  3259                      this._emitter.emit(message.msg, data.type, data.info);
  3260                      break;
  3261                  case _transmuxingEvents2.default.RECOMMEND_SEEKPOINT:
  3262                      this._emitter.emit(message.msg, data);
  3263                      break;
  3264                  case 'logcat_callback':
  3265                      _logger2.default.emitter.emit('log', data.type, data.logcat);
  3266                      break;
  3267                  default:
  3268                      break;
  3269              }
  3270          }
  3271      }]);
  3272  
  3273      return Transmuxer;
  3274  }();
  3275  
  3276  exports.default = Transmuxer;
  3277  
  3278  },{"../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){
  3279  'use strict';
  3280  
  3281  Object.defineProperty(exports, "__esModule", {
  3282      value: true
  3283  });
  3284  
  3285  var _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; }; }(); /*
  3286                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  3287                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  3288                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  3289                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  3290                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  3291                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  3292                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  3293                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  3294                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  3295                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  3296                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  3297                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  3298                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3299                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  3300                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  3301                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  3302  
  3303  var _events = _dereq_('events');
  3304  
  3305  var _events2 = _interopRequireDefault(_events);
  3306  
  3307  var _logger = _dereq_('../utils/logger.js');
  3308  
  3309  var _logger2 = _interopRequireDefault(_logger);
  3310  
  3311  var _browser = _dereq_('../utils/browser.js');
  3312  
  3313  var _browser2 = _interopRequireDefault(_browser);
  3314  
  3315  var _mediaInfo = _dereq_('./media-info.js');
  3316  
  3317  var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
  3318  
  3319  var _flvDemuxer = _dereq_('../demux/flv-demuxer.js');
  3320  
  3321  var _flvDemuxer2 = _interopRequireDefault(_flvDemuxer);
  3322  
  3323  var _mp4Remuxer = _dereq_('../remux/mp4-remuxer.js');
  3324  
  3325  var _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);
  3326  
  3327  var _demuxErrors = _dereq_('../demux/demux-errors.js');
  3328  
  3329  var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
  3330  
  3331  var _ioController = _dereq_('../io/io-controller.js');
  3332  
  3333  var _ioController2 = _interopRequireDefault(_ioController);
  3334  
  3335  var _transmuxingEvents = _dereq_('./transmuxing-events.js');
  3336  
  3337  var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
  3338  
  3339  var _loader = _dereq_('../io/loader.js');
  3340  
  3341  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  3342  
  3343  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3344  
  3345  // Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support
  3346  var TransmuxingController = function () {
  3347      function TransmuxingController(mediaDataSource, config) {
  3348          _classCallCheck(this, TransmuxingController);
  3349  
  3350          this.TAG = 'TransmuxingController';
  3351          this._emitter = new _events2.default();
  3352  
  3353          this._config = config;
  3354  
  3355          // treat single part media as multipart media, which has only one segment
  3356          if (!mediaDataSource.segments) {
  3357              mediaDataSource.segments = [{
  3358                  duration: mediaDataSource.duration,
  3359                  filesize: mediaDataSource.filesize,
  3360                  url: mediaDataSource.url
  3361              }];
  3362          }
  3363  
  3364          // fill in default IO params if not exists
  3365          if (typeof mediaDataSource.cors !== 'boolean') {
  3366              mediaDataSource.cors = true;
  3367          }
  3368          if (typeof mediaDataSource.withCredentials !== 'boolean') {
  3369              mediaDataSource.withCredentials = false;
  3370          }
  3371  
  3372          this._mediaDataSource = mediaDataSource;
  3373          this._currentSegmentIndex = 0;
  3374          var totalDuration = 0;
  3375  
  3376          this._mediaDataSource.segments.forEach(function (segment) {
  3377              // timestampBase for each segment, and calculate total duration
  3378              segment.timestampBase = totalDuration;
  3379              totalDuration += segment.duration;
  3380              // params needed by IOController
  3381              segment.cors = mediaDataSource.cors;
  3382              segment.withCredentials = mediaDataSource.withCredentials;
  3383              // referrer policy control, if exist
  3384              if (config.referrerPolicy) {
  3385                  segment.referrerPolicy = config.referrerPolicy;
  3386              }
  3387          });
  3388  
  3389          if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {
  3390              this._mediaDataSource.duration = totalDuration;
  3391          }
  3392  
  3393          this._mediaInfo = null;
  3394          this._demuxer = null;
  3395          this._remuxer = null;
  3396          this._ioctl = null;
  3397  
  3398          this._pendingSeekTime = null;
  3399          this._pendingResolveSeekPoint = null;
  3400  
  3401          this._statisticsReporter = null;
  3402      }
  3403  
  3404      _createClass(TransmuxingController, [{
  3405          key: 'destroy',
  3406          value: function destroy() {
  3407              this._mediaInfo = null;
  3408              this._mediaDataSource = null;
  3409  
  3410              if (this._statisticsReporter) {
  3411                  this._disableStatisticsReporter();
  3412              }
  3413              if (this._ioctl) {
  3414                  this._ioctl.destroy();
  3415                  this._ioctl = null;
  3416              }
  3417              if (this._demuxer) {
  3418                  this._demuxer.destroy();
  3419                  this._demuxer = null;
  3420              }
  3421              if (this._remuxer) {
  3422                  this._remuxer.destroy();
  3423                  this._remuxer = null;
  3424              }
  3425  
  3426              this._emitter.removeAllListeners();
  3427              this._emitter = null;
  3428          }
  3429      }, {
  3430          key: 'on',
  3431          value: function on(event, listener) {
  3432              this._emitter.addListener(event, listener);
  3433          }
  3434      }, {
  3435          key: 'off',
  3436          value: function off(event, listener) {
  3437              this._emitter.removeListener(event, listener);
  3438          }
  3439      }, {
  3440          key: 'start',
  3441          value: function start() {
  3442              this._loadSegment(0);
  3443              this._enableStatisticsReporter();
  3444          }
  3445      }, {
  3446          key: '_loadSegment',
  3447          value: function _loadSegment(segmentIndex, optionalFrom) {
  3448              this._currentSegmentIndex = segmentIndex;
  3449              var dataSource = this._mediaDataSource.segments[segmentIndex];
  3450  
  3451              var ioctl = this._ioctl = new _ioController2.default(dataSource, this._config, segmentIndex);
  3452              ioctl.onError = this._onIOException.bind(this);
  3453              ioctl.onSeeked = this._onIOSeeked.bind(this);
  3454              ioctl.onComplete = this._onIOComplete.bind(this);
  3455              ioctl.onRedirect = this._onIORedirect.bind(this);
  3456              ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);
  3457  
  3458              if (optionalFrom) {
  3459                  this._demuxer.bindDataSource(this._ioctl);
  3460              } else {
  3461                  ioctl.onDataArrival = this._onInitChunkArrival.bind(this);
  3462              }
  3463  
  3464              ioctl.open(optionalFrom);
  3465          }
  3466      }, {
  3467          key: 'stop',
  3468          value: function stop() {
  3469              this._internalAbort();
  3470              this._disableStatisticsReporter();
  3471          }
  3472      }, {
  3473          key: '_internalAbort',
  3474          value: function _internalAbort() {
  3475              if (this._ioctl) {
  3476                  this._ioctl.destroy();
  3477                  this._ioctl = null;
  3478              }
  3479          }
  3480      }, {
  3481          key: 'pause',
  3482          value: function pause() {
  3483              // take a rest
  3484              if (this._ioctl && this._ioctl.isWorking()) {
  3485                  this._ioctl.pause();
  3486                  this._disableStatisticsReporter();
  3487              }
  3488          }
  3489      }, {
  3490          key: 'resume',
  3491          value: function resume() {
  3492              if (this._ioctl && this._ioctl.isPaused()) {
  3493                  this._ioctl.resume();
  3494                  this._enableStatisticsReporter();
  3495              }
  3496          }
  3497      }, {
  3498          key: 'seek',
  3499          value: function seek(milliseconds) {
  3500              if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {
  3501                  return;
  3502              }
  3503  
  3504              var targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);
  3505  
  3506              if (targetSegmentIndex === this._currentSegmentIndex) {
  3507                  // intra-segment seeking
  3508                  var segmentInfo = this._mediaInfo.segments[targetSegmentIndex];
  3509  
  3510                  if (segmentInfo == undefined) {
  3511                      // current segment loading started, but mediainfo hasn't received yet
  3512                      // wait for the metadata loaded, then seek to expected position
  3513                      this._pendingSeekTime = milliseconds;
  3514                  } else {
  3515                      var keyframe = segmentInfo.getNearestKeyframe(milliseconds);
  3516                      this._remuxer.seek(keyframe.milliseconds);
  3517                      this._ioctl.seek(keyframe.fileposition);
  3518                      // Will be resolved in _onRemuxerMediaSegmentArrival()
  3519                      this._pendingResolveSeekPoint = keyframe.milliseconds;
  3520                  }
  3521              } else {
  3522                  // cross-segment seeking
  3523                  var targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];
  3524  
  3525                  if (targetSegmentInfo == undefined) {
  3526                      // target segment hasn't been loaded. We need metadata then seek to expected time
  3527                      this._pendingSeekTime = milliseconds;
  3528                      this._internalAbort();
  3529                      this._remuxer.seek();
  3530                      this._remuxer.insertDiscontinuity();
  3531                      this._loadSegment(targetSegmentIndex);
  3532                      // Here we wait for the metadata loaded, then seek to expected position
  3533                  } else {
  3534                      // We have target segment's metadata, direct seek to target position
  3535                      var _keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);
  3536                      this._internalAbort();
  3537                      this._remuxer.seek(milliseconds);
  3538                      this._remuxer.insertDiscontinuity();
  3539                      this._demuxer.resetMediaInfo();
  3540                      this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;
  3541                      this._loadSegment(targetSegmentIndex, _keyframe.fileposition);
  3542                      this._pendingResolveSeekPoint = _keyframe.milliseconds;
  3543                      this._reportSegmentMediaInfo(targetSegmentIndex);
  3544                  }
  3545              }
  3546  
  3547              this._enableStatisticsReporter();
  3548          }
  3549      }, {
  3550          key: '_searchSegmentIndexContains',
  3551          value: function _searchSegmentIndexContains(milliseconds) {
  3552              var segments = this._mediaDataSource.segments;
  3553              var idx = segments.length - 1;
  3554  
  3555              for (var i = 0; i < segments.length; i++) {
  3556                  if (milliseconds < segments[i].timestampBase) {
  3557                      idx = i - 1;
  3558                      break;
  3559                  }
  3560              }
  3561              return idx;
  3562          }
  3563      }, {
  3564          key: '_onInitChunkArrival',
  3565          value: function _onInitChunkArrival(data, byteStart) {
  3566              var _this = this;
  3567  
  3568              var probeData = null;
  3569              var consumed = 0;
  3570  
  3571              if (byteStart > 0) {
  3572                  // IOController seeked immediately after opened, byteStart > 0 callback may received
  3573                  this._demuxer.bindDataSource(this._ioctl);
  3574                  this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;
  3575  
  3576                  consumed = this._demuxer.parseChunks(data, byteStart);
  3577              } else if ((probeData = _flvDemuxer2.default.probe(data)).match) {
  3578                  // Always create new FLVDemuxer
  3579                  this._demuxer = new _flvDemuxer2.default(probeData, this._config);
  3580  
  3581                  if (!this._remuxer) {
  3582                      this._remuxer = new _mp4Remuxer2.default(this._config);
  3583                  }
  3584  
  3585                  var mds = this._mediaDataSource;
  3586                  if (mds.duration != undefined && !isNaN(mds.duration)) {
  3587                      this._demuxer.overridedDuration = mds.duration;
  3588                  }
  3589                  if (typeof mds.hasAudio === 'boolean') {
  3590                      this._demuxer.overridedHasAudio = mds.hasAudio;
  3591                  }
  3592                  if (typeof mds.hasVideo === 'boolean') {
  3593                      this._demuxer.overridedHasVideo = mds.hasVideo;
  3594                  }
  3595  
  3596                  this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;
  3597  
  3598                  this._demuxer.onError = this._onDemuxException.bind(this);
  3599                  this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);
  3600                  this._demuxer.onMetaDataArrived = this._onMetaDataArrived.bind(this);
  3601                  this._demuxer.onScriptDataArrived = this._onScriptDataArrived.bind(this);
  3602  
  3603                  this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl));
  3604  
  3605                  this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);
  3606                  this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);
  3607  
  3608                  consumed = this._demuxer.parseChunks(data, byteStart);
  3609              } else {
  3610                  probeData = null;
  3611                  _logger2.default.e(this.TAG, 'Non-FLV, Unsupported media type!');
  3612                  Promise.resolve().then(function () {
  3613                      _this._internalAbort();
  3614                  });
  3615                  this._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, _demuxErrors2.default.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');
  3616  
  3617                  consumed = 0;
  3618              }
  3619  
  3620              return consumed;
  3621          }
  3622      }, {
  3623          key: '_onMediaInfo',
  3624          value: function _onMediaInfo(mediaInfo) {
  3625              var _this2 = this;
  3626  
  3627              if (this._mediaInfo == null) {
  3628                  // Store first segment's mediainfo as global mediaInfo
  3629                  this._mediaInfo = Object.assign({}, mediaInfo);
  3630                  this._mediaInfo.keyframesIndex = null;
  3631                  this._mediaInfo.segments = [];
  3632                  this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;
  3633                  Object.setPrototypeOf(this._mediaInfo, _mediaInfo2.default.prototype);
  3634              }
  3635  
  3636              var segmentInfo = Object.assign({}, mediaInfo);
  3637              Object.setPrototypeOf(segmentInfo, _mediaInfo2.default.prototype);
  3638              this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;
  3639  
  3640              // notify mediaInfo update
  3641              this._reportSegmentMediaInfo(this._currentSegmentIndex);
  3642  
  3643              if (this._pendingSeekTime != null) {
  3644                  Promise.resolve().then(function () {
  3645                      var target = _this2._pendingSeekTime;
  3646                      _this2._pendingSeekTime = null;
  3647                      _this2.seek(target);
  3648                  });
  3649              }
  3650          }
  3651      }, {
  3652          key: '_onMetaDataArrived',
  3653          value: function _onMetaDataArrived(metadata) {
  3654              this._emitter.emit(_transmuxingEvents2.default.METADATA_ARRIVED, metadata);
  3655          }
  3656      }, {
  3657          key: '_onScriptDataArrived',
  3658          value: function _onScriptDataArrived(data) {
  3659              this._emitter.emit(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, data);
  3660          }
  3661      }, {
  3662          key: '_onIOSeeked',
  3663          value: function _onIOSeeked() {
  3664              this._remuxer.insertDiscontinuity();
  3665          }
  3666      }, {
  3667          key: '_onIOComplete',
  3668          value: function _onIOComplete(extraData) {
  3669              var segmentIndex = extraData;
  3670              var nextSegmentIndex = segmentIndex + 1;
  3671  
  3672              if (nextSegmentIndex < this._mediaDataSource.segments.length) {
  3673                  this._internalAbort();
  3674                  this._remuxer.flushStashedSamples();
  3675                  this._loadSegment(nextSegmentIndex);
  3676              } else {
  3677                  this._remuxer.flushStashedSamples();
  3678                  this._emitter.emit(_transmuxingEvents2.default.LOADING_COMPLETE);
  3679                  this._disableStatisticsReporter();
  3680              }
  3681          }
  3682      }, {
  3683          key: '_onIORedirect',
  3684          value: function _onIORedirect(redirectedURL) {
  3685              var segmentIndex = this._ioctl.extraData;
  3686              this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;
  3687          }
  3688      }, {
  3689          key: '_onIORecoveredEarlyEof',
  3690          value: function _onIORecoveredEarlyEof() {
  3691              this._emitter.emit(_transmuxingEvents2.default.RECOVERED_EARLY_EOF);
  3692          }
  3693      }, {
  3694          key: '_onIOException',
  3695          value: function _onIOException(type, info) {
  3696              _logger2.default.e(this.TAG, 'IOException: type = ' + type + ', code = ' + info.code + ', msg = ' + info.msg);
  3697              this._emitter.emit(_transmuxingEvents2.default.IO_ERROR, type, info);
  3698              this._disableStatisticsReporter();
  3699          }
  3700      }, {
  3701          key: '_onDemuxException',
  3702          value: function _onDemuxException(type, info) {
  3703              _logger2.default.e(this.TAG, 'DemuxException: type = ' + type + ', info = ' + info);
  3704              this._emitter.emit(_transmuxingEvents2.default.DEMUX_ERROR, type, info);
  3705          }
  3706      }, {
  3707          key: '_onRemuxerInitSegmentArrival',
  3708          value: function _onRemuxerInitSegmentArrival(type, initSegment) {
  3709              this._emitter.emit(_transmuxingEvents2.default.INIT_SEGMENT, type, initSegment);
  3710          }
  3711      }, {
  3712          key: '_onRemuxerMediaSegmentArrival',
  3713          value: function _onRemuxerMediaSegmentArrival(type, mediaSegment) {
  3714              if (this._pendingSeekTime != null) {
  3715                  // Media segments after new-segment cross-seeking should be dropped.
  3716                  return;
  3717              }
  3718              this._emitter.emit(_transmuxingEvents2.default.MEDIA_SEGMENT, type, mediaSegment);
  3719  
  3720              // Resolve pending seekPoint
  3721              if (this._pendingResolveSeekPoint != null && type === 'video') {
  3722                  var syncPoints = mediaSegment.info.syncPoints;
  3723                  var seekpoint = this._pendingResolveSeekPoint;
  3724                  this._pendingResolveSeekPoint = null;
  3725  
  3726                  // Safari: Pass PTS for recommend_seekpoint
  3727                  if (_browser2.default.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {
  3728                      seekpoint = syncPoints[0].pts;
  3729                  }
  3730                  // else: use original DTS (keyframe.milliseconds)
  3731  
  3732                  this._emitter.emit(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, seekpoint);
  3733              }
  3734          }
  3735      }, {
  3736          key: '_enableStatisticsReporter',
  3737          value: function _enableStatisticsReporter() {
  3738              if (this._statisticsReporter == null) {
  3739                  this._statisticsReporter = self.setInterval(this._reportStatisticsInfo.bind(this), this._config.statisticsInfoReportInterval);
  3740              }
  3741          }
  3742      }, {
  3743          key: '_disableStatisticsReporter',
  3744          value: function _disableStatisticsReporter() {
  3745              if (this._statisticsReporter) {
  3746                  self.clearInterval(this._statisticsReporter);
  3747                  this._statisticsReporter = null;
  3748              }
  3749          }
  3750      }, {
  3751          key: '_reportSegmentMediaInfo',
  3752          value: function _reportSegmentMediaInfo(segmentIndex) {
  3753              var segmentInfo = this._mediaInfo.segments[segmentIndex];
  3754              var exportInfo = Object.assign({}, segmentInfo);
  3755  
  3756              exportInfo.duration = this._mediaInfo.duration;
  3757              exportInfo.segmentCount = this._mediaInfo.segmentCount;
  3758              delete exportInfo.segments;
  3759              delete exportInfo.keyframesIndex;
  3760  
  3761              this._emitter.emit(_transmuxingEvents2.default.MEDIA_INFO, exportInfo);
  3762          }
  3763      }, {
  3764          key: '_reportStatisticsInfo',
  3765          value: function _reportStatisticsInfo() {
  3766              var info = {};
  3767  
  3768              info.url = this._ioctl.currentURL;
  3769              info.hasRedirect = this._ioctl.hasRedirect;
  3770              if (info.hasRedirect) {
  3771                  info.redirectedURL = this._ioctl.currentRedirectedURL;
  3772              }
  3773  
  3774              info.speed = this._ioctl.currentSpeed;
  3775              info.loaderType = this._ioctl.loaderType;
  3776              info.currentSegmentIndex = this._currentSegmentIndex;
  3777              info.totalSegmentCount = this._mediaDataSource.segments.length;
  3778  
  3779              this._emitter.emit(_transmuxingEvents2.default.STATISTICS_INFO, info);
  3780          }
  3781      }]);
  3782  
  3783      return TransmuxingController;
  3784  }();
  3785  
  3786  exports.default = TransmuxingController;
  3787  
  3788  },{"../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){
  3789  'use strict';
  3790  
  3791  Object.defineProperty(exports, "__esModule", {
  3792    value: true
  3793  });
  3794  /*
  3795   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  3796   *
  3797   * @author zheng qian <xqq@xqq.im>
  3798   *
  3799   * Licensed under the Apache License, Version 2.0 (the "License");
  3800   * you may not use this file except in compliance with the License.
  3801   * You may obtain a copy of the License at
  3802   *
  3803   *     http://www.apache.org/licenses/LICENSE-2.0
  3804   *
  3805   * Unless required by applicable law or agreed to in writing, software
  3806   * distributed under the License is distributed on an "AS IS" BASIS,
  3807   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3808   * See the License for the specific language governing permissions and
  3809   * limitations under the License.
  3810   */
  3811  
  3812  var TransmuxingEvents = {
  3813    IO_ERROR: 'io_error',
  3814    DEMUX_ERROR: 'demux_error',
  3815    INIT_SEGMENT: 'init_segment',
  3816    MEDIA_SEGMENT: 'media_segment',
  3817    LOADING_COMPLETE: 'loading_complete',
  3818    RECOVERED_EARLY_EOF: 'recovered_early_eof',
  3819    MEDIA_INFO: 'media_info',
  3820    METADATA_ARRIVED: 'metadata_arrived',
  3821    SCRIPTDATA_ARRIVED: 'scriptdata_arrived',
  3822    STATISTICS_INFO: 'statistics_info',
  3823    RECOMMEND_SEEKPOINT: 'recommend_seekpoint'
  3824  };
  3825  
  3826  exports.default = TransmuxingEvents;
  3827  
  3828  },{}],14:[function(_dereq_,module,exports){
  3829  'use strict';
  3830  
  3831  Object.defineProperty(exports, "__esModule", {
  3832      value: true
  3833  });
  3834  
  3835  var _logger = _dereq_('../utils/logger.js');
  3836  
  3837  var _logger2 = _interopRequireDefault(_logger);
  3838  
  3839  var _loggingControl = _dereq_('../utils/logging-control.js');
  3840  
  3841  var _loggingControl2 = _interopRequireDefault(_loggingControl);
  3842  
  3843  var _polyfill = _dereq_('../utils/polyfill.js');
  3844  
  3845  var _polyfill2 = _interopRequireDefault(_polyfill);
  3846  
  3847  var _transmuxingController = _dereq_('./transmuxing-controller.js');
  3848  
  3849  var _transmuxingController2 = _interopRequireDefault(_transmuxingController);
  3850  
  3851  var _transmuxingEvents = _dereq_('./transmuxing-events.js');
  3852  
  3853  var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
  3854  
  3855  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  3856  
  3857  /* post message to worker:
  3858     data: {
  3859         cmd: string
  3860         param: any
  3861     }
  3862  
  3863     receive message from worker:
  3864     data: {
  3865         msg: string,
  3866         data: any
  3867     }
  3868   */
  3869  
  3870  var TransmuxingWorker = function TransmuxingWorker(self) {
  3871  
  3872      var TAG = 'TransmuxingWorker';
  3873      var controller = null;
  3874      var logcatListener = onLogcatCallback.bind(this);
  3875  
  3876      _polyfill2.default.install();
  3877  
  3878      self.addEventListener('message', function (e) {
  3879          switch (e.data.cmd) {
  3880              case 'init':
  3881                  controller = new _transmuxingController2.default(e.data.param[0], e.data.param[1]);
  3882                  controller.on(_transmuxingEvents2.default.IO_ERROR, onIOError.bind(this));
  3883                  controller.on(_transmuxingEvents2.default.DEMUX_ERROR, onDemuxError.bind(this));
  3884                  controller.on(_transmuxingEvents2.default.INIT_SEGMENT, onInitSegment.bind(this));
  3885                  controller.on(_transmuxingEvents2.default.MEDIA_SEGMENT, onMediaSegment.bind(this));
  3886                  controller.on(_transmuxingEvents2.default.LOADING_COMPLETE, onLoadingComplete.bind(this));
  3887                  controller.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));
  3888                  controller.on(_transmuxingEvents2.default.MEDIA_INFO, onMediaInfo.bind(this));
  3889                  controller.on(_transmuxingEvents2.default.METADATA_ARRIVED, onMetaDataArrived.bind(this));
  3890                  controller.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, onScriptDataArrived.bind(this));
  3891                  controller.on(_transmuxingEvents2.default.STATISTICS_INFO, onStatisticsInfo.bind(this));
  3892                  controller.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));
  3893                  break;
  3894              case 'destroy':
  3895                  if (controller) {
  3896                      controller.destroy();
  3897                      controller = null;
  3898                  }
  3899                  self.postMessage({ msg: 'destroyed' });
  3900                  break;
  3901              case 'start':
  3902                  controller.start();
  3903                  break;
  3904              case 'stop':
  3905                  controller.stop();
  3906                  break;
  3907              case 'seek':
  3908                  controller.seek(e.data.param);
  3909                  break;
  3910              case 'pause':
  3911                  controller.pause();
  3912                  break;
  3913              case 'resume':
  3914                  controller.resume();
  3915                  break;
  3916              case 'logging_config':
  3917                  {
  3918                      var config = e.data.param;
  3919                      _loggingControl2.default.applyConfig(config);
  3920  
  3921                      if (config.enableCallback === true) {
  3922                          _loggingControl2.default.addLogListener(logcatListener);
  3923                      } else {
  3924                          _loggingControl2.default.removeLogListener(logcatListener);
  3925                      }
  3926                      break;
  3927                  }
  3928          }
  3929      });
  3930  
  3931      function onInitSegment(type, initSegment) {
  3932          var obj = {
  3933              msg: _transmuxingEvents2.default.INIT_SEGMENT,
  3934              data: {
  3935                  type: type,
  3936                  data: initSegment
  3937              }
  3938          };
  3939          self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer
  3940      }
  3941  
  3942      function onMediaSegment(type, mediaSegment) {
  3943          var obj = {
  3944              msg: _transmuxingEvents2.default.MEDIA_SEGMENT,
  3945              data: {
  3946                  type: type,
  3947                  data: mediaSegment
  3948              }
  3949          };
  3950          self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer
  3951      }
  3952  
  3953      function onLoadingComplete() {
  3954          var obj = {
  3955              msg: _transmuxingEvents2.default.LOADING_COMPLETE
  3956          };
  3957          self.postMessage(obj);
  3958      }
  3959  
  3960      function onRecoveredEarlyEof() {
  3961          var obj = {
  3962              msg: _transmuxingEvents2.default.RECOVERED_EARLY_EOF
  3963          };
  3964          self.postMessage(obj);
  3965      }
  3966  
  3967      function onMediaInfo(mediaInfo) {
  3968          var obj = {
  3969              msg: _transmuxingEvents2.default.MEDIA_INFO,
  3970              data: mediaInfo
  3971          };
  3972          self.postMessage(obj);
  3973      }
  3974  
  3975      function onMetaDataArrived(metadata) {
  3976          var obj = {
  3977              msg: _transmuxingEvents2.default.METADATA_ARRIVED,
  3978              data: metadata
  3979          };
  3980          self.postMessage(obj);
  3981      }
  3982  
  3983      function onScriptDataArrived(data) {
  3984          var obj = {
  3985              msg: _transmuxingEvents2.default.SCRIPTDATA_ARRIVED,
  3986              data: data
  3987          };
  3988          self.postMessage(obj);
  3989      }
  3990  
  3991      function onStatisticsInfo(statInfo) {
  3992          var obj = {
  3993              msg: _transmuxingEvents2.default.STATISTICS_INFO,
  3994              data: statInfo
  3995          };
  3996          self.postMessage(obj);
  3997      }
  3998  
  3999      function onIOError(type, info) {
  4000          self.postMessage({
  4001              msg: _transmuxingEvents2.default.IO_ERROR,
  4002              data: {
  4003                  type: type,
  4004                  info: info
  4005              }
  4006          });
  4007      }
  4008  
  4009      function onDemuxError(type, info) {
  4010          self.postMessage({
  4011              msg: _transmuxingEvents2.default.DEMUX_ERROR,
  4012              data: {
  4013                  type: type,
  4014                  info: info
  4015              }
  4016          });
  4017      }
  4018  
  4019      function onRecommendSeekpoint(milliseconds) {
  4020          self.postMessage({
  4021              msg: _transmuxingEvents2.default.RECOMMEND_SEEKPOINT,
  4022              data: milliseconds
  4023          });
  4024      }
  4025  
  4026      function onLogcatCallback(type, str) {
  4027          self.postMessage({
  4028              msg: 'logcat_callback',
  4029              data: {
  4030                  type: type,
  4031                  logcat: str
  4032              }
  4033          });
  4034      }
  4035  }; /*
  4036      * Copyright (C) 2016 Bilibili. All Rights Reserved.
  4037      *
  4038      * @author zheng qian <xqq@xqq.im>
  4039      *
  4040      * Licensed under the Apache License, Version 2.0 (the "License");
  4041      * you may not use this file except in compliance with the License.
  4042      * You may obtain a copy of the License at
  4043      *
  4044      *     http://www.apache.org/licenses/LICENSE-2.0
  4045      *
  4046      * Unless required by applicable law or agreed to in writing, software
  4047      * distributed under the License is distributed on an "AS IS" BASIS,
  4048      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4049      * See the License for the specific language governing permissions and
  4050      * limitations under the License.
  4051      */
  4052  
  4053  exports.default = TransmuxingWorker;
  4054  
  4055  },{"../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){
  4056  'use strict';
  4057  
  4058  Object.defineProperty(exports, "__esModule", {
  4059      value: true
  4060  });
  4061  
  4062  var _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; }; }(); /*
  4063                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  4064                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4065                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  4066                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4067                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  4068                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  4069                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  4070                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4071                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  4072                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4073                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  4074                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  4075                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4076                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  4077                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  4078                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  4079  
  4080  var _logger = _dereq_('../utils/logger.js');
  4081  
  4082  var _logger2 = _interopRequireDefault(_logger);
  4083  
  4084  var _utf8Conv = _dereq_('../utils/utf8-conv.js');
  4085  
  4086  var _utf8Conv2 = _interopRequireDefault(_utf8Conv);
  4087  
  4088  var _exception = _dereq_('../utils/exception.js');
  4089  
  4090  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  4091  
  4092  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4093  
  4094  var le = function () {
  4095      var buf = new ArrayBuffer(2);
  4096      new DataView(buf).setInt16(0, 256, true); // little-endian write
  4097      return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
  4098  }();
  4099  
  4100  var AMF = function () {
  4101      function AMF() {
  4102          _classCallCheck(this, AMF);
  4103      }
  4104  
  4105      _createClass(AMF, null, [{
  4106          key: 'parseScriptData',
  4107          value: function parseScriptData(arrayBuffer, dataOffset, dataSize) {
  4108              var data = {};
  4109  
  4110              try {
  4111                  var name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);
  4112                  var value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);
  4113  
  4114                  data[name.data] = value.data;
  4115              } catch (e) {
  4116                  _logger2.default.e('AMF', e.toString());
  4117              }
  4118  
  4119              return data;
  4120          }
  4121      }, {
  4122          key: 'parseObject',
  4123          value: function parseObject(arrayBuffer, dataOffset, dataSize) {
  4124              if (dataSize < 3) {
  4125                  throw new _exception.IllegalStateException('Data not enough when parse ScriptDataObject');
  4126              }
  4127              var name = AMF.parseString(arrayBuffer, dataOffset, dataSize);
  4128              var value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);
  4129              var isObjectEnd = value.objectEnd;
  4130  
  4131              return {
  4132                  data: {
  4133                      name: name.data,
  4134                      value: value.data
  4135                  },
  4136                  size: name.size + value.size,
  4137                  objectEnd: isObjectEnd
  4138              };
  4139          }
  4140      }, {
  4141          key: 'parseVariable',
  4142          value: function parseVariable(arrayBuffer, dataOffset, dataSize) {
  4143              return AMF.parseObject(arrayBuffer, dataOffset, dataSize);
  4144          }
  4145      }, {
  4146          key: 'parseString',
  4147          value: function parseString(arrayBuffer, dataOffset, dataSize) {
  4148              if (dataSize < 2) {
  4149                  throw new _exception.IllegalStateException('Data not enough when parse String');
  4150              }
  4151              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  4152              var length = v.getUint16(0, !le);
  4153  
  4154              var str = void 0;
  4155              if (length > 0) {
  4156                  str = (0, _utf8Conv2.default)(new Uint8Array(arrayBuffer, dataOffset + 2, length));
  4157              } else {
  4158                  str = '';
  4159              }
  4160  
  4161              return {
  4162                  data: str,
  4163                  size: 2 + length
  4164              };
  4165          }
  4166      }, {
  4167          key: 'parseLongString',
  4168          value: function parseLongString(arrayBuffer, dataOffset, dataSize) {
  4169              if (dataSize < 4) {
  4170                  throw new _exception.IllegalStateException('Data not enough when parse LongString');
  4171              }
  4172              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  4173              var length = v.getUint32(0, !le);
  4174  
  4175              var str = void 0;
  4176              if (length > 0) {
  4177                  str = (0, _utf8Conv2.default)(new Uint8Array(arrayBuffer, dataOffset + 4, length));
  4178              } else {
  4179                  str = '';
  4180              }
  4181  
  4182              return {
  4183                  data: str,
  4184                  size: 4 + length
  4185              };
  4186          }
  4187      }, {
  4188          key: 'parseDate',
  4189          value: function parseDate(arrayBuffer, dataOffset, dataSize) {
  4190              if (dataSize < 10) {
  4191                  throw new _exception.IllegalStateException('Data size invalid when parse Date');
  4192              }
  4193              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  4194              var timestamp = v.getFloat64(0, !le);
  4195              var localTimeOffset = v.getInt16(8, !le);
  4196              timestamp += localTimeOffset * 60 * 1000; // get UTC time
  4197  
  4198              return {
  4199                  data: new Date(timestamp),
  4200                  size: 8 + 2
  4201              };
  4202          }
  4203      }, {
  4204          key: 'parseValue',
  4205          value: function parseValue(arrayBuffer, dataOffset, dataSize) {
  4206              if (dataSize < 1) {
  4207                  throw new _exception.IllegalStateException('Data not enough when parse Value');
  4208              }
  4209  
  4210              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  4211  
  4212              var offset = 1;
  4213              var type = v.getUint8(0);
  4214              var value = void 0;
  4215              var objectEnd = false;
  4216  
  4217              try {
  4218                  switch (type) {
  4219                      case 0:
  4220                          // Number(Double) type
  4221                          value = v.getFloat64(1, !le);
  4222                          offset += 8;
  4223                          break;
  4224                      case 1:
  4225                          {
  4226                              // Boolean type
  4227                              var b = v.getUint8(1);
  4228                              value = b ? true : false;
  4229                              offset += 1;
  4230                              break;
  4231                          }
  4232                      case 2:
  4233                          {
  4234                              // String type
  4235                              var amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);
  4236                              value = amfstr.data;
  4237                              offset += amfstr.size;
  4238                              break;
  4239                          }
  4240                      case 3:
  4241                          {
  4242                              // Object(s) type
  4243                              value = {};
  4244                              var terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd
  4245                              if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
  4246                                  terminal = 3;
  4247                              }
  4248                              while (offset < dataSize - 4) {
  4249                                  // 4 === type(UI8) + ScriptDataObjectEnd(UI24)
  4250                                  var amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);
  4251                                  if (amfobj.objectEnd) break;
  4252                                  value[amfobj.data.name] = amfobj.data.value;
  4253                                  offset += amfobj.size;
  4254                              }
  4255                              if (offset <= dataSize - 3) {
  4256                                  var marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;
  4257                                  if (marker === 9) {
  4258                                      offset += 3;
  4259                                  }
  4260                              }
  4261                              break;
  4262                          }
  4263                      case 8:
  4264                          {
  4265                              // ECMA array type (Mixed array)
  4266                              value = {};
  4267                              offset += 4; // ECMAArrayLength(UI32)
  4268                              var _terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd
  4269                              if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {
  4270                                  _terminal = 3;
  4271                              }
  4272                              while (offset < dataSize - 8) {
  4273                                  // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)
  4274                                  var amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - _terminal);
  4275                                  if (amfvar.objectEnd) break;
  4276                                  value[amfvar.data.name] = amfvar.data.value;
  4277                                  offset += amfvar.size;
  4278                              }
  4279                              if (offset <= dataSize - 3) {
  4280                                  var _marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;
  4281                                  if (_marker === 9) {
  4282                                      offset += 3;
  4283                                  }
  4284                              }
  4285                              break;
  4286                          }
  4287                      case 9:
  4288                          // ScriptDataObjectEnd
  4289                          value = undefined;
  4290                          offset = 1;
  4291                          objectEnd = true;
  4292                          break;
  4293                      case 10:
  4294                          {
  4295                              // Strict array type
  4296                              // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf
  4297                              value = [];
  4298                              var strictArrayLength = v.getUint32(1, !le);
  4299                              offset += 4;
  4300                              for (var i = 0; i < strictArrayLength; i++) {
  4301                                  var val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);
  4302                                  value.push(val.data);
  4303                                  offset += val.size;
  4304                              }
  4305                              break;
  4306                          }
  4307                      case 11:
  4308                          {
  4309                              // Date type
  4310                              var date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);
  4311                              value = date.data;
  4312                              offset += date.size;
  4313                              break;
  4314                          }
  4315                      case 12:
  4316                          {
  4317                              // Long string type
  4318                              var amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);
  4319                              value = amfLongStr.data;
  4320                              offset += amfLongStr.size;
  4321                              break;
  4322                          }
  4323                      default:
  4324                          // ignore and skip
  4325                          offset = dataSize;
  4326                          _logger2.default.w('AMF', 'Unsupported AMF value type ' + type);
  4327                  }
  4328              } catch (e) {
  4329                  _logger2.default.e('AMF', e.toString());
  4330              }
  4331  
  4332              return {
  4333                  data: value,
  4334                  size: offset,
  4335                  objectEnd: objectEnd
  4336              };
  4337          }
  4338      }]);
  4339  
  4340      return AMF;
  4341  }();
  4342  
  4343  exports.default = AMF;
  4344  
  4345  },{"../utils/exception.js":40,"../utils/logger.js":41,"../utils/utf8-conv.js":44}],16:[function(_dereq_,module,exports){
  4346  'use strict';
  4347  
  4348  Object.defineProperty(exports, "__esModule", {
  4349    value: true
  4350  });
  4351  /*
  4352   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  4353   *
  4354   * @author zheng qian <xqq@xqq.im>
  4355   *
  4356   * Licensed under the Apache License, Version 2.0 (the "License");
  4357   * you may not use this file except in compliance with the License.
  4358   * You may obtain a copy of the License at
  4359   *
  4360   *     http://www.apache.org/licenses/LICENSE-2.0
  4361   *
  4362   * Unless required by applicable law or agreed to in writing, software
  4363   * distributed under the License is distributed on an "AS IS" BASIS,
  4364   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4365   * See the License for the specific language governing permissions and
  4366   * limitations under the License.
  4367   */
  4368  
  4369  var DemuxErrors = {
  4370    OK: 'OK',
  4371    FORMAT_ERROR: 'FormatError',
  4372    FORMAT_UNSUPPORTED: 'FormatUnsupported',
  4373    CODEC_UNSUPPORTED: 'CodecUnsupported'
  4374  };
  4375  
  4376  exports.default = DemuxErrors;
  4377  
  4378  },{}],17:[function(_dereq_,module,exports){
  4379  'use strict';
  4380  
  4381  Object.defineProperty(exports, "__esModule", {
  4382      value: true
  4383  });
  4384  
  4385  var _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; }; }(); /*
  4386                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  4387                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4388                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  4389                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4390                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  4391                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  4392                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  4393                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4394                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  4395                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4396                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  4397                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  4398                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4399                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  4400                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  4401                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  4402  
  4403  var _exception = _dereq_('../utils/exception.js');
  4404  
  4405  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4406  
  4407  // Exponential-Golomb buffer decoder
  4408  var ExpGolomb = function () {
  4409      function ExpGolomb(uint8array) {
  4410          _classCallCheck(this, ExpGolomb);
  4411  
  4412          this.TAG = 'ExpGolomb';
  4413  
  4414          this._buffer = uint8array;
  4415          this._buffer_index = 0;
  4416          this._total_bytes = uint8array.byteLength;
  4417          this._total_bits = uint8array.byteLength * 8;
  4418          this._current_word = 0;
  4419          this._current_word_bits_left = 0;
  4420      }
  4421  
  4422      _createClass(ExpGolomb, [{
  4423          key: 'destroy',
  4424          value: function destroy() {
  4425              this._buffer = null;
  4426          }
  4427      }, {
  4428          key: '_fillCurrentWord',
  4429          value: function _fillCurrentWord() {
  4430              var buffer_bytes_left = this._total_bytes - this._buffer_index;
  4431              if (buffer_bytes_left <= 0) throw new _exception.IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');
  4432  
  4433              var bytes_read = Math.min(4, buffer_bytes_left);
  4434              var word = new Uint8Array(4);
  4435              word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));
  4436              this._current_word = new DataView(word.buffer).getUint32(0, false);
  4437  
  4438              this._buffer_index += bytes_read;
  4439              this._current_word_bits_left = bytes_read * 8;
  4440          }
  4441      }, {
  4442          key: 'readBits',
  4443          value: function readBits(bits) {
  4444              if (bits > 32) throw new _exception.InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');
  4445  
  4446              if (bits <= this._current_word_bits_left) {
  4447                  var _result = this._current_word >>> 32 - bits;
  4448                  this._current_word <<= bits;
  4449                  this._current_word_bits_left -= bits;
  4450                  return _result;
  4451              }
  4452  
  4453              var result = this._current_word_bits_left ? this._current_word : 0;
  4454              result = result >>> 32 - this._current_word_bits_left;
  4455              var bits_need_left = bits - this._current_word_bits_left;
  4456  
  4457              this._fillCurrentWord();
  4458              var bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);
  4459  
  4460              var result2 = this._current_word >>> 32 - bits_read_next;
  4461              this._current_word <<= bits_read_next;
  4462              this._current_word_bits_left -= bits_read_next;
  4463  
  4464              result = result << bits_read_next | result2;
  4465              return result;
  4466          }
  4467      }, {
  4468          key: 'readBool',
  4469          value: function readBool() {
  4470              return this.readBits(1) === 1;
  4471          }
  4472      }, {
  4473          key: 'readByte',
  4474          value: function readByte() {
  4475              return this.readBits(8);
  4476          }
  4477      }, {
  4478          key: '_skipLeadingZero',
  4479          value: function _skipLeadingZero() {
  4480              var zero_count = void 0;
  4481              for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {
  4482                  if (0 !== (this._current_word & 0x80000000 >>> zero_count)) {
  4483                      this._current_word <<= zero_count;
  4484                      this._current_word_bits_left -= zero_count;
  4485                      return zero_count;
  4486                  }
  4487              }
  4488              this._fillCurrentWord();
  4489              return zero_count + this._skipLeadingZero();
  4490          }
  4491      }, {
  4492          key: 'readUEG',
  4493          value: function readUEG() {
  4494              // unsigned exponential golomb
  4495              var leading_zeros = this._skipLeadingZero();
  4496              return this.readBits(leading_zeros + 1) - 1;
  4497          }
  4498      }, {
  4499          key: 'readSEG',
  4500          value: function readSEG() {
  4501              // signed exponential golomb
  4502              var value = this.readUEG();
  4503              if (value & 0x01) {
  4504                  return value + 1 >>> 1;
  4505              } else {
  4506                  return -1 * (value >>> 1);
  4507              }
  4508          }
  4509      }]);
  4510  
  4511      return ExpGolomb;
  4512  }();
  4513  
  4514  exports.default = ExpGolomb;
  4515  
  4516  },{"../utils/exception.js":40}],18:[function(_dereq_,module,exports){
  4517  'use strict';
  4518  
  4519  Object.defineProperty(exports, "__esModule", {
  4520      value: true
  4521  });
  4522  
  4523  var _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; };
  4524  
  4525  var _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; }; }(); /*
  4526                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  4527                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4528                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  4529                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4530                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  4531                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  4532                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  4533                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4534                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  4535                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  4536                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  4537                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  4538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  4540                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  4541                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  4542  
  4543  var _logger = _dereq_('../utils/logger.js');
  4544  
  4545  var _logger2 = _interopRequireDefault(_logger);
  4546  
  4547  var _amfParser = _dereq_('./amf-parser.js');
  4548  
  4549  var _amfParser2 = _interopRequireDefault(_amfParser);
  4550  
  4551  var _spsParser = _dereq_('./sps-parser.js');
  4552  
  4553  var _spsParser2 = _interopRequireDefault(_spsParser);
  4554  
  4555  var _demuxErrors = _dereq_('./demux-errors.js');
  4556  
  4557  var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
  4558  
  4559  var _mediaInfo = _dereq_('../core/media-info.js');
  4560  
  4561  var _mediaInfo2 = _interopRequireDefault(_mediaInfo);
  4562  
  4563  var _exception = _dereq_('../utils/exception.js');
  4564  
  4565  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  4566  
  4567  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4568  
  4569  function Swap16(src) {
  4570      return src >>> 8 & 0xFF | (src & 0xFF) << 8;
  4571  }
  4572  
  4573  function Swap32(src) {
  4574      return (src & 0xFF000000) >>> 24 | (src & 0x00FF0000) >>> 8 | (src & 0x0000FF00) << 8 | (src & 0x000000FF) << 24;
  4575  }
  4576  
  4577  function ReadBig32(array, index) {
  4578      return array[index] << 24 | array[index + 1] << 16 | array[index + 2] << 8 | array[index + 3];
  4579  }
  4580  
  4581  var FLVDemuxer = function () {
  4582      function FLVDemuxer(probeData, config) {
  4583          _classCallCheck(this, FLVDemuxer);
  4584  
  4585          this.TAG = 'FLVDemuxer';
  4586  
  4587          this._config = config;
  4588  
  4589          this._onError = null;
  4590          this._onMediaInfo = null;
  4591          this._onMetaDataArrived = null;
  4592          this._onScriptDataArrived = null;
  4593          this._onTrackMetadata = null;
  4594          this._onDataAvailable = null;
  4595  
  4596          this._dataOffset = probeData.dataOffset;
  4597          this._firstParse = true;
  4598          this._dispatch = false;
  4599  
  4600          this._hasAudio = probeData.hasAudioTrack;
  4601          this._hasVideo = probeData.hasVideoTrack;
  4602  
  4603          this._hasAudioFlagOverrided = false;
  4604          this._hasVideoFlagOverrided = false;
  4605  
  4606          this._audioInitialMetadataDispatched = false;
  4607          this._videoInitialMetadataDispatched = false;
  4608  
  4609          this._mediaInfo = new _mediaInfo2.default();
  4610          this._mediaInfo.hasAudio = this._hasAudio;
  4611          this._mediaInfo.hasVideo = this._hasVideo;
  4612          this._metadata = null;
  4613          this._audioMetadata = null;
  4614          this._videoMetadata = null;
  4615  
  4616          this._naluLengthSize = 4;
  4617          this._timestampBase = 0; // int32, in milliseconds
  4618          this._timescale = 1000;
  4619          this._duration = 0; // int32, in milliseconds
  4620          this._durationOverrided = false;
  4621          this._referenceFrameRate = {
  4622              fixed: true,
  4623              fps: 23.976,
  4624              fps_num: 23976,
  4625              fps_den: 1000
  4626          };
  4627  
  4628          this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];
  4629  
  4630          this._mpegSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
  4631  
  4632          this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];
  4633          this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];
  4634          this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];
  4635  
  4636          this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];
  4637          this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];
  4638          this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];
  4639  
  4640          this._videoTrack = { type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0 };
  4641          this._audioTrack = { type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0 };
  4642  
  4643          this._littleEndian = function () {
  4644              var buf = new ArrayBuffer(2);
  4645              new DataView(buf).setInt16(0, 256, true); // little-endian write
  4646              return new Int16Array(buf)[0] === 256; // platform-spec read, if equal then LE
  4647          }();
  4648      }
  4649  
  4650      _createClass(FLVDemuxer, [{
  4651          key: 'destroy',
  4652          value: function destroy() {
  4653              this._mediaInfo = null;
  4654              this._metadata = null;
  4655              this._audioMetadata = null;
  4656              this._videoMetadata = null;
  4657              this._videoTrack = null;
  4658              this._audioTrack = null;
  4659  
  4660              this._onError = null;
  4661              this._onMediaInfo = null;
  4662              this._onMetaDataArrived = null;
  4663              this._onScriptDataArrived = null;
  4664              this._onTrackMetadata = null;
  4665              this._onDataAvailable = null;
  4666          }
  4667      }, {
  4668          key: 'bindDataSource',
  4669          value: function bindDataSource(loader) {
  4670              loader.onDataArrival = this.parseChunks.bind(this);
  4671              return this;
  4672          }
  4673  
  4674          // prototype: function(type: string, metadata: any): void
  4675  
  4676      }, {
  4677          key: 'resetMediaInfo',
  4678          value: function resetMediaInfo() {
  4679              this._mediaInfo = new _mediaInfo2.default();
  4680          }
  4681      }, {
  4682          key: '_isInitialMetadataDispatched',
  4683          value: function _isInitialMetadataDispatched() {
  4684              if (this._hasAudio && this._hasVideo) {
  4685                  // both audio & video
  4686                  return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;
  4687              }
  4688              if (this._hasAudio && !this._hasVideo) {
  4689                  // audio only
  4690                  return this._audioInitialMetadataDispatched;
  4691              }
  4692              if (!this._hasAudio && this._hasVideo) {
  4693                  // video only
  4694                  return this._videoInitialMetadataDispatched;
  4695              }
  4696              return false;
  4697          }
  4698  
  4699          // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;
  4700  
  4701      }, {
  4702          key: 'parseChunks',
  4703          value: function parseChunks(chunk, byteStart) {
  4704              if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {
  4705                  throw new _exception.IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');
  4706              }
  4707  
  4708              var offset = 0;
  4709              var le = this._littleEndian;
  4710  
  4711              if (byteStart === 0) {
  4712                  // buffer with FLV header
  4713                  if (chunk.byteLength > 13) {
  4714                      var probeData = FLVDemuxer.probe(chunk);
  4715                      offset = probeData.dataOffset;
  4716                  } else {
  4717                      return 0;
  4718                  }
  4719              }
  4720  
  4721              if (this._firstParse) {
  4722                  // handle PreviousTagSize0 before Tag1
  4723                  this._firstParse = false;
  4724                  if (byteStart + offset !== this._dataOffset) {
  4725                      _logger2.default.w(this.TAG, 'First time parsing but chunk byteStart invalid!');
  4726                  }
  4727  
  4728                  var v = new DataView(chunk, offset);
  4729                  var prevTagSize0 = v.getUint32(0, !le);
  4730                  if (prevTagSize0 !== 0) {
  4731                      _logger2.default.w(this.TAG, 'PrevTagSize0 !== 0 !!!');
  4732                  }
  4733                  offset += 4;
  4734              }
  4735  
  4736              while (offset < chunk.byteLength) {
  4737                  this._dispatch = true;
  4738  
  4739                  var _v = new DataView(chunk, offset);
  4740  
  4741                  if (offset + 11 + 4 > chunk.byteLength) {
  4742                      // data not enough for parsing an flv tag
  4743                      break;
  4744                  }
  4745  
  4746                  var tagType = _v.getUint8(0);
  4747                  var dataSize = _v.getUint32(0, !le) & 0x00FFFFFF;
  4748  
  4749                  if (offset + 11 + dataSize + 4 > chunk.byteLength) {
  4750                      // data not enough for parsing actual data body
  4751                      break;
  4752                  }
  4753  
  4754                  if (tagType !== 8 && tagType !== 9 && tagType !== 18) {
  4755                      _logger2.default.w(this.TAG, 'Unsupported tag type ' + tagType + ', skipped');
  4756                      // consume the whole tag (skip it)
  4757                      offset += 11 + dataSize + 4;
  4758                      continue;
  4759                  }
  4760  
  4761                  var ts2 = _v.getUint8(4);
  4762                  var ts1 = _v.getUint8(5);
  4763                  var ts0 = _v.getUint8(6);
  4764                  var ts3 = _v.getUint8(7);
  4765  
  4766                  var timestamp = ts0 | ts1 << 8 | ts2 << 16 | ts3 << 24;
  4767  
  4768                  var streamId = _v.getUint32(7, !le) & 0x00FFFFFF;
  4769                  if (streamId !== 0) {
  4770                      _logger2.default.w(this.TAG, 'Meet tag which has StreamID != 0!');
  4771                  }
  4772  
  4773                  var dataOffset = offset + 11;
  4774  
  4775                  switch (tagType) {
  4776                      case 8:
  4777                          // Audio
  4778                          this._parseAudioData(chunk, dataOffset, dataSize, timestamp);
  4779                          break;
  4780                      case 9:
  4781                          // Video
  4782                          this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);
  4783                          break;
  4784                      case 18:
  4785                          // ScriptDataObject
  4786                          this._parseScriptData(chunk, dataOffset, dataSize);
  4787                          break;
  4788                  }
  4789  
  4790                  var prevTagSize = _v.getUint32(11 + dataSize, !le);
  4791                  if (prevTagSize !== 11 + dataSize) {
  4792                      _logger2.default.w(this.TAG, 'Invalid PrevTagSize ' + prevTagSize);
  4793                  }
  4794  
  4795                  offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize
  4796              }
  4797  
  4798              // dispatch parsed frames to consumer (typically, the remuxer)
  4799              if (this._isInitialMetadataDispatched()) {
  4800                  if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
  4801                      this._onDataAvailable(this._audioTrack, this._videoTrack);
  4802                  }
  4803              }
  4804  
  4805              return offset; // consumed bytes, just equals latest offset index
  4806          }
  4807      }, {
  4808          key: '_parseScriptData',
  4809          value: function _parseScriptData(arrayBuffer, dataOffset, dataSize) {
  4810              var scriptData = _amfParser2.default.parseScriptData(arrayBuffer, dataOffset, dataSize);
  4811  
  4812              if (scriptData.hasOwnProperty('onMetaData')) {
  4813                  if (scriptData.onMetaData == null || _typeof(scriptData.onMetaData) !== 'object') {
  4814                      _logger2.default.w(this.TAG, 'Invalid onMetaData structure!');
  4815                      return;
  4816                  }
  4817                  if (this._metadata) {
  4818                      _logger2.default.w(this.TAG, 'Found another onMetaData tag!');
  4819                  }
  4820                  this._metadata = scriptData;
  4821                  var onMetaData = this._metadata.onMetaData;
  4822  
  4823                  if (this._onMetaDataArrived) {
  4824                      this._onMetaDataArrived(Object.assign({}, onMetaData));
  4825                  }
  4826  
  4827                  if (typeof onMetaData.hasAudio === 'boolean') {
  4828                      // hasAudio
  4829                      if (this._hasAudioFlagOverrided === false) {
  4830                          this._hasAudio = onMetaData.hasAudio;
  4831                          this._mediaInfo.hasAudio = this._hasAudio;
  4832                      }
  4833                  }
  4834                  if (typeof onMetaData.hasVideo === 'boolean') {
  4835                      // hasVideo
  4836                      if (this._hasVideoFlagOverrided === false) {
  4837                          this._hasVideo = onMetaData.hasVideo;
  4838                          this._mediaInfo.hasVideo = this._hasVideo;
  4839                      }
  4840                  }
  4841                  if (typeof onMetaData.audiodatarate === 'number') {
  4842                      // audiodatarate
  4843                      this._mediaInfo.audioDataRate = onMetaData.audiodatarate;
  4844                  }
  4845                  if (typeof onMetaData.videodatarate === 'number') {
  4846                      // videodatarate
  4847                      this._mediaInfo.videoDataRate = onMetaData.videodatarate;
  4848                  }
  4849                  if (typeof onMetaData.width === 'number') {
  4850                      // width
  4851                      this._mediaInfo.width = onMetaData.width;
  4852                  }
  4853                  if (typeof onMetaData.height === 'number') {
  4854                      // height
  4855                      this._mediaInfo.height = onMetaData.height;
  4856                  }
  4857                  if (typeof onMetaData.duration === 'number') {
  4858                      // duration
  4859                      if (!this._durationOverrided) {
  4860                          var duration = Math.floor(onMetaData.duration * this._timescale);
  4861                          this._duration = duration;
  4862                          this._mediaInfo.duration = duration;
  4863                      }
  4864                  } else {
  4865                      this._mediaInfo.duration = 0;
  4866                  }
  4867                  if (typeof onMetaData.framerate === 'number') {
  4868                      // framerate
  4869                      var fps_num = Math.floor(onMetaData.framerate * 1000);
  4870                      if (fps_num > 0) {
  4871                          var fps = fps_num / 1000;
  4872                          this._referenceFrameRate.fixed = true;
  4873                          this._referenceFrameRate.fps = fps;
  4874                          this._referenceFrameRate.fps_num = fps_num;
  4875                          this._referenceFrameRate.fps_den = 1000;
  4876                          this._mediaInfo.fps = fps;
  4877                      }
  4878                  }
  4879                  if (_typeof(onMetaData.keyframes) === 'object') {
  4880                      // keyframes
  4881                      this._mediaInfo.hasKeyframesIndex = true;
  4882                      var keyframes = onMetaData.keyframes;
  4883                      this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);
  4884                      onMetaData.keyframes = null; // keyframes has been extracted, remove it
  4885                  } else {
  4886                      this._mediaInfo.hasKeyframesIndex = false;
  4887                  }
  4888                  this._dispatch = false;
  4889                  this._mediaInfo.metadata = onMetaData;
  4890                  _logger2.default.v(this.TAG, 'Parsed onMetaData');
  4891                  if (this._mediaInfo.isComplete()) {
  4892                      this._onMediaInfo(this._mediaInfo);
  4893                  }
  4894              }
  4895  
  4896              if (Object.keys(scriptData).length > 0) {
  4897                  if (this._onScriptDataArrived) {
  4898                      this._onScriptDataArrived(Object.assign({}, scriptData));
  4899                  }
  4900              }
  4901          }
  4902      }, {
  4903          key: '_parseKeyframesIndex',
  4904          value: function _parseKeyframesIndex(keyframes) {
  4905              var times = [];
  4906              var filepositions = [];
  4907  
  4908              // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)
  4909              for (var i = 1; i < keyframes.times.length; i++) {
  4910                  var time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);
  4911                  times.push(time);
  4912                  filepositions.push(keyframes.filepositions[i]);
  4913              }
  4914  
  4915              return {
  4916                  times: times,
  4917                  filepositions: filepositions
  4918              };
  4919          }
  4920      }, {
  4921          key: '_parseAudioData',
  4922          value: function _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {
  4923              if (dataSize <= 1) {
  4924                  _logger2.default.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');
  4925                  return;
  4926              }
  4927  
  4928              if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {
  4929                  // If hasAudio: false indicated explicitly in MediaDataSource,
  4930                  // Ignore all the audio packets
  4931                  return;
  4932              }
  4933  
  4934              var le = this._littleEndian;
  4935              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  4936  
  4937              var soundSpec = v.getUint8(0);
  4938  
  4939              var soundFormat = soundSpec >>> 4;
  4940              if (soundFormat !== 2 && soundFormat !== 10) {
  4941                  // MP3 or AAC
  4942                  this._onError(_demuxErrors2.default.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);
  4943                  return;
  4944              }
  4945  
  4946              var soundRate = 0;
  4947              var soundRateIndex = (soundSpec & 12) >>> 2;
  4948              if (soundRateIndex >= 0 && soundRateIndex <= 4) {
  4949                  soundRate = this._flvSoundRateTable[soundRateIndex];
  4950              } else {
  4951                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);
  4952                  return;
  4953              }
  4954  
  4955              var soundSize = (soundSpec & 2) >>> 1; // unused
  4956              var soundType = soundSpec & 1;
  4957  
  4958              var meta = this._audioMetadata;
  4959              var track = this._audioTrack;
  4960  
  4961              if (!meta) {
  4962                  if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {
  4963                      this._hasAudio = true;
  4964                      this._mediaInfo.hasAudio = true;
  4965                  }
  4966  
  4967                  // initial metadata
  4968                  meta = this._audioMetadata = {};
  4969                  meta.type = 'audio';
  4970                  meta.id = track.id;
  4971                  meta.timescale = this._timescale;
  4972                  meta.duration = this._duration;
  4973                  meta.audioSampleRate = soundRate;
  4974                  meta.channelCount = soundType === 0 ? 1 : 2;
  4975              }
  4976  
  4977              if (soundFormat === 10) {
  4978                  // AAC
  4979                  var aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);
  4980                  if (aacData == undefined) {
  4981                      return;
  4982                  }
  4983  
  4984                  if (aacData.packetType === 0) {
  4985                      // AAC sequence header (AudioSpecificConfig)
  4986                      if (meta.config) {
  4987                          _logger2.default.w(this.TAG, 'Found another AudioSpecificConfig!');
  4988                      }
  4989                      var misc = aacData.data;
  4990                      meta.audioSampleRate = misc.samplingRate;
  4991                      meta.channelCount = misc.channelCount;
  4992                      meta.codec = misc.codec;
  4993                      meta.originalCodec = misc.originalCodec;
  4994                      meta.config = misc.config;
  4995                      // The decode result of an aac sample is 1024 PCM samples
  4996                      meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;
  4997                      _logger2.default.v(this.TAG, 'Parsed AudioSpecificConfig');
  4998  
  4999                      if (this._isInitialMetadataDispatched()) {
  5000                          // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer
  5001                          if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
  5002                              this._onDataAvailable(this._audioTrack, this._videoTrack);
  5003                          }
  5004                      } else {
  5005                          this._audioInitialMetadataDispatched = true;
  5006                      }
  5007                      // then notify new metadata
  5008                      this._dispatch = false;
  5009                      this._onTrackMetadata('audio', meta);
  5010  
  5011                      var mi = this._mediaInfo;
  5012                      mi.audioCodec = meta.originalCodec;
  5013                      mi.audioSampleRate = meta.audioSampleRate;
  5014                      mi.audioChannelCount = meta.channelCount;
  5015                      if (mi.hasVideo) {
  5016                          if (mi.videoCodec != null) {
  5017                              mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
  5018                          }
  5019                      } else {
  5020                          mi.mimeType = 'video/x-flv; codecs="' + mi.audioCodec + '"';
  5021                      }
  5022                      if (mi.isComplete()) {
  5023                          this._onMediaInfo(mi);
  5024                      }
  5025                  } else if (aacData.packetType === 1) {
  5026                      // AAC raw frame data
  5027                      var dts = this._timestampBase + tagTimestamp;
  5028                      var aacSample = { unit: aacData.data, length: aacData.data.byteLength, dts: dts, pts: dts };
  5029                      track.samples.push(aacSample);
  5030                      track.length += aacData.data.length;
  5031                  } else {
  5032                      _logger2.default.e(this.TAG, 'Flv: Unsupported AAC data type ' + aacData.packetType);
  5033                  }
  5034              } else if (soundFormat === 2) {
  5035                  // MP3
  5036                  if (!meta.codec) {
  5037                      // We need metadata for mp3 audio track, extract info from frame header
  5038                      var _misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);
  5039                      if (_misc == undefined) {
  5040                          return;
  5041                      }
  5042                      meta.audioSampleRate = _misc.samplingRate;
  5043                      meta.channelCount = _misc.channelCount;
  5044                      meta.codec = _misc.codec;
  5045                      meta.originalCodec = _misc.originalCodec;
  5046                      // The decode result of an mp3 sample is 1152 PCM samples
  5047                      meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;
  5048                      _logger2.default.v(this.TAG, 'Parsed MPEG Audio Frame Header');
  5049  
  5050                      this._audioInitialMetadataDispatched = true;
  5051                      this._onTrackMetadata('audio', meta);
  5052  
  5053                      var _mi = this._mediaInfo;
  5054                      _mi.audioCodec = meta.codec;
  5055                      _mi.audioSampleRate = meta.audioSampleRate;
  5056                      _mi.audioChannelCount = meta.channelCount;
  5057                      _mi.audioDataRate = _misc.bitRate;
  5058                      if (_mi.hasVideo) {
  5059                          if (_mi.videoCodec != null) {
  5060                              _mi.mimeType = 'video/x-flv; codecs="' + _mi.videoCodec + ',' + _mi.audioCodec + '"';
  5061                          }
  5062                      } else {
  5063                          _mi.mimeType = 'video/x-flv; codecs="' + _mi.audioCodec + '"';
  5064                      }
  5065                      if (_mi.isComplete()) {
  5066                          this._onMediaInfo(_mi);
  5067                      }
  5068                  }
  5069  
  5070                  // This packet is always a valid audio packet, extract it
  5071                  var data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);
  5072                  if (data == undefined) {
  5073                      return;
  5074                  }
  5075                  var _dts = this._timestampBase + tagTimestamp;
  5076                  var mp3Sample = { unit: data, length: data.byteLength, dts: _dts, pts: _dts };
  5077                  track.samples.push(mp3Sample);
  5078                  track.length += data.length;
  5079              }
  5080          }
  5081      }, {
  5082          key: '_parseAACAudioData',
  5083          value: function _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {
  5084              if (dataSize <= 1) {
  5085                  _logger2.default.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');
  5086                  return;
  5087              }
  5088  
  5089              var result = {};
  5090              var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
  5091  
  5092              result.packetType = array[0];
  5093  
  5094              if (array[0] === 0) {
  5095                  result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);
  5096              } else {
  5097                  result.data = array.subarray(1);
  5098              }
  5099  
  5100              return result;
  5101          }
  5102      }, {
  5103          key: '_parseAACAudioSpecificConfig',
  5104          value: function _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {
  5105              var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
  5106              var config = null;
  5107  
  5108              /* Audio Object Type:
  5109                 0: Null
  5110                 1: AAC Main
  5111                 2: AAC LC
  5112                 3: AAC SSR (Scalable Sample Rate)
  5113                 4: AAC LTP (Long Term Prediction)
  5114                 5: HE-AAC / SBR (Spectral Band Replication)
  5115                 6: AAC Scalable
  5116              */
  5117  
  5118              var audioObjectType = 0;
  5119              var originalAudioObjectType = 0;
  5120              var audioExtensionObjectType = null;
  5121              var samplingIndex = 0;
  5122              var extensionSamplingIndex = null;
  5123  
  5124              // 5 bits
  5125              audioObjectType = originalAudioObjectType = array[0] >>> 3;
  5126              // 4 bits
  5127              samplingIndex = (array[0] & 0x07) << 1 | array[1] >>> 7;
  5128              if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {
  5129                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');
  5130                  return;
  5131              }
  5132  
  5133              var samplingFrequence = this._mpegSamplingRates[samplingIndex];
  5134  
  5135              // 4 bits
  5136              var channelConfig = (array[1] & 0x78) >>> 3;
  5137              if (channelConfig < 0 || channelConfig >= 8) {
  5138                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');
  5139                  return;
  5140              }
  5141  
  5142              if (audioObjectType === 5) {
  5143                  // HE-AAC?
  5144                  // 4 bits
  5145                  extensionSamplingIndex = (array[1] & 0x07) << 1 | array[2] >>> 7;
  5146                  // 5 bits
  5147                  audioExtensionObjectType = (array[2] & 0x7C) >>> 2;
  5148              }
  5149  
  5150              // workarounds for various browsers
  5151              var userAgent = self.navigator.userAgent.toLowerCase();
  5152  
  5153              if (userAgent.indexOf('firefox') !== -1) {
  5154                  // firefox: use SBR (HE-AAC) if freq less than 24kHz
  5155                  if (samplingIndex >= 6) {
  5156                      audioObjectType = 5;
  5157                      config = new Array(4);
  5158                      extensionSamplingIndex = samplingIndex - 3;
  5159                  } else {
  5160                      // use LC-AAC
  5161                      audioObjectType = 2;
  5162                      config = new Array(2);
  5163                      extensionSamplingIndex = samplingIndex;
  5164                  }
  5165              } else if (userAgent.indexOf('android') !== -1) {
  5166                  // android: always use LC-AAC
  5167                  audioObjectType = 2;
  5168                  config = new Array(2);
  5169                  extensionSamplingIndex = samplingIndex;
  5170              } else {
  5171                  // for other browsers, e.g. chrome...
  5172                  // Always use HE-AAC to make it easier to switch aac codec profile
  5173                  audioObjectType = 5;
  5174                  extensionSamplingIndex = samplingIndex;
  5175                  config = new Array(4);
  5176  
  5177                  if (samplingIndex >= 6) {
  5178                      extensionSamplingIndex = samplingIndex - 3;
  5179                  } else if (channelConfig === 1) {
  5180                      // Mono channel
  5181                      audioObjectType = 2;
  5182                      config = new Array(2);
  5183                      extensionSamplingIndex = samplingIndex;
  5184                  }
  5185              }
  5186  
  5187              config[0] = audioObjectType << 3;
  5188              config[0] |= (samplingIndex & 0x0F) >>> 1;
  5189              config[1] = (samplingIndex & 0x0F) << 7;
  5190              config[1] |= (channelConfig & 0x0F) << 3;
  5191              if (audioObjectType === 5) {
  5192                  config[1] |= (extensionSamplingIndex & 0x0F) >>> 1;
  5193                  config[2] = (extensionSamplingIndex & 0x01) << 7;
  5194                  // extended audio object type: force to 2 (LC-AAC)
  5195                  config[2] |= 2 << 2;
  5196                  config[3] = 0;
  5197              }
  5198  
  5199              return {
  5200                  config: config,
  5201                  samplingRate: samplingFrequence,
  5202                  channelCount: channelConfig,
  5203                  codec: 'mp4a.40.' + audioObjectType,
  5204                  originalCodec: 'mp4a.40.' + originalAudioObjectType
  5205              };
  5206          }
  5207      }, {
  5208          key: '_parseMP3AudioData',
  5209          value: function _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {
  5210              if (dataSize < 4) {
  5211                  _logger2.default.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');
  5212                  return;
  5213              }
  5214  
  5215              var le = this._littleEndian;
  5216              var array = new Uint8Array(arrayBuffer, dataOffset, dataSize);
  5217              var result = null;
  5218  
  5219              if (requestHeader) {
  5220                  if (array[0] !== 0xFF) {
  5221                      return;
  5222                  }
  5223                  var ver = array[1] >>> 3 & 0x03;
  5224                  var layer = (array[1] & 0x06) >> 1;
  5225  
  5226                  var bitrate_index = (array[2] & 0xF0) >>> 4;
  5227                  var sampling_freq_index = (array[2] & 0x0C) >>> 2;
  5228  
  5229                  var channel_mode = array[3] >>> 6 & 0x03;
  5230                  var channel_count = channel_mode !== 3 ? 2 : 1;
  5231  
  5232                  var sample_rate = 0;
  5233                  var bit_rate = 0;
  5234                  var object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types
  5235  
  5236                  var codec = 'mp3';
  5237  
  5238                  switch (ver) {
  5239                      case 0:
  5240                          // MPEG 2.5
  5241                          sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];
  5242                          break;
  5243                      case 2:
  5244                          // MPEG 2
  5245                          sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];
  5246                          break;
  5247                      case 3:
  5248                          // MPEG 1
  5249                          sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];
  5250                          break;
  5251                  }
  5252  
  5253                  switch (layer) {
  5254                      case 1:
  5255                          // Layer 3
  5256                          object_type = 34;
  5257                          if (bitrate_index < this._mpegAudioL3BitRateTable.length) {
  5258                              bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];
  5259                          }
  5260                          break;
  5261                      case 2:
  5262                          // Layer 2
  5263                          object_type = 33;
  5264                          if (bitrate_index < this._mpegAudioL2BitRateTable.length) {
  5265                              bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];
  5266                          }
  5267                          break;
  5268                      case 3:
  5269                          // Layer 1
  5270                          object_type = 32;
  5271                          if (bitrate_index < this._mpegAudioL1BitRateTable.length) {
  5272                              bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];
  5273                          }
  5274                          break;
  5275                  }
  5276  
  5277                  result = {
  5278                      bitRate: bit_rate,
  5279                      samplingRate: sample_rate,
  5280                      channelCount: channel_count,
  5281                      codec: codec,
  5282                      originalCodec: codec
  5283                  };
  5284              } else {
  5285                  result = array;
  5286              }
  5287  
  5288              return result;
  5289          }
  5290      }, {
  5291          key: '_parseVideoData',
  5292          value: function _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {
  5293              if (dataSize <= 1) {
  5294                  _logger2.default.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');
  5295                  return;
  5296              }
  5297  
  5298              if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {
  5299                  // If hasVideo: false indicated explicitly in MediaDataSource,
  5300                  // Ignore all the video packets
  5301                  return;
  5302              }
  5303  
  5304              var spec = new Uint8Array(arrayBuffer, dataOffset, dataSize)[0];
  5305  
  5306              var frameType = (spec & 240) >>> 4;
  5307              var codecId = spec & 15;
  5308  
  5309              if (codecId !== 7) {
  5310                  this._onError(_demuxErrors2.default.CODEC_UNSUPPORTED, 'Flv: Unsupported codec in video frame: ' + codecId);
  5311                  return;
  5312              }
  5313  
  5314              this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);
  5315          }
  5316      }, {
  5317          key: '_parseAVCVideoPacket',
  5318          value: function _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {
  5319              if (dataSize < 4) {
  5320                  _logger2.default.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');
  5321                  return;
  5322              }
  5323  
  5324              var le = this._littleEndian;
  5325              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  5326  
  5327              var packetType = v.getUint8(0);
  5328              var cts_unsigned = v.getUint32(0, !le) & 0x00FFFFFF;
  5329              var cts = cts_unsigned << 8 >> 8; // convert to 24-bit signed int
  5330  
  5331              if (packetType === 0) {
  5332                  // AVCDecoderConfigurationRecord
  5333                  this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);
  5334              } else if (packetType === 1) {
  5335                  // One or more Nalus
  5336                  this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);
  5337              } else if (packetType === 2) {
  5338                  // empty, AVC end of sequence
  5339              } else {
  5340                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid video packet type ' + packetType);
  5341                  return;
  5342              }
  5343          }
  5344      }, {
  5345          key: '_parseAVCDecoderConfigurationRecord',
  5346          value: function _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {
  5347              if (dataSize < 7) {
  5348                  _logger2.default.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');
  5349                  return;
  5350              }
  5351  
  5352              var meta = this._videoMetadata;
  5353              var track = this._videoTrack;
  5354              var le = this._littleEndian;
  5355              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  5356  
  5357              if (!meta) {
  5358                  if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {
  5359                      this._hasVideo = true;
  5360                      this._mediaInfo.hasVideo = true;
  5361                  }
  5362  
  5363                  meta = this._videoMetadata = {};
  5364                  meta.type = 'video';
  5365                  meta.id = track.id;
  5366                  meta.timescale = this._timescale;
  5367                  meta.duration = this._duration;
  5368              } else {
  5369                  if (typeof meta.avcc !== 'undefined') {
  5370                      _logger2.default.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');
  5371                  }
  5372              }
  5373  
  5374              var version = v.getUint8(0); // configurationVersion
  5375              var avcProfile = v.getUint8(1); // avcProfileIndication
  5376              var profileCompatibility = v.getUint8(2); // profile_compatibility
  5377              var avcLevel = v.getUint8(3); // AVCLevelIndication
  5378  
  5379              if (version !== 1 || avcProfile === 0) {
  5380                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');
  5381                  return;
  5382              }
  5383  
  5384              this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne
  5385              if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) {
  5386                  // holy shit!!!
  5387                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Strange NaluLengthSizeMinusOne: ' + (this._naluLengthSize - 1));
  5388                  return;
  5389              }
  5390  
  5391              var spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets
  5392              if (spsCount === 0) {
  5393                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');
  5394                  return;
  5395              } else if (spsCount > 1) {
  5396                  _logger2.default.w(this.TAG, 'Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ' + spsCount);
  5397              }
  5398  
  5399              var offset = 6;
  5400  
  5401              for (var i = 0; i < spsCount; i++) {
  5402                  var len = v.getUint16(offset, !le); // sequenceParameterSetLength
  5403                  offset += 2;
  5404  
  5405                  if (len === 0) {
  5406                      continue;
  5407                  }
  5408  
  5409                  // Notice: Nalu without startcode header (00 00 00 01)
  5410                  var sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);
  5411                  offset += len;
  5412  
  5413                  var config = _spsParser2.default.parseSPS(sps);
  5414                  if (i !== 0) {
  5415                      // ignore other sps's config
  5416                      continue;
  5417                  }
  5418  
  5419                  meta.codecWidth = config.codec_size.width;
  5420                  meta.codecHeight = config.codec_size.height;
  5421                  meta.presentWidth = config.present_size.width;
  5422                  meta.presentHeight = config.present_size.height;
  5423  
  5424                  meta.profile = config.profile_string;
  5425                  meta.level = config.level_string;
  5426                  meta.bitDepth = config.bit_depth;
  5427                  meta.chromaFormat = config.chroma_format;
  5428                  meta.sarRatio = config.sar_ratio;
  5429                  meta.frameRate = config.frame_rate;
  5430  
  5431                  if (config.frame_rate.fixed === false || config.frame_rate.fps_num === 0 || config.frame_rate.fps_den === 0) {
  5432                      meta.frameRate = this._referenceFrameRate;
  5433                  }
  5434  
  5435                  var fps_den = meta.frameRate.fps_den;
  5436                  var fps_num = meta.frameRate.fps_num;
  5437                  meta.refSampleDuration = meta.timescale * (fps_den / fps_num);
  5438  
  5439                  var codecArray = sps.subarray(1, 4);
  5440                  var codecString = 'avc1.';
  5441                  for (var j = 0; j < 3; j++) {
  5442                      var h = codecArray[j].toString(16);
  5443                      if (h.length < 2) {
  5444                          h = '0' + h;
  5445                      }
  5446                      codecString += h;
  5447                  }
  5448                  meta.codec = codecString;
  5449  
  5450                  var mi = this._mediaInfo;
  5451                  mi.width = meta.codecWidth;
  5452                  mi.height = meta.codecHeight;
  5453                  mi.fps = meta.frameRate.fps;
  5454                  mi.profile = meta.profile;
  5455                  mi.level = meta.level;
  5456                  mi.refFrames = config.ref_frames;
  5457                  mi.chromaFormat = config.chroma_format_string;
  5458                  mi.sarNum = meta.sarRatio.width;
  5459                  mi.sarDen = meta.sarRatio.height;
  5460                  mi.videoCodec = codecString;
  5461  
  5462                  if (mi.hasAudio) {
  5463                      if (mi.audioCodec != null) {
  5464                          mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';
  5465                      }
  5466                  } else {
  5467                      mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + '"';
  5468                  }
  5469                  if (mi.isComplete()) {
  5470                      this._onMediaInfo(mi);
  5471                  }
  5472              }
  5473  
  5474              var ppsCount = v.getUint8(offset); // numOfPictureParameterSets
  5475              if (ppsCount === 0) {
  5476                  this._onError(_demuxErrors2.default.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');
  5477                  return;
  5478              } else if (ppsCount > 1) {
  5479                  _logger2.default.w(this.TAG, 'Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ' + ppsCount);
  5480              }
  5481  
  5482              offset++;
  5483  
  5484              for (var _i = 0; _i < ppsCount; _i++) {
  5485                  var _len = v.getUint16(offset, !le); // pictureParameterSetLength
  5486                  offset += 2;
  5487  
  5488                  if (_len === 0) {
  5489                      continue;
  5490                  }
  5491  
  5492                  // pps is useless for extracting video information
  5493                  offset += _len;
  5494              }
  5495  
  5496              meta.avcc = new Uint8Array(dataSize);
  5497              meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);
  5498              _logger2.default.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');
  5499  
  5500              if (this._isInitialMetadataDispatched()) {
  5501                  // flush parsed frames
  5502                  if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {
  5503                      this._onDataAvailable(this._audioTrack, this._videoTrack);
  5504                  }
  5505              } else {
  5506                  this._videoInitialMetadataDispatched = true;
  5507              }
  5508              // notify new metadata
  5509              this._dispatch = false;
  5510              this._onTrackMetadata('video', meta);
  5511          }
  5512      }, {
  5513          key: '_parseAVCVideoData',
  5514          value: function _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {
  5515              var le = this._littleEndian;
  5516              var v = new DataView(arrayBuffer, dataOffset, dataSize);
  5517  
  5518              var units = [],
  5519                  length = 0;
  5520  
  5521              var offset = 0;
  5522              var lengthSize = this._naluLengthSize;
  5523              var dts = this._timestampBase + tagTimestamp;
  5524              var keyframe = frameType === 1; // from FLV Frame Type constants
  5525  
  5526              while (offset < dataSize) {
  5527                  if (offset + 4 >= dataSize) {
  5528                      _logger2.default.w(this.TAG, 'Malformed Nalu near timestamp ' + dts + ', offset = ' + offset + ', dataSize = ' + dataSize);
  5529                      break; // data not enough for next Nalu
  5530                  }
  5531                  // Nalu with length-header (AVC1)
  5532                  var naluSize = v.getUint32(offset, !le); // Big-Endian read
  5533                  if (lengthSize === 3) {
  5534                      naluSize >>>= 8;
  5535                  }
  5536                  if (naluSize > dataSize - lengthSize) {
  5537                      _logger2.default.w(this.TAG, 'Malformed Nalus near timestamp ' + dts + ', NaluSize > DataSize!');
  5538                      return;
  5539                  }
  5540  
  5541                  var unitType = v.getUint8(offset + lengthSize) & 0x1F;
  5542  
  5543                  if (unitType === 5) {
  5544                      // IDR
  5545                      keyframe = true;
  5546                  }
  5547  
  5548                  var data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);
  5549                  var unit = { type: unitType, data: data };
  5550                  units.push(unit);
  5551                  length += data.byteLength;
  5552  
  5553                  offset += lengthSize + naluSize;
  5554              }
  5555  
  5556              if (units.length) {
  5557                  var track = this._videoTrack;
  5558                  var avcSample = {
  5559                      units: units,
  5560                      length: length,
  5561                      isKeyframe: keyframe,
  5562                      dts: dts,
  5563                      cts: cts,
  5564                      pts: dts + cts
  5565                  };
  5566                  if (keyframe) {
  5567                      avcSample.fileposition = tagPosition;
  5568                  }
  5569                  track.samples.push(avcSample);
  5570                  track.length += length;
  5571              }
  5572          }
  5573      }, {
  5574          key: 'onTrackMetadata',
  5575          get: function get() {
  5576              return this._onTrackMetadata;
  5577          },
  5578          set: function set(callback) {
  5579              this._onTrackMetadata = callback;
  5580          }
  5581  
  5582          // prototype: function(mediaInfo: MediaInfo): void
  5583  
  5584      }, {
  5585          key: 'onMediaInfo',
  5586          get: function get() {
  5587              return this._onMediaInfo;
  5588          },
  5589          set: function set(callback) {
  5590              this._onMediaInfo = callback;
  5591          }
  5592      }, {
  5593          key: 'onMetaDataArrived',
  5594          get: function get() {
  5595              return this._onMetaDataArrived;
  5596          },
  5597          set: function set(callback) {
  5598              this._onMetaDataArrived = callback;
  5599          }
  5600      }, {
  5601          key: 'onScriptDataArrived',
  5602          get: function get() {
  5603              return this._onScriptDataArrived;
  5604          },
  5605          set: function set(callback) {
  5606              this._onScriptDataArrived = callback;
  5607          }
  5608  
  5609          // prototype: function(type: number, info: string): void
  5610  
  5611      }, {
  5612          key: 'onError',
  5613          get: function get() {
  5614              return this._onError;
  5615          },
  5616          set: function set(callback) {
  5617              this._onError = callback;
  5618          }
  5619  
  5620          // prototype: function(videoTrack: any, audioTrack: any): void
  5621  
  5622      }, {
  5623          key: 'onDataAvailable',
  5624          get: function get() {
  5625              return this._onDataAvailable;
  5626          },
  5627          set: function set(callback) {
  5628              this._onDataAvailable = callback;
  5629          }
  5630  
  5631          // timestamp base for output samples, must be in milliseconds
  5632  
  5633      }, {
  5634          key: 'timestampBase',
  5635          get: function get() {
  5636              return this._timestampBase;
  5637          },
  5638          set: function set(base) {
  5639              this._timestampBase = base;
  5640          }
  5641      }, {
  5642          key: 'overridedDuration',
  5643          get: function get() {
  5644              return this._duration;
  5645          }
  5646  
  5647          // Force-override media duration. Must be in milliseconds, int32
  5648          ,
  5649          set: function set(duration) {
  5650              this._durationOverrided = true;
  5651              this._duration = duration;
  5652              this._mediaInfo.duration = duration;
  5653          }
  5654  
  5655          // Force-override audio track present flag, boolean
  5656  
  5657      }, {
  5658          key: 'overridedHasAudio',
  5659          set: function set(hasAudio) {
  5660              this._hasAudioFlagOverrided = true;
  5661              this._hasAudio = hasAudio;
  5662              this._mediaInfo.hasAudio = hasAudio;
  5663          }
  5664  
  5665          // Force-override video track present flag, boolean
  5666  
  5667      }, {
  5668          key: 'overridedHasVideo',
  5669          set: function set(hasVideo) {
  5670              this._hasVideoFlagOverrided = true;
  5671              this._hasVideo = hasVideo;
  5672              this._mediaInfo.hasVideo = hasVideo;
  5673          }
  5674      }], [{
  5675          key: 'probe',
  5676          value: function probe(buffer) {
  5677              var data = new Uint8Array(buffer);
  5678              var mismatch = { match: false };
  5679  
  5680              if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {
  5681                  return mismatch;
  5682              }
  5683  
  5684              var hasAudio = (data[4] & 4) >>> 2 !== 0;
  5685              var hasVideo = (data[4] & 1) !== 0;
  5686  
  5687              var offset = ReadBig32(data, 5);
  5688  
  5689              if (offset < 9) {
  5690                  return mismatch;
  5691              }
  5692  
  5693              return {
  5694                  match: true,
  5695                  consumed: offset,
  5696                  dataOffset: offset,
  5697                  hasAudioTrack: hasAudio,
  5698                  hasVideoTrack: hasVideo
  5699              };
  5700          }
  5701      }]);
  5702  
  5703      return FLVDemuxer;
  5704  }();
  5705  
  5706  exports.default = FLVDemuxer;
  5707  
  5708  },{"../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){
  5709  'use strict';
  5710  
  5711  Object.defineProperty(exports, "__esModule", {
  5712      value: true
  5713  });
  5714  
  5715  var _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; }; }(); /*
  5716                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  5717                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  5718                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  5719                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  5720                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  5721                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  5722                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  5723                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  5724                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  5725                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  5726                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  5727                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  5728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5729                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  5730                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  5731                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  5732  
  5733  var _expGolomb = _dereq_('./exp-golomb.js');
  5734  
  5735  var _expGolomb2 = _interopRequireDefault(_expGolomb);
  5736  
  5737  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  5738  
  5739  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5740  
  5741  var SPSParser = function () {
  5742      function SPSParser() {
  5743          _classCallCheck(this, SPSParser);
  5744      }
  5745  
  5746      _createClass(SPSParser, null, [{
  5747          key: '_ebsp2rbsp',
  5748          value: function _ebsp2rbsp(uint8array) {
  5749              var src = uint8array;
  5750              var src_length = src.byteLength;
  5751              var dst = new Uint8Array(src_length);
  5752              var dst_idx = 0;
  5753  
  5754              for (var i = 0; i < src_length; i++) {
  5755                  if (i >= 2) {
  5756                      // Unescape: Skip 0x03 after 00 00
  5757                      if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
  5758                          continue;
  5759                      }
  5760                  }
  5761                  dst[dst_idx] = src[i];
  5762                  dst_idx++;
  5763              }
  5764  
  5765              return new Uint8Array(dst.buffer, 0, dst_idx);
  5766          }
  5767      }, {
  5768          key: 'parseSPS',
  5769          value: function parseSPS(uint8array) {
  5770              var rbsp = SPSParser._ebsp2rbsp(uint8array);
  5771              var gb = new _expGolomb2.default(rbsp);
  5772  
  5773              gb.readByte();
  5774              var profile_idc = gb.readByte(); // profile_idc
  5775              gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]
  5776              var level_idc = gb.readByte(); // level_idc
  5777              gb.readUEG(); // seq_parameter_set_id
  5778  
  5779              var profile_string = SPSParser.getProfileString(profile_idc);
  5780              var level_string = SPSParser.getLevelString(level_idc);
  5781              var chroma_format_idc = 1;
  5782              var chroma_format = 420;
  5783              var chroma_format_table = [0, 420, 422, 444];
  5784              var bit_depth = 8;
  5785  
  5786              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) {
  5787  
  5788                  chroma_format_idc = gb.readUEG();
  5789                  if (chroma_format_idc === 3) {
  5790                      gb.readBits(1); // separate_colour_plane_flag
  5791                  }
  5792                  if (chroma_format_idc <= 3) {
  5793                      chroma_format = chroma_format_table[chroma_format_idc];
  5794                  }
  5795  
  5796                  bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8
  5797                  gb.readUEG(); // bit_depth_chroma_minus8
  5798                  gb.readBits(1); // qpprime_y_zero_transform_bypass_flag
  5799                  if (gb.readBool()) {
  5800                      // seq_scaling_matrix_present_flag
  5801                      var scaling_list_count = chroma_format_idc !== 3 ? 8 : 12;
  5802                      for (var i = 0; i < scaling_list_count; i++) {
  5803                          if (gb.readBool()) {
  5804                              // seq_scaling_list_present_flag
  5805                              if (i < 6) {
  5806                                  SPSParser._skipScalingList(gb, 16);
  5807                              } else {
  5808                                  SPSParser._skipScalingList(gb, 64);
  5809                              }
  5810                          }
  5811                      }
  5812                  }
  5813              }
  5814              gb.readUEG(); // log2_max_frame_num_minus4
  5815              var pic_order_cnt_type = gb.readUEG();
  5816              if (pic_order_cnt_type === 0) {
  5817                  gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4
  5818              } else if (pic_order_cnt_type === 1) {
  5819                  gb.readBits(1); // delta_pic_order_always_zero_flag
  5820                  gb.readSEG(); // offset_for_non_ref_pic
  5821                  gb.readSEG(); // offset_for_top_to_bottom_field
  5822                  var num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();
  5823                  for (var _i = 0; _i < num_ref_frames_in_pic_order_cnt_cycle; _i++) {
  5824                      gb.readSEG(); // offset_for_ref_frame
  5825                  }
  5826              }
  5827              var ref_frames = gb.readUEG(); // max_num_ref_frames
  5828              gb.readBits(1); // gaps_in_frame_num_value_allowed_flag
  5829  
  5830              var pic_width_in_mbs_minus1 = gb.readUEG();
  5831              var pic_height_in_map_units_minus1 = gb.readUEG();
  5832  
  5833              var frame_mbs_only_flag = gb.readBits(1);
  5834              if (frame_mbs_only_flag === 0) {
  5835                  gb.readBits(1); // mb_adaptive_frame_field_flag
  5836              }
  5837              gb.readBits(1); // direct_8x8_inference_flag
  5838  
  5839              var frame_crop_left_offset = 0;
  5840              var frame_crop_right_offset = 0;
  5841              var frame_crop_top_offset = 0;
  5842              var frame_crop_bottom_offset = 0;
  5843  
  5844              var frame_cropping_flag = gb.readBool();
  5845              if (frame_cropping_flag) {
  5846                  frame_crop_left_offset = gb.readUEG();
  5847                  frame_crop_right_offset = gb.readUEG();
  5848                  frame_crop_top_offset = gb.readUEG();
  5849                  frame_crop_bottom_offset = gb.readUEG();
  5850              }
  5851  
  5852              var sar_width = 1,
  5853                  sar_height = 1;
  5854              var fps = 0,
  5855                  fps_fixed = true,
  5856                  fps_num = 0,
  5857                  fps_den = 0;
  5858  
  5859              var vui_parameters_present_flag = gb.readBool();
  5860              if (vui_parameters_present_flag) {
  5861                  if (gb.readBool()) {
  5862                      // aspect_ratio_info_present_flag
  5863                      var aspect_ratio_idc = gb.readByte();
  5864                      var sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
  5865                      var sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
  5866  
  5867                      if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
  5868                          sar_width = sar_w_table[aspect_ratio_idc - 1];
  5869                          sar_height = sar_h_table[aspect_ratio_idc - 1];
  5870                      } else if (aspect_ratio_idc === 255) {
  5871                          sar_width = gb.readByte() << 8 | gb.readByte();
  5872                          sar_height = gb.readByte() << 8 | gb.readByte();
  5873                      }
  5874                  }
  5875  
  5876                  if (gb.readBool()) {
  5877                      // overscan_info_present_flag
  5878                      gb.readBool(); // overscan_appropriate_flag
  5879                  }
  5880                  if (gb.readBool()) {
  5881                      // video_signal_type_present_flag
  5882                      gb.readBits(4); // video_format & video_full_range_flag
  5883                      if (gb.readBool()) {
  5884                          // colour_description_present_flag
  5885                          gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients
  5886                      }
  5887                  }
  5888                  if (gb.readBool()) {
  5889                      // chroma_loc_info_present_flag
  5890                      gb.readUEG(); // chroma_sample_loc_type_top_field
  5891                      gb.readUEG(); // chroma_sample_loc_type_bottom_field
  5892                  }
  5893                  if (gb.readBool()) {
  5894                      // timing_info_present_flag
  5895                      var num_units_in_tick = gb.readBits(32);
  5896                      var time_scale = gb.readBits(32);
  5897                      fps_fixed = gb.readBool(); // fixed_frame_rate_flag
  5898  
  5899                      fps_num = time_scale;
  5900                      fps_den = num_units_in_tick * 2;
  5901                      fps = fps_num / fps_den;
  5902                  }
  5903              }
  5904  
  5905              var sarScale = 1;
  5906              if (sar_width !== 1 || sar_height !== 1) {
  5907                  sarScale = sar_width / sar_height;
  5908              }
  5909  
  5910              var crop_unit_x = 0,
  5911                  crop_unit_y = 0;
  5912              if (chroma_format_idc === 0) {
  5913                  crop_unit_x = 1;
  5914                  crop_unit_y = 2 - frame_mbs_only_flag;
  5915              } else {
  5916                  var sub_wc = chroma_format_idc === 3 ? 1 : 2;
  5917                  var sub_hc = chroma_format_idc === 1 ? 2 : 1;
  5918                  crop_unit_x = sub_wc;
  5919                  crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);
  5920              }
  5921  
  5922              var codec_width = (pic_width_in_mbs_minus1 + 1) * 16;
  5923              var codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);
  5924  
  5925              codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;
  5926              codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;
  5927  
  5928              var present_width = Math.ceil(codec_width * sarScale);
  5929  
  5930              gb.destroy();
  5931              gb = null;
  5932  
  5933              return {
  5934                  profile_string: profile_string, // baseline, high, high10, ...
  5935                  level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...
  5936                  bit_depth: bit_depth, // 8bit, 10bit, ...
  5937                  ref_frames: ref_frames,
  5938                  chroma_format: chroma_format, // 4:2:0, 4:2:2, ...
  5939                  chroma_format_string: SPSParser.getChromaFormatString(chroma_format),
  5940  
  5941                  frame_rate: {
  5942                      fixed: fps_fixed,
  5943                      fps: fps,
  5944                      fps_den: fps_den,
  5945                      fps_num: fps_num
  5946                  },
  5947  
  5948                  sar_ratio: {
  5949                      width: sar_width,
  5950                      height: sar_height
  5951                  },
  5952  
  5953                  codec_size: {
  5954                      width: codec_width,
  5955                      height: codec_height
  5956                  },
  5957  
  5958                  present_size: {
  5959                      width: present_width,
  5960                      height: codec_height
  5961                  }
  5962              };
  5963          }
  5964      }, {
  5965          key: '_skipScalingList',
  5966          value: function _skipScalingList(gb, count) {
  5967              var last_scale = 8,
  5968                  next_scale = 8;
  5969              var delta_scale = 0;
  5970              for (var i = 0; i < count; i++) {
  5971                  if (next_scale !== 0) {
  5972                      delta_scale = gb.readSEG();
  5973                      next_scale = (last_scale + delta_scale + 256) % 256;
  5974                  }
  5975                  last_scale = next_scale === 0 ? last_scale : next_scale;
  5976              }
  5977          }
  5978      }, {
  5979          key: 'getProfileString',
  5980          value: function getProfileString(profile_idc) {
  5981              switch (profile_idc) {
  5982                  case 66:
  5983                      return 'Baseline';
  5984                  case 77:
  5985                      return 'Main';
  5986                  case 88:
  5987                      return 'Extended';
  5988                  case 100:
  5989                      return 'High';
  5990                  case 110:
  5991                      return 'High10';
  5992                  case 122:
  5993                      return 'High422';
  5994                  case 244:
  5995                      return 'High444';
  5996                  default:
  5997                      return 'Unknown';
  5998              }
  5999          }
  6000      }, {
  6001          key: 'getLevelString',
  6002          value: function getLevelString(level_idc) {
  6003              return (level_idc / 10).toFixed(1);
  6004          }
  6005      }, {
  6006          key: 'getChromaFormatString',
  6007          value: function getChromaFormatString(chroma) {
  6008              switch (chroma) {
  6009                  case 420:
  6010                      return '4:2:0';
  6011                  case 422:
  6012                      return '4:2:2';
  6013                  case 444:
  6014                      return '4:4:4';
  6015                  default:
  6016                      return 'Unknown';
  6017              }
  6018          }
  6019      }]);
  6020  
  6021      return SPSParser;
  6022  }();
  6023  
  6024  exports.default = SPSParser;
  6025  
  6026  },{"./exp-golomb.js":17}],20:[function(_dereq_,module,exports){
  6027  'use strict';
  6028  
  6029  Object.defineProperty(exports, "__esModule", {
  6030      value: true
  6031  });
  6032  
  6033  var _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; }; /*
  6034                                                                                                                                                                                                                                                                                 * Copyright (C) 2016 Bilibili. All Rights Reserved.
  6035                                                                                                                                                                                                                                                                                 *
  6036                                                                                                                                                                                                                                                                                 * @author zheng qian <xqq@xqq.im>
  6037                                                                                                                                                                                                                                                                                 *
  6038                                                                                                                                                                                                                                                                                 * Licensed under the Apache License, Version 2.0 (the "License");
  6039                                                                                                                                                                                                                                                                                 * you may not use this file except in compliance with the License.
  6040                                                                                                                                                                                                                                                                                 * You may obtain a copy of the License at
  6041                                                                                                                                                                                                                                                                                 *
  6042                                                                                                                                                                                                                                                                                 *     http://www.apache.org/licenses/LICENSE-2.0
  6043                                                                                                                                                                                                                                                                                 *
  6044                                                                                                                                                                                                                                                                                 * Unless required by applicable law or agreed to in writing, software
  6045                                                                                                                                                                                                                                                                                 * distributed under the License is distributed on an "AS IS" BASIS,
  6046                                                                                                                                                                                                                                                                                 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6047                                                                                                                                                                                                                                                                                 * See the License for the specific language governing permissions and
  6048                                                                                                                                                                                                                                                                                 * limitations under the License.
  6049                                                                                                                                                                                                                                                                                 */
  6050  
  6051  var _polyfill = _dereq_('./utils/polyfill.js');
  6052  
  6053  var _polyfill2 = _interopRequireDefault(_polyfill);
  6054  
  6055  var _features = _dereq_('./core/features.js');
  6056  
  6057  var _features2 = _interopRequireDefault(_features);
  6058  
  6059  var _loader = _dereq_('./io/loader.js');
  6060  
  6061  var _flvPlayer = _dereq_('./player/flv-player.js');
  6062  
  6063  var _flvPlayer2 = _interopRequireDefault(_flvPlayer);
  6064  
  6065  var _nativePlayer = _dereq_('./player/native-player.js');
  6066  
  6067  var _nativePlayer2 = _interopRequireDefault(_nativePlayer);
  6068  
  6069  var _playerEvents = _dereq_('./player/player-events.js');
  6070  
  6071  var _playerEvents2 = _interopRequireDefault(_playerEvents);
  6072  
  6073  var _playerErrors = _dereq_('./player/player-errors.js');
  6074  
  6075  var _loggingControl = _dereq_('./utils/logging-control.js');
  6076  
  6077  var _loggingControl2 = _interopRequireDefault(_loggingControl);
  6078  
  6079  var _exception = _dereq_('./utils/exception.js');
  6080  
  6081  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  6082  
  6083  // here are all the interfaces
  6084  
  6085  // install polyfills
  6086  _polyfill2.default.install();
  6087  
  6088  // factory method
  6089  function createPlayer(mediaDataSource, optionalConfig) {
  6090      var mds = mediaDataSource;
  6091      if (mds == null || (typeof mds === 'undefined' ? 'undefined' : _typeof(mds)) !== 'object') {
  6092          throw new _exception.InvalidArgumentException('MediaDataSource must be an javascript object!');
  6093      }
  6094  
  6095      if (!mds.hasOwnProperty('type')) {
  6096          throw new _exception.InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');
  6097      }
  6098  
  6099      switch (mds.type) {
  6100          case 'flv':
  6101              return new _flvPlayer2.default(mds, optionalConfig);
  6102          default:
  6103              return new _nativePlayer2.default(mds, optionalConfig);
  6104      }
  6105  }
  6106  
  6107  // feature detection
  6108  function isSupported() {
  6109      return _features2.default.supportMSEH264Playback();
  6110  }
  6111  
  6112  function getFeatureList() {
  6113      return _features2.default.getFeatureList();
  6114  }
  6115  
  6116  // interfaces
  6117  var flvjs = {};
  6118  
  6119  flvjs.createPlayer = createPlayer;
  6120  flvjs.isSupported = isSupported;
  6121  flvjs.getFeatureList = getFeatureList;
  6122  
  6123  flvjs.BaseLoader = _loader.BaseLoader;
  6124  flvjs.LoaderStatus = _loader.LoaderStatus;
  6125  flvjs.LoaderErrors = _loader.LoaderErrors;
  6126  
  6127  flvjs.Events = _playerEvents2.default;
  6128  flvjs.ErrorTypes = _playerErrors.ErrorTypes;
  6129  flvjs.ErrorDetails = _playerErrors.ErrorDetails;
  6130  
  6131  flvjs.FlvPlayer = _flvPlayer2.default;
  6132  flvjs.NativePlayer = _nativePlayer2.default;
  6133  flvjs.LoggingControl = _loggingControl2.default;
  6134  
  6135  Object.defineProperty(flvjs, 'version', {
  6136      enumerable: true,
  6137      get: function get() {
  6138          // replaced by browserify-versionify transform
  6139          return '1.5.0';
  6140      }
  6141  });
  6142  
  6143  exports.default = flvjs;
  6144  
  6145  },{"./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){
  6146  'use strict';
  6147  
  6148  // entry/index file
  6149  
  6150  // make it compatible with browserify's umd wrapper
  6151  module.exports = _dereq_('./flv.js').default;
  6152  
  6153  },{"./flv.js":20}],22:[function(_dereq_,module,exports){
  6154  'use strict';
  6155  
  6156  Object.defineProperty(exports, "__esModule", {
  6157      value: true
  6158  });
  6159  
  6160  var _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; };
  6161  
  6162  var _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); } };
  6163  
  6164  var _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; }; }();
  6165  
  6166  var _logger = _dereq_('../utils/logger.js');
  6167  
  6168  var _logger2 = _interopRequireDefault(_logger);
  6169  
  6170  var _browser = _dereq_('../utils/browser.js');
  6171  
  6172  var _browser2 = _interopRequireDefault(_browser);
  6173  
  6174  var _loader = _dereq_('./loader.js');
  6175  
  6176  var _exception = _dereq_('../utils/exception.js');
  6177  
  6178  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  6179  
  6180  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6181  
  6182  function _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; }
  6183  
  6184  function _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; } /*
  6185                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (C) 2016 Bilibili. All Rights Reserved.
  6186                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  6187                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @author zheng qian <xqq@xqq.im>
  6188                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  6189                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Licensed under the Apache License, Version 2.0 (the "License");
  6190                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * you may not use this file except in compliance with the License.
  6191                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * You may obtain a copy of the License at
  6192                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  6193                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *     http://www.apache.org/licenses/LICENSE-2.0
  6194                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  6195                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Unless required by applicable law or agreed to in writing, software
  6196                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * distributed under the License is distributed on an "AS IS" BASIS,
  6197                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6198                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * See the License for the specific language governing permissions and
  6199                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * limitations under the License.
  6200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  6201  
  6202  /* fetch + stream IO loader. Currently working on chrome 43+.
  6203   * fetch provides a better alternative http API to XMLHttpRequest
  6204   *
  6205   * fetch spec   https://fetch.spec.whatwg.org/
  6206   * stream spec  https://streams.spec.whatwg.org/
  6207   */
  6208  var FetchStreamLoader = function (_BaseLoader) {
  6209      _inherits(FetchStreamLoader, _BaseLoader);
  6210  
  6211      _createClass(FetchStreamLoader, null, [{
  6212          key: 'isSupported',
  6213          value: function isSupported() {
  6214              try {
  6215                  // fetch + stream is broken on Microsoft Edge. Disable before build 15048.
  6216                  // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/
  6217                  // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.
  6218                  var isWorkWellEdge = _browser2.default.msedge && _browser2.default.version.minor >= 15048;
  6219                  var browserNotBlacklisted = _browser2.default.msedge ? isWorkWellEdge : true;
  6220                  return self.fetch && self.ReadableStream && browserNotBlacklisted;
  6221              } catch (e) {
  6222                  return false;
  6223              }
  6224          }
  6225      }]);
  6226  
  6227      function FetchStreamLoader(seekHandler, config) {
  6228          _classCallCheck(this, FetchStreamLoader);
  6229  
  6230          var _this = _possibleConstructorReturn(this, (FetchStreamLoader.__proto__ || Object.getPrototypeOf(FetchStreamLoader)).call(this, 'fetch-stream-loader'));
  6231  
  6232          _this.TAG = 'FetchStreamLoader';
  6233  
  6234          _this._seekHandler = seekHandler;
  6235          _this._config = config;
  6236          _this._needStash = true;
  6237  
  6238          _this._requestAbort = false;
  6239          _this._contentLength = null;
  6240          _this._receivedLength = 0;
  6241          return _this;
  6242      }
  6243  
  6244      _createClass(FetchStreamLoader, [{
  6245          key: 'destroy',
  6246          value: function destroy() {
  6247              if (this.isWorking()) {
  6248                  this.abort();
  6249              }
  6250              _get(FetchStreamLoader.prototype.__proto__ || Object.getPrototypeOf(FetchStreamLoader.prototype), 'destroy', this).call(this);
  6251          }
  6252      }, {
  6253          key: 'open',
  6254          value: function open(dataSource, range) {
  6255              var _this2 = this;
  6256  
  6257              this._dataSource = dataSource;
  6258              this._range = range;
  6259  
  6260              var sourceURL = dataSource.url;
  6261              if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {
  6262                  sourceURL = dataSource.redirectedURL;
  6263              }
  6264  
  6265              var seekConfig = this._seekHandler.getConfig(sourceURL, range);
  6266  
  6267              var headers = new self.Headers();
  6268  
  6269              if (_typeof(seekConfig.headers) === 'object') {
  6270                  var configHeaders = seekConfig.headers;
  6271                  for (var key in configHeaders) {
  6272                      if (configHeaders.hasOwnProperty(key)) {
  6273                          headers.append(key, configHeaders[key]);
  6274                      }
  6275                  }
  6276              }
  6277  
  6278              var params = {
  6279                  method: 'GET',
  6280                  headers: headers,
  6281                  mode: 'cors',
  6282                  cache: 'default',
  6283                  // The default policy of Fetch API in the whatwg standard
  6284                  // Safari incorrectly indicates 'no-referrer' as default policy, fuck it
  6285                  referrerPolicy: 'no-referrer-when-downgrade'
  6286              };
  6287  
  6288              // add additional headers
  6289              if (_typeof(this._config.headers) === 'object') {
  6290                  for (var _key in this._config.headers) {
  6291                      headers.append(_key, this._config.headers[_key]);
  6292                  }
  6293              }
  6294  
  6295              // cors is enabled by default
  6296              if (dataSource.cors === false) {
  6297                  // no-cors means 'disregard cors policy', which can only be used in ServiceWorker
  6298                  params.mode = 'same-origin';
  6299              }
  6300  
  6301              // withCredentials is disabled by default
  6302              if (dataSource.withCredentials) {
  6303                  params.credentials = 'include';
  6304              }
  6305  
  6306              // referrerPolicy from config
  6307              if (dataSource.referrerPolicy) {
  6308                  params.referrerPolicy = dataSource.referrerPolicy;
  6309              }
  6310  
  6311              this._status = _loader.LoaderStatus.kConnecting;
  6312              self.fetch(seekConfig.url, params).then(function (res) {
  6313                  if (_this2._requestAbort) {
  6314                      _this2._requestAbort = false;
  6315                      _this2._status = _loader.LoaderStatus.kIdle;
  6316                      return;
  6317                  }
  6318                  if (res.ok && res.status >= 200 && res.status <= 299) {
  6319                      if (res.url !== seekConfig.url) {
  6320                          if (_this2._onURLRedirect) {
  6321                              var redirectedURL = _this2._seekHandler.removeURLParameters(res.url);
  6322                              _this2._onURLRedirect(redirectedURL);
  6323                          }
  6324                      }
  6325  
  6326                      var lengthHeader = res.headers.get('Content-Length');
  6327                      if (lengthHeader != null) {
  6328                          _this2._contentLength = parseInt(lengthHeader);
  6329                          if (_this2._contentLength !== 0) {
  6330                              if (_this2._onContentLengthKnown) {
  6331                                  _this2._onContentLengthKnown(_this2._contentLength);
  6332                              }
  6333                          }
  6334                      }
  6335  
  6336                      return _this2._pump.call(_this2, res.body.getReader());
  6337                  } else {
  6338                      _this2._status = _loader.LoaderStatus.kError;
  6339                      if (_this2._onError) {
  6340                          _this2._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: res.status, msg: res.statusText });
  6341                      } else {
  6342                          throw new _exception.RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);
  6343                      }
  6344                  }
  6345              }).catch(function (e) {
  6346                  _this2._status = _loader.LoaderStatus.kError;
  6347                  if (_this2._onError) {
  6348                      _this2._onError(_loader.LoaderErrors.EXCEPTION, { code: -1, msg: e.message });
  6349                  } else {
  6350                      throw e;
  6351                  }
  6352              });
  6353          }
  6354      }, {
  6355          key: 'abort',
  6356          value: function abort() {
  6357              this._requestAbort = true;
  6358          }
  6359      }, {
  6360          key: '_pump',
  6361          value: function _pump(reader) {
  6362              var _this3 = this;
  6363  
  6364              // ReadableStreamReader
  6365              return reader.read().then(function (result) {
  6366                  if (result.done) {
  6367                      // First check received length
  6368                      if (_this3._contentLength !== null && _this3._receivedLength < _this3._contentLength) {
  6369                          // Report Early-EOF
  6370                          _this3._status = _loader.LoaderStatus.kError;
  6371                          var type = _loader.LoaderErrors.EARLY_EOF;
  6372                          var info = { code: -1, msg: 'Fetch stream meet Early-EOF' };
  6373                          if (_this3._onError) {
  6374                              _this3._onError(type, info);
  6375                          } else {
  6376                              throw new _exception.RuntimeException(info.msg);
  6377                          }
  6378                      } else {
  6379                          // OK. Download complete
  6380                          _this3._status = _loader.LoaderStatus.kComplete;
  6381                          if (_this3._onComplete) {
  6382                              _this3._onComplete(_this3._range.from, _this3._range.from + _this3._receivedLength - 1);
  6383                          }
  6384                      }
  6385                  } else {
  6386                      if (_this3._requestAbort === true) {
  6387                          _this3._requestAbort = false;
  6388                          _this3._status = _loader.LoaderStatus.kComplete;
  6389                          return reader.cancel();
  6390                      }
  6391  
  6392                      _this3._status = _loader.LoaderStatus.kBuffering;
  6393  
  6394                      var chunk = result.value.buffer;
  6395                      var byteStart = _this3._range.from + _this3._receivedLength;
  6396                      _this3._receivedLength += chunk.byteLength;
  6397  
  6398                      if (_this3._onDataArrival) {
  6399                          _this3._onDataArrival(chunk, byteStart, _this3._receivedLength);
  6400                      }
  6401  
  6402                      _this3._pump(reader);
  6403                  }
  6404              }).catch(function (e) {
  6405                  if (e.code === 11 && _browser2.default.msedge) {
  6406                      // InvalidStateError on Microsoft Edge
  6407                      // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call
  6408                      // Ignore the unknown exception.
  6409                      // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/
  6410                      return;
  6411                  }
  6412  
  6413                  _this3._status = _loader.LoaderStatus.kError;
  6414                  var type = 0;
  6415                  var info = null;
  6416  
  6417                  if ((e.code === 19 || e.message === 'network error') && ( // NETWORK_ERR
  6418                  _this3._contentLength === null || _this3._contentLength !== null && _this3._receivedLength < _this3._contentLength)) {
  6419                      type = _loader.LoaderErrors.EARLY_EOF;
  6420                      info = { code: e.code, msg: 'Fetch stream meet Early-EOF' };
  6421                  } else {
  6422                      type = _loader.LoaderErrors.EXCEPTION;
  6423                      info = { code: e.code, msg: e.message };
  6424                  }
  6425  
  6426                  if (_this3._onError) {
  6427                      _this3._onError(type, info);
  6428                  } else {
  6429                      throw new _exception.RuntimeException(info.msg);
  6430                  }
  6431              });
  6432          }
  6433      }]);
  6434  
  6435      return FetchStreamLoader;
  6436  }(_loader.BaseLoader);
  6437  
  6438  exports.default = FetchStreamLoader;
  6439  
  6440  },{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],23:[function(_dereq_,module,exports){
  6441  'use strict';
  6442  
  6443  Object.defineProperty(exports, "__esModule", {
  6444      value: true
  6445  });
  6446  
  6447  var _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; }; }(); /*
  6448                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  6449                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  6450                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  6451                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  6452                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  6453                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  6454                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  6455                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  6456                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  6457                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  6458                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  6459                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  6460                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6461                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  6462                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  6463                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  6464  
  6465  var _logger = _dereq_('../utils/logger.js');
  6466  
  6467  var _logger2 = _interopRequireDefault(_logger);
  6468  
  6469  var _speedSampler = _dereq_('./speed-sampler.js');
  6470  
  6471  var _speedSampler2 = _interopRequireDefault(_speedSampler);
  6472  
  6473  var _loader = _dereq_('./loader.js');
  6474  
  6475  var _fetchStreamLoader = _dereq_('./fetch-stream-loader.js');
  6476  
  6477  var _fetchStreamLoader2 = _interopRequireDefault(_fetchStreamLoader);
  6478  
  6479  var _xhrMozChunkedLoader = _dereq_('./xhr-moz-chunked-loader.js');
  6480  
  6481  var _xhrMozChunkedLoader2 = _interopRequireDefault(_xhrMozChunkedLoader);
  6482  
  6483  var _xhrMsstreamLoader = _dereq_('./xhr-msstream-loader.js');
  6484  
  6485  var _xhrMsstreamLoader2 = _interopRequireDefault(_xhrMsstreamLoader);
  6486  
  6487  var _xhrRangeLoader = _dereq_('./xhr-range-loader.js');
  6488  
  6489  var _xhrRangeLoader2 = _interopRequireDefault(_xhrRangeLoader);
  6490  
  6491  var _websocketLoader = _dereq_('./websocket-loader.js');
  6492  
  6493  var _websocketLoader2 = _interopRequireDefault(_websocketLoader);
  6494  
  6495  var _rangeSeekHandler = _dereq_('./range-seek-handler.js');
  6496  
  6497  var _rangeSeekHandler2 = _interopRequireDefault(_rangeSeekHandler);
  6498  
  6499  var _paramSeekHandler = _dereq_('./param-seek-handler.js');
  6500  
  6501  var _paramSeekHandler2 = _interopRequireDefault(_paramSeekHandler);
  6502  
  6503  var _exception = _dereq_('../utils/exception.js');
  6504  
  6505  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  6506  
  6507  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6508  
  6509  /**
  6510   * DataSource: {
  6511   *     url: string,
  6512   *     filesize: number,
  6513   *     cors: boolean,
  6514   *     withCredentials: boolean
  6515   * }
  6516   * 
  6517   */
  6518  
  6519  // Manage IO Loaders
  6520  var IOController = function () {
  6521      function IOController(dataSource, config, extraData) {
  6522          _classCallCheck(this, IOController);
  6523  
  6524          this.TAG = 'IOController';
  6525  
  6526          this._config = config;
  6527          this._extraData = extraData;
  6528  
  6529          this._stashInitialSize = 1024 * 384; // default initial size: 384KB
  6530          if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {
  6531              // apply from config
  6532              this._stashInitialSize = config.stashInitialSize;
  6533          }
  6534  
  6535          this._stashUsed = 0;
  6536          this._stashSize = this._stashInitialSize;
  6537          this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB
  6538          this._stashBuffer = new ArrayBuffer(this._bufferSize);
  6539          this._stashByteStart = 0;
  6540          this._enableStash = true;
  6541          if (config.enableStashBuffer === false) {
  6542              this._enableStash = false;
  6543          }
  6544  
  6545          this._loader = null;
  6546          this._loaderClass = null;
  6547          this._seekHandler = null;
  6548  
  6549          this._dataSource = dataSource;
  6550          this._isWebSocketURL = /wss?:\/\/(.+?)/.test(dataSource.url);
  6551          this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;
  6552          this._totalLength = this._refTotalLength;
  6553          this._fullRequestFlag = false;
  6554          this._currentRange = null;
  6555          this._redirectedURL = null;
  6556  
  6557          this._speedNormalized = 0;
  6558          this._speedSampler = new _speedSampler2.default();
  6559          this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];
  6560  
  6561          this._isEarlyEofReconnecting = false;
  6562  
  6563          this._paused = false;
  6564          this._resumeFrom = 0;
  6565  
  6566          this._onDataArrival = null;
  6567          this._onSeeked = null;
  6568          this._onError = null;
  6569          this._onComplete = null;
  6570          this._onRedirect = null;
  6571          this._onRecoveredEarlyEof = null;
  6572  
  6573          this._selectSeekHandler();
  6574          this._selectLoader();
  6575          this._createLoader();
  6576      }
  6577  
  6578      _createClass(IOController, [{
  6579          key: 'destroy',
  6580          value: function destroy() {
  6581              if (this._loader.isWorking()) {
  6582                  this._loader.abort();
  6583              }
  6584              this._loader.destroy();
  6585              this._loader = null;
  6586              this._loaderClass = null;
  6587              this._dataSource = null;
  6588              this._stashBuffer = null;
  6589              this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;
  6590              this._currentRange = null;
  6591              this._speedSampler = null;
  6592  
  6593              this._isEarlyEofReconnecting = false;
  6594  
  6595              this._onDataArrival = null;
  6596              this._onSeeked = null;
  6597              this._onError = null;
  6598              this._onComplete = null;
  6599              this._onRedirect = null;
  6600              this._onRecoveredEarlyEof = null;
  6601  
  6602              this._extraData = null;
  6603          }
  6604      }, {
  6605          key: 'isWorking',
  6606          value: function isWorking() {
  6607              return this._loader && this._loader.isWorking() && !this._paused;
  6608          }
  6609      }, {
  6610          key: 'isPaused',
  6611          value: function isPaused() {
  6612              return this._paused;
  6613          }
  6614      }, {
  6615          key: '_selectSeekHandler',
  6616          value: function _selectSeekHandler() {
  6617              var config = this._config;
  6618  
  6619              if (config.seekType === 'range') {
  6620                  this._seekHandler = new _rangeSeekHandler2.default(this._config.rangeLoadZeroStart);
  6621              } else if (config.seekType === 'param') {
  6622                  var paramStart = config.seekParamStart || 'bstart';
  6623                  var paramEnd = config.seekParamEnd || 'bend';
  6624  
  6625                  this._seekHandler = new _paramSeekHandler2.default(paramStart, paramEnd);
  6626              } else if (config.seekType === 'custom') {
  6627                  if (typeof config.customSeekHandler !== 'function') {
  6628                      throw new _exception.InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');
  6629                  }
  6630                  this._seekHandler = new config.customSeekHandler();
  6631              } else {
  6632                  throw new _exception.InvalidArgumentException('Invalid seekType in config: ' + config.seekType);
  6633              }
  6634          }
  6635      }, {
  6636          key: '_selectLoader',
  6637          value: function _selectLoader() {
  6638              if (this._config.customLoader != null) {
  6639                  this._loaderClass = this._config.customLoader;
  6640              } else if (this._isWebSocketURL) {
  6641                  this._loaderClass = _websocketLoader2.default;
  6642              } else if (_fetchStreamLoader2.default.isSupported()) {
  6643                  this._loaderClass = _fetchStreamLoader2.default;
  6644              } else if (_xhrMozChunkedLoader2.default.isSupported()) {
  6645                  this._loaderClass = _xhrMozChunkedLoader2.default;
  6646              } else if (_xhrRangeLoader2.default.isSupported()) {
  6647                  this._loaderClass = _xhrRangeLoader2.default;
  6648              } else {
  6649                  throw new _exception.RuntimeException('Your browser doesn\'t support xhr with arraybuffer responseType!');
  6650              }
  6651          }
  6652      }, {
  6653          key: '_createLoader',
  6654          value: function _createLoader() {
  6655              this._loader = new this._loaderClass(this._seekHandler, this._config);
  6656              if (this._loader.needStashBuffer === false) {
  6657                  this._enableStash = false;
  6658              }
  6659              this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);
  6660              this._loader.onURLRedirect = this._onURLRedirect.bind(this);
  6661              this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);
  6662              this._loader.onComplete = this._onLoaderComplete.bind(this);
  6663              this._loader.onError = this._onLoaderError.bind(this);
  6664          }
  6665      }, {
  6666          key: 'open',
  6667          value: function open(optionalFrom) {
  6668              this._currentRange = { from: 0, to: -1 };
  6669              if (optionalFrom) {
  6670                  this._currentRange.from = optionalFrom;
  6671              }
  6672  
  6673              this._speedSampler.reset();
  6674              if (!optionalFrom) {
  6675                  this._fullRequestFlag = true;
  6676              }
  6677  
  6678              this._loader.open(this._dataSource, Object.assign({}, this._currentRange));
  6679          }
  6680      }, {
  6681          key: 'abort',
  6682          value: function abort() {
  6683              this._loader.abort();
  6684  
  6685              if (this._paused) {
  6686                  this._paused = false;
  6687                  this._resumeFrom = 0;
  6688              }
  6689          }
  6690      }, {
  6691          key: 'pause',
  6692          value: function pause() {
  6693              if (this.isWorking()) {
  6694                  this._loader.abort();
  6695  
  6696                  if (this._stashUsed !== 0) {
  6697                      this._resumeFrom = this._stashByteStart;
  6698                      this._currentRange.to = this._stashByteStart - 1;
  6699                  } else {
  6700                      this._resumeFrom = this._currentRange.to + 1;
  6701                  }
  6702                  this._stashUsed = 0;
  6703                  this._stashByteStart = 0;
  6704                  this._paused = true;
  6705              }
  6706          }
  6707      }, {
  6708          key: 'resume',
  6709          value: function resume() {
  6710              if (this._paused) {
  6711                  this._paused = false;
  6712                  var bytes = this._resumeFrom;
  6713                  this._resumeFrom = 0;
  6714                  this._internalSeek(bytes, true);
  6715              }
  6716          }
  6717      }, {
  6718          key: 'seek',
  6719          value: function seek(bytes) {
  6720              this._paused = false;
  6721              this._stashUsed = 0;
  6722              this._stashByteStart = 0;
  6723              this._internalSeek(bytes, true);
  6724          }
  6725  
  6726          /**
  6727           * When seeking request is from media seeking, unconsumed stash data should be dropped
  6728           * However, stash data shouldn't be dropped if seeking requested from http reconnection
  6729           *
  6730           * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer
  6731           */
  6732  
  6733      }, {
  6734          key: '_internalSeek',
  6735          value: function _internalSeek(bytes, dropUnconsumed) {
  6736              if (this._loader.isWorking()) {
  6737                  this._loader.abort();
  6738              }
  6739  
  6740              // dispatch & flush stash buffer before seek
  6741              this._flushStashBuffer(dropUnconsumed);
  6742  
  6743              this._loader.destroy();
  6744              this._loader = null;
  6745  
  6746              var requestRange = { from: bytes, to: -1 };
  6747              this._currentRange = { from: requestRange.from, to: -1 };
  6748  
  6749              this._speedSampler.reset();
  6750              this._stashSize = this._stashInitialSize;
  6751              this._createLoader();
  6752              this._loader.open(this._dataSource, requestRange);
  6753  
  6754              if (this._onSeeked) {
  6755                  this._onSeeked();
  6756              }
  6757          }
  6758      }, {
  6759          key: 'updateUrl',
  6760          value: function updateUrl(url) {
  6761              if (!url || typeof url !== 'string' || url.length === 0) {
  6762                  throw new _exception.InvalidArgumentException('Url must be a non-empty string!');
  6763              }
  6764  
  6765              this._dataSource.url = url;
  6766  
  6767              // TODO: replace with new url
  6768          }
  6769      }, {
  6770          key: '_expandBuffer',
  6771          value: function _expandBuffer(expectedBytes) {
  6772              var bufferNewSize = this._stashSize;
  6773              while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {
  6774                  bufferNewSize *= 2;
  6775              }
  6776  
  6777              bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB
  6778              if (bufferNewSize === this._bufferSize) {
  6779                  return;
  6780              }
  6781  
  6782              var newBuffer = new ArrayBuffer(bufferNewSize);
  6783  
  6784              if (this._stashUsed > 0) {
  6785                  // copy existing data into new buffer
  6786                  var stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);
  6787                  var stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);
  6788                  stashNewArray.set(stashOldArray, 0);
  6789              }
  6790  
  6791              this._stashBuffer = newBuffer;
  6792              this._bufferSize = bufferNewSize;
  6793          }
  6794      }, {
  6795          key: '_normalizeSpeed',
  6796          value: function _normalizeSpeed(input) {
  6797              var list = this._speedNormalizeList;
  6798              var last = list.length - 1;
  6799              var mid = 0;
  6800              var lbound = 0;
  6801              var ubound = last;
  6802  
  6803              if (input < list[0]) {
  6804                  return list[0];
  6805              }
  6806  
  6807              // binary search
  6808              while (lbound <= ubound) {
  6809                  mid = lbound + Math.floor((ubound - lbound) / 2);
  6810                  if (mid === last || input >= list[mid] && input < list[mid + 1]) {
  6811                      return list[mid];
  6812                  } else if (list[mid] < input) {
  6813                      lbound = mid + 1;
  6814                  } else {
  6815                      ubound = mid - 1;
  6816                  }
  6817              }
  6818          }
  6819      }, {
  6820          key: '_adjustStashSize',
  6821          value: function _adjustStashSize(normalized) {
  6822              var stashSizeKB = 0;
  6823  
  6824              if (this._config.isLive) {
  6825                  // live stream: always use single normalized speed for size of stashSizeKB
  6826                  stashSizeKB = normalized;
  6827              } else {
  6828                  if (normalized < 512) {
  6829                      stashSizeKB = normalized;
  6830                  } else if (normalized >= 512 && normalized <= 1024) {
  6831                      stashSizeKB = Math.floor(normalized * 1.5);
  6832                  } else {
  6833                      stashSizeKB = normalized * 2;
  6834                  }
  6835              }
  6836  
  6837              if (stashSizeKB > 8192) {
  6838                  stashSizeKB = 8192;
  6839              }
  6840  
  6841              var bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB
  6842              if (this._bufferSize < bufferSize) {
  6843                  this._expandBuffer(bufferSize);
  6844              }
  6845              this._stashSize = stashSizeKB * 1024;
  6846          }
  6847      }, {
  6848          key: '_dispatchChunks',
  6849          value: function _dispatchChunks(chunks, byteStart) {
  6850              this._currentRange.to = byteStart + chunks.byteLength - 1;
  6851              return this._onDataArrival(chunks, byteStart);
  6852          }
  6853      }, {
  6854          key: '_onURLRedirect',
  6855          value: function _onURLRedirect(redirectedURL) {
  6856              this._redirectedURL = redirectedURL;
  6857              if (this._onRedirect) {
  6858                  this._onRedirect(redirectedURL);
  6859              }
  6860          }
  6861      }, {
  6862          key: '_onContentLengthKnown',
  6863          value: function _onContentLengthKnown(contentLength) {
  6864              if (contentLength && this._fullRequestFlag) {
  6865                  this._totalLength = contentLength;
  6866                  this._fullRequestFlag = false;
  6867              }
  6868          }
  6869      }, {
  6870          key: '_onLoaderChunkArrival',
  6871          value: function _onLoaderChunkArrival(chunk, byteStart, receivedLength) {
  6872              if (!this._onDataArrival) {
  6873                  throw new _exception.IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');
  6874              }
  6875              if (this._paused) {
  6876                  return;
  6877              }
  6878              if (this._isEarlyEofReconnecting) {
  6879                  // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback
  6880                  this._isEarlyEofReconnecting = false;
  6881                  if (this._onRecoveredEarlyEof) {
  6882                      this._onRecoveredEarlyEof();
  6883                  }
  6884              }
  6885  
  6886              this._speedSampler.addBytes(chunk.byteLength);
  6887  
  6888              // adjust stash buffer size according to network speed dynamically
  6889              var KBps = this._speedSampler.lastSecondKBps;
  6890              if (KBps !== 0) {
  6891                  var normalized = this._normalizeSpeed(KBps);
  6892                  if (this._speedNormalized !== normalized) {
  6893                      this._speedNormalized = normalized;
  6894                      this._adjustStashSize(normalized);
  6895                  }
  6896              }
  6897  
  6898              if (!this._enableStash) {
  6899                  // disable stash
  6900                  if (this._stashUsed === 0) {
  6901                      // dispatch chunk directly to consumer;
  6902                      // check ret value (consumed bytes) and stash unconsumed to stashBuffer
  6903                      var consumed = this._dispatchChunks(chunk, byteStart);
  6904                      if (consumed < chunk.byteLength) {
  6905                          // unconsumed data remain.
  6906                          var remain = chunk.byteLength - consumed;
  6907                          if (remain > this._bufferSize) {
  6908                              this._expandBuffer(remain);
  6909                          }
  6910                          var stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  6911                          stashArray.set(new Uint8Array(chunk, consumed), 0);
  6912                          this._stashUsed += remain;
  6913                          this._stashByteStart = byteStart + consumed;
  6914                      }
  6915                  } else {
  6916                      // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.
  6917                      if (this._stashUsed + chunk.byteLength > this._bufferSize) {
  6918                          this._expandBuffer(this._stashUsed + chunk.byteLength);
  6919                      }
  6920                      var _stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  6921                      _stashArray.set(new Uint8Array(chunk), this._stashUsed);
  6922                      this._stashUsed += chunk.byteLength;
  6923                      var _consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);
  6924                      if (_consumed < this._stashUsed && _consumed > 0) {
  6925                          // unconsumed data remain
  6926                          var remainArray = new Uint8Array(this._stashBuffer, _consumed);
  6927                          _stashArray.set(remainArray, 0);
  6928                      }
  6929                      this._stashUsed -= _consumed;
  6930                      this._stashByteStart += _consumed;
  6931                  }
  6932              } else {
  6933                  // enable stash
  6934                  if (this._stashUsed === 0 && this._stashByteStart === 0) {
  6935                      // seeked? or init chunk?
  6936                      // This is the first chunk after seek action
  6937                      this._stashByteStart = byteStart;
  6938                  }
  6939                  if (this._stashUsed + chunk.byteLength <= this._stashSize) {
  6940                      // just stash
  6941                      var _stashArray2 = new Uint8Array(this._stashBuffer, 0, this._stashSize);
  6942                      _stashArray2.set(new Uint8Array(chunk), this._stashUsed);
  6943                      this._stashUsed += chunk.byteLength;
  6944                  } else {
  6945                      // stashUsed + chunkSize > stashSize, size limit exceeded
  6946                      var _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  6947                      if (this._stashUsed > 0) {
  6948                          // There're stash datas in buffer
  6949                          // dispatch the whole stashBuffer, and stash remain data
  6950                          // then append chunk to stashBuffer (stash)
  6951                          var buffer = this._stashBuffer.slice(0, this._stashUsed);
  6952                          var _consumed2 = this._dispatchChunks(buffer, this._stashByteStart);
  6953                          if (_consumed2 < buffer.byteLength) {
  6954                              if (_consumed2 > 0) {
  6955                                  var _remainArray = new Uint8Array(buffer, _consumed2);
  6956                                  _stashArray3.set(_remainArray, 0);
  6957                                  this._stashUsed = _remainArray.byteLength;
  6958                                  this._stashByteStart += _consumed2;
  6959                              }
  6960                          } else {
  6961                              this._stashUsed = 0;
  6962                              this._stashByteStart += _consumed2;
  6963                          }
  6964                          if (this._stashUsed + chunk.byteLength > this._bufferSize) {
  6965                              this._expandBuffer(this._stashUsed + chunk.byteLength);
  6966                              _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  6967                          }
  6968                          _stashArray3.set(new Uint8Array(chunk), this._stashUsed);
  6969                          this._stashUsed += chunk.byteLength;
  6970                      } else {
  6971                          // stash buffer empty, but chunkSize > stashSize (oh, holy shit)
  6972                          // dispatch chunk directly and stash remain data
  6973                          var _consumed3 = this._dispatchChunks(chunk, byteStart);
  6974                          if (_consumed3 < chunk.byteLength) {
  6975                              var _remain = chunk.byteLength - _consumed3;
  6976                              if (_remain > this._bufferSize) {
  6977                                  this._expandBuffer(_remain);
  6978                                  _stashArray3 = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  6979                              }
  6980                              _stashArray3.set(new Uint8Array(chunk, _consumed3), 0);
  6981                              this._stashUsed += _remain;
  6982                              this._stashByteStart = byteStart + _consumed3;
  6983                          }
  6984                      }
  6985                  }
  6986              }
  6987          }
  6988      }, {
  6989          key: '_flushStashBuffer',
  6990          value: function _flushStashBuffer(dropUnconsumed) {
  6991              if (this._stashUsed > 0) {
  6992                  var buffer = this._stashBuffer.slice(0, this._stashUsed);
  6993                  var consumed = this._dispatchChunks(buffer, this._stashByteStart);
  6994                  var remain = buffer.byteLength - consumed;
  6995  
  6996                  if (consumed < buffer.byteLength) {
  6997                      if (dropUnconsumed) {
  6998                          _logger2.default.w(this.TAG, remain + ' bytes unconsumed data remain when flush buffer, dropped');
  6999                      } else {
  7000                          if (consumed > 0) {
  7001                              var stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);
  7002                              var remainArray = new Uint8Array(buffer, consumed);
  7003                              stashArray.set(remainArray, 0);
  7004                              this._stashUsed = remainArray.byteLength;
  7005                              this._stashByteStart += consumed;
  7006                          }
  7007                          return 0;
  7008                      }
  7009                  }
  7010                  this._stashUsed = 0;
  7011                  this._stashByteStart = 0;
  7012                  return remain;
  7013              }
  7014              return 0;
  7015          }
  7016      }, {
  7017          key: '_onLoaderComplete',
  7018          value: function _onLoaderComplete(from, to) {
  7019              // Force-flush stash buffer, and drop unconsumed data
  7020              this._flushStashBuffer(true);
  7021  
  7022              if (this._onComplete) {
  7023                  this._onComplete(this._extraData);
  7024              }
  7025          }
  7026      }, {
  7027          key: '_onLoaderError',
  7028          value: function _onLoaderError(type, data) {
  7029              _logger2.default.e(this.TAG, 'Loader error, code = ' + data.code + ', msg = ' + data.msg);
  7030  
  7031              this._flushStashBuffer(false);
  7032  
  7033              if (this._isEarlyEofReconnecting) {
  7034                  // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer
  7035                  this._isEarlyEofReconnecting = false;
  7036                  type = _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF;
  7037              }
  7038  
  7039              switch (type) {
  7040                  case _loader.LoaderErrors.EARLY_EOF:
  7041                      {
  7042                          if (!this._config.isLive) {
  7043                              // Do internal http reconnect if not live stream
  7044                              if (this._totalLength) {
  7045                                  var nextFrom = this._currentRange.to + 1;
  7046                                  if (nextFrom < this._totalLength) {
  7047                                      _logger2.default.w(this.TAG, 'Connection lost, trying reconnect...');
  7048                                      this._isEarlyEofReconnecting = true;
  7049                                      this._internalSeek(nextFrom, false);
  7050                                  }
  7051                                  return;
  7052                              }
  7053                              // else: We don't know totalLength, throw UnrecoverableEarlyEof
  7054                          }
  7055                          // live stream: throw UnrecoverableEarlyEof error to upper-layer
  7056                          type = _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF;
  7057                          break;
  7058                      }
  7059                  case _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF:
  7060                  case _loader.LoaderErrors.CONNECTING_TIMEOUT:
  7061                  case _loader.LoaderErrors.HTTP_STATUS_CODE_INVALID:
  7062                  case _loader.LoaderErrors.EXCEPTION:
  7063                      break;
  7064              }
  7065  
  7066              if (this._onError) {
  7067                  this._onError(type, data);
  7068              } else {
  7069                  throw new _exception.RuntimeException('IOException: ' + data.msg);
  7070              }
  7071          }
  7072      }, {
  7073          key: 'status',
  7074          get: function get() {
  7075              return this._loader.status;
  7076          }
  7077      }, {
  7078          key: 'extraData',
  7079          get: function get() {
  7080              return this._extraData;
  7081          },
  7082          set: function set(data) {
  7083              this._extraData = data;
  7084          }
  7085  
  7086          // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number
  7087  
  7088      }, {
  7089          key: 'onDataArrival',
  7090          get: function get() {
  7091              return this._onDataArrival;
  7092          },
  7093          set: function set(callback) {
  7094              this._onDataArrival = callback;
  7095          }
  7096      }, {
  7097          key: 'onSeeked',
  7098          get: function get() {
  7099              return this._onSeeked;
  7100          },
  7101          set: function set(callback) {
  7102              this._onSeeked = callback;
  7103          }
  7104  
  7105          // prototype: function onError(type: number, info: {code: number, msg: string}): void
  7106  
  7107      }, {
  7108          key: 'onError',
  7109          get: function get() {
  7110              return this._onError;
  7111          },
  7112          set: function set(callback) {
  7113              this._onError = callback;
  7114          }
  7115      }, {
  7116          key: 'onComplete',
  7117          get: function get() {
  7118              return this._onComplete;
  7119          },
  7120          set: function set(callback) {
  7121              this._onComplete = callback;
  7122          }
  7123      }, {
  7124          key: 'onRedirect',
  7125          get: function get() {
  7126              return this._onRedirect;
  7127          },
  7128          set: function set(callback) {
  7129              this._onRedirect = callback;
  7130          }
  7131      }, {
  7132          key: 'onRecoveredEarlyEof',
  7133          get: function get() {
  7134              return this._onRecoveredEarlyEof;
  7135          },
  7136          set: function set(callback) {
  7137              this._onRecoveredEarlyEof = callback;
  7138          }
  7139      }, {
  7140          key: 'currentURL',
  7141          get: function get() {
  7142              return this._dataSource.url;
  7143          }
  7144      }, {
  7145          key: 'hasRedirect',
  7146          get: function get() {
  7147              return this._redirectedURL != null || this._dataSource.redirectedURL != undefined;
  7148          }
  7149      }, {
  7150          key: 'currentRedirectedURL',
  7151          get: function get() {
  7152              return this._redirectedURL || this._dataSource.redirectedURL;
  7153          }
  7154  
  7155          // in KB/s
  7156  
  7157      }, {
  7158          key: 'currentSpeed',
  7159          get: function get() {
  7160              if (this._loaderClass === _xhrRangeLoader2.default) {
  7161                  // SpeedSampler is inaccuracy if loader is RangeLoader
  7162                  return this._loader.currentSpeed;
  7163              }
  7164              return this._speedSampler.lastSecondKBps;
  7165          }
  7166      }, {
  7167          key: 'loaderType',
  7168          get: function get() {
  7169              return this._loader.type;
  7170          }
  7171      }]);
  7172  
  7173      return IOController;
  7174  }();
  7175  
  7176  exports.default = IOController;
  7177  
  7178  },{"../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){
  7179  'use strict';
  7180  
  7181  Object.defineProperty(exports, "__esModule", {
  7182      value: true
  7183  });
  7184  exports.BaseLoader = exports.LoaderErrors = exports.LoaderStatus = undefined;
  7185  
  7186  var _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; }; }(); /*
  7187                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7188                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  7189                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  7190                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  7191                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  7192                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  7193                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  7194                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  7195                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  7196                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  7197                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  7198                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  7199                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  7201                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  7202                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  7203  
  7204  var _exception = _dereq_('../utils/exception.js');
  7205  
  7206  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7207  
  7208  var LoaderStatus = exports.LoaderStatus = {
  7209      kIdle: 0,
  7210      kConnecting: 1,
  7211      kBuffering: 2,
  7212      kError: 3,
  7213      kComplete: 4
  7214  };
  7215  
  7216  var LoaderErrors = exports.LoaderErrors = {
  7217      OK: 'OK',
  7218      EXCEPTION: 'Exception',
  7219      HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',
  7220      CONNECTING_TIMEOUT: 'ConnectingTimeout',
  7221      EARLY_EOF: 'EarlyEof',
  7222      UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'
  7223  };
  7224  
  7225  /* Loader has callbacks which have following prototypes:
  7226   *     function onContentLengthKnown(contentLength: number): void
  7227   *     function onURLRedirect(url: string): void
  7228   *     function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void
  7229   *     function onError(errorType: number, errorInfo: {code: number, msg: string}): void
  7230   *     function onComplete(rangeFrom: number, rangeTo: number): void
  7231   */
  7232  
  7233  var BaseLoader = exports.BaseLoader = function () {
  7234      function BaseLoader(typeName) {
  7235          _classCallCheck(this, BaseLoader);
  7236  
  7237          this._type = typeName || 'undefined';
  7238          this._status = LoaderStatus.kIdle;
  7239          this._needStash = false;
  7240          // callbacks
  7241          this._onContentLengthKnown = null;
  7242          this._onURLRedirect = null;
  7243          this._onDataArrival = null;
  7244          this._onError = null;
  7245          this._onComplete = null;
  7246      }
  7247  
  7248      _createClass(BaseLoader, [{
  7249          key: 'destroy',
  7250          value: function destroy() {
  7251              this._status = LoaderStatus.kIdle;
  7252              this._onContentLengthKnown = null;
  7253              this._onURLRedirect = null;
  7254              this._onDataArrival = null;
  7255              this._onError = null;
  7256              this._onComplete = null;
  7257          }
  7258      }, {
  7259          key: 'isWorking',
  7260          value: function isWorking() {
  7261              return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;
  7262          }
  7263      }, {
  7264          key: 'open',
  7265  
  7266  
  7267          // pure virtual
  7268          value: function open(dataSource, range) {
  7269              throw new _exception.NotImplementedException('Unimplemented abstract function!');
  7270          }
  7271      }, {
  7272          key: 'abort',
  7273          value: function abort() {
  7274              throw new _exception.NotImplementedException('Unimplemented abstract function!');
  7275          }
  7276      }, {
  7277          key: 'type',
  7278          get: function get() {
  7279              return this._type;
  7280          }
  7281      }, {
  7282          key: 'status',
  7283          get: function get() {
  7284              return this._status;
  7285          }
  7286      }, {
  7287          key: 'needStashBuffer',
  7288          get: function get() {
  7289              return this._needStash;
  7290          }
  7291      }, {
  7292          key: 'onContentLengthKnown',
  7293          get: function get() {
  7294              return this._onContentLengthKnown;
  7295          },
  7296          set: function set(callback) {
  7297              this._onContentLengthKnown = callback;
  7298          }
  7299      }, {
  7300          key: 'onURLRedirect',
  7301          get: function get() {
  7302              return this._onURLRedirect;
  7303          },
  7304          set: function set(callback) {
  7305              this._onURLRedirect = callback;
  7306          }
  7307      }, {
  7308          key: 'onDataArrival',
  7309          get: function get() {
  7310              return this._onDataArrival;
  7311          },
  7312          set: function set(callback) {
  7313              this._onDataArrival = callback;
  7314          }
  7315      }, {
  7316          key: 'onError',
  7317          get: function get() {
  7318              return this._onError;
  7319          },
  7320          set: function set(callback) {
  7321              this._onError = callback;
  7322          }
  7323      }, {
  7324          key: 'onComplete',
  7325          get: function get() {
  7326              return this._onComplete;
  7327          },
  7328          set: function set(callback) {
  7329              this._onComplete = callback;
  7330          }
  7331      }]);
  7332  
  7333      return BaseLoader;
  7334  }();
  7335  
  7336  },{"../utils/exception.js":40}],25:[function(_dereq_,module,exports){
  7337  'use strict';
  7338  
  7339  Object.defineProperty(exports, "__esModule", {
  7340      value: true
  7341  });
  7342  
  7343  var _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; }; }();
  7344  
  7345  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7346  
  7347  /*
  7348   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7349   *
  7350   * @author zheng qian <xqq@xqq.im>
  7351   *
  7352   * Licensed under the Apache License, Version 2.0 (the "License");
  7353   * you may not use this file except in compliance with the License.
  7354   * You may obtain a copy of the License at
  7355   *
  7356   *     http://www.apache.org/licenses/LICENSE-2.0
  7357   *
  7358   * Unless required by applicable law or agreed to in writing, software
  7359   * distributed under the License is distributed on an "AS IS" BASIS,
  7360   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7361   * See the License for the specific language governing permissions and
  7362   * limitations under the License.
  7363   */
  7364  
  7365  var ParamSeekHandler = function () {
  7366      function ParamSeekHandler(paramStart, paramEnd) {
  7367          _classCallCheck(this, ParamSeekHandler);
  7368  
  7369          this._startName = paramStart;
  7370          this._endName = paramEnd;
  7371      }
  7372  
  7373      _createClass(ParamSeekHandler, [{
  7374          key: 'getConfig',
  7375          value: function getConfig(baseUrl, range) {
  7376              var url = baseUrl;
  7377  
  7378              if (range.from !== 0 || range.to !== -1) {
  7379                  var needAnd = true;
  7380                  if (url.indexOf('?') === -1) {
  7381                      url += '?';
  7382                      needAnd = false;
  7383                  }
  7384  
  7385                  if (needAnd) {
  7386                      url += '&';
  7387                  }
  7388  
  7389                  url += this._startName + '=' + range.from.toString();
  7390  
  7391                  if (range.to !== -1) {
  7392                      url += '&' + this._endName + '=' + range.to.toString();
  7393                  }
  7394              }
  7395  
  7396              return {
  7397                  url: url,
  7398                  headers: {}
  7399              };
  7400          }
  7401      }, {
  7402          key: 'removeURLParameters',
  7403          value: function removeURLParameters(seekedURL) {
  7404              var baseURL = seekedURL.split('?')[0];
  7405              var params = undefined;
  7406  
  7407              var queryIndex = seekedURL.indexOf('?');
  7408              if (queryIndex !== -1) {
  7409                  params = seekedURL.substring(queryIndex + 1);
  7410              }
  7411  
  7412              var resultParams = '';
  7413  
  7414              if (params != undefined && params.length > 0) {
  7415                  var pairs = params.split('&');
  7416  
  7417                  for (var i = 0; i < pairs.length; i++) {
  7418                      var pair = pairs[i].split('=');
  7419                      var requireAnd = i > 0;
  7420  
  7421                      if (pair[0] !== this._startName && pair[0] !== this._endName) {
  7422                          if (requireAnd) {
  7423                              resultParams += '&';
  7424                          }
  7425                          resultParams += pairs[i];
  7426                      }
  7427                  }
  7428              }
  7429  
  7430              return resultParams.length === 0 ? baseURL : baseURL + '?' + resultParams;
  7431          }
  7432      }]);
  7433  
  7434      return ParamSeekHandler;
  7435  }();
  7436  
  7437  exports.default = ParamSeekHandler;
  7438  
  7439  },{}],26:[function(_dereq_,module,exports){
  7440  'use strict';
  7441  
  7442  Object.defineProperty(exports, "__esModule", {
  7443      value: true
  7444  });
  7445  
  7446  var _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; }; }();
  7447  
  7448  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7449  
  7450  /*
  7451   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7452   *
  7453   * @author zheng qian <xqq@xqq.im>
  7454   *
  7455   * Licensed under the Apache License, Version 2.0 (the "License");
  7456   * you may not use this file except in compliance with the License.
  7457   * You may obtain a copy of the License at
  7458   *
  7459   *     http://www.apache.org/licenses/LICENSE-2.0
  7460   *
  7461   * Unless required by applicable law or agreed to in writing, software
  7462   * distributed under the License is distributed on an "AS IS" BASIS,
  7463   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7464   * See the License for the specific language governing permissions and
  7465   * limitations under the License.
  7466   */
  7467  
  7468  var RangeSeekHandler = function () {
  7469      function RangeSeekHandler(zeroStart) {
  7470          _classCallCheck(this, RangeSeekHandler);
  7471  
  7472          this._zeroStart = zeroStart || false;
  7473      }
  7474  
  7475      _createClass(RangeSeekHandler, [{
  7476          key: 'getConfig',
  7477          value: function getConfig(url, range) {
  7478              var headers = {};
  7479  
  7480              if (range.from !== 0 || range.to !== -1) {
  7481                  var param = void 0;
  7482                  if (range.to !== -1) {
  7483                      param = 'bytes=' + range.from.toString() + '-' + range.to.toString();
  7484                  } else {
  7485                      param = 'bytes=' + range.from.toString() + '-';
  7486                  }
  7487                  headers['Range'] = param;
  7488              } else if (this._zeroStart) {
  7489                  headers['Range'] = 'bytes=0-';
  7490              }
  7491  
  7492              return {
  7493                  url: url,
  7494                  headers: headers
  7495              };
  7496          }
  7497      }, {
  7498          key: 'removeURLParameters',
  7499          value: function removeURLParameters(seekedURL) {
  7500              return seekedURL;
  7501          }
  7502      }]);
  7503  
  7504      return RangeSeekHandler;
  7505  }();
  7506  
  7507  exports.default = RangeSeekHandler;
  7508  
  7509  },{}],27:[function(_dereq_,module,exports){
  7510  "use strict";
  7511  
  7512  Object.defineProperty(exports, "__esModule", {
  7513      value: true
  7514  });
  7515  
  7516  var _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; }; }();
  7517  
  7518  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7519  
  7520  /*
  7521   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7522   *
  7523   * @author zheng qian <xqq@xqq.im>
  7524   *
  7525   * Licensed under the Apache License, Version 2.0 (the "License");
  7526   * you may not use this file except in compliance with the License.
  7527   * You may obtain a copy of the License at
  7528   *
  7529   *     http://www.apache.org/licenses/LICENSE-2.0
  7530   *
  7531   * Unless required by applicable law or agreed to in writing, software
  7532   * distributed under the License is distributed on an "AS IS" BASIS,
  7533   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7534   * See the License for the specific language governing permissions and
  7535   * limitations under the License.
  7536   */
  7537  
  7538  // Utility class to calculate realtime network I/O speed
  7539  var SpeedSampler = function () {
  7540      function SpeedSampler() {
  7541          _classCallCheck(this, SpeedSampler);
  7542  
  7543          // milliseconds
  7544          this._firstCheckpoint = 0;
  7545          this._lastCheckpoint = 0;
  7546          this._intervalBytes = 0;
  7547          this._totalBytes = 0;
  7548          this._lastSecondBytes = 0;
  7549  
  7550          // compatibility detection
  7551          if (self.performance && self.performance.now) {
  7552              this._now = self.performance.now.bind(self.performance);
  7553          } else {
  7554              this._now = Date.now;
  7555          }
  7556      }
  7557  
  7558      _createClass(SpeedSampler, [{
  7559          key: "reset",
  7560          value: function reset() {
  7561              this._firstCheckpoint = this._lastCheckpoint = 0;
  7562              this._totalBytes = this._intervalBytes = 0;
  7563              this._lastSecondBytes = 0;
  7564          }
  7565      }, {
  7566          key: "addBytes",
  7567          value: function addBytes(bytes) {
  7568              if (this._firstCheckpoint === 0) {
  7569                  this._firstCheckpoint = this._now();
  7570                  this._lastCheckpoint = this._firstCheckpoint;
  7571                  this._intervalBytes += bytes;
  7572                  this._totalBytes += bytes;
  7573              } else if (this._now() - this._lastCheckpoint < 1000) {
  7574                  this._intervalBytes += bytes;
  7575                  this._totalBytes += bytes;
  7576              } else {
  7577                  // duration >= 1000
  7578                  this._lastSecondBytes = this._intervalBytes;
  7579                  this._intervalBytes = bytes;
  7580                  this._totalBytes += bytes;
  7581                  this._lastCheckpoint = this._now();
  7582              }
  7583          }
  7584      }, {
  7585          key: "currentKBps",
  7586          get: function get() {
  7587              this.addBytes(0);
  7588  
  7589              var durationSeconds = (this._now() - this._lastCheckpoint) / 1000;
  7590              if (durationSeconds == 0) durationSeconds = 1;
  7591              return this._intervalBytes / durationSeconds / 1024;
  7592          }
  7593      }, {
  7594          key: "lastSecondKBps",
  7595          get: function get() {
  7596              this.addBytes(0);
  7597  
  7598              if (this._lastSecondBytes !== 0) {
  7599                  return this._lastSecondBytes / 1024;
  7600              } else {
  7601                  // lastSecondBytes === 0
  7602                  if (this._now() - this._lastCheckpoint >= 500) {
  7603                      // if time interval since last checkpoint has exceeded 500ms
  7604                      // the speed is nearly accurate
  7605                      return this.currentKBps;
  7606                  } else {
  7607                      // We don't know
  7608                      return 0;
  7609                  }
  7610              }
  7611          }
  7612      }, {
  7613          key: "averageKBps",
  7614          get: function get() {
  7615              var durationSeconds = (this._now() - this._firstCheckpoint) / 1000;
  7616              return this._totalBytes / durationSeconds / 1024;
  7617          }
  7618      }]);
  7619  
  7620      return SpeedSampler;
  7621  }();
  7622  
  7623  exports.default = SpeedSampler;
  7624  
  7625  },{}],28:[function(_dereq_,module,exports){
  7626  'use strict';
  7627  
  7628  Object.defineProperty(exports, "__esModule", {
  7629      value: true
  7630  });
  7631  
  7632  var _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); } };
  7633  
  7634  var _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; }; }();
  7635  
  7636  var _logger = _dereq_('../utils/logger.js');
  7637  
  7638  var _logger2 = _interopRequireDefault(_logger);
  7639  
  7640  var _loader = _dereq_('./loader.js');
  7641  
  7642  var _exception = _dereq_('../utils/exception.js');
  7643  
  7644  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  7645  
  7646  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7647  
  7648  function _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; }
  7649  
  7650  function _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; } /*
  7651                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7652                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7653                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @author zheng qian <xqq@xqq.im>
  7654                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7655                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Licensed under the Apache License, Version 2.0 (the "License");
  7656                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * you may not use this file except in compliance with the License.
  7657                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * You may obtain a copy of the License at
  7658                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7659                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *     http://www.apache.org/licenses/LICENSE-2.0
  7660                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7661                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Unless required by applicable law or agreed to in writing, software
  7662                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * distributed under the License is distributed on an "AS IS" BASIS,
  7663                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7664                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * See the License for the specific language governing permissions and
  7665                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * limitations under the License.
  7666                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  7667  
  7668  // For FLV over WebSocket live stream
  7669  var WebSocketLoader = function (_BaseLoader) {
  7670      _inherits(WebSocketLoader, _BaseLoader);
  7671  
  7672      _createClass(WebSocketLoader, null, [{
  7673          key: 'isSupported',
  7674          value: function isSupported() {
  7675              try {
  7676                  return typeof self.WebSocket !== 'undefined';
  7677              } catch (e) {
  7678                  return false;
  7679              }
  7680          }
  7681      }]);
  7682  
  7683      function WebSocketLoader() {
  7684          _classCallCheck(this, WebSocketLoader);
  7685  
  7686          var _this = _possibleConstructorReturn(this, (WebSocketLoader.__proto__ || Object.getPrototypeOf(WebSocketLoader)).call(this, 'websocket-loader'));
  7687  
  7688          _this.TAG = 'WebSocketLoader';
  7689  
  7690          _this._needStash = true;
  7691  
  7692          _this._ws = null;
  7693          _this._requestAbort = false;
  7694          _this._receivedLength = 0;
  7695          return _this;
  7696      }
  7697  
  7698      _createClass(WebSocketLoader, [{
  7699          key: 'destroy',
  7700          value: function destroy() {
  7701              if (this._ws) {
  7702                  this.abort();
  7703              }
  7704              _get(WebSocketLoader.prototype.__proto__ || Object.getPrototypeOf(WebSocketLoader.prototype), 'destroy', this).call(this);
  7705          }
  7706      }, {
  7707          key: 'open',
  7708          value: function open(dataSource) {
  7709              try {
  7710                  var ws = this._ws = new self.WebSocket(dataSource.url);
  7711                  ws.binaryType = 'arraybuffer';
  7712                  ws.onopen = this._onWebSocketOpen.bind(this);
  7713                  ws.onclose = this._onWebSocketClose.bind(this);
  7714                  ws.onmessage = this._onWebSocketMessage.bind(this);
  7715                  ws.onerror = this._onWebSocketError.bind(this);
  7716  
  7717                  this._status = _loader.LoaderStatus.kConnecting;
  7718              } catch (e) {
  7719                  this._status = _loader.LoaderStatus.kError;
  7720  
  7721                  var info = { code: e.code, msg: e.message };
  7722  
  7723                  if (this._onError) {
  7724                      this._onError(_loader.LoaderErrors.EXCEPTION, info);
  7725                  } else {
  7726                      throw new _exception.RuntimeException(info.msg);
  7727                  }
  7728              }
  7729          }
  7730      }, {
  7731          key: 'abort',
  7732          value: function abort() {
  7733              var ws = this._ws;
  7734              if (ws && (ws.readyState === 0 || ws.readyState === 1)) {
  7735                  // CONNECTING || OPEN
  7736                  this._requestAbort = true;
  7737                  ws.close();
  7738              }
  7739  
  7740              this._ws = null;
  7741              this._status = _loader.LoaderStatus.kComplete;
  7742          }
  7743      }, {
  7744          key: '_onWebSocketOpen',
  7745          value: function _onWebSocketOpen(e) {
  7746              this._status = _loader.LoaderStatus.kBuffering;
  7747          }
  7748      }, {
  7749          key: '_onWebSocketClose',
  7750          value: function _onWebSocketClose(e) {
  7751              if (this._requestAbort === true) {
  7752                  this._requestAbort = false;
  7753                  return;
  7754              }
  7755  
  7756              this._status = _loader.LoaderStatus.kComplete;
  7757  
  7758              if (this._onComplete) {
  7759                  this._onComplete(0, this._receivedLength - 1);
  7760              }
  7761          }
  7762      }, {
  7763          key: '_onWebSocketMessage',
  7764          value: function _onWebSocketMessage(e) {
  7765              var _this2 = this;
  7766  
  7767              if (e.data instanceof ArrayBuffer) {
  7768                  this._dispatchArrayBuffer(e.data);
  7769              } else if (e.data instanceof Blob) {
  7770                  var reader = new FileReader();
  7771                  reader.onload = function () {
  7772                      _this2._dispatchArrayBuffer(reader.result);
  7773                  };
  7774                  reader.readAsArrayBuffer(e.data);
  7775              } else {
  7776                  this._status = _loader.LoaderStatus.kError;
  7777                  var info = { code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name };
  7778  
  7779                  if (this._onError) {
  7780                      this._onError(_loader.LoaderErrors.EXCEPTION, info);
  7781                  } else {
  7782                      throw new _exception.RuntimeException(info.msg);
  7783                  }
  7784              }
  7785          }
  7786      }, {
  7787          key: '_dispatchArrayBuffer',
  7788          value: function _dispatchArrayBuffer(arraybuffer) {
  7789              var chunk = arraybuffer;
  7790              var byteStart = this._receivedLength;
  7791              this._receivedLength += chunk.byteLength;
  7792  
  7793              if (this._onDataArrival) {
  7794                  this._onDataArrival(chunk, byteStart, this._receivedLength);
  7795              }
  7796          }
  7797      }, {
  7798          key: '_onWebSocketError',
  7799          value: function _onWebSocketError(e) {
  7800              this._status = _loader.LoaderStatus.kError;
  7801  
  7802              var info = {
  7803                  code: e.code,
  7804                  msg: e.message
  7805              };
  7806  
  7807              if (this._onError) {
  7808                  this._onError(_loader.LoaderErrors.EXCEPTION, info);
  7809              } else {
  7810                  throw new _exception.RuntimeException(info.msg);
  7811              }
  7812          }
  7813      }]);
  7814  
  7815      return WebSocketLoader;
  7816  }(_loader.BaseLoader);
  7817  
  7818  exports.default = WebSocketLoader;
  7819  
  7820  },{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],29:[function(_dereq_,module,exports){
  7821  'use strict';
  7822  
  7823  Object.defineProperty(exports, "__esModule", {
  7824      value: true
  7825  });
  7826  
  7827  var _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; };
  7828  
  7829  var _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); } };
  7830  
  7831  var _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; }; }();
  7832  
  7833  var _logger = _dereq_('../utils/logger.js');
  7834  
  7835  var _logger2 = _interopRequireDefault(_logger);
  7836  
  7837  var _loader = _dereq_('./loader.js');
  7838  
  7839  var _exception = _dereq_('../utils/exception.js');
  7840  
  7841  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  7842  
  7843  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7844  
  7845  function _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; }
  7846  
  7847  function _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; } /*
  7848                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (C) 2016 Bilibili. All Rights Reserved.
  7849                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7850                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @author zheng qian <xqq@xqq.im>
  7851                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7852                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Licensed under the Apache License, Version 2.0 (the "License");
  7853                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * you may not use this file except in compliance with the License.
  7854                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * You may obtain a copy of the License at
  7855                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7856                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *     http://www.apache.org/licenses/LICENSE-2.0
  7857                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  7858                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Unless required by applicable law or agreed to in writing, software
  7859                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * distributed under the License is distributed on an "AS IS" BASIS,
  7860                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7861                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * See the License for the specific language governing permissions and
  7862                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * limitations under the License.
  7863                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  7864  
  7865  // For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`
  7866  var MozChunkedLoader = function (_BaseLoader) {
  7867      _inherits(MozChunkedLoader, _BaseLoader);
  7868  
  7869      _createClass(MozChunkedLoader, null, [{
  7870          key: 'isSupported',
  7871          value: function isSupported() {
  7872              try {
  7873                  var xhr = new XMLHttpRequest();
  7874                  // Firefox 37- requires .open() to be called before setting responseType
  7875                  xhr.open('GET', 'https://example.com', true);
  7876                  xhr.responseType = 'moz-chunked-arraybuffer';
  7877                  return xhr.responseType === 'moz-chunked-arraybuffer';
  7878              } catch (e) {
  7879                  _logger2.default.w('MozChunkedLoader', e.message);
  7880                  return false;
  7881              }
  7882          }
  7883      }]);
  7884  
  7885      function MozChunkedLoader(seekHandler, config) {
  7886          _classCallCheck(this, MozChunkedLoader);
  7887  
  7888          var _this = _possibleConstructorReturn(this, (MozChunkedLoader.__proto__ || Object.getPrototypeOf(MozChunkedLoader)).call(this, 'xhr-moz-chunked-loader'));
  7889  
  7890          _this.TAG = 'MozChunkedLoader';
  7891  
  7892          _this._seekHandler = seekHandler;
  7893          _this._config = config;
  7894          _this._needStash = true;
  7895  
  7896          _this._xhr = null;
  7897          _this._requestAbort = false;
  7898          _this._contentLength = null;
  7899          _this._receivedLength = 0;
  7900          return _this;
  7901      }
  7902  
  7903      _createClass(MozChunkedLoader, [{
  7904          key: 'destroy',
  7905          value: function destroy() {
  7906              if (this.isWorking()) {
  7907                  this.abort();
  7908              }
  7909              if (this._xhr) {
  7910                  this._xhr.onreadystatechange = null;
  7911                  this._xhr.onprogress = null;
  7912                  this._xhr.onloadend = null;
  7913                  this._xhr.onerror = null;
  7914                  this._xhr = null;
  7915              }
  7916              _get(MozChunkedLoader.prototype.__proto__ || Object.getPrototypeOf(MozChunkedLoader.prototype), 'destroy', this).call(this);
  7917          }
  7918      }, {
  7919          key: 'open',
  7920          value: function open(dataSource, range) {
  7921              this._dataSource = dataSource;
  7922              this._range = range;
  7923  
  7924              var sourceURL = dataSource.url;
  7925              if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {
  7926                  sourceURL = dataSource.redirectedURL;
  7927              }
  7928  
  7929              var seekConfig = this._seekHandler.getConfig(sourceURL, range);
  7930              this._requestURL = seekConfig.url;
  7931  
  7932              var xhr = this._xhr = new XMLHttpRequest();
  7933              xhr.open('GET', seekConfig.url, true);
  7934              xhr.responseType = 'moz-chunked-arraybuffer';
  7935              xhr.onreadystatechange = this._onReadyStateChange.bind(this);
  7936              xhr.onprogress = this._onProgress.bind(this);
  7937              xhr.onloadend = this._onLoadEnd.bind(this);
  7938              xhr.onerror = this._onXhrError.bind(this);
  7939  
  7940              // cors is auto detected and enabled by xhr
  7941  
  7942              // withCredentials is disabled by default
  7943              if (dataSource.withCredentials) {
  7944                  xhr.withCredentials = true;
  7945              }
  7946  
  7947              if (_typeof(seekConfig.headers) === 'object') {
  7948                  var headers = seekConfig.headers;
  7949  
  7950                  for (var key in headers) {
  7951                      if (headers.hasOwnProperty(key)) {
  7952                          xhr.setRequestHeader(key, headers[key]);
  7953                      }
  7954                  }
  7955              }
  7956  
  7957              // add additional headers
  7958              if (_typeof(this._config.headers) === 'object') {
  7959                  var _headers = this._config.headers;
  7960  
  7961                  for (var _key in _headers) {
  7962                      if (_headers.hasOwnProperty(_key)) {
  7963                          xhr.setRequestHeader(_key, _headers[_key]);
  7964                      }
  7965                  }
  7966              }
  7967  
  7968              this._status = _loader.LoaderStatus.kConnecting;
  7969              xhr.send();
  7970          }
  7971      }, {
  7972          key: 'abort',
  7973          value: function abort() {
  7974              this._requestAbort = true;
  7975              if (this._xhr) {
  7976                  this._xhr.abort();
  7977              }
  7978              this._status = _loader.LoaderStatus.kComplete;
  7979          }
  7980      }, {
  7981          key: '_onReadyStateChange',
  7982          value: function _onReadyStateChange(e) {
  7983              var xhr = e.target;
  7984  
  7985              if (xhr.readyState === 2) {
  7986                  // HEADERS_RECEIVED
  7987                  if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {
  7988                      if (this._onURLRedirect) {
  7989                          var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
  7990                          this._onURLRedirect(redirectedURL);
  7991                      }
  7992                  }
  7993  
  7994                  if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {
  7995                      this._status = _loader.LoaderStatus.kError;
  7996                      if (this._onError) {
  7997                          this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
  7998                      } else {
  7999                          throw new _exception.RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
  8000                      }
  8001                  } else {
  8002                      this._status = _loader.LoaderStatus.kBuffering;
  8003                  }
  8004              }
  8005          }
  8006      }, {
  8007          key: '_onProgress',
  8008          value: function _onProgress(e) {
  8009              if (this._status === _loader.LoaderStatus.kError) {
  8010                  // Ignore error response
  8011                  return;
  8012              }
  8013  
  8014              if (this._contentLength === null) {
  8015                  if (e.total !== null && e.total !== 0) {
  8016                      this._contentLength = e.total;
  8017                      if (this._onContentLengthKnown) {
  8018                          this._onContentLengthKnown(this._contentLength);
  8019                      }
  8020                  }
  8021              }
  8022  
  8023              var chunk = e.target.response;
  8024              var byteStart = this._range.from + this._receivedLength;
  8025              this._receivedLength += chunk.byteLength;
  8026  
  8027              if (this._onDataArrival) {
  8028                  this._onDataArrival(chunk, byteStart, this._receivedLength);
  8029              }
  8030          }
  8031      }, {
  8032          key: '_onLoadEnd',
  8033          value: function _onLoadEnd(e) {
  8034              if (this._requestAbort === true) {
  8035                  this._requestAbort = false;
  8036                  return;
  8037              } else if (this._status === _loader.LoaderStatus.kError) {
  8038                  return;
  8039              }
  8040  
  8041              this._status = _loader.LoaderStatus.kComplete;
  8042              if (this._onComplete) {
  8043                  this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
  8044              }
  8045          }
  8046      }, {
  8047          key: '_onXhrError',
  8048          value: function _onXhrError(e) {
  8049              this._status = _loader.LoaderStatus.kError;
  8050              var type = 0;
  8051              var info = null;
  8052  
  8053              if (this._contentLength && e.loaded < this._contentLength) {
  8054                  type = _loader.LoaderErrors.EARLY_EOF;
  8055                  info = { code: -1, msg: 'Moz-Chunked stream meet Early-Eof' };
  8056              } else {
  8057                  type = _loader.LoaderErrors.EXCEPTION;
  8058                  info = { code: -1, msg: e.constructor.name + ' ' + e.type };
  8059              }
  8060  
  8061              if (this._onError) {
  8062                  this._onError(type, info);
  8063              } else {
  8064                  throw new _exception.RuntimeException(info.msg);
  8065              }
  8066          }
  8067      }]);
  8068  
  8069      return MozChunkedLoader;
  8070  }(_loader.BaseLoader);
  8071  
  8072  exports.default = MozChunkedLoader;
  8073  
  8074  },{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],30:[function(_dereq_,module,exports){
  8075  'use strict';
  8076  
  8077  Object.defineProperty(exports, "__esModule", {
  8078      value: true
  8079  });
  8080  
  8081  var _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; };
  8082  
  8083  var _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); } };
  8084  
  8085  var _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; }; }();
  8086  
  8087  var _logger = _dereq_('../utils/logger.js');
  8088  
  8089  var _logger2 = _interopRequireDefault(_logger);
  8090  
  8091  var _loader = _dereq_('./loader.js');
  8092  
  8093  var _exception = _dereq_('../utils/exception.js');
  8094  
  8095  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8096  
  8097  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  8098  
  8099  function _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; }
  8100  
  8101  function _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; } /*
  8102                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (C) 2016 Bilibili. All Rights Reserved.
  8103                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8104                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @author zheng qian <xqq@xqq.im>
  8105                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8106                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Licensed under the Apache License, Version 2.0 (the "License");
  8107                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * you may not use this file except in compliance with the License.
  8108                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * You may obtain a copy of the License at
  8109                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8110                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *     http://www.apache.org/licenses/LICENSE-2.0
  8111                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8112                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Unless required by applicable law or agreed to in writing, software
  8113                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * distributed under the License is distributed on an "AS IS" BASIS,
  8114                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8115                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * See the License for the specific language governing permissions and
  8116                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * limitations under the License.
  8117                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  8118  
  8119  /* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!
  8120   * The browser may crash in wininet.dll. Disable for now.
  8121   *
  8122   * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`
  8123   * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.
  8124   *
  8125   * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.
  8126   * in order to release previous ArrayBuffer to avoid memory leak
  8127   *
  8128   * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.
  8129   */
  8130  var MSStreamLoader = function (_BaseLoader) {
  8131      _inherits(MSStreamLoader, _BaseLoader);
  8132  
  8133      _createClass(MSStreamLoader, null, [{
  8134          key: 'isSupported',
  8135          value: function isSupported() {
  8136              try {
  8137                  if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {
  8138                      return false;
  8139                  }
  8140  
  8141                  var xhr = new XMLHttpRequest();
  8142                  xhr.open('GET', 'https://example.com', true);
  8143                  xhr.responseType = 'ms-stream';
  8144                  return xhr.responseType === 'ms-stream';
  8145              } catch (e) {
  8146                  _logger2.default.w('MSStreamLoader', e.message);
  8147                  return false;
  8148              }
  8149          }
  8150      }]);
  8151  
  8152      function MSStreamLoader(seekHandler, config) {
  8153          _classCallCheck(this, MSStreamLoader);
  8154  
  8155          var _this = _possibleConstructorReturn(this, (MSStreamLoader.__proto__ || Object.getPrototypeOf(MSStreamLoader)).call(this, 'xhr-msstream-loader'));
  8156  
  8157          _this.TAG = 'MSStreamLoader';
  8158  
  8159          _this._seekHandler = seekHandler;
  8160          _this._config = config;
  8161          _this._needStash = true;
  8162  
  8163          _this._xhr = null;
  8164          _this._reader = null; // MSStreamReader
  8165  
  8166          _this._totalRange = null;
  8167          _this._currentRange = null;
  8168  
  8169          _this._currentRequestURL = null;
  8170          _this._currentRedirectedURL = null;
  8171  
  8172          _this._contentLength = null;
  8173          _this._receivedLength = 0;
  8174  
  8175          _this._bufferLimit = 16 * 1024 * 1024; // 16MB
  8176          _this._lastTimeBufferSize = 0;
  8177          _this._isReconnecting = false;
  8178          return _this;
  8179      }
  8180  
  8181      _createClass(MSStreamLoader, [{
  8182          key: 'destroy',
  8183          value: function destroy() {
  8184              if (this.isWorking()) {
  8185                  this.abort();
  8186              }
  8187              if (this._reader) {
  8188                  this._reader.onprogress = null;
  8189                  this._reader.onload = null;
  8190                  this._reader.onerror = null;
  8191                  this._reader = null;
  8192              }
  8193              if (this._xhr) {
  8194                  this._xhr.onreadystatechange = null;
  8195                  this._xhr = null;
  8196              }
  8197              _get(MSStreamLoader.prototype.__proto__ || Object.getPrototypeOf(MSStreamLoader.prototype), 'destroy', this).call(this);
  8198          }
  8199      }, {
  8200          key: 'open',
  8201          value: function open(dataSource, range) {
  8202              this._internalOpen(dataSource, range, false);
  8203          }
  8204      }, {
  8205          key: '_internalOpen',
  8206          value: function _internalOpen(dataSource, range, isSubrange) {
  8207              this._dataSource = dataSource;
  8208  
  8209              if (!isSubrange) {
  8210                  this._totalRange = range;
  8211              } else {
  8212                  this._currentRange = range;
  8213              }
  8214  
  8215              var sourceURL = dataSource.url;
  8216              if (this._config.reuseRedirectedURL) {
  8217                  if (this._currentRedirectedURL != undefined) {
  8218                      sourceURL = this._currentRedirectedURL;
  8219                  } else if (dataSource.redirectedURL != undefined) {
  8220                      sourceURL = dataSource.redirectedURL;
  8221                  }
  8222              }
  8223  
  8224              var seekConfig = this._seekHandler.getConfig(sourceURL, range);
  8225              this._currentRequestURL = seekConfig.url;
  8226  
  8227              var reader = this._reader = new self.MSStreamReader();
  8228              reader.onprogress = this._msrOnProgress.bind(this);
  8229              reader.onload = this._msrOnLoad.bind(this);
  8230              reader.onerror = this._msrOnError.bind(this);
  8231  
  8232              var xhr = this._xhr = new XMLHttpRequest();
  8233              xhr.open('GET', seekConfig.url, true);
  8234              xhr.responseType = 'ms-stream';
  8235              xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);
  8236              xhr.onerror = this._xhrOnError.bind(this);
  8237  
  8238              if (dataSource.withCredentials) {
  8239                  xhr.withCredentials = true;
  8240              }
  8241  
  8242              if (_typeof(seekConfig.headers) === 'object') {
  8243                  var headers = seekConfig.headers;
  8244  
  8245                  for (var key in headers) {
  8246                      if (headers.hasOwnProperty(key)) {
  8247                          xhr.setRequestHeader(key, headers[key]);
  8248                      }
  8249                  }
  8250              }
  8251  
  8252              // add additional headers
  8253              if (_typeof(this._config.headers) === 'object') {
  8254                  var _headers = this._config.headers;
  8255  
  8256                  for (var _key in _headers) {
  8257                      if (_headers.hasOwnProperty(_key)) {
  8258                          xhr.setRequestHeader(_key, _headers[_key]);
  8259                      }
  8260                  }
  8261              }
  8262  
  8263              if (this._isReconnecting) {
  8264                  this._isReconnecting = false;
  8265              } else {
  8266                  this._status = _loader.LoaderStatus.kConnecting;
  8267              }
  8268              xhr.send();
  8269          }
  8270      }, {
  8271          key: 'abort',
  8272          value: function abort() {
  8273              this._internalAbort();
  8274              this._status = _loader.LoaderStatus.kComplete;
  8275          }
  8276      }, {
  8277          key: '_internalAbort',
  8278          value: function _internalAbort() {
  8279              if (this._reader) {
  8280                  if (this._reader.readyState === 1) {
  8281                      // LOADING
  8282                      this._reader.abort();
  8283                  }
  8284                  this._reader.onprogress = null;
  8285                  this._reader.onload = null;
  8286                  this._reader.onerror = null;
  8287                  this._reader = null;
  8288              }
  8289              if (this._xhr) {
  8290                  this._xhr.abort();
  8291                  this._xhr.onreadystatechange = null;
  8292                  this._xhr = null;
  8293              }
  8294          }
  8295      }, {
  8296          key: '_xhrOnReadyStateChange',
  8297          value: function _xhrOnReadyStateChange(e) {
  8298              var xhr = e.target;
  8299  
  8300              if (xhr.readyState === 2) {
  8301                  // HEADERS_RECEIVED
  8302                  if (xhr.status >= 200 && xhr.status <= 299) {
  8303                      this._status = _loader.LoaderStatus.kBuffering;
  8304  
  8305                      if (xhr.responseURL != undefined) {
  8306                          var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
  8307                          if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {
  8308                              this._currentRedirectedURL = redirectedURL;
  8309                              if (this._onURLRedirect) {
  8310                                  this._onURLRedirect(redirectedURL);
  8311                              }
  8312                          }
  8313                      }
  8314  
  8315                      var lengthHeader = xhr.getResponseHeader('Content-Length');
  8316                      if (lengthHeader != null && this._contentLength == null) {
  8317                          var length = parseInt(lengthHeader);
  8318                          if (length > 0) {
  8319                              this._contentLength = length;
  8320                              if (this._onContentLengthKnown) {
  8321                                  this._onContentLengthKnown(this._contentLength);
  8322                              }
  8323                          }
  8324                      }
  8325                  } else {
  8326                      this._status = _loader.LoaderStatus.kError;
  8327                      if (this._onError) {
  8328                          this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
  8329                      } else {
  8330                          throw new _exception.RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
  8331                      }
  8332                  }
  8333              } else if (xhr.readyState === 3) {
  8334                  // LOADING
  8335                  if (xhr.status >= 200 && xhr.status <= 299) {
  8336                      this._status = _loader.LoaderStatus.kBuffering;
  8337  
  8338                      var msstream = xhr.response;
  8339                      this._reader.readAsArrayBuffer(msstream);
  8340                  }
  8341              }
  8342          }
  8343      }, {
  8344          key: '_xhrOnError',
  8345          value: function _xhrOnError(e) {
  8346              this._status = _loader.LoaderStatus.kError;
  8347              var type = _loader.LoaderErrors.EXCEPTION;
  8348              var info = { code: -1, msg: e.constructor.name + ' ' + e.type };
  8349  
  8350              if (this._onError) {
  8351                  this._onError(type, info);
  8352              } else {
  8353                  throw new _exception.RuntimeException(info.msg);
  8354              }
  8355          }
  8356      }, {
  8357          key: '_msrOnProgress',
  8358          value: function _msrOnProgress(e) {
  8359              var reader = e.target;
  8360              var bigbuffer = reader.result;
  8361              if (bigbuffer == null) {
  8362                  // result may be null, workaround for buggy M$
  8363                  this._doReconnectIfNeeded();
  8364                  return;
  8365              }
  8366  
  8367              var slice = bigbuffer.slice(this._lastTimeBufferSize);
  8368              this._lastTimeBufferSize = bigbuffer.byteLength;
  8369              var byteStart = this._totalRange.from + this._receivedLength;
  8370              this._receivedLength += slice.byteLength;
  8371  
  8372              if (this._onDataArrival) {
  8373                  this._onDataArrival(slice, byteStart, this._receivedLength);
  8374              }
  8375  
  8376              if (bigbuffer.byteLength >= this._bufferLimit) {
  8377                  _logger2.default.v(this.TAG, 'MSStream buffer exceeded max size near ' + (byteStart + slice.byteLength) + ', reconnecting...');
  8378                  this._doReconnectIfNeeded();
  8379              }
  8380          }
  8381      }, {
  8382          key: '_doReconnectIfNeeded',
  8383          value: function _doReconnectIfNeeded() {
  8384              if (this._contentLength == null || this._receivedLength < this._contentLength) {
  8385                  this._isReconnecting = true;
  8386                  this._lastTimeBufferSize = 0;
  8387                  this._internalAbort();
  8388  
  8389                  var range = {
  8390                      from: this._totalRange.from + this._receivedLength,
  8391                      to: -1
  8392                  };
  8393                  this._internalOpen(this._dataSource, range, true);
  8394              }
  8395          }
  8396      }, {
  8397          key: '_msrOnLoad',
  8398          value: function _msrOnLoad(e) {
  8399              // actually it is onComplete event
  8400              this._status = _loader.LoaderStatus.kComplete;
  8401              if (this._onComplete) {
  8402                  this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);
  8403              }
  8404          }
  8405      }, {
  8406          key: '_msrOnError',
  8407          value: function _msrOnError(e) {
  8408              this._status = _loader.LoaderStatus.kError;
  8409              var type = 0;
  8410              var info = null;
  8411  
  8412              if (this._contentLength && this._receivedLength < this._contentLength) {
  8413                  type = _loader.LoaderErrors.EARLY_EOF;
  8414                  info = { code: -1, msg: 'MSStream meet Early-Eof' };
  8415              } else {
  8416                  type = _loader.LoaderErrors.EARLY_EOF;
  8417                  info = { code: -1, msg: e.constructor.name + ' ' + e.type };
  8418              }
  8419  
  8420              if (this._onError) {
  8421                  this._onError(type, info);
  8422              } else {
  8423                  throw new _exception.RuntimeException(info.msg);
  8424              }
  8425          }
  8426      }]);
  8427  
  8428      return MSStreamLoader;
  8429  }(_loader.BaseLoader);
  8430  
  8431  exports.default = MSStreamLoader;
  8432  
  8433  },{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24}],31:[function(_dereq_,module,exports){
  8434  'use strict';
  8435  
  8436  Object.defineProperty(exports, "__esModule", {
  8437      value: true
  8438  });
  8439  
  8440  var _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; };
  8441  
  8442  var _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); } };
  8443  
  8444  var _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; }; }();
  8445  
  8446  var _logger = _dereq_('../utils/logger.js');
  8447  
  8448  var _logger2 = _interopRequireDefault(_logger);
  8449  
  8450  var _speedSampler = _dereq_('./speed-sampler.js');
  8451  
  8452  var _speedSampler2 = _interopRequireDefault(_speedSampler);
  8453  
  8454  var _loader = _dereq_('./loader.js');
  8455  
  8456  var _exception = _dereq_('../utils/exception.js');
  8457  
  8458  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8459  
  8460  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  8461  
  8462  function _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; }
  8463  
  8464  function _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; } /*
  8465                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (C) 2016 Bilibili. All Rights Reserved.
  8466                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8467                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @author zheng qian <xqq@xqq.im>
  8468                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8469                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Licensed under the Apache License, Version 2.0 (the "License");
  8470                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * you may not use this file except in compliance with the License.
  8471                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * You may obtain a copy of the License at
  8472                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8473                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *     http://www.apache.org/licenses/LICENSE-2.0
  8474                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
  8475                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Unless required by applicable law or agreed to in writing, software
  8476                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * distributed under the License is distributed on an "AS IS" BASIS,
  8477                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8478                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * See the License for the specific language governing permissions and
  8479                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * limitations under the License.
  8480                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  8481  
  8482  // Universal IO Loader, implemented by adding Range header in xhr's request header
  8483  var RangeLoader = function (_BaseLoader) {
  8484      _inherits(RangeLoader, _BaseLoader);
  8485  
  8486      _createClass(RangeLoader, null, [{
  8487          key: 'isSupported',
  8488          value: function isSupported() {
  8489              try {
  8490                  var xhr = new XMLHttpRequest();
  8491                  xhr.open('GET', 'https://example.com', true);
  8492                  xhr.responseType = 'arraybuffer';
  8493                  return xhr.responseType === 'arraybuffer';
  8494              } catch (e) {
  8495                  _logger2.default.w('RangeLoader', e.message);
  8496                  return false;
  8497              }
  8498          }
  8499      }]);
  8500  
  8501      function RangeLoader(seekHandler, config) {
  8502          _classCallCheck(this, RangeLoader);
  8503  
  8504          var _this = _possibleConstructorReturn(this, (RangeLoader.__proto__ || Object.getPrototypeOf(RangeLoader)).call(this, 'xhr-range-loader'));
  8505  
  8506          _this.TAG = 'RangeLoader';
  8507  
  8508          _this._seekHandler = seekHandler;
  8509          _this._config = config;
  8510          _this._needStash = false;
  8511  
  8512          _this._chunkSizeKBList = [128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192];
  8513          _this._currentChunkSizeKB = 384;
  8514          _this._currentSpeedNormalized = 0;
  8515          _this._zeroSpeedChunkCount = 0;
  8516  
  8517          _this._xhr = null;
  8518          _this._speedSampler = new _speedSampler2.default();
  8519  
  8520          _this._requestAbort = false;
  8521          _this._waitForTotalLength = false;
  8522          _this._totalLengthReceived = false;
  8523  
  8524          _this._currentRequestURL = null;
  8525          _this._currentRedirectedURL = null;
  8526          _this._currentRequestRange = null;
  8527          _this._totalLength = null; // size of the entire file
  8528          _this._contentLength = null; // Content-Length of entire request range
  8529          _this._receivedLength = 0; // total received bytes
  8530          _this._lastTimeLoaded = 0; // received bytes of current request sub-range
  8531          return _this;
  8532      }
  8533  
  8534      _createClass(RangeLoader, [{
  8535          key: 'destroy',
  8536          value: function destroy() {
  8537              if (this.isWorking()) {
  8538                  this.abort();
  8539              }
  8540              if (this._xhr) {
  8541                  this._xhr.onreadystatechange = null;
  8542                  this._xhr.onprogress = null;
  8543                  this._xhr.onload = null;
  8544                  this._xhr.onerror = null;
  8545                  this._xhr = null;
  8546              }
  8547              _get(RangeLoader.prototype.__proto__ || Object.getPrototypeOf(RangeLoader.prototype), 'destroy', this).call(this);
  8548          }
  8549      }, {
  8550          key: 'open',
  8551          value: function open(dataSource, range) {
  8552              this._dataSource = dataSource;
  8553              this._range = range;
  8554              this._status = _loader.LoaderStatus.kConnecting;
  8555  
  8556              var useRefTotalLength = false;
  8557              if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {
  8558                  useRefTotalLength = true;
  8559                  this._totalLength = this._dataSource.filesize;
  8560              }
  8561  
  8562              if (!this._totalLengthReceived && !useRefTotalLength) {
  8563                  // We need total filesize
  8564                  this._waitForTotalLength = true;
  8565                  this._internalOpen(this._dataSource, { from: 0, to: -1 });
  8566              } else {
  8567                  // We have filesize, start loading
  8568                  this._openSubRange();
  8569              }
  8570          }
  8571      }, {
  8572          key: '_openSubRange',
  8573          value: function _openSubRange() {
  8574              var chunkSize = this._currentChunkSizeKB * 1024;
  8575  
  8576              var from = this._range.from + this._receivedLength;
  8577              var to = from + chunkSize;
  8578  
  8579              if (this._contentLength != null) {
  8580                  if (to - this._range.from >= this._contentLength) {
  8581                      to = this._range.from + this._contentLength - 1;
  8582                  }
  8583              }
  8584  
  8585              this._currentRequestRange = { from: from, to: to };
  8586              this._internalOpen(this._dataSource, this._currentRequestRange);
  8587          }
  8588      }, {
  8589          key: '_internalOpen',
  8590          value: function _internalOpen(dataSource, range) {
  8591              this._lastTimeLoaded = 0;
  8592  
  8593              var sourceURL = dataSource.url;
  8594              if (this._config.reuseRedirectedURL) {
  8595                  if (this._currentRedirectedURL != undefined) {
  8596                      sourceURL = this._currentRedirectedURL;
  8597                  } else if (dataSource.redirectedURL != undefined) {
  8598                      sourceURL = dataSource.redirectedURL;
  8599                  }
  8600              }
  8601  
  8602              var seekConfig = this._seekHandler.getConfig(sourceURL, range);
  8603              this._currentRequestURL = seekConfig.url;
  8604  
  8605              var xhr = this._xhr = new XMLHttpRequest();
  8606              xhr.open('GET', seekConfig.url, true);
  8607              xhr.responseType = 'arraybuffer';
  8608              xhr.onreadystatechange = this._onReadyStateChange.bind(this);
  8609              xhr.onprogress = this._onProgress.bind(this);
  8610              xhr.onload = this._onLoad.bind(this);
  8611              xhr.onerror = this._onXhrError.bind(this);
  8612  
  8613              if (dataSource.withCredentials) {
  8614                  xhr.withCredentials = true;
  8615              }
  8616  
  8617              if (_typeof(seekConfig.headers) === 'object') {
  8618                  var headers = seekConfig.headers;
  8619  
  8620                  for (var key in headers) {
  8621                      if (headers.hasOwnProperty(key)) {
  8622                          xhr.setRequestHeader(key, headers[key]);
  8623                      }
  8624                  }
  8625              }
  8626  
  8627              // add additional headers
  8628              if (_typeof(this._config.headers) === 'object') {
  8629                  var _headers = this._config.headers;
  8630  
  8631                  for (var _key in _headers) {
  8632                      if (_headers.hasOwnProperty(_key)) {
  8633                          xhr.setRequestHeader(_key, _headers[_key]);
  8634                      }
  8635                  }
  8636              }
  8637  
  8638              xhr.send();
  8639          }
  8640      }, {
  8641          key: 'abort',
  8642          value: function abort() {
  8643              this._requestAbort = true;
  8644              this._internalAbort();
  8645              this._status = _loader.LoaderStatus.kComplete;
  8646          }
  8647      }, {
  8648          key: '_internalAbort',
  8649          value: function _internalAbort() {
  8650              if (this._xhr) {
  8651                  this._xhr.onreadystatechange = null;
  8652                  this._xhr.onprogress = null;
  8653                  this._xhr.onload = null;
  8654                  this._xhr.onerror = null;
  8655                  this._xhr.abort();
  8656                  this._xhr = null;
  8657              }
  8658          }
  8659      }, {
  8660          key: '_onReadyStateChange',
  8661          value: function _onReadyStateChange(e) {
  8662              var xhr = e.target;
  8663  
  8664              if (xhr.readyState === 2) {
  8665                  // HEADERS_RECEIVED
  8666                  if (xhr.responseURL != undefined) {
  8667                      // if the browser support this property
  8668                      var redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);
  8669                      if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {
  8670                          this._currentRedirectedURL = redirectedURL;
  8671                          if (this._onURLRedirect) {
  8672                              this._onURLRedirect(redirectedURL);
  8673                          }
  8674                      }
  8675                  }
  8676  
  8677                  if (xhr.status >= 200 && xhr.status <= 299) {
  8678                      if (this._waitForTotalLength) {
  8679                          return;
  8680                      }
  8681                      this._status = _loader.LoaderStatus.kBuffering;
  8682                  } else {
  8683                      this._status = _loader.LoaderStatus.kError;
  8684                      if (this._onError) {
  8685                          this._onError(_loader.LoaderErrors.HTTP_STATUS_CODE_INVALID, { code: xhr.status, msg: xhr.statusText });
  8686                      } else {
  8687                          throw new _exception.RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);
  8688                      }
  8689                  }
  8690              }
  8691          }
  8692      }, {
  8693          key: '_onProgress',
  8694          value: function _onProgress(e) {
  8695              if (this._status === _loader.LoaderStatus.kError) {
  8696                  // Ignore error response
  8697                  return;
  8698              }
  8699  
  8700              if (this._contentLength === null) {
  8701                  var openNextRange = false;
  8702  
  8703                  if (this._waitForTotalLength) {
  8704                      this._waitForTotalLength = false;
  8705                      this._totalLengthReceived = true;
  8706                      openNextRange = true;
  8707  
  8708                      var total = e.total;
  8709                      this._internalAbort();
  8710                      if (total != null & total !== 0) {
  8711                          this._totalLength = total;
  8712                      }
  8713                  }
  8714  
  8715                  // calculate currrent request range's contentLength
  8716                  if (this._range.to === -1) {
  8717                      this._contentLength = this._totalLength - this._range.from;
  8718                  } else {
  8719                      // to !== -1
  8720                      this._contentLength = this._range.to - this._range.from + 1;
  8721                  }
  8722  
  8723                  if (openNextRange) {
  8724                      this._openSubRange();
  8725                      return;
  8726                  }
  8727                  if (this._onContentLengthKnown) {
  8728                      this._onContentLengthKnown(this._contentLength);
  8729                  }
  8730              }
  8731  
  8732              var delta = e.loaded - this._lastTimeLoaded;
  8733              this._lastTimeLoaded = e.loaded;
  8734              this._speedSampler.addBytes(delta);
  8735          }
  8736      }, {
  8737          key: '_normalizeSpeed',
  8738          value: function _normalizeSpeed(input) {
  8739              var list = this._chunkSizeKBList;
  8740              var last = list.length - 1;
  8741              var mid = 0;
  8742              var lbound = 0;
  8743              var ubound = last;
  8744  
  8745              if (input < list[0]) {
  8746                  return list[0];
  8747              }
  8748  
  8749              while (lbound <= ubound) {
  8750                  mid = lbound + Math.floor((ubound - lbound) / 2);
  8751                  if (mid === last || input >= list[mid] && input < list[mid + 1]) {
  8752                      return list[mid];
  8753                  } else if (list[mid] < input) {
  8754                      lbound = mid + 1;
  8755                  } else {
  8756                      ubound = mid - 1;
  8757                  }
  8758              }
  8759          }
  8760      }, {
  8761          key: '_onLoad',
  8762          value: function _onLoad(e) {
  8763              if (this._status === _loader.LoaderStatus.kError) {
  8764                  // Ignore error response
  8765                  return;
  8766              }
  8767  
  8768              if (this._waitForTotalLength) {
  8769                  this._waitForTotalLength = false;
  8770                  return;
  8771              }
  8772  
  8773              this._lastTimeLoaded = 0;
  8774              var KBps = this._speedSampler.lastSecondKBps;
  8775              if (KBps === 0) {
  8776                  this._zeroSpeedChunkCount++;
  8777                  if (this._zeroSpeedChunkCount >= 3) {
  8778                      // Try get currentKBps after 3 chunks
  8779                      KBps = this._speedSampler.currentKBps;
  8780                  }
  8781              }
  8782  
  8783              if (KBps !== 0) {
  8784                  var normalized = this._normalizeSpeed(KBps);
  8785                  if (this._currentSpeedNormalized !== normalized) {
  8786                      this._currentSpeedNormalized = normalized;
  8787                      this._currentChunkSizeKB = normalized;
  8788                  }
  8789              }
  8790  
  8791              var chunk = e.target.response;
  8792              var byteStart = this._range.from + this._receivedLength;
  8793              this._receivedLength += chunk.byteLength;
  8794  
  8795              var reportComplete = false;
  8796  
  8797              if (this._contentLength != null && this._receivedLength < this._contentLength) {
  8798                  // continue load next chunk
  8799                  this._openSubRange();
  8800              } else {
  8801                  reportComplete = true;
  8802              }
  8803  
  8804              // dispatch received chunk
  8805              if (this._onDataArrival) {
  8806                  this._onDataArrival(chunk, byteStart, this._receivedLength);
  8807              }
  8808  
  8809              if (reportComplete) {
  8810                  this._status = _loader.LoaderStatus.kComplete;
  8811                  if (this._onComplete) {
  8812                      this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
  8813                  }
  8814              }
  8815          }
  8816      }, {
  8817          key: '_onXhrError',
  8818          value: function _onXhrError(e) {
  8819              this._status = _loader.LoaderStatus.kError;
  8820              var type = 0;
  8821              var info = null;
  8822  
  8823              if (this._contentLength && this._receivedLength > 0 && this._receivedLength < this._contentLength) {
  8824                  type = _loader.LoaderErrors.EARLY_EOF;
  8825                  info = { code: -1, msg: 'RangeLoader meet Early-Eof' };
  8826              } else {
  8827                  type = _loader.LoaderErrors.EXCEPTION;
  8828                  info = { code: -1, msg: e.constructor.name + ' ' + e.type };
  8829              }
  8830  
  8831              if (this._onError) {
  8832                  this._onError(type, info);
  8833              } else {
  8834                  throw new _exception.RuntimeException(info.msg);
  8835              }
  8836          }
  8837      }, {
  8838          key: 'currentSpeed',
  8839          get: function get() {
  8840              return this._speedSampler.lastSecondKBps;
  8841          }
  8842      }]);
  8843  
  8844      return RangeLoader;
  8845  }(_loader.BaseLoader);
  8846  
  8847  exports.default = RangeLoader;
  8848  
  8849  },{"../utils/exception.js":40,"../utils/logger.js":41,"./loader.js":24,"./speed-sampler.js":27}],32:[function(_dereq_,module,exports){
  8850  'use strict';
  8851  
  8852  Object.defineProperty(exports, "__esModule", {
  8853      value: true
  8854  });
  8855  
  8856  var _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; };
  8857  
  8858  var _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; }; }(); /*
  8859                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  8860                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  8861                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  8862                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  8863                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  8864                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  8865                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  8866                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  8867                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  8868                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  8869                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  8870                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  8871                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8872                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  8873                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  8874                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  8875  
  8876  var _events = _dereq_('events');
  8877  
  8878  var _events2 = _interopRequireDefault(_events);
  8879  
  8880  var _logger = _dereq_('../utils/logger.js');
  8881  
  8882  var _logger2 = _interopRequireDefault(_logger);
  8883  
  8884  var _browser = _dereq_('../utils/browser.js');
  8885  
  8886  var _browser2 = _interopRequireDefault(_browser);
  8887  
  8888  var _playerEvents = _dereq_('./player-events.js');
  8889  
  8890  var _playerEvents2 = _interopRequireDefault(_playerEvents);
  8891  
  8892  var _transmuxer = _dereq_('../core/transmuxer.js');
  8893  
  8894  var _transmuxer2 = _interopRequireDefault(_transmuxer);
  8895  
  8896  var _transmuxingEvents = _dereq_('../core/transmuxing-events.js');
  8897  
  8898  var _transmuxingEvents2 = _interopRequireDefault(_transmuxingEvents);
  8899  
  8900  var _mseController = _dereq_('../core/mse-controller.js');
  8901  
  8902  var _mseController2 = _interopRequireDefault(_mseController);
  8903  
  8904  var _mseEvents = _dereq_('../core/mse-events.js');
  8905  
  8906  var _mseEvents2 = _interopRequireDefault(_mseEvents);
  8907  
  8908  var _playerErrors = _dereq_('./player-errors.js');
  8909  
  8910  var _config = _dereq_('../config.js');
  8911  
  8912  var _exception = _dereq_('../utils/exception.js');
  8913  
  8914  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8915  
  8916  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  8917  
  8918  var FlvPlayer = function () {
  8919      function FlvPlayer(mediaDataSource, config) {
  8920          _classCallCheck(this, FlvPlayer);
  8921  
  8922          this.TAG = 'FlvPlayer';
  8923          this._type = 'FlvPlayer';
  8924          this._emitter = new _events2.default();
  8925  
  8926          this._config = (0, _config.createDefaultConfig)();
  8927          if ((typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object') {
  8928              Object.assign(this._config, config);
  8929          }
  8930  
  8931          if (mediaDataSource.type.toLowerCase() !== 'flv') {
  8932              throw new _exception.InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');
  8933          }
  8934  
  8935          if (mediaDataSource.isLive === true) {
  8936              this._config.isLive = true;
  8937          }
  8938  
  8939          this.e = {
  8940              onvLoadedMetadata: this._onvLoadedMetadata.bind(this),
  8941              onvSeeking: this._onvSeeking.bind(this),
  8942              onvCanPlay: this._onvCanPlay.bind(this),
  8943              onvStalled: this._onvStalled.bind(this),
  8944              onvProgress: this._onvProgress.bind(this)
  8945          };
  8946  
  8947          if (self.performance && self.performance.now) {
  8948              this._now = self.performance.now.bind(self.performance);
  8949          } else {
  8950              this._now = Date.now;
  8951          }
  8952  
  8953          this._pendingSeekTime = null; // in seconds
  8954          this._requestSetTime = false;
  8955          this._seekpointRecord = null;
  8956          this._progressChecker = null;
  8957  
  8958          this._mediaDataSource = mediaDataSource;
  8959          this._mediaElement = null;
  8960          this._msectl = null;
  8961          this._transmuxer = null;
  8962  
  8963          this._mseSourceOpened = false;
  8964          this._hasPendingLoad = false;
  8965          this._receivedCanPlay = false;
  8966  
  8967          this._mediaInfo = null;
  8968          this._statisticsInfo = null;
  8969  
  8970          var chromeNeedIDRFix = _browser2.default.chrome && (_browser2.default.version.major < 50 || _browser2.default.version.major === 50 && _browser2.default.version.build < 2661);
  8971          this._alwaysSeekKeyframe = chromeNeedIDRFix || _browser2.default.msedge || _browser2.default.msie ? true : false;
  8972  
  8973          if (this._alwaysSeekKeyframe) {
  8974              this._config.accurateSeek = false;
  8975          }
  8976      }
  8977  
  8978      _createClass(FlvPlayer, [{
  8979          key: 'destroy',
  8980          value: function destroy() {
  8981              if (this._progressChecker != null) {
  8982                  window.clearInterval(this._progressChecker);
  8983                  this._progressChecker = null;
  8984              }
  8985              if (this._transmuxer) {
  8986                  this.unload();
  8987              }
  8988              if (this._mediaElement) {
  8989                  this.detachMediaElement();
  8990              }
  8991              this.e = null;
  8992              this._mediaDataSource = null;
  8993  
  8994              this._emitter.removeAllListeners();
  8995              this._emitter = null;
  8996          }
  8997      }, {
  8998          key: 'on',
  8999          value: function on(event, listener) {
  9000              var _this = this;
  9001  
  9002              if (event === _playerEvents2.default.MEDIA_INFO) {
  9003                  if (this._mediaInfo != null) {
  9004                      Promise.resolve().then(function () {
  9005                          _this._emitter.emit(_playerEvents2.default.MEDIA_INFO, _this.mediaInfo);
  9006                      });
  9007                  }
  9008              } else if (event === _playerEvents2.default.STATISTICS_INFO) {
  9009                  if (this._statisticsInfo != null) {
  9010                      Promise.resolve().then(function () {
  9011                          _this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, _this.statisticsInfo);
  9012                      });
  9013                  }
  9014              }
  9015              this._emitter.addListener(event, listener);
  9016          }
  9017      }, {
  9018          key: 'off',
  9019          value: function off(event, listener) {
  9020              this._emitter.removeListener(event, listener);
  9021          }
  9022      }, {
  9023          key: 'attachMediaElement',
  9024          value: function attachMediaElement(mediaElement) {
  9025              var _this2 = this;
  9026  
  9027              this._mediaElement = mediaElement;
  9028              mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);
  9029              mediaElement.addEventListener('seeking', this.e.onvSeeking);
  9030              mediaElement.addEventListener('canplay', this.e.onvCanPlay);
  9031              mediaElement.addEventListener('stalled', this.e.onvStalled);
  9032              mediaElement.addEventListener('progress', this.e.onvProgress);
  9033  
  9034              this._msectl = new _mseController2.default(this._config);
  9035  
  9036              this._msectl.on(_mseEvents2.default.UPDATE_END, this._onmseUpdateEnd.bind(this));
  9037              this._msectl.on(_mseEvents2.default.BUFFER_FULL, this._onmseBufferFull.bind(this));
  9038              this._msectl.on(_mseEvents2.default.SOURCE_OPEN, function () {
  9039                  _this2._mseSourceOpened = true;
  9040                  if (_this2._hasPendingLoad) {
  9041                      _this2._hasPendingLoad = false;
  9042                      _this2.load();
  9043                  }
  9044              });
  9045              this._msectl.on(_mseEvents2.default.ERROR, function (info) {
  9046                  _this2._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.MEDIA_ERROR, _playerErrors.ErrorDetails.MEDIA_MSE_ERROR, info);
  9047              });
  9048  
  9049              this._msectl.attachMediaElement(mediaElement);
  9050  
  9051              if (this._pendingSeekTime != null) {
  9052                  try {
  9053                      mediaElement.currentTime = this._pendingSeekTime;
  9054                      this._pendingSeekTime = null;
  9055                  } catch (e) {
  9056                      // IE11 may throw InvalidStateError if readyState === 0
  9057                      // We can defer set currentTime operation after loadedmetadata
  9058                  }
  9059              }
  9060          }
  9061      }, {
  9062          key: 'detachMediaElement',
  9063          value: function detachMediaElement() {
  9064              if (this._mediaElement) {
  9065                  this._msectl.detachMediaElement();
  9066                  this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);
  9067                  this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);
  9068                  this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);
  9069                  this._mediaElement.removeEventListener('stalled', this.e.onvStalled);
  9070                  this._mediaElement.removeEventListener('progress', this.e.onvProgress);
  9071                  this._mediaElement = null;
  9072              }
  9073              if (this._msectl) {
  9074                  this._msectl.destroy();
  9075                  this._msectl = null;
  9076              }
  9077          }
  9078      }, {
  9079          key: 'load',
  9080          value: function load() {
  9081              var _this3 = this;
  9082  
  9083              if (!this._mediaElement) {
  9084                  throw new _exception.IllegalStateException('HTMLMediaElement must be attached before load()!');
  9085              }
  9086              if (this._transmuxer) {
  9087                  throw new _exception.IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');
  9088              }
  9089              if (this._hasPendingLoad) {
  9090                  return;
  9091              }
  9092  
  9093              if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {
  9094                  this._hasPendingLoad = true;
  9095                  return;
  9096              }
  9097  
  9098              if (this._mediaElement.readyState > 0) {
  9099                  this._requestSetTime = true;
  9100                  // IE11 may throw InvalidStateError if readyState === 0
  9101                  this._mediaElement.currentTime = 0;
  9102              }
  9103  
  9104              this._transmuxer = new _transmuxer2.default(this._mediaDataSource, this._config);
  9105  
  9106              this._transmuxer.on(_transmuxingEvents2.default.INIT_SEGMENT, function (type, is) {
  9107                  _this3._msectl.appendInitSegment(is);
  9108              });
  9109              this._transmuxer.on(_transmuxingEvents2.default.MEDIA_SEGMENT, function (type, ms) {
  9110                  _this3._msectl.appendMediaSegment(ms);
  9111  
  9112                  // lazyLoad check
  9113                  if (_this3._config.lazyLoad && !_this3._config.isLive) {
  9114                      var currentTime = _this3._mediaElement.currentTime;
  9115                      if (ms.info.endDts >= (currentTime + _this3._config.lazyLoadMaxDuration) * 1000) {
  9116                          if (_this3._progressChecker == null) {
  9117                              _logger2.default.v(_this3.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');
  9118                              _this3._suspendTransmuxer();
  9119                          }
  9120                      }
  9121                  }
  9122              });
  9123              this._transmuxer.on(_transmuxingEvents2.default.LOADING_COMPLETE, function () {
  9124                  _this3._msectl.endOfStream();
  9125                  _this3._emitter.emit(_playerEvents2.default.LOADING_COMPLETE);
  9126              });
  9127              this._transmuxer.on(_transmuxingEvents2.default.RECOVERED_EARLY_EOF, function () {
  9128                  _this3._emitter.emit(_playerEvents2.default.RECOVERED_EARLY_EOF);
  9129              });
  9130              this._transmuxer.on(_transmuxingEvents2.default.IO_ERROR, function (detail, info) {
  9131                  _this3._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.NETWORK_ERROR, detail, info);
  9132              });
  9133              this._transmuxer.on(_transmuxingEvents2.default.DEMUX_ERROR, function (detail, info) {
  9134                  _this3._emitter.emit(_playerEvents2.default.ERROR, _playerErrors.ErrorTypes.MEDIA_ERROR, detail, { code: -1, msg: info });
  9135              });
  9136              this._transmuxer.on(_transmuxingEvents2.default.MEDIA_INFO, function (mediaInfo) {
  9137                  _this3._mediaInfo = mediaInfo;
  9138                  _this3._emitter.emit(_playerEvents2.default.MEDIA_INFO, Object.assign({}, mediaInfo));
  9139              });
  9140              this._transmuxer.on(_transmuxingEvents2.default.METADATA_ARRIVED, function (metadata) {
  9141                  _this3._emitter.emit(_playerEvents2.default.METADATA_ARRIVED, metadata);
  9142              });
  9143              this._transmuxer.on(_transmuxingEvents2.default.SCRIPTDATA_ARRIVED, function (data) {
  9144                  _this3._emitter.emit(_playerEvents2.default.SCRIPTDATA_ARRIVED, data);
  9145              });
  9146              this._transmuxer.on(_transmuxingEvents2.default.STATISTICS_INFO, function (statInfo) {
  9147                  _this3._statisticsInfo = _this3._fillStatisticsInfo(statInfo);
  9148                  _this3._emitter.emit(_playerEvents2.default.STATISTICS_INFO, Object.assign({}, _this3._statisticsInfo));
  9149              });
  9150              this._transmuxer.on(_transmuxingEvents2.default.RECOMMEND_SEEKPOINT, function (milliseconds) {
  9151                  if (_this3._mediaElement && !_this3._config.accurateSeek) {
  9152                      _this3._requestSetTime = true;
  9153                      _this3._mediaElement.currentTime = milliseconds / 1000;
  9154                  }
  9155              });
  9156  
  9157              this._transmuxer.open();
  9158          }
  9159      }, {
  9160          key: 'unload',
  9161          value: function unload() {
  9162              if (this._mediaElement) {
  9163                  this._mediaElement.pause();
  9164              }
  9165              if (this._msectl) {
  9166                  this._msectl.seek(0);
  9167              }
  9168              if (this._transmuxer) {
  9169                  this._transmuxer.close();
  9170                  this._transmuxer.destroy();
  9171                  this._transmuxer = null;
  9172              }
  9173          }
  9174      }, {
  9175          key: 'play',
  9176          value: function play() {
  9177              return this._mediaElement.play();
  9178          }
  9179      }, {
  9180          key: 'pause',
  9181          value: function pause() {
  9182              this._mediaElement.pause();
  9183          }
  9184      }, {
  9185          key: '_fillStatisticsInfo',
  9186          value: function _fillStatisticsInfo(statInfo) {
  9187              statInfo.playerType = this._type;
  9188  
  9189              if (!(this._mediaElement instanceof HTMLVideoElement)) {
  9190                  return statInfo;
  9191              }
  9192  
  9193              var hasQualityInfo = true;
  9194              var decoded = 0;
  9195              var dropped = 0;
  9196  
  9197              if (this._mediaElement.getVideoPlaybackQuality) {
  9198                  var quality = this._mediaElement.getVideoPlaybackQuality();
  9199                  decoded = quality.totalVideoFrames;
  9200                  dropped = quality.droppedVideoFrames;
  9201              } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {
  9202                  decoded = this._mediaElement.webkitDecodedFrameCount;
  9203                  dropped = this._mediaElement.webkitDroppedFrameCount;
  9204              } else {
  9205                  hasQualityInfo = false;
  9206              }
  9207  
  9208              if (hasQualityInfo) {
  9209                  statInfo.decodedFrames = decoded;
  9210                  statInfo.droppedFrames = dropped;
  9211              }
  9212  
  9213              return statInfo;
  9214          }
  9215      }, {
  9216          key: '_onmseUpdateEnd',
  9217          value: function _onmseUpdateEnd() {
  9218              if (!this._config.lazyLoad || this._config.isLive) {
  9219                  return;
  9220              }
  9221  
  9222              var buffered = this._mediaElement.buffered;
  9223              var currentTime = this._mediaElement.currentTime;
  9224              var currentRangeStart = 0;
  9225              var currentRangeEnd = 0;
  9226  
  9227              for (var i = 0; i < buffered.length; i++) {
  9228                  var start = buffered.start(i);
  9229                  var end = buffered.end(i);
  9230                  if (start <= currentTime && currentTime < end) {
  9231                      currentRangeStart = start;
  9232                      currentRangeEnd = end;
  9233                      break;
  9234                  }
  9235              }
  9236  
  9237              if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {
  9238                  _logger2.default.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');
  9239                  this._suspendTransmuxer();
  9240              }
  9241          }
  9242      }, {
  9243          key: '_onmseBufferFull',
  9244          value: function _onmseBufferFull() {
  9245              _logger2.default.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');
  9246              if (this._progressChecker == null) {
  9247                  this._suspendTransmuxer();
  9248              }
  9249          }
  9250      }, {
  9251          key: '_suspendTransmuxer',
  9252          value: function _suspendTransmuxer() {
  9253              if (this._transmuxer) {
  9254                  this._transmuxer.pause();
  9255  
  9256                  if (this._progressChecker == null) {
  9257                      this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);
  9258                  }
  9259              }
  9260          }
  9261      }, {
  9262          key: '_checkProgressAndResume',
  9263          value: function _checkProgressAndResume() {
  9264              var currentTime = this._mediaElement.currentTime;
  9265              var buffered = this._mediaElement.buffered;
  9266  
  9267              var needResume = false;
  9268  
  9269              for (var i = 0; i < buffered.length; i++) {
  9270                  var from = buffered.start(i);
  9271                  var to = buffered.end(i);
  9272                  if (currentTime >= from && currentTime < to) {
  9273                      if (currentTime >= to - this._config.lazyLoadRecoverDuration) {
  9274                          needResume = true;
  9275                      }
  9276                      break;
  9277                  }
  9278              }
  9279  
  9280              if (needResume) {
  9281                  window.clearInterval(this._progressChecker);
  9282                  this._progressChecker = null;
  9283                  if (needResume) {
  9284                      _logger2.default.v(this.TAG, 'Continue loading from paused position');
  9285                      this._transmuxer.resume();
  9286                  }
  9287              }
  9288          }
  9289      }, {
  9290          key: '_isTimepointBuffered',
  9291          value: function _isTimepointBuffered(seconds) {
  9292              var buffered = this._mediaElement.buffered;
  9293  
  9294              for (var i = 0; i < buffered.length; i++) {
  9295                  var from = buffered.start(i);
  9296                  var to = buffered.end(i);
  9297                  if (seconds >= from && seconds < to) {
  9298                      return true;
  9299                  }
  9300              }
  9301              return false;
  9302          }
  9303      }, {
  9304          key: '_internalSeek',
  9305          value: function _internalSeek(seconds) {
  9306              var directSeek = this._isTimepointBuffered(seconds);
  9307  
  9308              var directSeekBegin = false;
  9309              var directSeekBeginTime = 0;
  9310  
  9311              if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {
  9312                  var videoBeginTime = this._mediaElement.buffered.start(0);
  9313                  if (videoBeginTime < 1.0 && seconds < videoBeginTime || _browser2.default.safari) {
  9314                      directSeekBegin = true;
  9315                      // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid
  9316                      directSeekBeginTime = _browser2.default.safari ? 0.1 : videoBeginTime;
  9317                  }
  9318              }
  9319  
  9320              if (directSeekBegin) {
  9321                  // seek to video begin, set currentTime directly if beginPTS buffered
  9322                  this._requestSetTime = true;
  9323                  this._mediaElement.currentTime = directSeekBeginTime;
  9324              } else if (directSeek) {
  9325                  // buffered position
  9326                  if (!this._alwaysSeekKeyframe) {
  9327                      this._requestSetTime = true;
  9328                      this._mediaElement.currentTime = seconds;
  9329                  } else {
  9330                      var idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));
  9331                      this._requestSetTime = true;
  9332                      if (idr != null) {
  9333                          this._mediaElement.currentTime = idr.dts / 1000;
  9334                      } else {
  9335                          this._mediaElement.currentTime = seconds;
  9336                      }
  9337                  }
  9338                  if (this._progressChecker != null) {
  9339                      this._checkProgressAndResume();
  9340                  }
  9341              } else {
  9342                  if (this._progressChecker != null) {
  9343                      window.clearInterval(this._progressChecker);
  9344                      this._progressChecker = null;
  9345                  }
  9346                  this._msectl.seek(seconds);
  9347                  this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds
  9348                  // no need to set mediaElement.currentTime if non-accurateSeek,
  9349                  // just wait for the recommend_seekpoint callback
  9350                  if (this._config.accurateSeek) {
  9351                      this._requestSetTime = true;
  9352                      this._mediaElement.currentTime = seconds;
  9353                  }
  9354              }
  9355          }
  9356      }, {
  9357          key: '_checkAndApplyUnbufferedSeekpoint',
  9358          value: function _checkAndApplyUnbufferedSeekpoint() {
  9359              if (this._seekpointRecord) {
  9360                  if (this._seekpointRecord.recordTime <= this._now() - 100) {
  9361                      var target = this._mediaElement.currentTime;
  9362                      this._seekpointRecord = null;
  9363                      if (!this._isTimepointBuffered(target)) {
  9364                          if (this._progressChecker != null) {
  9365                              window.clearTimeout(this._progressChecker);
  9366                              this._progressChecker = null;
  9367                          }
  9368                          // .currentTime is consists with .buffered timestamp
  9369                          // Chrome/Edge use DTS, while FireFox/Safari use PTS
  9370                          this._msectl.seek(target);
  9371                          this._transmuxer.seek(Math.floor(target * 1000));
  9372                          // set currentTime if accurateSeek, or wait for recommend_seekpoint callback
  9373                          if (this._config.accurateSeek) {
  9374                              this._requestSetTime = true;
  9375                              this._mediaElement.currentTime = target;
  9376                          }
  9377                      }
  9378                  } else {
  9379                      window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);
  9380                  }
  9381              }
  9382          }
  9383      }, {
  9384          key: '_checkAndResumeStuckPlayback',
  9385          value: function _checkAndResumeStuckPlayback(stalled) {
  9386              var media = this._mediaElement;
  9387              if (stalled || !this._receivedCanPlay || media.readyState < 2) {
  9388                  // HAVE_CURRENT_DATA
  9389                  var buffered = media.buffered;
  9390                  if (buffered.length > 0 && media.currentTime < buffered.start(0)) {
  9391                      _logger2.default.w(this.TAG, 'Playback seems stuck at ' + media.currentTime + ', seek to ' + buffered.start(0));
  9392                      this._requestSetTime = true;
  9393                      this._mediaElement.currentTime = buffered.start(0);
  9394                      this._mediaElement.removeEventListener('progress', this.e.onvProgress);
  9395                  }
  9396              } else {
  9397                  // Playback didn't stuck, remove progress event listener
  9398                  this._mediaElement.removeEventListener('progress', this.e.onvProgress);
  9399              }
  9400          }
  9401      }, {
  9402          key: '_onvLoadedMetadata',
  9403          value: function _onvLoadedMetadata(e) {
  9404              if (this._pendingSeekTime != null) {
  9405                  this._mediaElement.currentTime = this._pendingSeekTime;
  9406                  this._pendingSeekTime = null;
  9407              }
  9408          }
  9409      }, {
  9410          key: '_onvSeeking',
  9411          value: function _onvSeeking(e) {
  9412              // handle seeking request from browser's progress bar
  9413              var target = this._mediaElement.currentTime;
  9414              var buffered = this._mediaElement.buffered;
  9415  
  9416              if (this._requestSetTime) {
  9417                  this._requestSetTime = false;
  9418                  return;
  9419              }
  9420  
  9421              if (target < 1.0 && buffered.length > 0) {
  9422                  // seek to video begin, set currentTime directly if beginPTS buffered
  9423                  var videoBeginTime = buffered.start(0);
  9424                  if (videoBeginTime < 1.0 && target < videoBeginTime || _browser2.default.safari) {
  9425                      this._requestSetTime = true;
  9426                      // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid
  9427                      this._mediaElement.currentTime = _browser2.default.safari ? 0.1 : videoBeginTime;
  9428                      return;
  9429                  }
  9430              }
  9431  
  9432              if (this._isTimepointBuffered(target)) {
  9433                  if (this._alwaysSeekKeyframe) {
  9434                      var idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));
  9435                      if (idr != null) {
  9436                          this._requestSetTime = true;
  9437                          this._mediaElement.currentTime = idr.dts / 1000;
  9438                      }
  9439                  }
  9440                  if (this._progressChecker != null) {
  9441                      this._checkProgressAndResume();
  9442                  }
  9443                  return;
  9444              }
  9445  
  9446              this._seekpointRecord = {
  9447                  seekPoint: target,
  9448                  recordTime: this._now()
  9449              };
  9450              window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);
  9451          }
  9452      }, {
  9453          key: '_onvCanPlay',
  9454          value: function _onvCanPlay(e) {
  9455              this._receivedCanPlay = true;
  9456              this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);
  9457          }
  9458      }, {
  9459          key: '_onvStalled',
  9460          value: function _onvStalled(e) {
  9461              this._checkAndResumeStuckPlayback(true);
  9462          }
  9463      }, {
  9464          key: '_onvProgress',
  9465          value: function _onvProgress(e) {
  9466              this._checkAndResumeStuckPlayback();
  9467          }
  9468      }, {
  9469          key: 'type',
  9470          get: function get() {
  9471              return this._type;
  9472          }
  9473      }, {
  9474          key: 'buffered',
  9475          get: function get() {
  9476              return this._mediaElement.buffered;
  9477          }
  9478      }, {
  9479          key: 'duration',
  9480          get: function get() {
  9481              return this._mediaElement.duration;
  9482          }
  9483      }, {
  9484          key: 'volume',
  9485          get: function get() {
  9486              return this._mediaElement.volume;
  9487          },
  9488          set: function set(value) {
  9489              this._mediaElement.volume = value;
  9490          }
  9491      }, {
  9492          key: 'muted',
  9493          get: function get() {
  9494              return this._mediaElement.muted;
  9495          },
  9496          set: function set(muted) {
  9497              this._mediaElement.muted = muted;
  9498          }
  9499      }, {
  9500          key: 'currentTime',
  9501          get: function get() {
  9502              if (this._mediaElement) {
  9503                  return this._mediaElement.currentTime;
  9504              }
  9505              return 0;
  9506          },
  9507          set: function set(seconds) {
  9508              if (this._mediaElement) {
  9509                  this._internalSeek(seconds);
  9510              } else {
  9511                  this._pendingSeekTime = seconds;
  9512              }
  9513          }
  9514      }, {
  9515          key: 'mediaInfo',
  9516          get: function get() {
  9517              return Object.assign({}, this._mediaInfo);
  9518          }
  9519      }, {
  9520          key: 'statisticsInfo',
  9521          get: function get() {
  9522              if (this._statisticsInfo == null) {
  9523                  this._statisticsInfo = {};
  9524              }
  9525              this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);
  9526              return Object.assign({}, this._statisticsInfo);
  9527          }
  9528      }]);
  9529  
  9530      return FlvPlayer;
  9531  }();
  9532  
  9533  exports.default = FlvPlayer;
  9534  
  9535  },{"../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){
  9536  'use strict';
  9537  
  9538  Object.defineProperty(exports, "__esModule", {
  9539      value: true
  9540  });
  9541  
  9542  var _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; };
  9543  
  9544  var _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; }; }(); /*
  9545                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
  9546                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  9547                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
  9548                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  9549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
  9550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
  9551                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
  9552                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  9553                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
  9554                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
  9555                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
  9556                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
  9557                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9558                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
  9559                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
  9560                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
  9561  
  9562  var _events = _dereq_('events');
  9563  
  9564  var _events2 = _interopRequireDefault(_events);
  9565  
  9566  var _playerEvents = _dereq_('./player-events.js');
  9567  
  9568  var _playerEvents2 = _interopRequireDefault(_playerEvents);
  9569  
  9570  var _config = _dereq_('../config.js');
  9571  
  9572  var _exception = _dereq_('../utils/exception.js');
  9573  
  9574  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9575  
  9576  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  9577  
  9578  // Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. 
  9579  var NativePlayer = function () {
  9580      function NativePlayer(mediaDataSource, config) {
  9581          _classCallCheck(this, NativePlayer);
  9582  
  9583          this.TAG = 'NativePlayer';
  9584          this._type = 'NativePlayer';
  9585          this._emitter = new _events2.default();
  9586  
  9587          this._config = (0, _config.createDefaultConfig)();
  9588          if ((typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object') {
  9589              Object.assign(this._config, config);
  9590          }
  9591  
  9592          if (mediaDataSource.type.toLowerCase() === 'flv') {
  9593              throw new _exception.InvalidArgumentException('NativePlayer does\'t support flv MediaDataSource input!');
  9594          }
  9595          if (mediaDataSource.hasOwnProperty('segments')) {
  9596              throw new _exception.InvalidArgumentException('NativePlayer(' + mediaDataSource.type + ') doesn\'t support multipart playback!');
  9597          }
  9598  
  9599          this.e = {
  9600              onvLoadedMetadata: this._onvLoadedMetadata.bind(this)
  9601          };
  9602  
  9603          this._pendingSeekTime = null;
  9604          this._statisticsReporter = null;
  9605  
  9606          this._mediaDataSource = mediaDataSource;
  9607          this._mediaElement = null;
  9608      }
  9609  
  9610      _createClass(NativePlayer, [{
  9611          key: 'destroy',
  9612          value: function destroy() {
  9613              if (this._mediaElement) {
  9614                  this.unload();
  9615                  this.detachMediaElement();
  9616              }
  9617              this.e = null;
  9618              this._mediaDataSource = null;
  9619              this._emitter.removeAllListeners();
  9620              this._emitter = null;
  9621          }
  9622      }, {
  9623          key: 'on',
  9624          value: function on(event, listener) {
  9625              var _this = this;
  9626  
  9627              if (event === _playerEvents2.default.MEDIA_INFO) {
  9628                  if (this._mediaElement != null && this._mediaElement.readyState !== 0) {
  9629                      // HAVE_NOTHING
  9630                      Promise.resolve().then(function () {
  9631                          _this._emitter.emit(_playerEvents2.default.MEDIA_INFO, _this.mediaInfo);
  9632                      });
  9633                  }
  9634              } else if (event === _playerEvents2.default.STATISTICS_INFO) {
  9635                  if (this._mediaElement != null && this._mediaElement.readyState !== 0) {
  9636                      Promise.resolve().then(function () {
  9637                          _this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, _this.statisticsInfo);
  9638                      });
  9639                  }
  9640              }
  9641              this._emitter.addListener(event, listener);
  9642          }
  9643      }, {
  9644          key: 'off',
  9645          value: function off(event, listener) {
  9646              this._emitter.removeListener(event, listener);
  9647          }
  9648      }, {
  9649          key: 'attachMediaElement',
  9650          value: function attachMediaElement(mediaElement) {
  9651              this._mediaElement = mediaElement;
  9652              mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);
  9653  
  9654              if (this._pendingSeekTime != null) {
  9655                  try {
  9656                      mediaElement.currentTime = this._pendingSeekTime;
  9657                      this._pendingSeekTime = null;
  9658                  } catch (e) {
  9659                      // IE11 may throw InvalidStateError if readyState === 0
  9660                      // Defer set currentTime operation after loadedmetadata
  9661                  }
  9662              }
  9663          }
  9664      }, {
  9665          key: 'detachMediaElement',
  9666          value: function detachMediaElement() {
  9667              if (this._mediaElement) {
  9668                  this._mediaElement.src = '';
  9669                  this._mediaElement.removeAttribute('src');
  9670                  this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);
  9671                  this._mediaElement = null;
  9672              }
  9673              if (this._statisticsReporter != null) {
  9674                  window.clearInterval(this._statisticsReporter);
  9675                  this._statisticsReporter = null;
  9676              }
  9677          }
  9678      }, {
  9679          key: 'load',
  9680          value: function load() {
  9681              if (!this._mediaElement) {
  9682                  throw new _exception.IllegalStateException('HTMLMediaElement must be attached before load()!');
  9683              }
  9684              this._mediaElement.src = this._mediaDataSource.url;
  9685  
  9686              if (this._mediaElement.readyState > 0) {
  9687                  this._mediaElement.currentTime = 0;
  9688              }
  9689  
  9690              this._mediaElement.preload = 'auto';
  9691              this._mediaElement.load();
  9692              this._statisticsReporter = window.setInterval(this._reportStatisticsInfo.bind(this), this._config.statisticsInfoReportInterval);
  9693          }
  9694      }, {
  9695          key: 'unload',
  9696          value: function unload() {
  9697              if (this._mediaElement) {
  9698                  this._mediaElement.src = '';
  9699                  this._mediaElement.removeAttribute('src');
  9700              }
  9701              if (this._statisticsReporter != null) {
  9702                  window.clearInterval(this._statisticsReporter);
  9703                  this._statisticsReporter = null;
  9704              }
  9705          }
  9706      }, {
  9707          key: 'play',
  9708          value: function play() {
  9709              return this._mediaElement.play();
  9710          }
  9711      }, {
  9712          key: 'pause',
  9713          value: function pause() {
  9714              this._mediaElement.pause();
  9715          }
  9716      }, {
  9717          key: '_onvLoadedMetadata',
  9718          value: function _onvLoadedMetadata(e) {
  9719              if (this._pendingSeekTime != null) {
  9720                  this._mediaElement.currentTime = this._pendingSeekTime;
  9721                  this._pendingSeekTime = null;
  9722              }
  9723              this._emitter.emit(_playerEvents2.default.MEDIA_INFO, this.mediaInfo);
  9724          }
  9725      }, {
  9726          key: '_reportStatisticsInfo',
  9727          value: function _reportStatisticsInfo() {
  9728              this._emitter.emit(_playerEvents2.default.STATISTICS_INFO, this.statisticsInfo);
  9729          }
  9730      }, {
  9731          key: 'type',
  9732          get: function get() {
  9733              return this._type;
  9734          }
  9735      }, {
  9736          key: 'buffered',
  9737          get: function get() {
  9738              return this._mediaElement.buffered;
  9739          }
  9740      }, {
  9741          key: 'duration',
  9742          get: function get() {
  9743              return this._mediaElement.duration;
  9744          }
  9745      }, {
  9746          key: 'volume',
  9747          get: function get() {
  9748              return this._mediaElement.volume;
  9749          },
  9750          set: function set(value) {
  9751              this._mediaElement.volume = value;
  9752          }
  9753      }, {
  9754          key: 'muted',
  9755          get: function get() {
  9756              return this._mediaElement.muted;
  9757          },
  9758          set: function set(muted) {
  9759              this._mediaElement.muted = muted;
  9760          }
  9761      }, {
  9762          key: 'currentTime',
  9763          get: function get() {
  9764              if (this._mediaElement) {
  9765                  return this._mediaElement.currentTime;
  9766              }
  9767              return 0;
  9768          },
  9769          set: function set(seconds) {
  9770              if (this._mediaElement) {
  9771                  this._mediaElement.currentTime = seconds;
  9772              } else {
  9773                  this._pendingSeekTime = seconds;
  9774              }
  9775          }
  9776      }, {
  9777          key: 'mediaInfo',
  9778          get: function get() {
  9779              var mediaPrefix = this._mediaElement instanceof HTMLAudioElement ? 'audio/' : 'video/';
  9780              var info = {
  9781                  mimeType: mediaPrefix + this._mediaDataSource.type
  9782              };
  9783              if (this._mediaElement) {
  9784                  info.duration = Math.floor(this._mediaElement.duration * 1000);
  9785                  if (this._mediaElement instanceof HTMLVideoElement) {
  9786                      info.width = this._mediaElement.videoWidth;
  9787                      info.height = this._mediaElement.videoHeight;
  9788                  }
  9789              }
  9790              return info;
  9791          }
  9792      }, {
  9793          key: 'statisticsInfo',
  9794          get: function get() {
  9795              var info = {
  9796                  playerType: this._type,
  9797                  url: this._mediaDataSource.url
  9798              };
  9799  
  9800              if (!(this._mediaElement instanceof HTMLVideoElement)) {
  9801                  return info;
  9802              }
  9803  
  9804              var hasQualityInfo = true;
  9805              var decoded = 0;
  9806              var dropped = 0;
  9807  
  9808              if (this._mediaElement.getVideoPlaybackQuality) {
  9809                  var quality = this._mediaElement.getVideoPlaybackQuality();
  9810                  decoded = quality.totalVideoFrames;
  9811                  dropped = quality.droppedVideoFrames;
  9812              } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {
  9813                  decoded = this._mediaElement.webkitDecodedFrameCount;
  9814                  dropped = this._mediaElement.webkitDroppedFrameCount;
  9815              } else {
  9816                  hasQualityInfo = false;
  9817              }
  9818  
  9819              if (hasQualityInfo) {
  9820                  info.decodedFrames = decoded;
  9821                  info.droppedFrames = dropped;
  9822              }
  9823  
  9824              return info;
  9825          }
  9826      }]);
  9827  
  9828      return NativePlayer;
  9829  }();
  9830  
  9831  exports.default = NativePlayer;
  9832  
  9833  },{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,"events":2}],34:[function(_dereq_,module,exports){
  9834  'use strict';
  9835  
  9836  Object.defineProperty(exports, "__esModule", {
  9837      value: true
  9838  });
  9839  exports.ErrorDetails = exports.ErrorTypes = undefined;
  9840  
  9841  var _loader = _dereq_('../io/loader.js');
  9842  
  9843  var _demuxErrors = _dereq_('../demux/demux-errors.js');
  9844  
  9845  var _demuxErrors2 = _interopRequireDefault(_demuxErrors);
  9846  
  9847  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9848  
  9849  /*
  9850   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  9851   *
  9852   * @author zheng qian <xqq@xqq.im>
  9853   *
  9854   * Licensed under the Apache License, Version 2.0 (the "License");
  9855   * you may not use this file except in compliance with the License.
  9856   * You may obtain a copy of the License at
  9857   *
  9858   *     http://www.apache.org/licenses/LICENSE-2.0
  9859   *
  9860   * Unless required by applicable law or agreed to in writing, software
  9861   * distributed under the License is distributed on an "AS IS" BASIS,
  9862   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9863   * See the License for the specific language governing permissions and
  9864   * limitations under the License.
  9865   */
  9866  
  9867  var ErrorTypes = exports.ErrorTypes = {
  9868      NETWORK_ERROR: 'NetworkError',
  9869      MEDIA_ERROR: 'MediaError',
  9870      OTHER_ERROR: 'OtherError'
  9871  };
  9872  
  9873  var ErrorDetails = exports.ErrorDetails = {
  9874      NETWORK_EXCEPTION: _loader.LoaderErrors.EXCEPTION,
  9875      NETWORK_STATUS_CODE_INVALID: _loader.LoaderErrors.HTTP_STATUS_CODE_INVALID,
  9876      NETWORK_TIMEOUT: _loader.LoaderErrors.CONNECTING_TIMEOUT,
  9877      NETWORK_UNRECOVERABLE_EARLY_EOF: _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF,
  9878  
  9879      MEDIA_MSE_ERROR: 'MediaMSEError',
  9880  
  9881      MEDIA_FORMAT_ERROR: _demuxErrors2.default.FORMAT_ERROR,
  9882      MEDIA_FORMAT_UNSUPPORTED: _demuxErrors2.default.FORMAT_UNSUPPORTED,
  9883      MEDIA_CODEC_UNSUPPORTED: _demuxErrors2.default.CODEC_UNSUPPORTED
  9884  };
  9885  
  9886  },{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(_dereq_,module,exports){
  9887  'use strict';
  9888  
  9889  Object.defineProperty(exports, "__esModule", {
  9890    value: true
  9891  });
  9892  /*
  9893   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  9894   *
  9895   * @author zheng qian <xqq@xqq.im>
  9896   *
  9897   * Licensed under the Apache License, Version 2.0 (the "License");
  9898   * you may not use this file except in compliance with the License.
  9899   * You may obtain a copy of the License at
  9900   *
  9901   *     http://www.apache.org/licenses/LICENSE-2.0
  9902   *
  9903   * Unless required by applicable law or agreed to in writing, software
  9904   * distributed under the License is distributed on an "AS IS" BASIS,
  9905   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9906   * See the License for the specific language governing permissions and
  9907   * limitations under the License.
  9908   */
  9909  
  9910  var PlayerEvents = {
  9911    ERROR: 'error',
  9912    LOADING_COMPLETE: 'loading_complete',
  9913    RECOVERED_EARLY_EOF: 'recovered_early_eof',
  9914    MEDIA_INFO: 'media_info',
  9915    METADATA_ARRIVED: 'metadata_arrived',
  9916    SCRIPTDATA_ARRIVED: 'scriptdata_arrived',
  9917    STATISTICS_INFO: 'statistics_info'
  9918  };
  9919  
  9920  exports.default = PlayerEvents;
  9921  
  9922  },{}],36:[function(_dereq_,module,exports){
  9923  'use strict';
  9924  
  9925  Object.defineProperty(exports, "__esModule", {
  9926      value: true
  9927  });
  9928  
  9929  var _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; }; }();
  9930  
  9931  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  9932  
  9933  /*
  9934   * Copyright (C) 2016 Bilibili. All Rights Reserved.
  9935   *
  9936   * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)
  9937   * @author zheng qian <xqq@xqq.im>
  9938   *
  9939   * Licensed under the Apache License, Version 2.0 (the "License");
  9940   * you may not use this file except in compliance with the License.
  9941   * You may obtain a copy of the License at
  9942   *
  9943   *     http://www.apache.org/licenses/LICENSE-2.0
  9944   *
  9945   * Unless required by applicable law or agreed to in writing, software
  9946   * distributed under the License is distributed on an "AS IS" BASIS,
  9947   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9948   * See the License for the specific language governing permissions and
  9949   * limitations under the License.
  9950   */
  9951  
  9952  var AAC = function () {
  9953      function AAC() {
  9954          _classCallCheck(this, AAC);
  9955      }
  9956  
  9957      _createClass(AAC, null, [{
  9958          key: 'getSilentFrame',
  9959          value: function getSilentFrame(codec, channelCount) {
  9960              if (codec === 'mp4a.40.2') {
  9961                  // handle LC-AAC
  9962                  if (channelCount === 1) {
  9963                      return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
  9964                  } else if (channelCount === 2) {
  9965                      return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
  9966                  } else if (channelCount === 3) {
  9967                      return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
  9968                  } else if (channelCount === 4) {
  9969                      return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
  9970                  } else if (channelCount === 5) {
  9971                      return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
  9972                  } else if (channelCount === 6) {
  9973                      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]);
  9974                  }
  9975              } else {
  9976                  // handle HE-AAC (mp4a.40.5 / mp4a.40.29)
  9977                  if (channelCount === 1) {
  9978                      // 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
  9979                      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]);
  9980                  } else if (channelCount === 2) {
  9981                      // 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
  9982                      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]);
  9983                  } else if (channelCount === 3) {
  9984                      // 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
  9985                      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]);
  9986                  }
  9987              }
  9988              return null;
  9989          }
  9990      }]);
  9991  
  9992      return AAC;
  9993  }();
  9994  
  9995  exports.default = AAC;
  9996  
  9997  },{}],37:[function(_dereq_,module,exports){
  9998  'use strict';
  9999  
 10000  Object.defineProperty(exports, "__esModule", {
 10001      value: true
 10002  });
 10003  
 10004  var _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; }; }();
 10005  
 10006  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 10007  
 10008  /*
 10009   * Copyright (C) 2016 Bilibili. All Rights Reserved.
 10010   *
 10011   * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)
 10012   * @author zheng qian <xqq@xqq.im>
 10013   *
 10014   * Licensed under the Apache License, Version 2.0 (the "License");
 10015   * you may not use this file except in compliance with the License.
 10016   * You may obtain a copy of the License at
 10017   *
 10018   *     http://www.apache.org/licenses/LICENSE-2.0
 10019   *
 10020   * Unless required by applicable law or agreed to in writing, software
 10021   * distributed under the License is distributed on an "AS IS" BASIS,
 10022   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 10023   * See the License for the specific language governing permissions and
 10024   * limitations under the License.
 10025   */
 10026  
 10027  //  MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)
 10028  var MP4 = function () {
 10029      function MP4() {
 10030          _classCallCheck(this, MP4);
 10031      }
 10032  
 10033      _createClass(MP4, null, [{
 10034          key: 'init',
 10035          value: function init() {
 10036              MP4.types = {
 10037                  avc1: [], avcC: [], btrt: [], dinf: [],
 10038                  dref: [], esds: [], ftyp: [], hdlr: [],
 10039                  mdat: [], mdhd: [], mdia: [], mfhd: [],
 10040                  minf: [], moof: [], moov: [], mp4a: [],
 10041                  mvex: [], mvhd: [], sdtp: [], stbl: [],
 10042                  stco: [], stsc: [], stsd: [], stsz: [],
 10043                  stts: [], tfdt: [], tfhd: [], traf: [],
 10044                  trak: [], trun: [], trex: [], tkhd: [],
 10045                  vmhd: [], smhd: [], '.mp3': []
 10046              };
 10047  
 10048              for (var name in MP4.types) {
 10049                  if (MP4.types.hasOwnProperty(name)) {
 10050                      MP4.types[name] = [name.charCodeAt(0), name.charCodeAt(1), name.charCodeAt(2), name.charCodeAt(3)];
 10051                  }
 10052              }
 10053  
 10054              var constants = MP4.constants = {};
 10055  
 10056              constants.FTYP = new Uint8Array([0x69, 0x73, 0x6F, 0x6D, // major_brand: isom
 10057              0x0, 0x0, 0x0, 0x1, // minor_version: 0x01
 10058              0x69, 0x73, 0x6F, 0x6D, // isom
 10059              0x61, 0x76, 0x63, 0x31 // avc1
 10060              ]);
 10061  
 10062              constants.STSD_PREFIX = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10063              0x00, 0x00, 0x00, 0x01 // entry_count
 10064              ]);
 10065  
 10066              constants.STTS = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10067              0x00, 0x00, 0x00, 0x00 // entry_count
 10068              ]);
 10069  
 10070              constants.STSC = constants.STCO = constants.STTS;
 10071  
 10072              constants.STSZ = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10073              0x00, 0x00, 0x00, 0x00, // sample_size
 10074              0x00, 0x00, 0x00, 0x00 // sample_count
 10075              ]);
 10076  
 10077              constants.HDLR_VIDEO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10078              0x00, 0x00, 0x00, 0x00, // pre_defined
 10079              0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
 10080              0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
 10081              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x69, 0x64, 0x65, 0x6F, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler
 10082              ]);
 10083  
 10084              constants.HDLR_AUDIO = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10085              0x00, 0x00, 0x00, 0x00, // pre_defined
 10086              0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'
 10087              0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes
 10088              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x6F, 0x75, 0x6E, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler
 10089              ]);
 10090  
 10091              constants.DREF = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10092              0x00, 0x00, 0x00, 0x01, // entry_count
 10093              0x00, 0x00, 0x00, 0x0C, // entry_size
 10094              0x75, 0x72, 0x6C, 0x20, // type 'url '
 10095              0x00, 0x00, 0x00, 0x01 // version(0) + flags
 10096              ]);
 10097  
 10098              // Sound media header
 10099              constants.SMHD = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10100              0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)
 10101              ]);
 10102  
 10103              // video media header
 10104              constants.VMHD = new Uint8Array([0x00, 0x00, 0x00, 0x01, // version(0) + flags
 10105              0x00, 0x00, // graphicsmode: 2 bytes
 10106              0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes
 10107              0x00, 0x00]);
 10108          }
 10109  
 10110          // Generate a box
 10111  
 10112      }, {
 10113          key: 'box',
 10114          value: function box(type) {
 10115              var size = 8;
 10116              var result = null;
 10117              var datas = Array.prototype.slice.call(arguments, 1);
 10118              var arrayCount = datas.length;
 10119  
 10120              for (var i = 0; i < arrayCount; i++) {
 10121                  size += datas[i].byteLength;
 10122              }
 10123  
 10124              result = new Uint8Array(size);
 10125              result[0] = size >>> 24 & 0xFF; // size
 10126              result[1] = size >>> 16 & 0xFF;
 10127              result[2] = size >>> 8 & 0xFF;
 10128              result[3] = size & 0xFF;
 10129  
 10130              result.set(type, 4); // type
 10131  
 10132              var offset = 8;
 10133              for (var _i = 0; _i < arrayCount; _i++) {
 10134                  // data body
 10135                  result.set(datas[_i], offset);
 10136                  offset += datas[_i].byteLength;
 10137              }
 10138  
 10139              return result;
 10140          }
 10141  
 10142          // emit ftyp & moov
 10143  
 10144      }, {
 10145          key: 'generateInitSegment',
 10146          value: function generateInitSegment(meta) {
 10147              var ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);
 10148              var moov = MP4.moov(meta);
 10149  
 10150              var result = new Uint8Array(ftyp.byteLength + moov.byteLength);
 10151              result.set(ftyp, 0);
 10152              result.set(moov, ftyp.byteLength);
 10153              return result;
 10154          }
 10155  
 10156          // Movie metadata box
 10157  
 10158      }, {
 10159          key: 'moov',
 10160          value: function moov(meta) {
 10161              var mvhd = MP4.mvhd(meta.timescale, meta.duration);
 10162              var trak = MP4.trak(meta);
 10163              var mvex = MP4.mvex(meta);
 10164              return MP4.box(MP4.types.moov, mvhd, trak, mvex);
 10165          }
 10166  
 10167          // Movie header box
 10168  
 10169      }, {
 10170          key: 'mvhd',
 10171          value: function mvhd(timescale, duration) {
 10172              return MP4.box(MP4.types.mvhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10173              0x00, 0x00, 0x00, 0x00, // creation_time
 10174              0x00, 0x00, 0x00, 0x00, // modification_time
 10175              timescale >>> 24 & 0xFF, // timescale: 4 bytes
 10176              timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes
 10177              duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0
 10178              0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)
 10179              0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes
 10180              0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
 10181              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----
 10182              0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----
 10183              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----
 10184              0xFF, 0xFF, 0xFF, 0xFF // next_track_ID
 10185              ]));
 10186          }
 10187  
 10188          // Track box
 10189  
 10190      }, {
 10191          key: 'trak',
 10192          value: function trak(meta) {
 10193              return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));
 10194          }
 10195  
 10196          // Track header box
 10197  
 10198      }, {
 10199          key: 'tkhd',
 10200          value: function tkhd(meta) {
 10201              var trackId = meta.id,
 10202                  duration = meta.duration;
 10203              var width = meta.presentWidth,
 10204                  height = meta.presentHeight;
 10205  
 10206              return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, 0x00, 0x00, 0x07, // version(0) + flags
 10207              0x00, 0x00, 0x00, 0x00, // creation_time
 10208              0x00, 0x00, 0x00, 0x00, // modification_time
 10209              trackId >>> 24 & 0xFF, // track_ID: 4 bytes
 10210              trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
 10211              duration >>> 24 & 0xFF, // duration: 4 bytes
 10212              duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
 10213              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)
 10214              0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)
 10215              0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
 10216              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----
 10217              width >>> 8 & 0xFF, // width and height
 10218              width & 0xFF, 0x00, 0x00, height >>> 8 & 0xFF, height & 0xFF, 0x00, 0x00]));
 10219          }
 10220  
 10221          // Media Box
 10222  
 10223      }, {
 10224          key: 'mdia',
 10225          value: function mdia(meta) {
 10226              return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));
 10227          }
 10228  
 10229          // Media header box
 10230  
 10231      }, {
 10232          key: 'mdhd',
 10233          value: function mdhd(meta) {
 10234              var timescale = meta.timescale;
 10235              var duration = meta.duration;
 10236              return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10237              0x00, 0x00, 0x00, 0x00, // creation_time
 10238              0x00, 0x00, 0x00, 0x00, // modification_time
 10239              timescale >>> 24 & 0xFF, // timescale: 4 bytes
 10240              timescale >>> 16 & 0xFF, timescale >>> 8 & 0xFF, timescale & 0xFF, duration >>> 24 & 0xFF, // duration: 4 bytes
 10241              duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, 0x55, 0xC4, // language: und (undetermined)
 10242              0x00, 0x00 // pre_defined = 0
 10243              ]));
 10244          }
 10245  
 10246          // Media handler reference box
 10247  
 10248      }, {
 10249          key: 'hdlr',
 10250          value: function hdlr(meta) {
 10251              var data = null;
 10252              if (meta.type === 'audio') {
 10253                  data = MP4.constants.HDLR_AUDIO;
 10254              } else {
 10255                  data = MP4.constants.HDLR_VIDEO;
 10256              }
 10257              return MP4.box(MP4.types.hdlr, data);
 10258          }
 10259  
 10260          // Media infomation box
 10261  
 10262      }, {
 10263          key: 'minf',
 10264          value: function minf(meta) {
 10265              var xmhd = null;
 10266              if (meta.type === 'audio') {
 10267                  xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);
 10268              } else {
 10269                  xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);
 10270              }
 10271              return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));
 10272          }
 10273  
 10274          // Data infomation box
 10275  
 10276      }, {
 10277          key: 'dinf',
 10278          value: function dinf() {
 10279              var result = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, MP4.constants.DREF));
 10280              return result;
 10281          }
 10282  
 10283          // Sample table box
 10284  
 10285      }, {
 10286          key: 'stbl',
 10287          value: function stbl(meta) {
 10288              var result = MP4.box(MP4.types.stbl, // type: stbl
 10289              MP4.stsd(meta), // Sample Description Table
 10290              MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample
 10291              MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk
 10292              MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size
 10293              MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset
 10294              );
 10295              return result;
 10296          }
 10297  
 10298          // Sample description box
 10299  
 10300      }, {
 10301          key: 'stsd',
 10302          value: function stsd(meta) {
 10303              if (meta.type === 'audio') {
 10304                  if (meta.codec === 'mp3') {
 10305                      return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));
 10306                  }
 10307                  // else: aac -> mp4a
 10308                  return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));
 10309              } else {
 10310                  return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));
 10311              }
 10312          }
 10313      }, {
 10314          key: 'mp3',
 10315          value: function mp3(meta) {
 10316              var channelCount = meta.channelCount;
 10317              var sampleRate = meta.audioSampleRate;
 10318  
 10319              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
 10320              0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
 10321              0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
 10322              0x00, 0x00, 0x00, 0x00, 0x00, channelCount, // channelCount(2)
 10323              0x00, 0x10, // sampleSize(2)
 10324              0x00, 0x00, 0x00, 0x00, // reserved(4)
 10325              sampleRate >>> 8 & 0xFF, // Audio sample rate
 10326              sampleRate & 0xFF, 0x00, 0x00]);
 10327  
 10328              return MP4.box(MP4.types['.mp3'], data);
 10329          }
 10330      }, {
 10331          key: 'mp4a',
 10332          value: function mp4a(meta) {
 10333              var channelCount = meta.channelCount;
 10334              var sampleRate = meta.audioSampleRate;
 10335  
 10336              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
 10337              0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
 10338              0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes
 10339              0x00, 0x00, 0x00, 0x00, 0x00, channelCount, // channelCount(2)
 10340              0x00, 0x10, // sampleSize(2)
 10341              0x00, 0x00, 0x00, 0x00, // reserved(4)
 10342              sampleRate >>> 8 & 0xFF, // Audio sample rate
 10343              sampleRate & 0xFF, 0x00, 0x00]);
 10344  
 10345              return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));
 10346          }
 10347      }, {
 10348          key: 'esds',
 10349          value: function esds(meta) {
 10350              var config = meta.config || [];
 10351              var configSize = config.length;
 10352              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version 0 + flags
 10353  
 10354              0x03, // descriptor_type
 10355              0x17 + configSize, // length3
 10356              0x00, 0x01, // es_id
 10357              0x00, // stream_priority
 10358  
 10359              0x04, // descriptor_type
 10360              0x0F + configSize, // length
 10361              0x40, // codec: mpeg4_audio
 10362              0x15, // stream_type: Audio
 10363              0x00, 0x00, 0x00, // buffer_size
 10364              0x00, 0x00, 0x00, 0x00, // maxBitrate
 10365              0x00, 0x00, 0x00, 0x00, // avgBitrate
 10366  
 10367              0x05 // descriptor_type
 10368              ].concat([configSize]).concat(config).concat([0x06, 0x01, 0x02 // GASpecificConfig
 10369              ]));
 10370              return MP4.box(MP4.types.esds, data);
 10371          }
 10372      }, {
 10373          key: 'avc1',
 10374          value: function avc1(meta) {
 10375              var avcc = meta.avcc;
 10376              var width = meta.codecWidth,
 10377                  height = meta.codecHeight;
 10378  
 10379              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // reserved(4)
 10380              0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)
 10381              0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)
 10382              0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes
 10383              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, width >>> 8 & 0xFF, // width: 2 bytes
 10384              width & 0xFF, height >>> 8 & 0xFF, // height: 2 bytes
 10385              height & 0xFF, 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes
 10386              0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes
 10387              0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes
 10388              0x00, 0x01, // frame_count
 10389              0x0A, // strlen
 10390              0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes
 10391              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
 10392              0xFF, 0xFF // pre_defined = -1
 10393              ]);
 10394              return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));
 10395          }
 10396  
 10397          // Movie Extends box
 10398  
 10399      }, {
 10400          key: 'mvex',
 10401          value: function mvex(meta) {
 10402              return MP4.box(MP4.types.mvex, MP4.trex(meta));
 10403          }
 10404  
 10405          // Track Extends box
 10406  
 10407      }, {
 10408          key: 'trex',
 10409          value: function trex(meta) {
 10410              var trackId = meta.id;
 10411              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) + flags
 10412              trackId >>> 24 & 0xFF, // track_ID
 10413              trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF, 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
 10414              0x00, 0x00, 0x00, 0x00, // default_sample_duration
 10415              0x00, 0x00, 0x00, 0x00, // default_sample_size
 10416              0x00, 0x01, 0x00, 0x01 // default_sample_flags
 10417              ]);
 10418              return MP4.box(MP4.types.trex, data);
 10419          }
 10420  
 10421          // Movie fragment box
 10422  
 10423      }, {
 10424          key: 'moof',
 10425          value: function moof(track, baseMediaDecodeTime) {
 10426              return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));
 10427          }
 10428      }, {
 10429          key: 'mfhd',
 10430          value: function mfhd(sequenceNumber) {
 10431              var data = new Uint8Array([0x00, 0x00, 0x00, 0x00, sequenceNumber >>> 24 & 0xFF, // sequence_number: int32
 10432              sequenceNumber >>> 16 & 0xFF, sequenceNumber >>> 8 & 0xFF, sequenceNumber & 0xFF]);
 10433              return MP4.box(MP4.types.mfhd, data);
 10434          }
 10435  
 10436          // Track fragment box
 10437  
 10438      }, {
 10439          key: 'traf',
 10440          value: function traf(track, baseMediaDecodeTime) {
 10441              var trackId = track.id;
 10442  
 10443              // Track fragment header box
 10444              var tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
 10445              trackId >>> 24 & 0xFF, // track_ID
 10446              trackId >>> 16 & 0xFF, trackId >>> 8 & 0xFF, trackId & 0xFF]));
 10447              // Track Fragment Decode Time
 10448              var tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([0x00, 0x00, 0x00, 0x00, // version(0) & flags
 10449              baseMediaDecodeTime >>> 24 & 0xFF, // baseMediaDecodeTime: int32
 10450              baseMediaDecodeTime >>> 16 & 0xFF, baseMediaDecodeTime >>> 8 & 0xFF, baseMediaDecodeTime & 0xFF]));
 10451              var sdtp = MP4.sdtp(track);
 10452              var trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);
 10453  
 10454              return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);
 10455          }
 10456  
 10457          // Sample Dependency Type box
 10458  
 10459      }, {
 10460          key: 'sdtp',
 10461          value: function sdtp(track) {
 10462              var samples = track.samples || [];
 10463              var sampleCount = samples.length;
 10464              var data = new Uint8Array(4 + sampleCount);
 10465              // 0~4 bytes: version(0) & flags
 10466              for (var i = 0; i < sampleCount; i++) {
 10467                  var flags = samples[i].flags;
 10468                  data[i + 4] = flags.isLeading << 6 | // is_leading: 2 (bit)
 10469                  flags.dependsOn << 4 // sample_depends_on
 10470                  | flags.isDependedOn << 2 // sample_is_depended_on
 10471                  | flags.hasRedundancy; // sample_has_redundancy
 10472              }
 10473              return MP4.box(MP4.types.sdtp, data);
 10474          }
 10475  
 10476          // Track fragment run box
 10477  
 10478      }, {
 10479          key: 'trun',
 10480          value: function trun(track, offset) {
 10481              var samples = track.samples || [];
 10482              var sampleCount = samples.length;
 10483              var dataSize = 12 + 16 * sampleCount;
 10484              var data = new Uint8Array(dataSize);
 10485              offset += 8 + dataSize;
 10486  
 10487              data.set([0x00, 0x00, 0x0F, 0x01, // version(0) & flags
 10488              sampleCount >>> 24 & 0xFF, // sample_count
 10489              sampleCount >>> 16 & 0xFF, sampleCount >>> 8 & 0xFF, sampleCount & 0xFF, offset >>> 24 & 0xFF, // data_offset
 10490              offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF], 0);
 10491  
 10492              for (var i = 0; i < sampleCount; i++) {
 10493                  var duration = samples[i].duration;
 10494                  var size = samples[i].size;
 10495                  var flags = samples[i].flags;
 10496                  var cts = samples[i].cts;
 10497                  data.set([duration >>> 24 & 0xFF, // sample_duration
 10498                  duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, size >>> 24 & 0xFF, // sample_size
 10499                  size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, flags.isLeading << 2 | flags.dependsOn, // sample_flags
 10500                  flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.isNonSync, 0x00, 0x00, // sample_degradation_priority
 10501                  cts >>> 24 & 0xFF, // sample_composition_time_offset
 10502                  cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF], 12 + 16 * i);
 10503              }
 10504              return MP4.box(MP4.types.trun, data);
 10505          }
 10506      }, {
 10507          key: 'mdat',
 10508          value: function mdat(data) {
 10509              return MP4.box(MP4.types.mdat, data);
 10510          }
 10511      }]);
 10512  
 10513      return MP4;
 10514  }();
 10515  
 10516  MP4.init();
 10517  
 10518  exports.default = MP4;
 10519  
 10520  },{}],38:[function(_dereq_,module,exports){
 10521  'use strict';
 10522  
 10523  Object.defineProperty(exports, "__esModule", {
 10524      value: true
 10525  });
 10526  
 10527  var _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; }; }(); /*
 10528                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
 10529                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 10530                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
 10531                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 10532                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
 10533                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
 10534                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
 10535                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 10536                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
 10537                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 10538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
 10539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
 10540                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 10541                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
 10542                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
 10543                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
 10544  
 10545  var _logger = _dereq_('../utils/logger.js');
 10546  
 10547  var _logger2 = _interopRequireDefault(_logger);
 10548  
 10549  var _mp4Generator = _dereq_('./mp4-generator.js');
 10550  
 10551  var _mp4Generator2 = _interopRequireDefault(_mp4Generator);
 10552  
 10553  var _aacSilent = _dereq_('./aac-silent.js');
 10554  
 10555  var _aacSilent2 = _interopRequireDefault(_aacSilent);
 10556  
 10557  var _browser = _dereq_('../utils/browser.js');
 10558  
 10559  var _browser2 = _interopRequireDefault(_browser);
 10560  
 10561  var _mediaSegmentInfo = _dereq_('../core/media-segment-info.js');
 10562  
 10563  var _exception = _dereq_('../utils/exception.js');
 10564  
 10565  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 10566  
 10567  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 10568  
 10569  // Fragmented mp4 remuxer
 10570  var MP4Remuxer = function () {
 10571      function MP4Remuxer(config) {
 10572          _classCallCheck(this, MP4Remuxer);
 10573  
 10574          this.TAG = 'MP4Remuxer';
 10575  
 10576          this._config = config;
 10577          this._isLive = config.isLive === true ? true : false;
 10578  
 10579          this._dtsBase = -1;
 10580          this._dtsBaseInited = false;
 10581          this._audioDtsBase = Infinity;
 10582          this._videoDtsBase = Infinity;
 10583          this._audioNextDts = undefined;
 10584          this._videoNextDts = undefined;
 10585          this._audioStashedLastSample = null;
 10586          this._videoStashedLastSample = null;
 10587  
 10588          this._audioMeta = null;
 10589          this._videoMeta = null;
 10590  
 10591          this._audioSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('audio');
 10592          this._videoSegmentInfoList = new _mediaSegmentInfo.MediaSegmentInfoList('video');
 10593  
 10594          this._onInitSegment = null;
 10595          this._onMediaSegment = null;
 10596  
 10597          // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment
 10598          // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
 10599          this._forceFirstIDR = _browser2.default.chrome && (_browser2.default.version.major < 50 || _browser2.default.version.major === 50 && _browser2.default.version.build < 2661) ? true : false;
 10600  
 10601          // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking
 10602          // Make audio beginDts equals with video beginDts, in order to fix seek freeze
 10603          this._fillSilentAfterSeek = _browser2.default.msedge || _browser2.default.msie;
 10604  
 10605          // While only FireFox supports 'audio/mp4, codecs="mp3"', use 'audio/mpeg' for chrome, safari, ...
 10606          this._mp3UseMpegAudio = !_browser2.default.firefox;
 10607  
 10608          this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;
 10609      }
 10610  
 10611      _createClass(MP4Remuxer, [{
 10612          key: 'destroy',
 10613          value: function destroy() {
 10614              this._dtsBase = -1;
 10615              this._dtsBaseInited = false;
 10616              this._audioMeta = null;
 10617              this._videoMeta = null;
 10618              this._audioSegmentInfoList.clear();
 10619              this._audioSegmentInfoList = null;
 10620              this._videoSegmentInfoList.clear();
 10621              this._videoSegmentInfoList = null;
 10622              this._onInitSegment = null;
 10623              this._onMediaSegment = null;
 10624          }
 10625      }, {
 10626          key: 'bindDataSource',
 10627          value: function bindDataSource(producer) {
 10628              producer.onDataAvailable = this.remux.bind(this);
 10629              producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);
 10630              return this;
 10631          }
 10632  
 10633          /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void
 10634             InitSegment: {
 10635                 type: string,
 10636                 data: ArrayBuffer,
 10637                 codec: string,
 10638                 container: string
 10639             }
 10640          */
 10641  
 10642      }, {
 10643          key: 'insertDiscontinuity',
 10644          value: function insertDiscontinuity() {
 10645              this._audioNextDts = this._videoNextDts = undefined;
 10646          }
 10647      }, {
 10648          key: 'seek',
 10649          value: function seek(originalDts) {
 10650              this._audioStashedLastSample = null;
 10651              this._videoStashedLastSample = null;
 10652              this._videoSegmentInfoList.clear();
 10653              this._audioSegmentInfoList.clear();
 10654          }
 10655      }, {
 10656          key: 'remux',
 10657          value: function remux(audioTrack, videoTrack) {
 10658              if (!this._onMediaSegment) {
 10659                  throw new _exception.IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');
 10660              }
 10661              if (!this._dtsBaseInited) {
 10662                  this._calculateDtsBase(audioTrack, videoTrack);
 10663              }
 10664              this._remuxVideo(videoTrack);
 10665              this._remuxAudio(audioTrack);
 10666          }
 10667      }, {
 10668          key: '_onTrackMetadataReceived',
 10669          value: function _onTrackMetadataReceived(type, metadata) {
 10670              var metabox = null;
 10671  
 10672              var container = 'mp4';
 10673              var codec = metadata.codec;
 10674  
 10675              if (type === 'audio') {
 10676                  this._audioMeta = metadata;
 10677                  if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {
 10678                      // 'audio/mpeg' for MP3 audio track
 10679                      container = 'mpeg';
 10680                      codec = '';
 10681                      metabox = new Uint8Array();
 10682                  } else {
 10683                      // 'audio/mp4, codecs="codec"'
 10684                      metabox = _mp4Generator2.default.generateInitSegment(metadata);
 10685                  }
 10686              } else if (type === 'video') {
 10687                  this._videoMeta = metadata;
 10688                  metabox = _mp4Generator2.default.generateInitSegment(metadata);
 10689              } else {
 10690                  return;
 10691              }
 10692  
 10693              // dispatch metabox (Initialization Segment)
 10694              if (!this._onInitSegment) {
 10695                  throw new _exception.IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');
 10696              }
 10697              this._onInitSegment(type, {
 10698                  type: type,
 10699                  data: metabox.buffer,
 10700                  codec: codec,
 10701                  container: type + '/' + container,
 10702                  mediaDuration: metadata.duration // in timescale 1000 (milliseconds)
 10703              });
 10704          }
 10705      }, {
 10706          key: '_calculateDtsBase',
 10707          value: function _calculateDtsBase(audioTrack, videoTrack) {
 10708              if (this._dtsBaseInited) {
 10709                  return;
 10710              }
 10711  
 10712              if (audioTrack.samples && audioTrack.samples.length) {
 10713                  this._audioDtsBase = audioTrack.samples[0].dts;
 10714              }
 10715              if (videoTrack.samples && videoTrack.samples.length) {
 10716                  this._videoDtsBase = videoTrack.samples[0].dts;
 10717              }
 10718  
 10719              this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);
 10720              this._dtsBaseInited = true;
 10721          }
 10722      }, {
 10723          key: 'flushStashedSamples',
 10724          value: function flushStashedSamples() {
 10725              var videoSample = this._videoStashedLastSample;
 10726              var audioSample = this._audioStashedLastSample;
 10727  
 10728              var videoTrack = {
 10729                  type: 'video',
 10730                  id: 1,
 10731                  sequenceNumber: 0,
 10732                  samples: [],
 10733                  length: 0
 10734              };
 10735  
 10736              if (videoSample != null) {
 10737                  videoTrack.samples.push(videoSample);
 10738                  videoTrack.length = videoSample.length;
 10739              }
 10740  
 10741              var audioTrack = {
 10742                  type: 'audio',
 10743                  id: 2,
 10744                  sequenceNumber: 0,
 10745                  samples: [],
 10746                  length: 0
 10747              };
 10748  
 10749              if (audioSample != null) {
 10750                  audioTrack.samples.push(audioSample);
 10751                  audioTrack.length = audioSample.length;
 10752              }
 10753  
 10754              this._videoStashedLastSample = null;
 10755              this._audioStashedLastSample = null;
 10756  
 10757              this._remuxVideo(videoTrack, true);
 10758              this._remuxAudio(audioTrack, true);
 10759          }
 10760      }, {
 10761          key: '_remuxAudio',
 10762          value: function _remuxAudio(audioTrack, force) {
 10763              if (this._audioMeta == null) {
 10764                  return;
 10765              }
 10766  
 10767              var track = audioTrack;
 10768              var samples = track.samples;
 10769              var dtsCorrection = undefined;
 10770              var firstDts = -1,
 10771                  lastDts = -1,
 10772                  lastPts = -1;
 10773              var refSampleDuration = this._audioMeta.refSampleDuration;
 10774  
 10775              var mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;
 10776              var firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;
 10777  
 10778              var insertPrefixSilentFrame = false;
 10779  
 10780              if (!samples || samples.length === 0) {
 10781                  return;
 10782              }
 10783              if (samples.length === 1 && !force) {
 10784                  // If [sample count in current batch] === 1 && (force != true)
 10785                  // Ignore and keep in demuxer's queue
 10786                  return;
 10787              } // else if (force === true) do remux
 10788  
 10789              var offset = 0;
 10790              var mdatbox = null;
 10791              var mdatBytes = 0;
 10792  
 10793              // calculate initial mdat size
 10794              if (mpegRawTrack) {
 10795                  // for raw mpeg buffer
 10796                  offset = 0;
 10797                  mdatBytes = track.length;
 10798              } else {
 10799                  // for fmp4 mdat box
 10800                  offset = 8; // size + type
 10801                  mdatBytes = 8 + track.length;
 10802              }
 10803  
 10804              var lastSample = null;
 10805  
 10806              // Pop the lastSample and waiting for stash
 10807              if (samples.length > 1) {
 10808                  lastSample = samples.pop();
 10809                  mdatBytes -= lastSample.length;
 10810              }
 10811  
 10812              // Insert [stashed lastSample in the previous batch] to the front
 10813              if (this._audioStashedLastSample != null) {
 10814                  var sample = this._audioStashedLastSample;
 10815                  this._audioStashedLastSample = null;
 10816                  samples.unshift(sample);
 10817                  mdatBytes += sample.length;
 10818              }
 10819  
 10820              // Stash the lastSample of current batch, waiting for next batch
 10821              if (lastSample != null) {
 10822                  this._audioStashedLastSample = lastSample;
 10823              }
 10824  
 10825              var firstSampleOriginalDts = samples[0].dts - this._dtsBase;
 10826  
 10827              // calculate dtsCorrection
 10828              if (this._audioNextDts) {
 10829                  dtsCorrection = firstSampleOriginalDts - this._audioNextDts;
 10830              } else {
 10831                  // this._audioNextDts == undefined
 10832                  if (this._audioSegmentInfoList.isEmpty()) {
 10833                      dtsCorrection = 0;
 10834                      if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {
 10835                          if (this._audioMeta.originalCodec !== 'mp3') {
 10836                              insertPrefixSilentFrame = true;
 10837                          }
 10838                      }
 10839                  } else {
 10840                      var _lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);
 10841                      if (_lastSample != null) {
 10842                          var distance = firstSampleOriginalDts - (_lastSample.originalDts + _lastSample.duration);
 10843                          if (distance <= 3) {
 10844                              distance = 0;
 10845                          }
 10846                          var expectedDts = _lastSample.dts + _lastSample.duration + distance;
 10847                          dtsCorrection = firstSampleOriginalDts - expectedDts;
 10848                      } else {
 10849                          // lastSample == null, cannot found
 10850                          dtsCorrection = 0;
 10851                      }
 10852                  }
 10853              }
 10854  
 10855              if (insertPrefixSilentFrame) {
 10856                  // align audio segment beginDts to match with current video segment's beginDts
 10857                  var firstSampleDts = firstSampleOriginalDts - dtsCorrection;
 10858                  var videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);
 10859                  if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {
 10860                      var silentUnit = _aacSilent2.default.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);
 10861                      if (silentUnit) {
 10862                          var dts = videoSegment.beginDts;
 10863                          var silentFrameDuration = firstSampleDts - videoSegment.beginDts;
 10864                          _logger2.default.v(this.TAG, 'InsertPrefixSilentAudio: dts: ' + dts + ', duration: ' + silentFrameDuration);
 10865                          samples.unshift({ unit: silentUnit, dts: dts, pts: dts });
 10866                          mdatBytes += silentUnit.byteLength;
 10867                      } // silentUnit == null: Cannot generate, skip
 10868                  } else {
 10869                      insertPrefixSilentFrame = false;
 10870                  }
 10871              }
 10872  
 10873              var mp4Samples = [];
 10874  
 10875              // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples
 10876              for (var i = 0; i < samples.length; i++) {
 10877                  var _sample = samples[i];
 10878                  var unit = _sample.unit;
 10879                  var originalDts = _sample.dts - this._dtsBase;
 10880                  var _dts = originalDts - dtsCorrection;
 10881  
 10882                  if (firstDts === -1) {
 10883                      firstDts = _dts;
 10884                  }
 10885  
 10886                  var sampleDuration = 0;
 10887  
 10888                  if (i !== samples.length - 1) {
 10889                      var nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;
 10890                      sampleDuration = nextDts - _dts;
 10891                  } else {
 10892                      // the last sample
 10893                      if (lastSample != null) {
 10894                          // use stashed sample's dts to calculate sample duration
 10895                          var _nextDts = lastSample.dts - this._dtsBase - dtsCorrection;
 10896                          sampleDuration = _nextDts - _dts;
 10897                      } else if (mp4Samples.length >= 1) {
 10898                          // use second last sample duration
 10899                          sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
 10900                      } else {
 10901                          // the only one sample, use reference sample duration
 10902                          sampleDuration = Math.floor(refSampleDuration);
 10903                      }
 10904                  }
 10905  
 10906                  var needFillSilentFrames = false;
 10907                  var silentFrames = null;
 10908  
 10909                  // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap
 10910                  if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !_browser2.default.safari) {
 10911                      // We need to insert silent frames to fill timestamp gap
 10912                      needFillSilentFrames = true;
 10913                      var delta = Math.abs(sampleDuration - refSampleDuration);
 10914                      var frameCount = Math.ceil(delta / refSampleDuration);
 10915                      var currentDts = _dts + refSampleDuration; // Notice: in float
 10916  
 10917                      _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'));
 10918  
 10919                      var _silentUnit = _aacSilent2.default.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);
 10920                      if (_silentUnit == null) {
 10921                          _logger2.default.w(this.TAG, 'Unable to generate silent frame for ' + (this._audioMeta.originalCodec + ' with ' + this._audioMeta.channelCount + ' channels, repeat last frame'));
 10922                          // Repeat last frame
 10923                          _silentUnit = unit;
 10924                      }
 10925                      silentFrames = [];
 10926  
 10927                      for (var j = 0; j < frameCount; j++) {
 10928                          var intDts = Math.round(currentDts); // round to integer
 10929                          if (silentFrames.length > 0) {
 10930                              // Set previous frame sample duration
 10931                              var previousFrame = silentFrames[silentFrames.length - 1];
 10932                              previousFrame.duration = intDts - previousFrame.dts;
 10933                          }
 10934                          var frame = {
 10935                              dts: intDts,
 10936                              pts: intDts,
 10937                              cts: 0,
 10938                              unit: _silentUnit,
 10939                              size: _silentUnit.byteLength,
 10940                              duration: 0, // wait for next sample
 10941                              originalDts: originalDts,
 10942                              flags: {
 10943                                  isLeading: 0,
 10944                                  dependsOn: 1,
 10945                                  isDependedOn: 0,
 10946                                  hasRedundancy: 0
 10947                              }
 10948                          };
 10949                          silentFrames.push(frame);
 10950                          mdatBytes += frame.size;
 10951                          currentDts += refSampleDuration;
 10952                      }
 10953  
 10954                      // last frame: align end time to next frame dts
 10955                      var lastFrame = silentFrames[silentFrames.length - 1];
 10956                      lastFrame.duration = _dts + sampleDuration - lastFrame.dts;
 10957  
 10958                      // silentFrames.forEach((frame) => {
 10959                      //     Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);
 10960                      // });
 10961  
 10962                      // Set correct sample duration for current frame
 10963                      sampleDuration = Math.round(refSampleDuration);
 10964                  }
 10965  
 10966                  mp4Samples.push({
 10967                      dts: _dts,
 10968                      pts: _dts,
 10969                      cts: 0,
 10970                      unit: _sample.unit,
 10971                      size: _sample.unit.byteLength,
 10972                      duration: sampleDuration,
 10973                      originalDts: originalDts,
 10974                      flags: {
 10975                          isLeading: 0,
 10976                          dependsOn: 1,
 10977                          isDependedOn: 0,
 10978                          hasRedundancy: 0
 10979                      }
 10980                  });
 10981  
 10982                  if (needFillSilentFrames) {
 10983                      // Silent frames should be inserted after wrong-duration frame
 10984                      mp4Samples.push.apply(mp4Samples, silentFrames);
 10985                  }
 10986              }
 10987  
 10988              // allocate mdatbox
 10989              if (mpegRawTrack) {
 10990                  // allocate for raw mpeg buffer
 10991                  mdatbox = new Uint8Array(mdatBytes);
 10992              } else {
 10993                  // allocate for fmp4 mdat box
 10994                  mdatbox = new Uint8Array(mdatBytes);
 10995                  // size field
 10996                  mdatbox[0] = mdatBytes >>> 24 & 0xFF;
 10997                  mdatbox[1] = mdatBytes >>> 16 & 0xFF;
 10998                  mdatbox[2] = mdatBytes >>> 8 & 0xFF;
 10999                  mdatbox[3] = mdatBytes & 0xFF;
 11000                  // type field (fourCC)
 11001                  mdatbox.set(_mp4Generator2.default.types.mdat, 4);
 11002              }
 11003  
 11004              // Write samples into mdatbox
 11005              for (var _i = 0; _i < mp4Samples.length; _i++) {
 11006                  var _unit = mp4Samples[_i].unit;
 11007                  mdatbox.set(_unit, offset);
 11008                  offset += _unit.byteLength;
 11009              }
 11010  
 11011              var latest = mp4Samples[mp4Samples.length - 1];
 11012              lastDts = latest.dts + latest.duration;
 11013              this._audioNextDts = lastDts;
 11014  
 11015              // fill media segment info & add to info list
 11016              var info = new _mediaSegmentInfo.MediaSegmentInfo();
 11017              info.beginDts = firstDts;
 11018              info.endDts = lastDts;
 11019              info.beginPts = firstDts;
 11020              info.endPts = lastDts;
 11021              info.originalBeginDts = mp4Samples[0].originalDts;
 11022              info.originalEndDts = latest.originalDts + latest.duration;
 11023              info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, false);
 11024              info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, false);
 11025              if (!this._isLive) {
 11026                  this._audioSegmentInfoList.append(info);
 11027              }
 11028  
 11029              track.samples = mp4Samples;
 11030              track.sequenceNumber++;
 11031  
 11032              var moofbox = null;
 11033  
 11034              if (mpegRawTrack) {
 11035                  // Generate empty buffer, because useless for raw mpeg
 11036                  moofbox = new Uint8Array();
 11037              } else {
 11038                  // Generate moof for fmp4 segment
 11039                  moofbox = _mp4Generator2.default.moof(track, firstDts);
 11040              }
 11041  
 11042              track.samples = [];
 11043              track.length = 0;
 11044  
 11045              var segment = {
 11046                  type: 'audio',
 11047                  data: this._mergeBoxes(moofbox, mdatbox).buffer,
 11048                  sampleCount: mp4Samples.length,
 11049                  info: info
 11050              };
 11051  
 11052              if (mpegRawTrack && firstSegmentAfterSeek) {
 11053                  // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer
 11054                  // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.
 11055                  segment.timestampOffset = firstDts;
 11056              }
 11057  
 11058              this._onMediaSegment('audio', segment);
 11059          }
 11060      }, {
 11061          key: '_remuxVideo',
 11062          value: function _remuxVideo(videoTrack, force) {
 11063              if (this._videoMeta == null) {
 11064                  return;
 11065              }
 11066  
 11067              var track = videoTrack;
 11068              var samples = track.samples;
 11069              var dtsCorrection = undefined;
 11070              var firstDts = -1,
 11071                  lastDts = -1;
 11072              var firstPts = -1,
 11073                  lastPts = -1;
 11074  
 11075              if (!samples || samples.length === 0) {
 11076                  return;
 11077              }
 11078              if (samples.length === 1 && !force) {
 11079                  // If [sample count in current batch] === 1 && (force != true)
 11080                  // Ignore and keep in demuxer's queue
 11081                  return;
 11082              } // else if (force === true) do remux
 11083  
 11084              var offset = 8;
 11085              var mdatbox = null;
 11086              var mdatBytes = 8 + videoTrack.length;
 11087  
 11088              var lastSample = null;
 11089  
 11090              // Pop the lastSample and waiting for stash
 11091              if (samples.length > 1) {
 11092                  lastSample = samples.pop();
 11093                  mdatBytes -= lastSample.length;
 11094              }
 11095  
 11096              // Insert [stashed lastSample in the previous batch] to the front
 11097              if (this._videoStashedLastSample != null) {
 11098                  var sample = this._videoStashedLastSample;
 11099                  this._videoStashedLastSample = null;
 11100                  samples.unshift(sample);
 11101                  mdatBytes += sample.length;
 11102              }
 11103  
 11104              // Stash the lastSample of current batch, waiting for next batch
 11105              if (lastSample != null) {
 11106                  this._videoStashedLastSample = lastSample;
 11107              }
 11108  
 11109              var firstSampleOriginalDts = samples[0].dts - this._dtsBase;
 11110  
 11111              // calculate dtsCorrection
 11112              if (this._videoNextDts) {
 11113                  dtsCorrection = firstSampleOriginalDts - this._videoNextDts;
 11114              } else {
 11115                  // this._videoNextDts == undefined
 11116                  if (this._videoSegmentInfoList.isEmpty()) {
 11117                      dtsCorrection = 0;
 11118                  } else {
 11119                      var _lastSample2 = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);
 11120                      if (_lastSample2 != null) {
 11121                          var distance = firstSampleOriginalDts - (_lastSample2.originalDts + _lastSample2.duration);
 11122                          if (distance <= 3) {
 11123                              distance = 0;
 11124                          }
 11125                          var expectedDts = _lastSample2.dts + _lastSample2.duration + distance;
 11126                          dtsCorrection = firstSampleOriginalDts - expectedDts;
 11127                      } else {
 11128                          // lastSample == null, cannot found
 11129                          dtsCorrection = 0;
 11130                      }
 11131                  }
 11132              }
 11133  
 11134              var info = new _mediaSegmentInfo.MediaSegmentInfo();
 11135              var mp4Samples = [];
 11136  
 11137              // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples
 11138              for (var i = 0; i < samples.length; i++) {
 11139                  var _sample2 = samples[i];
 11140                  var originalDts = _sample2.dts - this._dtsBase;
 11141                  var isKeyframe = _sample2.isKeyframe;
 11142                  var dts = originalDts - dtsCorrection;
 11143                  var cts = _sample2.cts;
 11144                  var pts = dts + cts;
 11145  
 11146                  if (firstDts === -1) {
 11147                      firstDts = dts;
 11148                      firstPts = pts;
 11149                  }
 11150  
 11151                  var sampleDuration = 0;
 11152  
 11153                  if (i !== samples.length - 1) {
 11154                      var nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;
 11155                      sampleDuration = nextDts - dts;
 11156                  } else {
 11157                      // the last sample
 11158                      if (lastSample != null) {
 11159                          // use stashed sample's dts to calculate sample duration
 11160                          var _nextDts2 = lastSample.dts - this._dtsBase - dtsCorrection;
 11161                          sampleDuration = _nextDts2 - dts;
 11162                      } else if (mp4Samples.length >= 1) {
 11163                          // use second last sample duration
 11164                          sampleDuration = mp4Samples[mp4Samples.length - 1].duration;
 11165                      } else {
 11166                          // the only one sample, use reference sample duration
 11167                          sampleDuration = Math.floor(this._videoMeta.refSampleDuration);
 11168                      }
 11169                  }
 11170  
 11171                  if (isKeyframe) {
 11172                      var syncPoint = new _mediaSegmentInfo.SampleInfo(dts, pts, sampleDuration, _sample2.dts, true);
 11173                      syncPoint.fileposition = _sample2.fileposition;
 11174                      info.appendSyncPoint(syncPoint);
 11175                  }
 11176  
 11177                  mp4Samples.push({
 11178                      dts: dts,
 11179                      pts: pts,
 11180                      cts: cts,
 11181                      units: _sample2.units,
 11182                      size: _sample2.length,
 11183                      isKeyframe: isKeyframe,
 11184                      duration: sampleDuration,
 11185                      originalDts: originalDts,
 11186                      flags: {
 11187                          isLeading: 0,
 11188                          dependsOn: isKeyframe ? 2 : 1,
 11189                          isDependedOn: isKeyframe ? 1 : 0,
 11190                          hasRedundancy: 0,
 11191                          isNonSync: isKeyframe ? 0 : 1
 11192                      }
 11193                  });
 11194              }
 11195  
 11196              // allocate mdatbox
 11197              mdatbox = new Uint8Array(mdatBytes);
 11198              mdatbox[0] = mdatBytes >>> 24 & 0xFF;
 11199              mdatbox[1] = mdatBytes >>> 16 & 0xFF;
 11200              mdatbox[2] = mdatBytes >>> 8 & 0xFF;
 11201              mdatbox[3] = mdatBytes & 0xFF;
 11202              mdatbox.set(_mp4Generator2.default.types.mdat, 4);
 11203  
 11204              // Write samples into mdatbox
 11205              for (var _i2 = 0; _i2 < mp4Samples.length; _i2++) {
 11206                  var units = mp4Samples[_i2].units;
 11207                  while (units.length) {
 11208                      var unit = units.shift();
 11209                      var data = unit.data;
 11210                      mdatbox.set(data, offset);
 11211                      offset += data.byteLength;
 11212                  }
 11213              }
 11214  
 11215              var latest = mp4Samples[mp4Samples.length - 1];
 11216              lastDts = latest.dts + latest.duration;
 11217              lastPts = latest.pts + latest.duration;
 11218              this._videoNextDts = lastDts;
 11219  
 11220              // fill media segment info & add to info list
 11221              info.beginDts = firstDts;
 11222              info.endDts = lastDts;
 11223              info.beginPts = firstPts;
 11224              info.endPts = lastPts;
 11225              info.originalBeginDts = mp4Samples[0].originalDts;
 11226              info.originalEndDts = latest.originalDts + latest.duration;
 11227              info.firstSample = new _mediaSegmentInfo.SampleInfo(mp4Samples[0].dts, mp4Samples[0].pts, mp4Samples[0].duration, mp4Samples[0].originalDts, mp4Samples[0].isKeyframe);
 11228              info.lastSample = new _mediaSegmentInfo.SampleInfo(latest.dts, latest.pts, latest.duration, latest.originalDts, latest.isKeyframe);
 11229              if (!this._isLive) {
 11230                  this._videoSegmentInfoList.append(info);
 11231              }
 11232  
 11233              track.samples = mp4Samples;
 11234              track.sequenceNumber++;
 11235  
 11236              // workaround for chrome < 50: force first sample as a random access point
 11237              // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412
 11238              if (this._forceFirstIDR) {
 11239                  var flags = mp4Samples[0].flags;
 11240                  flags.dependsOn = 2;
 11241                  flags.isNonSync = 0;
 11242              }
 11243  
 11244              var moofbox = _mp4Generator2.default.moof(track, firstDts);
 11245              track.samples = [];
 11246              track.length = 0;
 11247  
 11248              this._onMediaSegment('video', {
 11249                  type: 'video',
 11250                  data: this._mergeBoxes(moofbox, mdatbox).buffer,
 11251                  sampleCount: mp4Samples.length,
 11252                  info: info
 11253              });
 11254          }
 11255      }, {
 11256          key: '_mergeBoxes',
 11257          value: function _mergeBoxes(moof, mdat) {
 11258              var result = new Uint8Array(moof.byteLength + mdat.byteLength);
 11259              result.set(moof, 0);
 11260              result.set(mdat, moof.byteLength);
 11261              return result;
 11262          }
 11263      }, {
 11264          key: 'onInitSegment',
 11265          get: function get() {
 11266              return this._onInitSegment;
 11267          },
 11268          set: function set(callback) {
 11269              this._onInitSegment = callback;
 11270          }
 11271  
 11272          /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void
 11273             MediaSegment: {
 11274                 type: string,
 11275                 data: ArrayBuffer,
 11276                 sampleCount: int32
 11277                 info: MediaSegmentInfo
 11278             }
 11279          */
 11280  
 11281      }, {
 11282          key: 'onMediaSegment',
 11283          get: function get() {
 11284              return this._onMediaSegment;
 11285          },
 11286          set: function set(callback) {
 11287              this._onMediaSegment = callback;
 11288          }
 11289      }]);
 11290  
 11291      return MP4Remuxer;
 11292  }();
 11293  
 11294  exports.default = MP4Remuxer;
 11295  
 11296  },{"../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){
 11297  'use strict';
 11298  
 11299  Object.defineProperty(exports, "__esModule", {
 11300      value: true
 11301  });
 11302  /*
 11303   * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11304   *
 11305   * @author zheng qian <xqq@xqq.im>
 11306   *
 11307   * Licensed under the Apache License, Version 2.0 (the "License");
 11308   * you may not use this file except in compliance with the License.
 11309   * You may obtain a copy of the License at
 11310   *
 11311   *     http://www.apache.org/licenses/LICENSE-2.0
 11312   *
 11313   * Unless required by applicable law or agreed to in writing, software
 11314   * distributed under the License is distributed on an "AS IS" BASIS,
 11315   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11316   * See the License for the specific language governing permissions and
 11317   * limitations under the License.
 11318   */
 11319  
 11320  var Browser = {};
 11321  
 11322  function detect() {
 11323      // modified from jquery-browser-plugin
 11324  
 11325      var ua = self.navigator.userAgent.toLowerCase();
 11326  
 11327      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) || [];
 11328  
 11329      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) || [];
 11330  
 11331      var matched = {
 11332          browser: match[5] || match[3] || match[1] || '',
 11333          version: match[2] || match[4] || '0',
 11334          majorVersion: match[4] || match[2] || '0',
 11335          platform: platform_match[0] || ''
 11336      };
 11337  
 11338      var browser = {};
 11339      if (matched.browser) {
 11340          browser[matched.browser] = true;
 11341  
 11342          var versionArray = matched.majorVersion.split('.');
 11343          browser.version = {
 11344              major: parseInt(matched.majorVersion, 10),
 11345              string: matched.version
 11346          };
 11347          if (versionArray.length > 1) {
 11348              browser.version.minor = parseInt(versionArray[1], 10);
 11349          }
 11350          if (versionArray.length > 2) {
 11351              browser.version.build = parseInt(versionArray[2], 10);
 11352          }
 11353      }
 11354  
 11355      if (matched.platform) {
 11356          browser[matched.platform] = true;
 11357      }
 11358  
 11359      if (browser.chrome || browser.opr || browser.safari) {
 11360          browser.webkit = true;
 11361      }
 11362  
 11363      // MSIE. IE11 has 'rv' identifer
 11364      if (browser.rv || browser.iemobile) {
 11365          if (browser.rv) {
 11366              delete browser.rv;
 11367          }
 11368          var msie = 'msie';
 11369          matched.browser = msie;
 11370          browser[msie] = true;
 11371      }
 11372  
 11373      // Microsoft Edge
 11374      if (browser.edge) {
 11375          delete browser.edge;
 11376          var msedge = 'msedge';
 11377          matched.browser = msedge;
 11378          browser[msedge] = true;
 11379      }
 11380  
 11381      // Opera 15+
 11382      if (browser.opr) {
 11383          var opera = 'opera';
 11384          matched.browser = opera;
 11385          browser[opera] = true;
 11386      }
 11387  
 11388      // Stock android browsers are marked as Safari
 11389      if (browser.safari && browser.android) {
 11390          var android = 'android';
 11391          matched.browser = android;
 11392          browser[android] = true;
 11393      }
 11394  
 11395      browser.name = matched.browser;
 11396      browser.platform = matched.platform;
 11397  
 11398      for (var key in Browser) {
 11399          if (Browser.hasOwnProperty(key)) {
 11400              delete Browser[key];
 11401          }
 11402      }
 11403      Object.assign(Browser, browser);
 11404  }
 11405  
 11406  detect();
 11407  
 11408  exports.default = Browser;
 11409  
 11410  },{}],40:[function(_dereq_,module,exports){
 11411  'use strict';
 11412  
 11413  Object.defineProperty(exports, "__esModule", {
 11414      value: true
 11415  });
 11416  
 11417  var _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; }; }();
 11418  
 11419  function _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; }
 11420  
 11421  function _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; }
 11422  
 11423  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 11424  
 11425  /*
 11426   * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11427   *
 11428   * @author zheng qian <xqq@xqq.im>
 11429   *
 11430   * Licensed under the Apache License, Version 2.0 (the "License");
 11431   * you may not use this file except in compliance with the License.
 11432   * You may obtain a copy of the License at
 11433   *
 11434   *     http://www.apache.org/licenses/LICENSE-2.0
 11435   *
 11436   * Unless required by applicable law or agreed to in writing, software
 11437   * distributed under the License is distributed on an "AS IS" BASIS,
 11438   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11439   * See the License for the specific language governing permissions and
 11440   * limitations under the License.
 11441   */
 11442  
 11443  var RuntimeException = exports.RuntimeException = function () {
 11444      function RuntimeException(message) {
 11445          _classCallCheck(this, RuntimeException);
 11446  
 11447          this._message = message;
 11448      }
 11449  
 11450      _createClass(RuntimeException, [{
 11451          key: 'toString',
 11452          value: function toString() {
 11453              return this.name + ': ' + this.message;
 11454          }
 11455      }, {
 11456          key: 'name',
 11457          get: function get() {
 11458              return 'RuntimeException';
 11459          }
 11460      }, {
 11461          key: 'message',
 11462          get: function get() {
 11463              return this._message;
 11464          }
 11465      }]);
 11466  
 11467      return RuntimeException;
 11468  }();
 11469  
 11470  var IllegalStateException = exports.IllegalStateException = function (_RuntimeException) {
 11471      _inherits(IllegalStateException, _RuntimeException);
 11472  
 11473      function IllegalStateException(message) {
 11474          _classCallCheck(this, IllegalStateException);
 11475  
 11476          return _possibleConstructorReturn(this, (IllegalStateException.__proto__ || Object.getPrototypeOf(IllegalStateException)).call(this, message));
 11477      }
 11478  
 11479      _createClass(IllegalStateException, [{
 11480          key: 'name',
 11481          get: function get() {
 11482              return 'IllegalStateException';
 11483          }
 11484      }]);
 11485  
 11486      return IllegalStateException;
 11487  }(RuntimeException);
 11488  
 11489  var InvalidArgumentException = exports.InvalidArgumentException = function (_RuntimeException2) {
 11490      _inherits(InvalidArgumentException, _RuntimeException2);
 11491  
 11492      function InvalidArgumentException(message) {
 11493          _classCallCheck(this, InvalidArgumentException);
 11494  
 11495          return _possibleConstructorReturn(this, (InvalidArgumentException.__proto__ || Object.getPrototypeOf(InvalidArgumentException)).call(this, message));
 11496      }
 11497  
 11498      _createClass(InvalidArgumentException, [{
 11499          key: 'name',
 11500          get: function get() {
 11501              return 'InvalidArgumentException';
 11502          }
 11503      }]);
 11504  
 11505      return InvalidArgumentException;
 11506  }(RuntimeException);
 11507  
 11508  var NotImplementedException = exports.NotImplementedException = function (_RuntimeException3) {
 11509      _inherits(NotImplementedException, _RuntimeException3);
 11510  
 11511      function NotImplementedException(message) {
 11512          _classCallCheck(this, NotImplementedException);
 11513  
 11514          return _possibleConstructorReturn(this, (NotImplementedException.__proto__ || Object.getPrototypeOf(NotImplementedException)).call(this, message));
 11515      }
 11516  
 11517      _createClass(NotImplementedException, [{
 11518          key: 'name',
 11519          get: function get() {
 11520              return 'NotImplementedException';
 11521          }
 11522      }]);
 11523  
 11524      return NotImplementedException;
 11525  }(RuntimeException);
 11526  
 11527  },{}],41:[function(_dereq_,module,exports){
 11528  'use strict';
 11529  
 11530  Object.defineProperty(exports, "__esModule", {
 11531      value: true
 11532  });
 11533  
 11534  var _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; }; }(); /*
 11535                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11536                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11537                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
 11538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
 11540                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
 11541                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
 11542                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11543                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
 11544                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11545                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
 11546                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
 11547                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11548                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
 11549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
 11550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
 11551  
 11552  var _events = _dereq_('events');
 11553  
 11554  var _events2 = _interopRequireDefault(_events);
 11555  
 11556  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 11557  
 11558  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 11559  
 11560  var Log = function () {
 11561      function Log() {
 11562          _classCallCheck(this, Log);
 11563      }
 11564  
 11565      _createClass(Log, null, [{
 11566          key: 'e',
 11567          value: function e(tag, msg) {
 11568              if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
 11569  
 11570              var str = '[' + tag + '] > ' + msg;
 11571  
 11572              if (Log.ENABLE_CALLBACK) {
 11573                  Log.emitter.emit('log', 'error', str);
 11574              }
 11575  
 11576              if (!Log.ENABLE_ERROR) {
 11577                  return;
 11578              }
 11579  
 11580              if (console.error) {
 11581                  console.error(str);
 11582              } else if (console.warn) {
 11583                  console.warn(str);
 11584              } else {
 11585                  console.log(str);
 11586              }
 11587          }
 11588      }, {
 11589          key: 'i',
 11590          value: function i(tag, msg) {
 11591              if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
 11592  
 11593              var str = '[' + tag + '] > ' + msg;
 11594  
 11595              if (Log.ENABLE_CALLBACK) {
 11596                  Log.emitter.emit('log', 'info', str);
 11597              }
 11598  
 11599              if (!Log.ENABLE_INFO) {
 11600                  return;
 11601              }
 11602  
 11603              if (console.info) {
 11604                  console.info(str);
 11605              } else {
 11606                  console.log(str);
 11607              }
 11608          }
 11609      }, {
 11610          key: 'w',
 11611          value: function w(tag, msg) {
 11612              if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
 11613  
 11614              var str = '[' + tag + '] > ' + msg;
 11615  
 11616              if (Log.ENABLE_CALLBACK) {
 11617                  Log.emitter.emit('log', 'warn', str);
 11618              }
 11619  
 11620              if (!Log.ENABLE_WARN) {
 11621                  return;
 11622              }
 11623  
 11624              if (console.warn) {
 11625                  console.warn(str);
 11626              } else {
 11627                  console.log(str);
 11628              }
 11629          }
 11630      }, {
 11631          key: 'd',
 11632          value: function d(tag, msg) {
 11633              if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
 11634  
 11635              var str = '[' + tag + '] > ' + msg;
 11636  
 11637              if (Log.ENABLE_CALLBACK) {
 11638                  Log.emitter.emit('log', 'debug', str);
 11639              }
 11640  
 11641              if (!Log.ENABLE_DEBUG) {
 11642                  return;
 11643              }
 11644  
 11645              if (console.debug) {
 11646                  console.debug(str);
 11647              } else {
 11648                  console.log(str);
 11649              }
 11650          }
 11651      }, {
 11652          key: 'v',
 11653          value: function v(tag, msg) {
 11654              if (!tag || Log.FORCE_GLOBAL_TAG) tag = Log.GLOBAL_TAG;
 11655  
 11656              var str = '[' + tag + '] > ' + msg;
 11657  
 11658              if (Log.ENABLE_CALLBACK) {
 11659                  Log.emitter.emit('log', 'verbose', str);
 11660              }
 11661  
 11662              if (!Log.ENABLE_VERBOSE) {
 11663                  return;
 11664              }
 11665  
 11666              console.log(str);
 11667          }
 11668      }]);
 11669  
 11670      return Log;
 11671  }();
 11672  
 11673  Log.GLOBAL_TAG = 'flv.js';
 11674  Log.FORCE_GLOBAL_TAG = false;
 11675  Log.ENABLE_ERROR = true;
 11676  Log.ENABLE_INFO = true;
 11677  Log.ENABLE_WARN = true;
 11678  Log.ENABLE_DEBUG = true;
 11679  Log.ENABLE_VERBOSE = true;
 11680  
 11681  Log.ENABLE_CALLBACK = false;
 11682  
 11683  Log.emitter = new _events2.default();
 11684  
 11685  exports.default = Log;
 11686  
 11687  },{"events":2}],42:[function(_dereq_,module,exports){
 11688  'use strict';
 11689  
 11690  Object.defineProperty(exports, "__esModule", {
 11691      value: true
 11692  });
 11693  
 11694  var _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; }; }(); /*
 11695                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11696                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11697                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * @author zheng qian <xqq@xqq.im>
 11698                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11699                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Licensed under the Apache License, Version 2.0 (the "License");
 11700                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * you may not use this file except in compliance with the License.
 11701                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * You may obtain a copy of the License at
 11702                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11703                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *     http://www.apache.org/licenses/LICENSE-2.0
 11704                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        *
 11705                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Unless required by applicable law or agreed to in writing, software
 11706                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * distributed under the License is distributed on an "AS IS" BASIS,
 11707                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11708                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * See the License for the specific language governing permissions and
 11709                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * limitations under the License.
 11710                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        */
 11711  
 11712  var _events = _dereq_('events');
 11713  
 11714  var _events2 = _interopRequireDefault(_events);
 11715  
 11716  var _logger = _dereq_('./logger.js');
 11717  
 11718  var _logger2 = _interopRequireDefault(_logger);
 11719  
 11720  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 11721  
 11722  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 11723  
 11724  var LoggingControl = function () {
 11725      function LoggingControl() {
 11726          _classCallCheck(this, LoggingControl);
 11727      }
 11728  
 11729      _createClass(LoggingControl, null, [{
 11730          key: 'getConfig',
 11731          value: function getConfig() {
 11732              return {
 11733                  globalTag: _logger2.default.GLOBAL_TAG,
 11734                  forceGlobalTag: _logger2.default.FORCE_GLOBAL_TAG,
 11735                  enableVerbose: _logger2.default.ENABLE_VERBOSE,
 11736                  enableDebug: _logger2.default.ENABLE_DEBUG,
 11737                  enableInfo: _logger2.default.ENABLE_INFO,
 11738                  enableWarn: _logger2.default.ENABLE_WARN,
 11739                  enableError: _logger2.default.ENABLE_ERROR,
 11740                  enableCallback: _logger2.default.ENABLE_CALLBACK
 11741              };
 11742          }
 11743      }, {
 11744          key: 'applyConfig',
 11745          value: function applyConfig(config) {
 11746              _logger2.default.GLOBAL_TAG = config.globalTag;
 11747              _logger2.default.FORCE_GLOBAL_TAG = config.forceGlobalTag;
 11748              _logger2.default.ENABLE_VERBOSE = config.enableVerbose;
 11749              _logger2.default.ENABLE_DEBUG = config.enableDebug;
 11750              _logger2.default.ENABLE_INFO = config.enableInfo;
 11751              _logger2.default.ENABLE_WARN = config.enableWarn;
 11752              _logger2.default.ENABLE_ERROR = config.enableError;
 11753              _logger2.default.ENABLE_CALLBACK = config.enableCallback;
 11754          }
 11755      }, {
 11756          key: '_notifyChange',
 11757          value: function _notifyChange() {
 11758              var emitter = LoggingControl.emitter;
 11759  
 11760              if (emitter.listenerCount('change') > 0) {
 11761                  var config = LoggingControl.getConfig();
 11762                  emitter.emit('change', config);
 11763              }
 11764          }
 11765      }, {
 11766          key: 'registerListener',
 11767          value: function registerListener(listener) {
 11768              LoggingControl.emitter.addListener('change', listener);
 11769          }
 11770      }, {
 11771          key: 'removeListener',
 11772          value: function removeListener(listener) {
 11773              LoggingControl.emitter.removeListener('change', listener);
 11774          }
 11775      }, {
 11776          key: 'addLogListener',
 11777          value: function addLogListener(listener) {
 11778              _logger2.default.emitter.addListener('log', listener);
 11779              if (_logger2.default.emitter.listenerCount('log') > 0) {
 11780                  _logger2.default.ENABLE_CALLBACK = true;
 11781                  LoggingControl._notifyChange();
 11782              }
 11783          }
 11784      }, {
 11785          key: 'removeLogListener',
 11786          value: function removeLogListener(listener) {
 11787              _logger2.default.emitter.removeListener('log', listener);
 11788              if (_logger2.default.emitter.listenerCount('log') === 0) {
 11789                  _logger2.default.ENABLE_CALLBACK = false;
 11790                  LoggingControl._notifyChange();
 11791              }
 11792          }
 11793      }, {
 11794          key: 'forceGlobalTag',
 11795          get: function get() {
 11796              return _logger2.default.FORCE_GLOBAL_TAG;
 11797          },
 11798          set: function set(enable) {
 11799              _logger2.default.FORCE_GLOBAL_TAG = enable;
 11800              LoggingControl._notifyChange();
 11801          }
 11802      }, {
 11803          key: 'globalTag',
 11804          get: function get() {
 11805              return _logger2.default.GLOBAL_TAG;
 11806          },
 11807          set: function set(tag) {
 11808              _logger2.default.GLOBAL_TAG = tag;
 11809              LoggingControl._notifyChange();
 11810          }
 11811      }, {
 11812          key: 'enableAll',
 11813          get: function get() {
 11814              return _logger2.default.ENABLE_VERBOSE && _logger2.default.ENABLE_DEBUG && _logger2.default.ENABLE_INFO && _logger2.default.ENABLE_WARN && _logger2.default.ENABLE_ERROR;
 11815          },
 11816          set: function set(enable) {
 11817              _logger2.default.ENABLE_VERBOSE = enable;
 11818              _logger2.default.ENABLE_DEBUG = enable;
 11819              _logger2.default.ENABLE_INFO = enable;
 11820              _logger2.default.ENABLE_WARN = enable;
 11821              _logger2.default.ENABLE_ERROR = enable;
 11822              LoggingControl._notifyChange();
 11823          }
 11824      }, {
 11825          key: 'enableDebug',
 11826          get: function get() {
 11827              return _logger2.default.ENABLE_DEBUG;
 11828          },
 11829          set: function set(enable) {
 11830              _logger2.default.ENABLE_DEBUG = enable;
 11831              LoggingControl._notifyChange();
 11832          }
 11833      }, {
 11834          key: 'enableVerbose',
 11835          get: function get() {
 11836              return _logger2.default.ENABLE_VERBOSE;
 11837          },
 11838          set: function set(enable) {
 11839              _logger2.default.ENABLE_VERBOSE = enable;
 11840              LoggingControl._notifyChange();
 11841          }
 11842      }, {
 11843          key: 'enableInfo',
 11844          get: function get() {
 11845              return _logger2.default.ENABLE_INFO;
 11846          },
 11847          set: function set(enable) {
 11848              _logger2.default.ENABLE_INFO = enable;
 11849              LoggingControl._notifyChange();
 11850          }
 11851      }, {
 11852          key: 'enableWarn',
 11853          get: function get() {
 11854              return _logger2.default.ENABLE_WARN;
 11855          },
 11856          set: function set(enable) {
 11857              _logger2.default.ENABLE_WARN = enable;
 11858              LoggingControl._notifyChange();
 11859          }
 11860      }, {
 11861          key: 'enableError',
 11862          get: function get() {
 11863              return _logger2.default.ENABLE_ERROR;
 11864          },
 11865          set: function set(enable) {
 11866              _logger2.default.ENABLE_ERROR = enable;
 11867              LoggingControl._notifyChange();
 11868          }
 11869      }]);
 11870  
 11871      return LoggingControl;
 11872  }();
 11873  
 11874  LoggingControl.emitter = new _events2.default();
 11875  
 11876  exports.default = LoggingControl;
 11877  
 11878  },{"./logger.js":41,"events":2}],43:[function(_dereq_,module,exports){
 11879  'use strict';
 11880  
 11881  Object.defineProperty(exports, "__esModule", {
 11882      value: true
 11883  });
 11884  
 11885  var _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; }; }();
 11886  
 11887  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 11888  
 11889  /*
 11890   * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11891   *
 11892   * @author zheng qian <xqq@xqq.im>
 11893   *
 11894   * Licensed under the Apache License, Version 2.0 (the "License");
 11895   * you may not use this file except in compliance with the License.
 11896   * You may obtain a copy of the License at
 11897   *
 11898   *     http://www.apache.org/licenses/LICENSE-2.0
 11899   *
 11900   * Unless required by applicable law or agreed to in writing, software
 11901   * distributed under the License is distributed on an "AS IS" BASIS,
 11902   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11903   * See the License for the specific language governing permissions and
 11904   * limitations under the License.
 11905   */
 11906  
 11907  var Polyfill = function () {
 11908      function Polyfill() {
 11909          _classCallCheck(this, Polyfill);
 11910      }
 11911  
 11912      _createClass(Polyfill, null, [{
 11913          key: 'install',
 11914          value: function install() {
 11915              // ES6 Object.setPrototypeOf
 11916              Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
 11917                  obj.__proto__ = proto;
 11918                  return obj;
 11919              };
 11920  
 11921              // ES6 Object.assign
 11922              Object.assign = Object.assign || function (target) {
 11923                  if (target === undefined || target === null) {
 11924                      throw new TypeError('Cannot convert undefined or null to object');
 11925                  }
 11926  
 11927                  var output = Object(target);
 11928                  for (var i = 1; i < arguments.length; i++) {
 11929                      var source = arguments[i];
 11930                      if (source !== undefined && source !== null) {
 11931                          for (var key in source) {
 11932                              if (source.hasOwnProperty(key)) {
 11933                                  output[key] = source[key];
 11934                              }
 11935                          }
 11936                      }
 11937                  }
 11938                  return output;
 11939              };
 11940  
 11941              // ES6 Promise (missing support in IE11)
 11942              if (typeof self.Promise !== 'function') {
 11943                  _dereq_('es6-promise').polyfill();
 11944              }
 11945          }
 11946      }]);
 11947  
 11948      return Polyfill;
 11949  }();
 11950  
 11951  Polyfill.install();
 11952  
 11953  exports.default = Polyfill;
 11954  
 11955  },{"es6-promise":1}],44:[function(_dereq_,module,exports){
 11956  'use strict';
 11957  
 11958  Object.defineProperty(exports, "__esModule", {
 11959      value: true
 11960  });
 11961  /*
 11962   * Copyright (C) 2016 Bilibili. All Rights Reserved.
 11963   *
 11964   * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)
 11965   * @author zheng qian <xqq@xqq.im>
 11966   *
 11967   * Licensed under the Apache License, Version 2.0 (the "License");
 11968   * you may not use this file except in compliance with the License.
 11969   * You may obtain a copy of the License at
 11970   *
 11971   *     http://www.apache.org/licenses/LICENSE-2.0
 11972   *
 11973   * Unless required by applicable law or agreed to in writing, software
 11974   * distributed under the License is distributed on an "AS IS" BASIS,
 11975   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11976   * See the License for the specific language governing permissions and
 11977   * limitations under the License.
 11978   */
 11979  
 11980  function checkContinuation(uint8array, start, checkLength) {
 11981      var array = uint8array;
 11982      if (start + checkLength < array.length) {
 11983          while (checkLength--) {
 11984              if ((array[++start] & 0xC0) !== 0x80) return false;
 11985          }
 11986          return true;
 11987      } else {
 11988          return false;
 11989      }
 11990  }
 11991  
 11992  function decodeUTF8(uint8array) {
 11993      var out = [];
 11994      var input = uint8array;
 11995      var i = 0;
 11996      var length = uint8array.length;
 11997  
 11998      while (i < length) {
 11999          if (input[i] < 0x80) {
 12000              out.push(String.fromCharCode(input[i]));
 12001              ++i;
 12002              continue;
 12003          } else if (input[i] < 0xC0) {
 12004              // fallthrough
 12005          } else if (input[i] < 0xE0) {
 12006              if (checkContinuation(input, i, 1)) {
 12007                  var ucs4 = (input[i] & 0x1F) << 6 | input[i + 1] & 0x3F;
 12008                  if (ucs4 >= 0x80) {
 12009                      out.push(String.fromCharCode(ucs4 & 0xFFFF));
 12010                      i += 2;
 12011                      continue;
 12012                  }
 12013              }
 12014          } else if (input[i] < 0xF0) {
 12015              if (checkContinuation(input, i, 2)) {
 12016                  var _ucs = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;
 12017                  if (_ucs >= 0x800 && (_ucs & 0xF800) !== 0xD800) {
 12018                      out.push(String.fromCharCode(_ucs & 0xFFFF));
 12019                      i += 3;
 12020                      continue;
 12021                  }
 12022              }
 12023          } else if (input[i] < 0xF8) {
 12024              if (checkContinuation(input, i, 3)) {
 12025                  var _ucs2 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12 | (input[i + 2] & 0x3F) << 6 | input[i + 3] & 0x3F;
 12026                  if (_ucs2 > 0x10000 && _ucs2 < 0x110000) {
 12027                      _ucs2 -= 0x10000;
 12028                      out.push(String.fromCharCode(_ucs2 >>> 10 | 0xD800));
 12029                      out.push(String.fromCharCode(_ucs2 & 0x3FF | 0xDC00));
 12030                      i += 4;
 12031                      continue;
 12032                  }
 12033              }
 12034          }
 12035          out.push(String.fromCharCode(0xFFFD));
 12036          ++i;
 12037      }
 12038  
 12039      return out.join('');
 12040  }
 12041  
 12042  exports.default = decodeUTF8;
 12043  
 12044  },{}]},{},[21])(21)
 12045  });
 12046  
 12047  //# sourceMappingURL=flv.js.map