import f from"events";import h from"../utils/logger.js";import m from"../utils/browser.js";import n from"./player-events.js";import c from"../core/transmuxer.js";import a from"../core/transmuxing-events.js";import E from"../core/mse-controller.js";import o from"../core/mse-events.js";import{ErrorTypes as _,ErrorDetails as g}from"./player-errors.js";import{createDefaultConfig as p}from"../config.js";import{InvalidArgumentException as T,IllegalStateException as u}from"../utils/exception.js";class v{constructor(e,t){if(this.TAG="FlvPlayer",this._type="FlvPlayer",this._emitter=new f,this._config=p(),typeof t=="object"&&Object.assign(this._config,t),e.type.toLowerCase()!=="flv")throw new T("FlvPlayer requires an flv MediaDataSource input!");e.isLive===!0&&(this._config.isLive=!0),this.e={onvLoadedMetadata:this._onvLoadedMetadata.bind(this),onvSeeking:this._onvSeeking.bind(this),onvCanPlay:this._onvCanPlay.bind(this),onvStalled:this._onvStalled.bind(this),onvProgress:this._onvProgress.bind(this)},self.performance&&self.performance.now?this._now=self.performance.now.bind(self.performance):this._now=Date.now,this._pendingSeekTime=null,this._requestSetTime=!1,this._seekpointRecord=null,this._progressChecker=null,this._mediaDataSource=e,this._mediaElement=null,this._msectl=null,this._transmuxer=null,this._mseSourceOpened=!1,this._hasPendingLoad=!1,this._receivedCanPlay=!1,this._mediaInfo=null,this._statisticsInfo=null;let i=m.chrome&&(m.version.major<50||m.version.major===50&&m.version.build<2661);this._alwaysSeekKeyframe=!!(i||m.msedge||m.msie),this._alwaysSeekKeyframe&&(this._config.accurateSeek=!1)}destroy(){this._progressChecker!=null&&(window.clearInterval(this._progressChecker),this._progressChecker=null),this._transmuxer&&this.unload(),this._mediaElement&&this.detachMediaElement(),this.e=null,this._mediaDataSource=null,this._emitter.removeAllListeners(),this._emitter=null}on(e,t){e===n.MEDIA_INFO?this._mediaInfo!=null&&Promise.resolve().then(()=>{this._emitter.emit(n.MEDIA_INFO,this.mediaInfo)}):e===n.STATISTICS_INFO&&this._statisticsInfo!=null&&Promise.resolve().then(()=>{this._emitter.emit(n.STATISTICS_INFO,this.statisticsInfo)}),this._emitter.addListener(e,t)}off(e,t){this._emitter.removeListener(e,t)}attachMediaElement(e){if(this._mediaElement=e,e.addEventListener("loadedmetadata",this.e.onvLoadedMetadata),e.addEventListener("seeking",this.e.onvSeeking),e.addEventListener("canplay",this.e.onvCanPlay),e.addEventListener("stalled",this.e.onvStalled),e.addEventListener("progress",this.e.onvProgress),this._msectl=new E(this._config),this._msectl.on(o.UPDATE_END,this._onmseUpdateEnd.bind(this)),this._msectl.on(o.BUFFER_FULL,this._onmseBufferFull.bind(this)),this._msectl.on(o.SOURCE_OPEN,()=>{this._mseSourceOpened=!0,this._hasPendingLoad&&(this._hasPendingLoad=!1,this.load())}),this._msectl.on(o.ERROR,t=>{this._emitter.emit(n.ERROR,_.MEDIA_ERROR,g.MEDIA_MSE_ERROR,t)}),this._msectl.attachMediaElement(e),this._pendingSeekTime!=null)try{e.currentTime=this._pendingSeekTime,this._pendingSeekTime=null}catch(t){}}detachMediaElement(){this._mediaElement&&(this._msectl.detachMediaElement(),this._mediaElement.removeEventListener("loadedmetadata",this.e.onvLoadedMetadata),this._mediaElement.removeEventListener("seeking",this.e.onvSeeking),this._mediaElement.removeEventListener("canplay",this.e.onvCanPlay),this._mediaElement.removeEventListener("stalled",this.e.onvStalled),this._mediaElement.removeEventListener("progress",this.e.onvProgress),this._mediaElement=null),this._msectl&&(this._msectl.destroy(),this._msectl=null)}load(){if(!this._mediaElement)throw new u("HTMLMediaElement must be attached before load()!");if(this._transmuxer)throw new u("FlvPlayer.load() has been called, please call unload() first!");if(!this._hasPendingLoad){if(this._config.deferLoadAfterSourceOpen&&this._mseSourceOpened===!1){this._hasPendingLoad=!0;return}this._mediaElement.readyState>0&&(this._requestSetTime=!0,this._mediaElement.currentTime=0),this._transmuxer=new c(this._mediaDataSource,this._config),this._transmuxer.on(a.INIT_SEGMENT,(e,t)=>{this._msectl.appendInitSegment(t)}),this._transmuxer.on(a.MEDIA_SEGMENT,(e,t)=>{if(this._msectl.appendMediaSegment(t),this._config.lazyLoad&&!this._config.isLive){let i=this._mediaElement.currentTime;t.info.endDts>=(i+this._config.lazyLoadMaxDuration)*1e3&&this._progressChecker==null&&(h.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}}),this._transmuxer.on(a.LOADING_COMPLETE,()=>{this._msectl.endOfStream(),this._emitter.emit(n.LOADING_COMPLETE)}),this._transmuxer.on(a.RECOVERED_EARLY_EOF,()=>{this._emitter.emit(n.RECOVERED_EARLY_EOF)}),this._transmuxer.on(a.IO_ERROR,(e,t)=>{this._emitter.emit(n.ERROR,_.NETWORK_ERROR,e,t)}),this._transmuxer.on(a.DEMUX_ERROR,(e,t)=>{this._emitter.emit(n.ERROR,_.MEDIA_ERROR,e,{code:-1,msg:t})}),this._transmuxer.on(a.MEDIA_INFO,e=>{this._mediaInfo=e,this._emitter.emit(n.MEDIA_INFO,Object.assign({},e))}),this._transmuxer.on(a.METADATA_ARRIVED,e=>{this._emitter.emit(n.METADATA_ARRIVED,e)}),this._transmuxer.on(a.SCRIPTDATA_ARRIVED,e=>{this._emitter.emit(n.SCRIPTDATA_ARRIVED,e)}),this._transmuxer.on(a.STATISTICS_INFO,e=>{this._statisticsInfo=this._fillStatisticsInfo(e),this._emitter.emit(n.STATISTICS_INFO,Object.assign({},this._statisticsInfo))}),this._transmuxer.on(a.RECOMMEND_SEEKPOINT,e=>{this._mediaElement&&!this._config.accurateSeek&&(this._requestSetTime=!0,this._mediaElement.currentTime=e/1e3)}),this._transmuxer.open()}}unload(){this._mediaElement&&this._mediaElement.pause(),this._msectl&&this._msectl.seek(0),this._transmuxer&&(this._transmuxer.close(),this._transmuxer.destroy(),this._transmuxer=null)}play(){return this._mediaElement.play()}pause(){this._mediaElement.pause()}get type(){return this._type}get buffered(){return this._mediaElement.buffered}get duration(){return this._mediaElement.duration}get volume(){return this._mediaElement.volume}set volume(e){this._mediaElement.volume=e}get muted(){return this._mediaElement.muted}set muted(e){this._mediaElement.muted=e}get currentTime(){return this._mediaElement?this._mediaElement.currentTime:0}set currentTime(e){this._mediaElement?this._internalSeek(e):this._pendingSeekTime=e}get mediaInfo(){return Object.assign({},this._mediaInfo)}get statisticsInfo(){return this._statisticsInfo==null&&(this._statisticsInfo={}),this._statisticsInfo=this._fillStatisticsInfo(this._statisticsInfo),Object.assign({},this._statisticsInfo)}_fillStatisticsInfo(e){if(e.playerType=this._type,!(this._mediaElement instanceof HTMLVideoElement))return e;let t=!0,i=0,s=0;if(this._mediaElement.getVideoPlaybackQuality){let r=this._mediaElement.getVideoPlaybackQuality();i=r.totalVideoFrames,s=r.droppedVideoFrames}else this._mediaElement.webkitDecodedFrameCount!=null?(i=this._mediaElement.webkitDecodedFrameCount,s=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=i,e.droppedFrames=s),e}_onmseUpdateEnd(){if(!this._config.lazyLoad||this._config.isLive)return;let e=this._mediaElement.buffered,t=this._mediaElement.currentTime,i=0,s=0;for(let r=0;r=t+this._config.lazyLoadMaxDuration&&this._progressChecker==null&&(h.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}_onmseBufferFull(){h.v(this.TAG,"MSE SourceBuffer is full, suspend transmuxing task"),this._progressChecker==null&&this._suspendTransmuxer()}_suspendTransmuxer(){this._transmuxer&&(this._transmuxer.pause(),this._progressChecker==null&&(this._progressChecker=window.setInterval(this._checkProgressAndResume.bind(this),1e3)))}_checkProgressAndResume(){let e=this._mediaElement.currentTime,t=this._mediaElement.buffered,i=!1;for(let s=0;s=r&&e=l-this._config.lazyLoadRecoverDuration&&(i=!0);break}}i&&(window.clearInterval(this._progressChecker),this._progressChecker=null,i&&(h.v(this.TAG,"Continue loading from paused position"),this._transmuxer.resume()))}_isTimepointBuffered(e){let t=this._mediaElement.buffered;for(let i=0;i=s&&e0){let r=this._mediaElement.buffered.start(0);(r<1&&e0&&t.currentTime0){let s=i.start(0);if(s<1&&t