1 line
12 KiB
JavaScript
1 line
12 KiB
JavaScript
define(["exports","../utils/logger.js","./speed-sampler.js","./loader.js","./fetch-stream-loader.js","./range-seek-handler.js","./param-seek-handler.js","../utils/exception.js"],function(_exports,_logger,_speedSampler,_loader,_fetchStreamLoader,_rangeSeekHandler,_paramSeekHandler,_exception){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;var IOController=function(){function IOController(dataSource,config,extraData){babelHelpers.classCallCheck(this,IOController),this.TAG="IOController",this._config=config,this._extraData=extraData,this._stashInitialSize=393216,null!=config.stashInitialSize&&0<config.stashInitialSize&&(this._stashInitialSize=config.stashInitialSize),this._stashUsed=0,this._stashSize=this._stashInitialSize,this._bufferSize=3145728,this._stashBuffer=new ArrayBuffer(this._bufferSize),this._stashByteStart=0,!(this._enableStash=!0)===config.enableStashBuffer&&(this._enableStash=!1),this._loader=null,this._loaderClass=null,this._seekHandler=null,this._dataSource=dataSource,this._isWebSocketURL=/wss?:\/\/(.+?)/.test(dataSource.url),this._refTotalLength=dataSource.filesize||null,this._totalLength=this._refTotalLength,this._fullRequestFlag=!1,this._currentRange=null,this._redirectedURL=null,this._speedNormalized=0,this._speedSampler=new _speedSampler.default,this._speedNormalizeList=[64,128,256,384,512,768,1024,1536,2048,3072,4096],this._isEarlyEofReconnecting=!1,this._paused=!1,this._resumeFrom=0,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._selectSeekHandler(),this._selectLoader(),this._createLoader()}return babelHelpers.createClass(IOController,[{key:"destroy",value:function(){this._loader.isWorking()&&this._loader.abort(),this._loader.destroy(),this._loader=null,this._loaderClass=null,this._dataSource=null,this._stashBuffer=null,this._stashUsed=this._stashSize=this._bufferSize=this._stashByteStart=0,this._currentRange=null,this._speedSampler=null,this._isEarlyEofReconnecting=!1,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._extraData=null}},{key:"isWorking",value:function(){return this._loader&&this._loader.isWorking()&&!this._paused}},{key:"isPaused",value:function(){return this._paused}},{key:"status",get:function(){return this._loader.status}},{key:"extraData",get:function(){return this._extraData},set:function(data){this._extraData=data}},{key:"onDataArrival",get:function(){return this._onDataArrival},set:function(callback){this._onDataArrival=callback}},{key:"onSeeked",get:function(){return this._onSeeked},set:function(callback){this._onSeeked=callback}},{key:"onError",get:function(){return this._onError},set:function(callback){this._onError=callback}},{key:"onComplete",get:function(){return this._onComplete},set:function(callback){this._onComplete=callback}},{key:"onRedirect",get:function(){return this._onRedirect},set:function(callback){this._onRedirect=callback}},{key:"onRecoveredEarlyEof",get:function(){return this._onRecoveredEarlyEof},set:function(callback){this._onRecoveredEarlyEof=callback}},{key:"currentURL",get:function(){return this._dataSource.url}},{key:"hasRedirect",get:function(){return null!=this._redirectedURL||null!=this._dataSource.redirectedURL}},{key:"currentRedirectedURL",get:function(){return this._redirectedURL||this._dataSource.redirectedURL}},{key:"currentSpeed",get:function(){return this._speedSampler.lastSecondKBps}},{key:"loaderType",get:function(){return this._loader.type}},{key:"_selectSeekHandler",value:function(){var config=this._config;if("range"===config.seekType)this._seekHandler=new _rangeSeekHandler.default(this._config.rangeLoadZeroStart);else if("param"===config.seekType){var paramStart=config.seekParamStart||"bstart",paramEnd=config.seekParamEnd||"bend";this._seekHandler=new _paramSeekHandler.default(paramStart,paramEnd)}else{if("custom"!==config.seekType)throw new _exception.InvalidArgumentException("Invalid seekType in config: ".concat(config.seekType));if("function"!=typeof config.customSeekHandler)throw new _exception.InvalidArgumentException("Custom seekType specified in config but invalid customSeekHandler!");this._seekHandler=new config.customSeekHandler}}},{key:"_selectLoader",value:function(){if(null!=this._config.customLoader)this._loaderClass=this._config.customLoader;else{if(!_fetchStreamLoader.default.isSupported())throw new _exception.RuntimeException("Your browser doesn't support xhr with arraybuffer responseType!");this._loaderClass=_fetchStreamLoader.default}}},{key:"_createLoader",value:function(){this._loader=new this._loaderClass(this._seekHandler,this._config),!1===this._loader.needStashBuffer&&(this._enableStash=!1),this._loader.onContentLengthKnown=this._onContentLengthKnown.bind(this),this._loader.onURLRedirect=this._onURLRedirect.bind(this),this._loader.onDataArrival=this._onLoaderChunkArrival.bind(this),this._loader.onComplete=this._onLoaderComplete.bind(this),this._loader.onError=this._onLoaderError.bind(this)}},{key:"open",value:function(optionalFrom){this._currentRange={from:0,to:-1},optionalFrom&&(this._currentRange.from=optionalFrom),this._speedSampler.reset(),optionalFrom||(this._fullRequestFlag=!0),this._loader.open(this._dataSource,Object.assign({},this._currentRange))}},{key:"abort",value:function(){this._loader.abort(),this._paused&&(this._paused=!1,this._resumeFrom=0)}},{key:"pause",value:function(){this.isWorking()&&(this._loader.abort(),0!==this._stashUsed?(this._resumeFrom=this._stashByteStart,this._currentRange.to=this._stashByteStart-1):this._resumeFrom=this._currentRange.to+1,this._stashUsed=0,this._stashByteStart=0,this._paused=!0)}},{key:"resume",value:function(){var bytes;this._paused&&(this._paused=!1,bytes=this._resumeFrom,this._resumeFrom=0,this._internalSeek(bytes,!0))}},{key:"seek",value:function(bytes){this._paused=!1,this._stashUsed=0,this._stashByteStart=0,this._internalSeek(bytes,!0)}},{key:"_internalSeek",value:function(bytes,dropUnconsumed){this._loader.isWorking()&&this._loader.abort(),this._flushStashBuffer(dropUnconsumed),this._loader.destroy(),this._loader=null;dropUnconsumed={from:bytes,to:-1};this._currentRange={from:dropUnconsumed.from,to:-1},this._speedSampler.reset(),this._stashSize=this._stashInitialSize,this._createLoader(),this._loader.open(this._dataSource,dropUnconsumed),this._onSeeked&&this._onSeeked()}},{key:"updateUrl",value:function(url){if(!url||"string"!=typeof url||0===url.length)throw new _exception.InvalidArgumentException("Url must be a non-empty string!");this._dataSource.url=url}},{key:"_expandBuffer",value:function(expectedBytes){for(var newBuffer,stashOldArray,bufferNewSize=this._stashSize;bufferNewSize+1048576<expectedBytes;)bufferNewSize*=2;(bufferNewSize+=1048576)!==this._bufferSize&&(newBuffer=new ArrayBuffer(bufferNewSize),0<this._stashUsed&&(stashOldArray=new Uint8Array(this._stashBuffer,0,this._stashUsed),new Uint8Array(newBuffer,0,bufferNewSize).set(stashOldArray,0)),this._stashBuffer=newBuffer,this._bufferSize=bufferNewSize)}},{key:"_normalizeSpeed",value:function(input){var mid,list=this._speedNormalizeList,last=list.length-1,lbound=0,ubound=last;if(input<list[0])return list[0];for(;lbound<=ubound;){if((mid=lbound+Math.floor((ubound-lbound)/2))===last||input>=list[mid]&&input<list[mid+1])return list[mid];list[mid]<input?lbound=mid+1:ubound=mid-1}}},{key:"_adjustStashSize",value:function(normalized){var stashSizeKB=0,normalized=1024*(stashSizeKB=8192<(stashSizeKB=this._config.isLive||normalized<512?normalized:512<=normalized&&normalized<=1024?Math.floor(1.5*normalized):2*normalized)?8192:stashSizeKB)+1048576;this._bufferSize<normalized&&this._expandBuffer(normalized),this._stashSize=1024*stashSizeKB}},{key:"_dispatchChunks",value:function(chunks,byteStart){return this._currentRange.to=byteStart+chunks.byteLength-1,this._onDataArrival(chunks,byteStart)}},{key:"_onURLRedirect",value:function(redirectedURL){this._redirectedURL=redirectedURL,this._onRedirect&&this._onRedirect(redirectedURL)}},{key:"_onContentLengthKnown",value:function(contentLength){contentLength&&this._fullRequestFlag&&(this._totalLength=contentLength,this._fullRequestFlag=!1)}},{key:"_onLoaderChunkArrival",value:function(chunk,byteStart,receivedLength){if(!this._onDataArrival)throw new _exception.IllegalStateException("IOController: No existing consumer (onDataArrival) callback!");var KBps,buffer,_consumed2;this._paused||(this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,this._onRecoveredEarlyEof)&&this._onRecoveredEarlyEof(),this._speedSampler.addBytes(chunk.byteLength),0!==(KBps=this._speedSampler.lastSecondKBps)&&(KBps=this._normalizeSpeed(KBps),this._speedNormalized!==KBps)&&(this._speedNormalized=KBps,this._adjustStashSize(KBps)),this._enableStash?(0===this._stashUsed&&0===this._stashByteStart&&(this._stashByteStart=byteStart),this._stashUsed+chunk.byteLength<=this._stashSize?(new Uint8Array(this._stashBuffer,0,this._stashSize).set(new Uint8Array(chunk),this._stashUsed),this._stashUsed+=chunk.byteLength):(KBps=new Uint8Array(this._stashBuffer,0,this._bufferSize),0<this._stashUsed?(buffer=this._stashBuffer.slice(0,this._stashUsed),(_consumed2=this._dispatchChunks(buffer,this._stashByteStart))<buffer.byteLength?0<_consumed2&&(buffer=new Uint8Array(buffer,_consumed2),KBps.set(buffer,0),this._stashUsed=buffer.byteLength,this._stashByteStart+=_consumed2):(this._stashUsed=0,this._stashByteStart+=_consumed2),this._stashUsed+chunk.byteLength>this._bufferSize&&(this._expandBuffer(this._stashUsed+chunk.byteLength),KBps=new Uint8Array(this._stashBuffer,0,this._bufferSize)),KBps.set(new Uint8Array(chunk),this._stashUsed),this._stashUsed+=chunk.byteLength):(buffer=this._dispatchChunks(chunk,byteStart))<chunk.byteLength&&((_consumed2=chunk.byteLength-buffer)>this._bufferSize&&(this._expandBuffer(_consumed2),KBps=new Uint8Array(this._stashBuffer,0,this._bufferSize)),KBps.set(new Uint8Array(chunk,buffer),0),this._stashUsed+=_consumed2,this._stashByteStart=byteStart+buffer))):0===this._stashUsed?(KBps=this._dispatchChunks(chunk,byteStart))<chunk.byteLength&&((_consumed2=chunk.byteLength-KBps)>this._bufferSize&&this._expandBuffer(_consumed2),new Uint8Array(this._stashBuffer,0,this._bufferSize).set(new Uint8Array(chunk,KBps),0),this._stashUsed+=_consumed2,this._stashByteStart=byteStart+KBps):(this._stashUsed+chunk.byteLength>this._bufferSize&&this._expandBuffer(this._stashUsed+chunk.byteLength),(buffer=new Uint8Array(this._stashBuffer,0,this._bufferSize)).set(new Uint8Array(chunk),this._stashUsed),this._stashUsed+=chunk.byteLength,(_consumed2=this._dispatchChunks(this._stashBuffer.slice(0,this._stashUsed),this._stashByteStart))<this._stashUsed&&0<_consumed2&&(byteStart=new Uint8Array(this._stashBuffer,_consumed2),buffer.set(byteStart,0)),this._stashUsed-=_consumed2,this._stashByteStart+=_consumed2))}},{key:"_flushStashBuffer",value:function(dropUnconsumed){if(0<this._stashUsed){var buffer=this._stashBuffer.slice(0,this._stashUsed),consumed=this._dispatchChunks(buffer,this._stashByteStart),remain=buffer.byteLength-consumed;if(consumed<buffer.byteLength){if(!dropUnconsumed)return 0<consumed&&(dropUnconsumed=new Uint8Array(this._stashBuffer,0,this._bufferSize),buffer=new Uint8Array(buffer,consumed),dropUnconsumed.set(buffer,0),this._stashUsed=buffer.byteLength,this._stashByteStart+=consumed),0;_logger.default.w(this.TAG,"".concat(remain," bytes unconsumed data remain when flush buffer, dropped"))}return this._stashUsed=0,this._stashByteStart=0,remain}return 0}},{key:"_onLoaderComplete",value:function(from,to){this._flushStashBuffer(!0),this._onComplete&&this._onComplete(this._extraData)}},{key:"_onLoaderError",value:function(type,data){switch(_logger.default.e(this.TAG,"Loader error, code = ".concat(data.code,", msg = ").concat(data.msg)),this._flushStashBuffer(!1),this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,type=_loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF),type){case _loader.LoaderErrors.EARLY_EOF:var nextFrom;if(!this._config.isLive)if(this._totalLength)return void((nextFrom=this._currentRange.to+1)<this._totalLength&&(_logger.default.w(this.TAG,"Connection lost, trying reconnect..."),this._isEarlyEofReconnecting=!0,this._internalSeek(nextFrom,!1)));type=_loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF;break;case _loader.LoaderErrors.UNRECOVERABLE_EARLY_EOF:case _loader.LoaderErrors.CONNECTING_TIMEOUT:case _loader.LoaderErrors.HTTP_STATUS_CODE_INVALID:case _loader.LoaderErrors.EXCEPTION:}if(!this._onError)throw new _exception.RuntimeException("IOException: "+data.msg);this._onError(type,data)}}]),IOController}();_exports.default=IOController}); |