UNPKG

dashjs

Version:

A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.

58 lines (57 loc) 22.1 kB
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _ABRRulesCollection=require('../rules/abr/ABRRulesCollection');var _ABRRulesCollection2=_interopRequireDefault(_ABRRulesCollection);var _Constants=require('../constants/Constants');var _Constants2=_interopRequireDefault(_Constants);var _MetricsConstants=require('../constants/MetricsConstants');var _MetricsConstants2=_interopRequireDefault(_MetricsConstants);var _BitrateInfo=require('../vo/BitrateInfo');var _BitrateInfo2=_interopRequireDefault(_BitrateInfo);var _FragmentModel=require('../models/FragmentModel');var _FragmentModel2=_interopRequireDefault(_FragmentModel);var _EventBus=require('../../core/EventBus');var _EventBus2=_interopRequireDefault(_EventBus);var _Events=require('../../core/events/Events');var _Events2=_interopRequireDefault(_Events);var _FactoryMaker=require('../../core/FactoryMaker');var _FactoryMaker2=_interopRequireDefault(_FactoryMaker);var _RulesContext=require('../rules/RulesContext');var _RulesContext2=_interopRequireDefault(_RulesContext);var _SwitchRequest=require('../rules/SwitchRequest');var _SwitchRequest2=_interopRequireDefault(_SwitchRequest);var _SwitchRequestHistory=require('../rules/SwitchRequestHistory');var _SwitchRequestHistory2=_interopRequireDefault(_SwitchRequestHistory);var _DroppedFramesHistory=require('../rules/DroppedFramesHistory');var _DroppedFramesHistory2=_interopRequireDefault(_DroppedFramesHistory);var _ThroughputHistory=require('../rules/ThroughputHistory');var _ThroughputHistory2=_interopRequireDefault(_ThroughputHistory);var _Debug=require('../../core/Debug');var _Debug2=_interopRequireDefault(_Debug);var _HTTPRequest=require('../vo/metrics/HTTPRequest');var _SupervisorTools=require('../utils/SupervisorTools');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}/** * The copyright in this software is being made available under the BSD License, * included below. This software may be subject to other third party and contributor * rights, including patent rights, and no such rights are granted under this license. * * Copyright (c) 2013, Dash Industry Forum. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * Neither the name of Dash Industry Forum nor the names of its * contributors may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */var ABANDON_LOAD='abandonload';var ALLOW_LOAD='allowload';var DEFAULT_VIDEO_BITRATE=1000;var DEFAULT_AUDIO_BITRATE=100;var QUALITY_DEFAULT=0;function AbrController(){var context=this.context;var debug=(0,_Debug2.default)(context).getInstance();var eventBus=(0,_EventBus2.default)(context).getInstance();var instance=void 0,logger=void 0,abrRulesCollection=void 0,streamController=void 0,topQualities=void 0,qualityDict=void 0,streamProcessorDict=void 0,abandonmentStateDict=void 0,abandonmentTimeout=void 0,windowResizeEventCalled=void 0,elementWidth=void 0,elementHeight=void 0,adapter=void 0,videoModel=void 0,mediaPlayerModel=void 0,domStorage=void 0,playbackIndex=void 0,switchHistoryDict=void 0,droppedFramesHistory=void 0,throughputHistory=void 0,isUsingBufferOccupancyABRDict=void 0,dashMetrics=void 0,settings=void 0;function setup(){logger=debug.getLogger(instance);resetInitialSettings();}function registerStreamType(type,streamProcessor){switchHistoryDict[type]=switchHistoryDict[type]||(0,_SwitchRequestHistory2.default)(context).create();streamProcessorDict[type]=streamProcessor;abandonmentStateDict[type]=abandonmentStateDict[type]||{};abandonmentStateDict[type].state=ALLOW_LOAD;isUsingBufferOccupancyABRDict[type]=false;eventBus.on(_Events2.default.LOADING_PROGRESS,onFragmentLoadProgress,this);if(type==_Constants2.default.VIDEO){eventBus.on(_Events2.default.QUALITY_CHANGE_RENDERED,onQualityChangeRendered,this);droppedFramesHistory=droppedFramesHistory||(0,_DroppedFramesHistory2.default)(context).create();setElementSize();}eventBus.on(_Events2.default.METRIC_ADDED,onMetricAdded,this);eventBus.on(_Events2.default.PERIOD_SWITCH_COMPLETED,createAbrRulesCollection,this);throughputHistory=throughputHistory||(0,_ThroughputHistory2.default)(context).create({settings:settings});}function unRegisterStreamType(type){delete streamProcessorDict[type];}function createAbrRulesCollection(){abrRulesCollection=(0,_ABRRulesCollection2.default)(context).create({dashMetrics:dashMetrics,mediaPlayerModel:mediaPlayerModel,settings:settings});abrRulesCollection.initialize();}function resetInitialSettings(){topQualities={};qualityDict={};abandonmentStateDict={};streamProcessorDict={};switchHistoryDict={};isUsingBufferOccupancyABRDict={};if(windowResizeEventCalled===undefined){windowResizeEventCalled=false;}playbackIndex=undefined;droppedFramesHistory=undefined;throughputHistory=undefined;clearTimeout(abandonmentTimeout);abandonmentTimeout=null;}function reset(){resetInitialSettings();eventBus.off(_Events2.default.LOADING_PROGRESS,onFragmentLoadProgress,this);eventBus.off(_Events2.default.QUALITY_CHANGE_RENDERED,onQualityChangeRendered,this);eventBus.off(_Events2.default.METRIC_ADDED,onMetricAdded,this);eventBus.off(_Events2.default.PERIOD_SWITCH_COMPLETED,createAbrRulesCollection,this);if(abrRulesCollection){abrRulesCollection.reset();}}function setConfig(config){if(!config)return;if(config.streamController){streamController=config.streamController;}if(config.domStorage){domStorage=config.domStorage;}if(config.mediaPlayerModel){mediaPlayerModel=config.mediaPlayerModel;}if(config.dashMetrics){dashMetrics=config.dashMetrics;}if(config.adapter){adapter=config.adapter;}if(config.videoModel){videoModel=config.videoModel;}if(config.settings){settings=config.settings;}}function checkConfig(){if(!domStorage||!domStorage.hasOwnProperty('getSavedBitrateSettings')){throw new Error(_Constants2.default.MISSING_CONFIG_ERROR);}}function onQualityChangeRendered(e){if(e.mediaType===_Constants2.default.VIDEO){playbackIndex=e.oldQuality;droppedFramesHistory.push(playbackIndex,videoModel.getPlaybackQuality());}}function onMetricAdded(e){if(e.metric===_MetricsConstants2.default.HTTP_REQUEST&&e.value&&e.value.type===_HTTPRequest.HTTPRequest.MEDIA_SEGMENT_TYPE&&(e.mediaType===_Constants2.default.AUDIO||e.mediaType===_Constants2.default.VIDEO)){throughputHistory.push(e.mediaType,e.value,settings.get().streaming.abr.useDeadTimeLatency);}if(e.metric===_MetricsConstants2.default.BUFFER_LEVEL&&(e.mediaType===_Constants2.default.AUDIO||e.mediaType===_Constants2.default.VIDEO)){updateIsUsingBufferOccupancyABR(e.mediaType,0.001*e.value.level);}}function getTopQualityIndexFor(type,id){var idx=void 0;topQualities[id]=topQualities[id]||{};if(!topQualities[id].hasOwnProperty(type)){topQualities[id][type]=0;}idx=checkMaxBitrate(topQualities[id][type],type);idx=checkMaxRepresentationRatio(idx,type,topQualities[id][type]);idx=checkPortalSize(idx,type);return idx;}/** * Gets top BitrateInfo for the player * @param {string} type - 'video' or 'audio' are the type options. * @returns {BitrateInfo | null} */function getTopBitrateInfoFor(type){if(type&&streamProcessorDict&&streamProcessorDict[type]){var streamInfo=streamProcessorDict[type].getStreamInfo();if(streamInfo&&streamInfo.id){var idx=getTopQualityIndexFor(type,streamInfo.id);var bitrates=getBitrateList(streamProcessorDict[type].getMediaInfo());return bitrates[idx]?bitrates[idx]:null;}}return null;}/** * @param {string} type * @returns {number} A value of the initial bitrate, kbps * @memberof AbrController# */function getInitialBitrateFor(type){checkConfig();if(type===_Constants2.default.TEXT||type===_Constants2.default.FRAGMENTED_TEXT){return NaN;}var savedBitrate=domStorage.getSavedBitrateSettings(type);var configBitrate=settings.get().streaming.abr.initialBitrate[type];var configRatio=settings.get().streaming.abr.initialRepresentationRatio[type];if(configBitrate===-1){if(configRatio>-1){var representation=adapter.getAdaptationForType(0,type).Representation;if(Array.isArray(representation)){var repIdx=Math.max(Math.round(representation.length*configRatio)-1,0);configBitrate=representation[repIdx].bandwidth;}else{configBitrate=0;}}else if(!isNaN(savedBitrate)){configBitrate=savedBitrate;}else{configBitrate=type===_Constants2.default.VIDEO?DEFAULT_VIDEO_BITRATE:DEFAULT_AUDIO_BITRATE;}}return configBitrate;}function getMaxAllowedBitrateFor(type){return settings.get().streaming.abr.maxBitrate[type];}function getMinAllowedBitrateFor(type){return settings.get().streaming.abr.minBitrate[type];}function getMaxAllowedIndexFor(type){var maxBitrate=getMaxAllowedBitrateFor(type);if(maxBitrate>-1){return getQualityForBitrate(streamProcessorDict[type].getMediaInfo(),maxBitrate);}else{return undefined;}}function getMinAllowedIndexFor(type){var minBitrate=getMinAllowedBitrateFor(type);if(minBitrate>-1){var mediaInfo=streamProcessorDict[type].getMediaInfo();var bitrateList=getBitrateList(mediaInfo);// This returns the quality index <= for the given bitrate var minIdx=getQualityForBitrate(mediaInfo,minBitrate);if(bitrateList[minIdx]&&minIdx<bitrateList.length-1&&bitrateList[minIdx].bitrate<minBitrate*1000){minIdx++;// Go to the next bitrate }return minIdx;}else{return undefined;}}function getMaxAllowedRepresentationRatioFor(type){return settings.get().streaming.abr.maxRepresentationRatio[type];}function getAutoSwitchBitrateFor(type){return!!settings.get().streaming.abr.autoSwitchBitrate[type];}function checkPlaybackQuality(type){if(type&&streamProcessorDict&&streamProcessorDict[type]){var streamInfo=streamProcessorDict[type].getStreamInfo();var streamId=streamInfo?streamInfo.id:null;var oldQuality=getQualityFor(type);var rulesContext=(0,_RulesContext2.default)(context).create({abrController:instance,streamProcessor:streamProcessorDict[type],currentValue:oldQuality,switchHistory:switchHistoryDict[type],droppedFramesHistory:droppedFramesHistory,useBufferOccupancyABR:useBufferOccupancyABR(type)});if(droppedFramesHistory){var playbackQuality=videoModel.getPlaybackQuality();if(playbackQuality){droppedFramesHistory.push(playbackIndex,playbackQuality);}}if(getAutoSwitchBitrateFor(type)){var minIdx=getMinAllowedIndexFor(type);var topQualityIdx=getTopQualityIndexFor(type,streamId);var switchRequest=abrRulesCollection.getMaxQuality(rulesContext);var newQuality=switchRequest.quality;if(minIdx!==undefined&&(newQuality>_SwitchRequest2.default.NO_CHANGE?newQuality:oldQuality)<minIdx){newQuality=minIdx;}if(newQuality>topQualityIdx){newQuality=topQualityIdx;}switchHistoryDict[type].push({oldValue:oldQuality,newValue:newQuality});if(newQuality>_SwitchRequest2.default.NO_CHANGE&&newQuality!=oldQuality){if(abandonmentStateDict[type].state===ALLOW_LOAD||newQuality>oldQuality){changeQuality(type,oldQuality,newQuality,topQualityIdx,switchRequest.reason);}}else if(settings.get().debug.logLevel===_Debug2.default.LOG_LEVEL_DEBUG){var bufferLevel=dashMetrics.getCurrentBufferLevel(type,true);logger.debug('AbrController ('+type+') stay on '+oldQuality+'/'+topQualityIdx+' (buffer: '+bufferLevel+')');}}}}function setPlaybackQuality(type,streamInfo,newQuality,reason){var id=streamInfo.id;var oldQuality=getQualityFor(type);(0,_SupervisorTools.checkInteger)(newQuality);var topQualityIdx=getTopQualityIndexFor(type,id);if(newQuality!==oldQuality&&newQuality>=0&&newQuality<=topQualityIdx){changeQuality(type,oldQuality,newQuality,topQualityIdx,reason);}}function changeQuality(type,oldQuality,newQuality,topQualityIdx,reason){if(type&&streamProcessorDict[type]){var streamInfo=streamProcessorDict[type].getStreamInfo();var id=streamInfo?streamInfo.id:null;if(settings.get().debug.logLevel===_Debug2.default.LOG_LEVEL_DEBUG){var bufferLevel=dashMetrics.getCurrentBufferLevel(type,true);logger.info('AbrController ('+type+') switch from '+oldQuality+' to '+newQuality+'/'+topQualityIdx+' (buffer: '+bufferLevel+') '+(reason?JSON.stringify(reason):'.'));}setQualityFor(type,id,newQuality);eventBus.trigger(_Events2.default.QUALITY_CHANGE_REQUESTED,{mediaType:type,streamInfo:streamInfo,oldQuality:oldQuality,newQuality:newQuality,reason:reason});var bitrate=throughputHistory.getAverageThroughput(type);if(!isNaN(bitrate)){domStorage.setSavedBitrateSettings(type,bitrate);}}}function setAbandonmentStateFor(type,state){abandonmentStateDict[type].state=state;}function getAbandonmentStateFor(type){return abandonmentStateDict[type]?abandonmentStateDict[type].state:null;}/** * @param {MediaInfo} mediaInfo * @param {number} bitrate A bitrate value, kbps * @param {number} latency Expected latency of connection, ms * @returns {number} A quality index <= for the given bitrate * @memberof AbrController# */function getQualityForBitrate(mediaInfo,bitrate,latency){var voRepresentation=mediaInfo&&mediaInfo.type?streamProcessorDict[mediaInfo.type].getRepresentationInfo():null;if(settings.get().streaming.abr.useDeadTimeLatency&&latency&&voRepresentation&&voRepresentation.fragmentDuration){latency=latency/1000;var fragmentDuration=voRepresentation.fragmentDuration;if(latency>fragmentDuration){return 0;}else{var deadTimeRatio=latency/fragmentDuration;bitrate=bitrate*(1-deadTimeRatio);}}var bitrateList=getBitrateList(mediaInfo);for(var i=bitrateList.length-1;i>=0;i--){var bitrateInfo=bitrateList[i];if(bitrate*1000>=bitrateInfo.bitrate){return i;}}return QUALITY_DEFAULT;}/** * @param {MediaInfo} mediaInfo * @returns {Array|null} A list of {@link BitrateInfo} objects * @memberof AbrController# */function getBitrateList(mediaInfo){var infoList=[];if(!mediaInfo||!mediaInfo.bitrateList)return infoList;var bitrateList=mediaInfo.bitrateList;var type=mediaInfo.type;var bitrateInfo=void 0;for(var i=0,ln=bitrateList.length;i<ln;i++){bitrateInfo=new _BitrateInfo2.default();bitrateInfo.mediaType=type;bitrateInfo.qualityIndex=i;bitrateInfo.bitrate=bitrateList[i].bandwidth;bitrateInfo.width=bitrateList[i].width;bitrateInfo.height=bitrateList[i].height;bitrateInfo.scanType=bitrateList[i].scanType;infoList.push(bitrateInfo);}return infoList;}function updateIsUsingBufferOccupancyABR(mediaType,bufferLevel){var strategy=settings.get().streaming.ABRStrategy;if(strategy===_Constants2.default.ABR_STRATEGY_BOLA){isUsingBufferOccupancyABRDict[mediaType]=true;return;}else if(strategy===_Constants2.default.ABR_STRATEGY_THROUGHPUT){isUsingBufferOccupancyABRDict[mediaType]=false;return;}// else ABR_STRATEGY_DYNAMIC var stableBufferTime=mediaPlayerModel.getStableBufferTime();var switchOnThreshold=stableBufferTime;var switchOffThreshold=0.5*stableBufferTime;var useBufferABR=isUsingBufferOccupancyABRDict[mediaType];var newUseBufferABR=bufferLevel>(useBufferABR?switchOffThreshold:switchOnThreshold);// use hysteresis to avoid oscillating rules isUsingBufferOccupancyABRDict[mediaType]=newUseBufferABR;if(newUseBufferABR!==useBufferABR){if(newUseBufferABR){logger.info('AbrController ('+mediaType+') switching from throughput to buffer occupancy ABR rule (buffer: '+bufferLevel.toFixed(3)+').');}else{logger.info('AbrController ('+mediaType+') switching from buffer occupancy to throughput ABR rule (buffer: '+bufferLevel.toFixed(3)+').');}}}function useBufferOccupancyABR(mediaType){return isUsingBufferOccupancyABRDict[mediaType];}function getThroughputHistory(){return throughputHistory;}function updateTopQualityIndex(mediaInfo){var type=mediaInfo.type;var streamId=mediaInfo.streamInfo.id;var max=mediaInfo.representationCount-1;setTopQualityIndex(type,streamId,max);return max;}function isPlayingAtTopQuality(streamInfo){var streamId=streamInfo?streamInfo.id:null;var audioQuality=getQualityFor(_Constants2.default.AUDIO);var videoQuality=getQualityFor(_Constants2.default.VIDEO);var isAtTop=audioQuality===getTopQualityIndexFor(_Constants2.default.AUDIO,streamId)&&videoQuality===getTopQualityIndexFor(_Constants2.default.VIDEO,streamId);return isAtTop;}function getQualityFor(type){if(type&&streamProcessorDict[type]){var streamInfo=streamProcessorDict[type].getStreamInfo();var id=streamInfo?streamInfo.id:null;var quality=void 0;if(id){qualityDict[id]=qualityDict[id]||{};if(!qualityDict[id].hasOwnProperty(type)){qualityDict[id][type]=QUALITY_DEFAULT;}quality=qualityDict[id][type];return quality;}}return QUALITY_DEFAULT;}function setQualityFor(type,id,value){qualityDict[id]=qualityDict[id]||{};qualityDict[id][type]=value;}function setTopQualityIndex(type,id,value){topQualities[id]=topQualities[id]||{};topQualities[id][type]=value;}function checkMaxBitrate(idx,type){var newIdx=idx;if(!streamProcessorDict[type]){return newIdx;}var minIdx=getMinAllowedIndexFor(type);if(minIdx!==undefined){newIdx=Math.max(idx,minIdx);}var maxIdx=getMaxAllowedIndexFor(type);if(maxIdx!==undefined){newIdx=Math.min(newIdx,maxIdx);}return newIdx;}function checkMaxRepresentationRatio(idx,type,maxIdx){var maxRepresentationRatio=getMaxAllowedRepresentationRatioFor(type);if(isNaN(maxRepresentationRatio)||maxRepresentationRatio>=1||maxRepresentationRatio<0){return idx;}return Math.min(idx,Math.round(maxIdx*maxRepresentationRatio));}function setWindowResizeEventCalled(value){windowResizeEventCalled=value;}function setElementSize(){if(videoModel){var hasPixelRatio=settings.get().streaming.abr.usePixelRatioInLimitBitrateByPortal&&window.hasOwnProperty('devicePixelRatio');var pixelRatio=hasPixelRatio?window.devicePixelRatio:1;elementWidth=videoModel.getClientWidth()*pixelRatio;elementHeight=videoModel.getClientHeight()*pixelRatio;}}function checkPortalSize(idx,type){if(type!==_Constants2.default.VIDEO||!settings.get().streaming.abr.limitBitrateByPortal||!streamProcessorDict[type]){return idx;}if(!windowResizeEventCalled){setElementSize();}var representation=adapter.getAdaptationForType(0,type).Representation;var newIdx=idx;if(elementWidth>0&&elementHeight>0){while(newIdx>0&&representation[newIdx]&&elementWidth<representation[newIdx].width&&elementWidth-representation[newIdx-1].width<representation[newIdx].width-elementWidth){newIdx=newIdx-1;}// Make sure that in case of multiple representation elements have same // resolution, every such element is included while(newIdx<representation.length-1&&representation[newIdx].width===representation[newIdx+1].width){newIdx=newIdx+1;}}return newIdx;}function onFragmentLoadProgress(e){var type=e.request.mediaType;if(getAutoSwitchBitrateFor(type)){var streamProcessor=streamProcessorDict[type];if(!streamProcessor)return;// There may be a fragment load in progress when we switch periods and recreated some controllers. var rulesContext=(0,_RulesContext2.default)(context).create({abrController:instance,streamProcessor:streamProcessor,currentRequest:e.request,useBufferOccupancyABR:useBufferOccupancyABR(type)});var switchRequest=abrRulesCollection.shouldAbandonFragment(rulesContext);if(switchRequest.quality>_SwitchRequest2.default.NO_CHANGE){var fragmentModel=streamProcessor.getFragmentModel();var request=fragmentModel.getRequests({state:_FragmentModel2.default.FRAGMENT_MODEL_LOADING,index:e.request.index})[0];if(request){//TODO Check if we should abort or if better to finish download. check bytesLoaded/Total fragmentModel.abortRequests();setAbandonmentStateFor(type,ABANDON_LOAD);switchHistoryDict[type].reset();switchHistoryDict[type].push({oldValue:getQualityFor(type),newValue:switchRequest.quality,confidence:1,reason:switchRequest.reason});setPlaybackQuality(type,streamController.getActiveStreamInfo(),switchRequest.quality,switchRequest.reason);clearTimeout(abandonmentTimeout);abandonmentTimeout=setTimeout(function(){setAbandonmentStateFor(type,ALLOW_LOAD);abandonmentTimeout=null;},settings.get().streaming.abandonLoadTimeout);}}}}instance={isPlayingAtTopQuality:isPlayingAtTopQuality,updateTopQualityIndex:updateTopQualityIndex,getThroughputHistory:getThroughputHistory,getBitrateList:getBitrateList,getQualityForBitrate:getQualityForBitrate,getTopBitrateInfoFor:getTopBitrateInfoFor,getMaxAllowedIndexFor:getMaxAllowedIndexFor,getMinAllowedIndexFor:getMinAllowedIndexFor,getInitialBitrateFor:getInitialBitrateFor,getQualityFor:getQualityFor,getAbandonmentStateFor:getAbandonmentStateFor,setPlaybackQuality:setPlaybackQuality,checkPlaybackQuality:checkPlaybackQuality,getTopQualityIndexFor:getTopQualityIndexFor,setElementSize:setElementSize,setWindowResizeEventCalled:setWindowResizeEventCalled,createAbrRulesCollection:createAbrRulesCollection,registerStreamType:registerStreamType,unRegisterStreamType:unRegisterStreamType,setConfig:setConfig,reset:reset};setup();return instance;}AbrController.__dashjs_factory_name='AbrController';var factory=_FactoryMaker2.default.getSingletonFactory(AbrController);factory.ABANDON_LOAD=ABANDON_LOAD;factory.QUALITY_DEFAULT=QUALITY_DEFAULT;_FactoryMaker2.default.updateSingletonFactory(AbrController.__dashjs_factory_name,factory);exports.default=factory; //# sourceMappingURL=AbrController.js.map