|
|
(self["webpackChunk"] = self["webpackChunk"] || []).push([[36144],{
|
|
|
|
|
|
/***/ 36144:
|
|
|
/*!*****************************************!*\
|
|
|
!*** ./node_modules/hls.js/dist/hls.js ***!
|
|
|
\*****************************************/
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
/* module decorator */ module = __webpack_require__.nmd(module);
|
|
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var _typeof=(__webpack_require__(/*! ./node_modules/@babel/runtime/helpers/typeof.js */ 22191)["default"]);typeof window!=="undefined"&&function webpackUniversalModuleDefinition(root,factory){if(( false?0:_typeof(exports))==='object'&&( false?0:_typeof(module))==='object')module.exports=factory();else if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
|
|
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
|
|
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
|
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}}(this,function(){return(/******/function(){// webpackBootstrap
|
|
|
/******/var __webpack_modules__={/***/"./src/config.ts":/*!***********************!*\
|
|
|
!*** ./src/config.ts ***!
|
|
|
\***********************/ /***/function srcConfigTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_846__){"use strict";__nested_webpack_require_846__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_846__.d(__webpack_exports__,{/* harmony export */"enableStreamingMode":function enableStreamingMode(){return(/* binding */_enableStreamingMode);},/* harmony export */"hlsDefaultConfig":function hlsDefaultConfig(){return(/* binding */_hlsDefaultConfig);},/* harmony export */"mergeConfig":function mergeConfig(){return(/* binding */_mergeConfig);}/* harmony export */});/* harmony import */var _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_846__(/*! ./controller/abr-controller */"./src/controller/abr-controller.ts");/* harmony import */var _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_846__(/*! ./controller/audio-stream-controller */"./src/controller/audio-stream-controller.ts");/* harmony import */var _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_846__(/*! ./controller/audio-track-controller */"./src/controller/audio-track-controller.ts");/* harmony import */var _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_846__(/*! ./controller/subtitle-stream-controller */"./src/controller/subtitle-stream-controller.ts");/* harmony import */var _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_846__(/*! ./controller/subtitle-track-controller */"./src/controller/subtitle-track-controller.ts");/* harmony import */var _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_846__(/*! ./controller/buffer-controller */"./src/controller/buffer-controller.ts");/* harmony import */var _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_846__(/*! ./controller/timeline-controller */"./src/controller/timeline-controller.ts");/* harmony import */var _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_846__(/*! ./controller/cap-level-controller */"./src/controller/cap-level-controller.ts");/* harmony import */var _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_846__(/*! ./controller/fps-controller */"./src/controller/fps-controller.ts");/* harmony import */var _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_846__(/*! ./controller/eme-controller */"./src/controller/eme-controller.ts");/* harmony import */var _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__=__nested_webpack_require_846__(/*! ./controller/cmcd-controller */"./src/controller/cmcd-controller.ts");/* harmony import */var _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__=__nested_webpack_require_846__(/*! ./utils/xhr-loader */"./src/utils/xhr-loader.ts");/* harmony import */var _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__=__nested_webpack_require_846__(/*! ./utils/fetch-loader */"./src/utils/fetch-loader.ts");/* harmony import */var _utils_cues__WEBPACK_IMPORTED_MODULE_13__=__nested_webpack_require_846__(/*! ./utils/cues */"./src/utils/cues.ts");/* harmony import */var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__=__nested_webpack_require_846__(/*! ./utils/mediakeys-helper */"./src/utils/mediakeys-helper.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_15__=__nested_webpack_require_846__(/*! ./utils/logger */"./src/utils/logger.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);enumerableOnly&&(symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable;})),keys.push.apply(keys,symbols);}return keys;}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=null!=arguments[i]?arguments[i]:{};i%2?ownKeys(Object(source),!0).forEach(function(key){_defineProperty(target,key,source[key]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(target,Object.getOwnPropertyDescriptors(source)):ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key));});}return target;}function _defineProperty(obj,key,value){key=_toPropertyKey(key);if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}// If possible, keep hlsDefaultConfig shallow
|
|
|
// It is cloned whenever a new Hls instance is created, by keeping the config
|
|
|
// shallow the properties are cloned, and we don't end up manipulating the default
|
|
|
var _hlsDefaultConfig=_objectSpread(_objectSpread({autoStartLoad:true,// used by stream-controller
|
|
|
startPosition:-1,// used by stream-controller
|
|
|
defaultAudioCodec:undefined,// used by stream-controller
|
|
|
debug:false,// used by logger
|
|
|
capLevelOnFPSDrop:false,// used by fps-controller
|
|
|
capLevelToPlayerSize:false,// used by cap-level-controller
|
|
|
ignoreDevicePixelRatio:false,// used by cap-level-controller
|
|
|
initialLiveManifestSize:1,// used by stream-controller
|
|
|
maxBufferLength:30,// used by stream-controller
|
|
|
backBufferLength:Infinity,// used by buffer-controller
|
|
|
maxBufferSize:60*1000*1000,// used by stream-controller
|
|
|
maxBufferHole:0.1,// used by stream-controller
|
|
|
highBufferWatchdogPeriod:2,// used by stream-controller
|
|
|
nudgeOffset:0.1,// used by stream-controller
|
|
|
nudgeMaxRetry:3,// used by stream-controller
|
|
|
maxFragLookUpTolerance:0.25,// used by stream-controller
|
|
|
liveSyncDurationCount:3,// used by latency-controller
|
|
|
liveMaxLatencyDurationCount:Infinity,// used by latency-controller
|
|
|
liveSyncDuration:undefined,// used by latency-controller
|
|
|
liveMaxLatencyDuration:undefined,// used by latency-controller
|
|
|
maxLiveSyncPlaybackRate:1,// used by latency-controller
|
|
|
liveDurationInfinity:false,// used by buffer-controller
|
|
|
liveBackBufferLength:null,// used by buffer-controller
|
|
|
maxMaxBufferLength:600,// used by stream-controller
|
|
|
enableWorker:true,// used by demuxer
|
|
|
enableSoftwareAES:true,// used by decrypter
|
|
|
manifestLoadingTimeOut:10000,// used by playlist-loader
|
|
|
manifestLoadingMaxRetry:1,// used by playlist-loader
|
|
|
manifestLoadingRetryDelay:1000,// used by playlist-loader
|
|
|
manifestLoadingMaxRetryTimeout:64000,// used by playlist-loader
|
|
|
startLevel:undefined,// used by level-controller
|
|
|
levelLoadingTimeOut:10000,// used by playlist-loader
|
|
|
levelLoadingMaxRetry:4,// used by playlist-loader
|
|
|
levelLoadingRetryDelay:1000,// used by playlist-loader
|
|
|
levelLoadingMaxRetryTimeout:64000,// used by playlist-loader
|
|
|
fragLoadingTimeOut:20000,// used by fragment-loader
|
|
|
fragLoadingMaxRetry:6,// used by fragment-loader
|
|
|
fragLoadingRetryDelay:1000,// used by fragment-loader
|
|
|
fragLoadingMaxRetryTimeout:64000,// used by fragment-loader
|
|
|
startFragPrefetch:false,// used by stream-controller
|
|
|
fpsDroppedMonitoringPeriod:5000,// used by fps-controller
|
|
|
fpsDroppedMonitoringThreshold:0.2,// used by fps-controller
|
|
|
appendErrorMaxRetry:3,// used by buffer-controller
|
|
|
loader:_utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"],// loader: FetchLoader,
|
|
|
fLoader:undefined,// used by fragment-loader
|
|
|
pLoader:undefined,// used by playlist-loader
|
|
|
xhrSetup:undefined,// used by xhr-loader
|
|
|
licenseXhrSetup:undefined,// used by eme-controller
|
|
|
licenseResponseCallback:undefined,// used by eme-controller
|
|
|
abrController:_controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__["default"],bufferController:_controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__["default"],capLevelController:_controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__["default"],fpsController:_controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__["default"],stretchShortVideoTrack:false,// used by mp4-remuxer
|
|
|
maxAudioFramesDrift:1,// used by mp4-remuxer
|
|
|
forceKeyFrameOnDiscontinuity:true,// used by ts-demuxer
|
|
|
abrEwmaFastLive:3,// used by abr-controller
|
|
|
abrEwmaSlowLive:9,// used by abr-controller
|
|
|
abrEwmaFastVoD:3,// used by abr-controller
|
|
|
abrEwmaSlowVoD:9,// used by abr-controller
|
|
|
abrEwmaDefaultEstimate:5e5,// 500 kbps // used by abr-controller
|
|
|
abrBandWidthFactor:0.95,// used by abr-controller
|
|
|
abrBandWidthUpFactor:0.7,// used by abr-controller
|
|
|
abrMaxWithRealBitrate:false,// used by abr-controller
|
|
|
maxStarvationDelay:4,// used by abr-controller
|
|
|
maxLoadingDelay:4,// used by abr-controller
|
|
|
minAutoBitrate:0,// used by hls
|
|
|
emeEnabled:false,// used by eme-controller
|
|
|
widevineLicenseUrl:undefined,// used by eme-controller
|
|
|
drmSystems:{},// used by eme-controller
|
|
|
drmSystemOptions:{},// used by eme-controller
|
|
|
requestMediaKeySystemAccessFunc:_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__.requestMediaKeySystemAccess,// used by eme-controller
|
|
|
testBandwidth:true,progressive:false,lowLatencyMode:true,cmcd:undefined,enableDateRangeMetadataCues:true,enableEmsgMetadataCues:true,enableID3MetadataCues:true},timelineConfig()),{},{subtitleStreamController: true?_controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__.SubtitleStreamController:0,subtitleTrackController: true?_controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__["default"]:0,timelineController: true?_controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__.TimelineController:0,audioStreamController: true?_controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]:0,audioTrackController: true?_controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"]:0,emeController: true?_controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__["default"]:0,cmcdController: true?_controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__["default"]:0});function timelineConfig(){return{cueHandler:_utils_cues__WEBPACK_IMPORTED_MODULE_13__["default"],// used by timeline-controller
|
|
|
enableWebVTT:true,// used by timeline-controller
|
|
|
enableIMSC1:true,// used by timeline-controller
|
|
|
enableCEA708Captions:true,// used by timeline-controller
|
|
|
captionsTextTrack1Label:'English',// used by timeline-controller
|
|
|
captionsTextTrack1LanguageCode:'en',// used by timeline-controller
|
|
|
captionsTextTrack2Label:'Spanish',// used by timeline-controller
|
|
|
captionsTextTrack2LanguageCode:'es',// used by timeline-controller
|
|
|
captionsTextTrack3Label:'Unknown CC',// used by timeline-controller
|
|
|
captionsTextTrack3LanguageCode:'',// used by timeline-controller
|
|
|
captionsTextTrack4Label:'Unknown CC',// used by timeline-controller
|
|
|
captionsTextTrack4LanguageCode:'',// used by timeline-controller
|
|
|
renderTextTracksNatively:true};}function _mergeConfig(defaultConfig,userConfig){if((userConfig.liveSyncDurationCount||userConfig.liveMaxLatencyDurationCount)&&(userConfig.liveSyncDuration||userConfig.liveMaxLatencyDuration)){throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");}if(userConfig.liveMaxLatencyDurationCount!==undefined&&(userConfig.liveSyncDurationCount===undefined||userConfig.liveMaxLatencyDurationCount<=userConfig.liveSyncDurationCount)){throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"');}if(userConfig.liveMaxLatencyDuration!==undefined&&(userConfig.liveSyncDuration===undefined||userConfig.liveMaxLatencyDuration<=userConfig.liveSyncDuration)){throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"');}return _extends({},defaultConfig,userConfig);}function _enableStreamingMode(config){var currentLoader=config.loader;if(currentLoader!==_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"]&¤tLoader!==_utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"]){// If a developer has configured their own loader, respect that choice
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_15__.logger.log('[config]: Custom loader detected, cannot enable progressive streaming');config.progressive=false;}else{var canStreamProgressively=(0,_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__.fetchSupported)();if(canStreamProgressively){config.loader=_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"];config.progressive=true;config.enableSoftwareAES=true;_utils_logger__WEBPACK_IMPORTED_MODULE_15__.logger.log('[config]: Progressive streaming enabled, using FetchLoader');}}}/***/},/***/"./src/controller/abr-controller.ts":/*!******************************************!*\
|
|
|
!*** ./src/controller/abr-controller.ts ***!
|
|
|
\******************************************/ /***/function srcControllerAbrControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_13872__){"use strict";__nested_webpack_require_13872__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_13872__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_13872__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_13872__(/*! ../utils/ewma-bandwidth-estimator */"./src/utils/ewma-bandwidth-estimator.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_13872__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_13872__(/*! ../errors */"./src/errors.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_13872__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_13872__(/*! ../utils/logger */"./src/utils/logger.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var AbrController=/*#__PURE__*/function(){function AbrController(hls){this.hls=void 0;this.lastLoadedFragLevel=0;this._nextAutoLevel=-1;this.timer=void 0;this.onCheck=this._abandonRulesCheck.bind(this);this.fragCurrent=null;this.partCurrent=null;this.bitrateTestDelay=0;this.bwEstimator=void 0;this.hls=hls;var config=hls.config;this.bwEstimator=new _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__["default"](config.abrEwmaSlowVoD,config.abrEwmaFastVoD,config.abrEwmaDefaultEstimate);this.registerListeners();}var _proto=AbrController.prototype;_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADING,this.onFragLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED,this.onFragBuffered,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,this.onError,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADING,this.onFragLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED,this.onFragBuffered,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,this.onError,this);};_proto.destroy=function destroy(){this.unregisterListeners();this.clearTimer();// @ts-ignore
|
|
|
this.hls=this.onCheck=null;this.fragCurrent=this.partCurrent=null;};_proto.onFragLoading=function onFragLoading(event,data){var frag=data.frag;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN){if(!this.timer){var _data$part;this.fragCurrent=frag;this.partCurrent=(_data$part=data.part)!=null?_data$part:null;this.timer=self.setInterval(this.onCheck,100);}}};_proto.onLevelLoaded=function onLevelLoaded(event,data){var config=this.hls.config;if(data.details.live){this.bwEstimator.update(config.abrEwmaSlowLive,config.abrEwmaFastLive);}else{this.bwEstimator.update(config.abrEwmaSlowVoD,config.abrEwmaFastVoD);}}/*
|
|
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
|
|
quickly enough to prevent underbuffering
|
|
|
*/;_proto._abandonRulesCheck=function _abandonRulesCheck(){var frag=this.fragCurrent,part=this.partCurrent,hls=this.hls;var autoLevelEnabled=hls.autoLevelEnabled,media=hls.media;if(!frag||!media){return;}var stats=part?part.stats:frag.stats;var duration=part?part.duration:frag.duration;// If frag loading is aborted, complete, or from lowest level, stop timer and return
|
|
|
if(stats.aborted||stats.loaded&&stats.loaded===stats.total||frag.level===0){this.clearTimer();// reset forced auto level value so that next level will be selected
|
|
|
this._nextAutoLevel=-1;return;}// This check only runs if we're in ABR mode and actually playing
|
|
|
if(!autoLevelEnabled||media.paused||!media.playbackRate||!media.readyState){return;}var bufferInfo=hls.mainForwardBufferInfo;if(bufferInfo===null){return;}var requestDelay=performance.now()-stats.loading.start;var playbackRate=Math.abs(media.playbackRate);// In order to work with a stable bandwidth, only begin monitoring bandwidth after half of the fragment has been loaded
|
|
|
if(requestDelay<=500*duration/playbackRate){return;}var loadedFirstByte=stats.loaded&&stats.loading.first;var bwEstimate=this.bwEstimator.getEstimate();var levels=hls.levels,minAutoLevel=hls.minAutoLevel;var level=levels[frag.level];var expectedLen=stats.total||Math.max(stats.loaded,Math.round(duration*level.maxBitrate/8));var loadRate=loadedFirstByte?stats.loaded*1000/requestDelay:0;// fragLoadDelay is an estimate of the time (in seconds) it will take to buffer the remainder of the fragment
|
|
|
var fragLoadedDelay=loadRate?(expectedLen-stats.loaded)/loadRate:expectedLen*8/bwEstimate;// bufferStarvationDelay is an estimate of the amount time (in seconds) it will take to exhaust the buffer
|
|
|
var bufferStarvationDelay=bufferInfo.len/playbackRate;// Only downswitch if the time to finish loading the current fragment is greater than the amount of buffer left
|
|
|
if(fragLoadedDelay<=bufferStarvationDelay){return;}var fragLevelNextLoadedDelay=Number.POSITIVE_INFINITY;var nextLoadLevel;// Iterate through lower level and try to find the largest one that avoids rebuffering
|
|
|
for(nextLoadLevel=frag.level-1;nextLoadLevel>minAutoLevel;nextLoadLevel--){// compute time to load next fragment at lower level
|
|
|
// 0.8 : consider only 80% of current bw to be conservative
|
|
|
// 8 = bits per byte (bps/Bps)
|
|
|
var levelNextBitrate=levels[nextLoadLevel].maxBitrate;fragLevelNextLoadedDelay=loadRate?duration*levelNextBitrate/(8*0.8*loadRate):duration*levelNextBitrate/bwEstimate;if(fragLevelNextLoadedDelay<bufferStarvationDelay){break;}}// Only emergency switch down if it takes less time to load a new fragment at lowest level instead of continuing
|
|
|
// to load the current one
|
|
|
if(fragLevelNextLoadedDelay>=fragLoadedDelay){return;}_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("Fragment "+frag.sn+(part?' part '+part.index:'')+" of level "+frag.level+" is loading too slowly and will cause an underbuffer; aborting and switching to level "+nextLoadLevel+"\n Current BW estimate: "+((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(bwEstimate)?(bwEstimate/1024).toFixed(3):'Unknown')+" Kb/s\n Estimated load time for current fragment: "+fragLoadedDelay.toFixed(3)+" s\n Estimated load time for the next fragment: "+fragLevelNextLoadedDelay.toFixed(3)+" s\n Time to underbuffer: "+bufferStarvationDelay.toFixed(3)+" s");hls.nextLoadLevel=nextLoadLevel;if(loadedFirstByte){// If there has been loading progress, sample bandwidth
|
|
|
this.bwEstimator.sample(requestDelay,stats.loaded);}this.clearTimer();if(frag.loader||frag.keyLoader){this.fragCurrent=this.partCurrent=null;frag.abortRequests();}hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOAD_EMERGENCY_ABORTED,{frag:frag,part:part,stats:stats});};_proto.onFragLoaded=function onFragLoaded(event,_ref){var frag=_ref.frag,part=_ref.part;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.sn)){var stats=part?part.stats:frag.stats;var duration=part?part.duration:frag.duration;// stop monitoring bw once frag loaded
|
|
|
this.clearTimer();// store level id after successful fragment load
|
|
|
this.lastLoadedFragLevel=frag.level;// reset forced auto level value so that next level will be selected
|
|
|
this._nextAutoLevel=-1;// compute level average bitrate
|
|
|
if(this.hls.config.abrMaxWithRealBitrate){var level=this.hls.levels[frag.level];var loadedBytes=(level.loaded?level.loaded.bytes:0)+stats.loaded;var loadedDuration=(level.loaded?level.loaded.duration:0)+duration;level.loaded={bytes:loadedBytes,duration:loadedDuration};level.realBitrate=Math.round(8*loadedBytes/loadedDuration);}if(frag.bitrateTest){var fragBufferedData={stats:stats,frag:frag,part:part,id:frag.type};this.onFragBuffered(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED,fragBufferedData);}}};_proto.onFragBuffered=function onFragBuffered(event,data){var frag=data.frag,part=data.part;var stats=part?part.stats:frag.stats;if(stats.aborted){return;}// Only count non-alt-audio frags which were actually buffered in our BW calculations
|
|
|
if(frag.type!==_types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN||frag.sn==='initSegment'){return;}// Use the difference between parsing and request instead of buffering and request to compute fragLoadingProcessing;
|
|
|
// rationale is that buffer appending only happens once media is attached. This can happen when config.startFragPrefetch
|
|
|
// is used. If we used buffering in that case, our BW estimate sample will be very large.
|
|
|
var processingMs=stats.parsing.end-stats.loading.start;this.bwEstimator.sample(processingMs,stats.loaded);stats.bwEstimate=this.bwEstimator.getEstimate();if(frag.bitrateTest){this.bitrateTestDelay=processingMs/1000;}else{this.bitrateTestDelay=0;}};_proto.onError=function onError(event,data){var _data$frag;// stop timer in case of frag loading error
|
|
|
if(((_data$frag=data.frag)===null||_data$frag===void 0?void 0:_data$frag.type)===_types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN){if(data.type===_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.KEY_SYSTEM_ERROR){this.clearTimer();return;}switch(data.details){case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.FRAG_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.FRAG_LOAD_TIMEOUT:case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.KEY_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.KEY_LOAD_TIMEOUT:this.clearTimer();break;default:break;}}};_proto.clearTimer=function clearTimer(){self.clearInterval(this.timer);this.timer=undefined;}// return next auto level
|
|
|
;_proto.getNextABRAutoLevel=function getNextABRAutoLevel(){var fragCurrent=this.fragCurrent,partCurrent=this.partCurrent,hls=this.hls;var maxAutoLevel=hls.maxAutoLevel,config=hls.config,minAutoLevel=hls.minAutoLevel,media=hls.media;var currentFragDuration=partCurrent?partCurrent.duration:fragCurrent?fragCurrent.duration:0;// playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as
|
|
|
// if we're playing back at the normal rate.
|
|
|
var playbackRate=media&&media.playbackRate!==0?Math.abs(media.playbackRate):1.0;var avgbw=this.bwEstimator?this.bwEstimator.getEstimate():config.abrEwmaDefaultEstimate;// bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted.
|
|
|
var bufferInfo=hls.mainForwardBufferInfo;var bufferStarvationDelay=(bufferInfo?bufferInfo.len:0)/playbackRate;// First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all
|
|
|
var bestLevel=this.findBestLevel(avgbw,minAutoLevel,maxAutoLevel,bufferStarvationDelay,config.abrBandWidthFactor,config.abrBandWidthUpFactor);if(bestLevel>=0){return bestLevel;}_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace((bufferStarvationDelay?'rebuffering expected':'buffer is empty')+", finding optimal quality level");// not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering
|
|
|
// if no matching level found, logic will return 0
|
|
|
var maxStarvationDelay=currentFragDuration?Math.min(currentFragDuration,config.maxStarvationDelay):config.maxStarvationDelay;var bwFactor=config.abrBandWidthFactor;var bwUpFactor=config.abrBandWidthUpFactor;if(!bufferStarvationDelay){// in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test
|
|
|
var bitrateTestDelay=this.bitrateTestDelay;if(bitrateTestDelay){// if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value
|
|
|
// max video loading delay used in automatic start level selection :
|
|
|
// in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level +
|
|
|
// the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` )
|
|
|
// cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
|
|
|
var maxLoadingDelay=currentFragDuration?Math.min(currentFragDuration,config.maxLoadingDelay):config.maxLoadingDelay;maxStarvationDelay=maxLoadingDelay-bitrateTestDelay;_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace("bitrate test took "+Math.round(1000*bitrateTestDelay)+"ms, set first fragment max fetchDuration to "+Math.round(1000*maxStarvationDelay)+" ms");// don't use conservative factor on bitrate test
|
|
|
bwFactor=bwUpFactor=1;}}bestLevel=this.findBestLevel(avgbw,minAutoLevel,maxAutoLevel,bufferStarvationDelay+maxStarvationDelay,bwFactor,bwUpFactor);return Math.max(bestLevel,0);};_proto.findBestLevel=function findBestLevel(currentBw,minAutoLevel,maxAutoLevel,maxFetchDuration,bwFactor,bwUpFactor){var _level$details;var fragCurrent=this.fragCurrent,partCurrent=this.partCurrent,currentLevel=this.lastLoadedFragLevel;var levels=this.hls.levels;var level=levels[currentLevel];var live=!!(level!==null&&level!==void 0&&(_level$details=level.details)!==null&&_level$details!==void 0&&_level$details.live);var currentCodecSet=level===null||level===void 0?void 0:level.codecSet;var currentFragDuration=partCurrent?partCurrent.duration:fragCurrent?fragCurrent.duration:0;for(var i=maxAutoLevel;i>=minAutoLevel;i--){var levelInfo=levels[i];if(!levelInfo||currentCodecSet&&levelInfo.codecSet!==currentCodecSet){continue;}var levelDetails=levelInfo.details;var avgDuration=(partCurrent?levelDetails===null||levelDetails===void 0?void 0:levelDetails.partTarget:levelDetails===null||levelDetails===void 0?void 0:levelDetails.averagetargetduration)||currentFragDuration;var adjustedbw=void 0;// follow algorithm captured from stagefright :
|
|
|
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
|
|
|
// Pick the highest bandwidth stream below or equal to estimated bandwidth.
|
|
|
// consider only 80% of the available bandwidth, but if we are switching up,
|
|
|
// be even more conservative (70%) to avoid overestimating and immediately
|
|
|
// switching back.
|
|
|
if(i<=currentLevel){adjustedbw=bwFactor*currentBw;}else{adjustedbw=bwUpFactor*currentBw;}var bitrate=levels[i].maxBitrate;var fetchDuration=bitrate*avgDuration/adjustedbw;_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: "+i+"/"+Math.round(adjustedbw)+"/"+bitrate+"/"+avgDuration+"/"+maxFetchDuration+"/"+fetchDuration);// if adjusted bw is greater than level bitrate AND
|
|
|
if(adjustedbw>bitrate&&(// fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches
|
|
|
// we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ...
|
|
|
// special case to support startLevel = -1 (bitrateTest) on live streams : in that case we should not exit loop so that findBestLevel will return -1
|
|
|
fetchDuration===0||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fetchDuration)||live&&!this.bitrateTestDelay||fetchDuration<maxFetchDuration)){// as we are looping from highest to lowest, this will return the best achievable quality level
|
|
|
return i;}}// not enough time budget even with quality level 0 ... rebuffering might happen
|
|
|
return-1;};_createClass(AbrController,[{key:"nextAutoLevel",get:function get(){var forcedAutoLevel=this._nextAutoLevel;var bwEstimator=this.bwEstimator;// in case next auto level has been forced, and bw not available or not reliable, return forced value
|
|
|
if(forcedAutoLevel!==-1&&!bwEstimator.canEstimate()){return forcedAutoLevel;}// compute next level using ABR logic
|
|
|
var nextABRAutoLevel=this.getNextABRAutoLevel();// use forced auto level when ABR selected level has errored
|
|
|
if(forcedAutoLevel!==-1&&this.hls.levels[nextABRAutoLevel].loadError){return forcedAutoLevel;}// if forced auto level has been defined, use it to cap ABR computed quality level
|
|
|
if(forcedAutoLevel!==-1){nextABRAutoLevel=Math.min(forcedAutoLevel,nextABRAutoLevel);}return nextABRAutoLevel;},set:function set(nextLevel){this._nextAutoLevel=nextLevel;}}]);return AbrController;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=AbrController;/***/},/***/"./src/controller/audio-stream-controller.ts":/*!***************************************************!*\
|
|
|
!*** ./src/controller/audio-stream-controller.ts ***!
|
|
|
\***************************************************/ /***/function srcControllerAudioStreamControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_32113__){"use strict";__nested_webpack_require_32113__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_32113__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_32113__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_32113__(/*! ./base-stream-controller */"./src/controller/base-stream-controller.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_32113__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_32113__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_32113__(/*! ./fragment-tracker */"./src/controller/fragment-tracker.ts");/* harmony import */var _types_level__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_32113__(/*! ../types/level */"./src/types/level.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_32113__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_32113__(/*! ../loader/fragment */"./src/loader/fragment.ts");/* harmony import */var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_32113__(/*! ../demux/chunk-cache */"./src/demux/chunk-cache.ts");/* harmony import */var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_32113__(/*! ../demux/transmuxer-interface */"./src/demux/transmuxer-interface.ts");/* harmony import */var _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__=__nested_webpack_require_32113__(/*! ../types/transmuxer */"./src/types/transmuxer.ts");/* harmony import */var _fragment_finders__WEBPACK_IMPORTED_MODULE_11__=__nested_webpack_require_32113__(/*! ./fragment-finders */"./src/controller/fragment-finders.ts");/* harmony import */var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__=__nested_webpack_require_32113__(/*! ../utils/discontinuities */"./src/utils/discontinuities.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_13__=__nested_webpack_require_32113__(/*! ../errors */"./src/errors.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var TICK_INTERVAL=100;// how often to tick in ms
|
|
|
var AudioStreamController=/*#__PURE__*/function(_BaseStreamController){_inheritsLoose(AudioStreamController,_BaseStreamController);function AudioStreamController(hls,fragmentTracker,keyLoader){var _this;_this=_BaseStreamController.call(this,hls,fragmentTracker,keyLoader,'[audio-stream-controller]')||this;_this.videoBuffer=null;_this.videoTrackCC=-1;_this.waitingVideoCC=-1;_this.audioSwitch=false;_this.trackId=-1;_this.waitingData=null;_this.mainDetails=null;_this.bufferFlushed=false;_this.cachedTrackLoadedData=null;_this._registerListeners();return _this;}var _proto=AudioStreamController.prototype;_proto.onHandlerDestroying=function onHandlerDestroying(){this._unregisterListeners();this.mainDetails=null;};_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACKS_UPDATED,this.onAudioTracksUpdated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHING,this.onAudioTrackSwitching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED,this.onAudioTrackLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,this.onError,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_RESET,this.onBufferReset,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CREATED,this.onBufferCreated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_FLUSHED,this.onBufferFlushed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.INIT_PTS_FOUND,this.onInitPtsFound,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED,this.onFragBuffered,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACKS_UPDATED,this.onAudioTracksUpdated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHING,this.onAudioTrackSwitching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED,this.onAudioTrackLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,this.onError,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_RESET,this.onBufferReset,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CREATED,this.onBufferCreated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_FLUSHED,this.onBufferFlushed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.INIT_PTS_FOUND,this.onInitPtsFound,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED,this.onFragBuffered,this);}// INIT_PTS_FOUND is triggered when the video track parsed in the stream-controller has a new PTS value
|
|
|
;_proto.onInitPtsFound=function onInitPtsFound(event,_ref){var frag=_ref.frag,id=_ref.id,initPTS=_ref.initPTS;// Always update the new INIT PTS
|
|
|
// Can change due level switch
|
|
|
if(id==='main'){var cc=frag.cc;this.initPTS[frag.cc]=initPTS;this.log("InitPTS for cc: "+cc+" found from main: "+initPTS);this.videoTrackCC=cc;// If we are waiting, tick immediately to unblock audio fragment transmuxing
|
|
|
if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS){this.tick();}}};_proto.startLoad=function startLoad(startPosition){if(!this.levels){this.startPosition=startPosition;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;return;}var lastCurrentTime=this.lastCurrentTime;this.stopLoad();this.setInterval(TICK_INTERVAL);this.fragLoadError=0;if(lastCurrentTime>0&&startPosition===-1){this.log("Override startPosition with lastCurrentTime @"+lastCurrentTime.toFixed(3));startPosition=lastCurrentTime;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}else{this.loadedmetadata=false;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK;}this.nextLoadPosition=this.startPosition=this.lastCurrentTime=startPosition;this.tick();};_proto.doTick=function doTick(){switch(this.state){case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE:this.doTickIdle();break;case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK:{var _levels$trackId;var levels=this.levels,trackId=this.trackId;var details=levels===null||levels===void 0?void 0:(_levels$trackId=levels[trackId])===null||_levels$trackId===void 0?void 0:_levels$trackId.details;if(details){if(this.waitForCdnTuneIn(details)){break;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;}break;}case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:{var _this$media;var now=performance.now();var retryDate=this.retryDate;// if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
|
|
|
if(!retryDate||now>=retryDate||(_this$media=this.media)!==null&&_this$media!==void 0&&_this$media.seeking){this.log('RetryDate reached, switch back to IDLE state');this.resetStartWhenNotLoaded(this.trackId);this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}break;}case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS:{// Ensure we don't get stuck in the WAITING_INIT_PTS state if the waiting frag CC doesn't match any initPTS
|
|
|
var waitingData=this.waitingData;if(waitingData){var frag=waitingData.frag,part=waitingData.part,cache=waitingData.cache,complete=waitingData.complete;if(this.initPTS[frag.cc]!==undefined){this.waitingData=null;this.waitingVideoCC=-1;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING;var payload=cache.flush();var data={frag:frag,part:part,payload:payload,networkDetails:null};this._handleFragmentLoadProgress(data);if(complete){_BaseStreamController.prototype._handleFragmentLoadComplete.call(this,data);}}else if(this.videoTrackCC!==this.waitingVideoCC){// Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
|
|
|
this.log("Waiting fragment cc ("+frag.cc+") cancelled because video is at cc "+this.videoTrackCC);this.clearWaitingFragment();}else{// Drop waiting fragment if an earlier fragment is needed
|
|
|
var pos=this.getLoadPosition();var bufferInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(this.mediaBuffer,pos,this.config.maxBufferHole);var waitingFragmentAtPosition=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_11__.fragmentWithinToleranceTest)(bufferInfo.end,this.config.maxFragLookUpTolerance,frag);if(waitingFragmentAtPosition<0){this.log("Waiting fragment cc ("+frag.cc+") @ "+frag.start+" cancelled because another fragment at "+bufferInfo.end+" is needed");this.clearWaitingFragment();}}}else{this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}}}this.onTickEnd();};_proto.clearWaitingFragment=function clearWaitingFragment(){var waitingData=this.waitingData;if(waitingData){this.fragmentTracker.removeFragment(waitingData.frag);this.waitingData=null;this.waitingVideoCC=-1;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}};_proto.resetLoadingState=function resetLoadingState(){this.clearWaitingFragment();_BaseStreamController.prototype.resetLoadingState.call(this);};_proto.onTickEnd=function onTickEnd(){var media=this.media;if(!media||!media.readyState){// Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0)
|
|
|
return;}this.lastCurrentTime=media.currentTime;};_proto.doTickIdle=function doTickIdle(){var hls=this.hls,levels=this.levels,media=this.media,trackId=this.trackId;var config=hls.config;if(!levels||!levels[trackId]){return;}// if video not attached AND
|
|
|
// start fragment already requested OR start frag prefetch not enabled
|
|
|
// exit loop
|
|
|
// => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
|
|
|
if(!media&&(this.startFragRequested||!config.startFragPrefetch)){return;}var levelInfo=levels[trackId];var trackDetails=levelInfo.details;if(!trackDetails||trackDetails.live&&this.levelLastLoaded!==trackId||this.waitForCdnTuneIn(trackDetails)){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK;return;}var bufferable=this.mediaBuffer?this.mediaBuffer:this.media;if(this.bufferFlushed&&bufferable){this.bufferFlushed=false;this.afterBufferFlushed(bufferable,_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);}var bufferInfo=this.getFwdBufferInfo(bufferable,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);if(bufferInfo===null){return;}var audioSwitch=this.audioSwitch;if(!audioSwitch&&this._streamEnded(bufferInfo,trackDetails)){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_EOS,{type:'audio'});this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED;return;}var mainBufferInfo=this.getFwdBufferInfo(this.videoBuffer?this.videoBuffer:this.media,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);var bufferLen=bufferInfo.len;var maxBufLen=this.getMaxBufferLength(mainBufferInfo===null||mainBufferInfo===void 0?void 0:mainBufferInfo.len);// if buffer length is less than maxBufLen try to load a new fragment
|
|
|
if(bufferLen>=maxBufLen&&!audioSwitch){return;}var fragments=trackDetails.fragments;var start=fragments[0].start;var targetBufferTime=bufferInfo.end;if(audioSwitch&&media){var pos=this.getLoadPosition();targetBufferTime=pos;// if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime
|
|
|
if(trackDetails.PTSKnown&&pos<start){// if everything is buffered from pos to start or if audio buffer upfront, let's seek to start
|
|
|
if(bufferInfo.end>start||bufferInfo.nextStart){this.log('Alt audio track ahead of main track, seek to start of alt audio track');media.currentTime=start+0.05;}}}// buffer audio up to one target duration ahead of main buffer
|
|
|
if(mainBufferInfo&&targetBufferTime>mainBufferInfo.end+trackDetails.targetduration){return;}// wait for main buffer after buffing some audio
|
|
|
if((!mainBufferInfo||!mainBufferInfo.len)&&bufferInfo.len){return;}var frag=this.getNextFragment(targetBufferTime,trackDetails);if(!frag){this.bufferFlushed=true;return;}this.loadFragment(frag,trackDetails,targetBufferTime);};_proto.getMaxBufferLength=function getMaxBufferLength(mainBufferLength){var maxConfigBuffer=_BaseStreamController.prototype.getMaxBufferLength.call(this);if(!mainBufferLength){return maxConfigBuffer;}return Math.max(maxConfigBuffer,mainBufferLength);};_proto.onMediaDetaching=function onMediaDetaching(){this.videoBuffer=null;_BaseStreamController.prototype.onMediaDetaching.call(this);};_proto.onAudioTracksUpdated=function onAudioTracksUpdated(event,_ref2){var audioTracks=_ref2.audioTracks;this.resetTransmuxer();this.levels=audioTracks.map(function(mediaPlaylist){return new _types_level__WEBPACK_IMPORTED_MODULE_5__.Level(mediaPlaylist);});};_proto.onAudioTrackSwitching=function onAudioTrackSwitching(event,data){// if any URL found on new audio track, it is an alternate audio track
|
|
|
var altAudio=!!data.url;this.trackId=data.id;var fragCurrent=this.fragCurrent;if(fragCurrent){fragCurrent.abortRequests();}this.fragCurrent=null;this.clearWaitingFragment();// destroy useless transmuxer when switching audio to main
|
|
|
if(!altAudio){this.resetTransmuxer();}else{// switching to audio track, start timer if not already started
|
|
|
this.setInterval(TICK_INTERVAL);}// should we switch tracks ?
|
|
|
if(altAudio){this.audioSwitch=true;// main audio track are handled by stream-controller, just do something if switching to alt audio track
|
|
|
this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}else{this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;}this.tick();};_proto.onManifestLoading=function onManifestLoading(){this.mainDetails=null;this.fragmentTracker.removeAllFragments();this.startPosition=this.lastCurrentTime=0;this.bufferFlushed=false;};_proto.onLevelLoaded=function onLevelLoaded(event,data){this.mainDetails=data.details;if(this.cachedTrackLoadedData!==null){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED,this.cachedTrackLoadedData);this.cachedTrackLoadedData=null;}};_proto.onAudioTrackLoaded=function onAudioTrackLoaded(event,data){var _track$details;if(this.mainDetails==null){this.cachedTrackLoadedData=data;return;}var levels=this.levels;var newDetails=data.details,trackId=data.id;if(!levels){this.warn("Audio tracks were reset while loading level "+trackId);return;}this.log("Track "+trackId+" loaded ["+newDetails.startSN+","+newDetails.endSN+"],duration:"+newDetails.totalduration);var track=levels[trackId];var sliding=0;if(newDetails.live||(_track$details=track.details)!==null&&_track$details!==void 0&&_track$details.live){var mainDetails=this.mainDetails;if(!newDetails.fragments[0]){newDetails.deltaUpdateFailed=true;}if(newDetails.deltaUpdateFailed||!mainDetails){return;}if(!track.details&&newDetails.hasProgramDateTime&&mainDetails.hasProgramDateTime){// Make sure our audio rendition is aligned with the "main" rendition, using
|
|
|
// pdt as our reference times.
|
|
|
(0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__.alignMediaPlaylistByPDT)(newDetails,mainDetails);sliding=newDetails.fragments[0].start;}else{sliding=this.alignPlaylists(newDetails,track.details);}}track.details=newDetails;this.levelLastLoaded=trackId;// compute start position if we are aligned with the main playlist
|
|
|
if(!this.startFragRequested&&(this.mainDetails||!newDetails.live)){this.setStartPosition(track.details,sliding);}// only switch back to IDLE state if we were waiting for track to start downloading a new fragment
|
|
|
if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK&&!this.waitForCdnTuneIn(newDetails)){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}// trigger handler right now
|
|
|
this.tick();};_proto._handleFragmentLoadProgress=function _handleFragmentLoadProgress(data){var _frag$initSegment;var frag=data.frag,part=data.part,payload=data.payload;var config=this.config,trackId=this.trackId,levels=this.levels;if(!levels){this.warn("Audio tracks were reset while fragment load was in progress. Fragment "+frag.sn+" of level "+frag.level+" will not be buffered");return;}var track=levels[trackId];console.assert(track,'Audio track is defined on fragment load progress');var details=track.details;console.assert(details,'Audio track details are defined on fragment load progress');var audioCodec=config.defaultAudioCodec||track.audioCodec||'mp4a.40.2';var transmuxer=this.transmuxer;if(!transmuxer){transmuxer=this.transmuxer=new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](this.hls,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO,this._handleTransmuxComplete.bind(this),this._handleTransmuxerFlush.bind(this));}// Check if we have video initPTS
|
|
|
// If not we need to wait for it
|
|
|
var initPTS=this.initPTS[frag.cc];var initSegmentData=(_frag$initSegment=frag.initSegment)===null||_frag$initSegment===void 0?void 0:_frag$initSegment.data;if(initPTS!==undefined){// this.log(`Transmuxing ${sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`);
|
|
|
// time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
|
|
|
var accurateTimeOffset=false;// details.PTSKnown || !details.live;
|
|
|
var partIndex=part?part.index:-1;var partial=partIndex!==-1;var chunkMeta=new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__.ChunkMetadata(frag.level,frag.sn,frag.stats.chunkCount,payload.byteLength,partIndex,partial);transmuxer.push(payload,initSegmentData,audioCodec,'',frag,part,details.totalduration,accurateTimeOffset,chunkMeta,initPTS);}else{this.log("Unknown video PTS for cc "+frag.cc+", waiting for video PTS before demuxing audio frag "+frag.sn+" of ["+details.startSN+" ,"+details.endSN+"],track "+trackId);var _this$waitingData=this.waitingData=this.waitingData||{frag:frag,part:part,cache:new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__["default"](),complete:false},cache=_this$waitingData.cache;cache.push(new Uint8Array(payload));this.waitingVideoCC=this.videoTrackCC;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;}};_proto._handleFragmentLoadComplete=function _handleFragmentLoadComplete(fragLoadedData){if(this.waitingData){this.waitingData.complete=true;return;}_BaseStreamController.prototype._handleFragmentLoadComplete.call(this,fragLoadedData);};_proto.onBufferReset=function onBufferReset(/* event: Events.BUFFER_RESET */){// reset reference to sourcebuffers
|
|
|
this.mediaBuffer=this.videoBuffer=null;this.loadedmetadata=false;};_proto.onBufferCreated=function onBufferCreated(event,data){var audioTrack=data.tracks.audio;if(audioTrack){this.mediaBuffer=audioTrack.buffer||null;}if(data.tracks.video){this.videoBuffer=data.tracks.video.buffer||null;}};_proto.onFragBuffered=function onFragBuffered(event,data){var frag=data.frag,part=data.part;if(frag.type!==_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO){if(!this.loadedmetadata&&frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN){var _ref3;if((_ref3=this.videoBuffer||this.media)!==null&&_ref3!==void 0&&_ref3.buffered.length){this.loadedmetadata=true;}}return;}if(this.fragContextChanged(frag)){// If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion
|
|
|
// Avoid setting state back to IDLE or concluding the audio switch; otherwise, the switched-to track will not buffer
|
|
|
this.warn("Fragment "+frag.sn+(part?' p: '+part.index:'')+" of level "+frag.level+" finished buffering, but was aborted. state: "+this.state+", audioSwitch: "+this.audioSwitch);return;}if(frag.sn!=='initSegment'){this.fragPrevious=frag;if(this.audioSwitch){this.audioSwitch=false;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHED,{id:this.trackId});}}this.fragBufferedComplete(frag,part);};_proto.onError=function onError(event,data){if(data.type===_errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes.KEY_SYSTEM_ERROR){this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO,data);return;}switch(data.details){case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_LOAD_TIMEOUT:case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_PARSING_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.KEY_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.KEY_LOAD_TIMEOUT:// TODO: Skip fragments that do not belong to this.fragCurrent audio-group id
|
|
|
this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO,data);break;case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT:// when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received
|
|
|
if(this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR&&this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED){// if fatal error, stop processing, otherwise move to IDLE to retry loading
|
|
|
this.state=data.fatal?_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR:_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;this.warn(data.details+" while loading frag, switching to "+this.state+" state");}break;case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.BUFFER_FULL_ERROR:// if in appending state
|
|
|
if(data.parent==='audio'&&(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING||this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED)){var flushBuffer=true;var bufferedInfo=this.getFwdBufferInfo(this.mediaBuffer,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);// 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
|
|
|
// reduce max buf len if current position is buffered
|
|
|
if(bufferedInfo&&bufferedInfo.len>0.5){flushBuffer=!this.reduceMaxBufferLength(bufferedInfo.len);}if(flushBuffer){// current position is not buffered, but browser is still complaining about buffer full error
|
|
|
// this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
|
|
|
// in that case flush the whole audio buffer to recover
|
|
|
this.warn('Buffer full error also media.currentTime is not buffered, flush audio buffer');this.fragCurrent=null;_BaseStreamController.prototype.flushMainBuffer.call(this,0,Number.POSITIVE_INFINITY,'audio');}this.resetLoadingState();}break;default:break;}};_proto.onBufferFlushed=function onBufferFlushed(event,_ref4){var type=_ref4.type;if(type===_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO){this.bufferFlushed=true;if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}}};_proto._handleTransmuxComplete=function _handleTransmuxComplete(transmuxResult){var _id3$samples;var id='audio';var hls=this.hls;var remuxResult=transmuxResult.remuxResult,chunkMeta=transmuxResult.chunkMeta;var context=this.getCurrentContext(chunkMeta);if(!context){this.warn("The loading context changed while buffering fragment "+chunkMeta.sn+" of level "+chunkMeta.level+". This chunk will not be buffered.");this.resetStartWhenNotLoaded(chunkMeta.level);return;}var frag=context.frag,part=context.part,details=context.level.details;var audio=remuxResult.audio,text=remuxResult.text,id3=remuxResult.id3,initSegment=remuxResult.initSegment;// Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level.
|
|
|
// If we are, subsequently check if the currently loading fragment (fragCurrent) has changed.
|
|
|
if(this.fragContextChanged(frag)||!details){return;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING;if(this.audioSwitch&&audio){this.completeAudioSwitch();}if(initSegment!==null&&initSegment!==void 0&&initSegment.tracks){this._bufferInitSegment(initSegment.tracks,frag,chunkMeta);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_INIT_SEGMENT,{frag:frag,id:id,tracks:initSegment.tracks});// Only flush audio from old audio tracks when PTS is known on new audio track
|
|
|
}if(audio){var startPTS=audio.startPTS,endPTS=audio.endPTS,startDTS=audio.startDTS,endDTS=audio.endDTS;if(part){part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO]={startPTS:startPTS,endPTS:endPTS,startDTS:startDTS,endDTS:endDTS};}frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO,startPTS,endPTS,startDTS,endDTS);this.bufferFragmentData(audio,frag,part,chunkMeta);}if(id3!==null&&id3!==void 0&&(_id3$samples=id3.samples)!==null&&_id3$samples!==void 0&&_id3$samples.length){var emittedID3=_extends({id:id,frag:frag,details:details},id3);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_METADATA,emittedID3);}if(text){var emittedText=_extends({id:id,frag:frag,details:details},text);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_USERDATA,emittedText);}};_proto._bufferInitSegment=function _bufferInitSegment(tracks,frag,chunkMeta){if(this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING){return;}// delete any video track found on audio transmuxer
|
|
|
if(tracks.video){delete tracks.video;}// include levelCodec in audio and video tracks
|
|
|
var track=tracks.audio;if(!track){return;}track.levelCodec=track.codec;track.id='audio';this.log("Init audio buffer, container:"+track.container+", codecs[parsed]=["+track.codec+"]");this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CODECS,tracks);var initSegment=track.initSegment;if(initSegment!==null&&initSegment!==void 0&&initSegment.byteLength){var segment={type:'audio',frag:frag,part:null,chunkMeta:chunkMeta,parent:frag.type,data:initSegment};this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_APPENDING,segment);}// trigger handler right now
|
|
|
this.tick();};_proto.loadFragment=function loadFragment(frag,trackDetails,targetBufferTime){// only load if fragment is not loaded or if in audio switch
|
|
|
var fragState=this.fragmentTracker.getState(frag);this.fragCurrent=frag;// we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
|
|
|
if(this.audioSwitch||fragState===_fragment_tracker__WEBPACK_IMPORTED_MODULE_4__.FragmentState.NOT_LOADED||fragState===_fragment_tracker__WEBPACK_IMPORTED_MODULE_4__.FragmentState.PARTIAL){if(frag.sn==='initSegment'){this._loadInitSegment(frag,trackDetails);}else if(trackDetails.live&&!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.initPTS[frag.cc])){this.log("Waiting for video PTS in continuity counter "+frag.cc+" of live stream before loading audio fragment "+frag.sn+" of level "+this.trackId);this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;}else{this.startFragRequested=true;_BaseStreamController.prototype.loadFragment.call(this,frag,trackDetails,targetBufferTime);}}};_proto.completeAudioSwitch=function completeAudioSwitch(){var hls=this.hls,media=this.media,trackId=this.trackId;if(media){this.log('Switching audio track : flushing all audio');_BaseStreamController.prototype.flushMainBuffer.call(this,0,Number.POSITIVE_INFINITY,'audio');}this.audioSwitch=false;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHED,{id:trackId});};return AudioStreamController;}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]);/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=AudioStreamController;/***/},/***/"./src/controller/audio-track-controller.ts":/*!**************************************************!*\
|
|
|
!*** ./src/controller/audio-track-controller.ts ***!
|
|
|
\**************************************************/ /***/function srcControllerAudioTrackControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_62202__){"use strict";__nested_webpack_require_62202__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_62202__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_62202__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_62202__(/*! ../errors */"./src/errors.ts");/* harmony import */var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_62202__(/*! ./base-playlist-controller */"./src/controller/base-playlist-controller.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_62202__(/*! ../types/loader */"./src/types/loader.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var AudioTrackController=/*#__PURE__*/function(_BasePlaylistControll){_inheritsLoose(AudioTrackController,_BasePlaylistControll);function AudioTrackController(hls){var _this;_this=_BasePlaylistControll.call(this,hls,'[audio-track-controller]')||this;_this.tracks=[];_this.groupId=null;_this.tracksInGroup=[];_this.trackId=-1;_this.trackName='';_this.selectDefaultTrack=true;_this.registerListeners();return _this;}var _proto=AudioTrackController.prototype;_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING,this.onLevelSwitching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADED,this.onAudioTrackLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING,this.onLevelSwitching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADED,this.onAudioTrackLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);};_proto.destroy=function destroy(){this.unregisterListeners();this.tracks.length=0;this.tracksInGroup.length=0;_BasePlaylistControll.prototype.destroy.call(this);};_proto.onManifestLoading=function onManifestLoading(){this.tracks=[];this.groupId=null;this.tracksInGroup=[];this.trackId=-1;this.trackName='';this.selectDefaultTrack=true;};_proto.onManifestParsed=function onManifestParsed(event,data){this.tracks=data.audioTracks||[];};_proto.onAudioTrackLoaded=function onAudioTrackLoaded(event,data){var id=data.id,details=data.details;var currentTrack=this.tracksInGroup[id];if(!currentTrack){this.warn("Invalid audio track id "+id);return;}var curDetails=currentTrack.details;currentTrack.details=data.details;this.log("audioTrack "+id+" loaded ["+details.startSN+"-"+details.endSN+"]");if(id===this.trackId){this.retryCount=0;this.playlistLoaded(id,data,curDetails);}};_proto.onLevelLoading=function onLevelLoading(event,data){this.switchLevel(data.level);};_proto.onLevelSwitching=function onLevelSwitching(event,data){this.switchLevel(data.level);};_proto.switchLevel=function switchLevel(levelIndex){var levelInfo=this.hls.levels[levelIndex];if(!(levelInfo!==null&&levelInfo!==void 0&&levelInfo.audioGroupIds)){return;}var audioGroupId=levelInfo.audioGroupIds[levelInfo.urlId];if(this.groupId!==audioGroupId){this.groupId=audioGroupId;var audioTracks=this.tracks.filter(function(track){return!audioGroupId||track.groupId===audioGroupId;});// Disable selectDefaultTrack if there are no default tracks
|
|
|
if(this.selectDefaultTrack&&!audioTracks.some(function(track){return track["default"];})){this.selectDefaultTrack=false;}this.tracksInGroup=audioTracks;var audioTracksUpdated={audioTracks:audioTracks};this.log("Updating audio tracks, "+audioTracks.length+" track(s) found in \""+audioGroupId+"\" group-id");this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACKS_UPDATED,audioTracksUpdated);this.selectInitialTrack();}};_proto.onError=function onError(event,data){_BasePlaylistControll.prototype.onError.call(this,event,data);if(data.fatal||!data.context){return;}if(data.context.type===_types_loader__WEBPACK_IMPORTED_MODULE_3__.PlaylistContextType.AUDIO_TRACK&&data.context.id===this.trackId&&data.context.groupId===this.groupId){this.retryLoadingOrFail(data);}};_proto.setAudioTrack=function setAudioTrack(newId){var tracks=this.tracksInGroup;// check if level idx is valid
|
|
|
if(newId<0||newId>=tracks.length){this.warn('Invalid id passed to audio-track controller');return;}// stopping live reloading timer if any
|
|
|
this.clearTimer();var lastTrack=tracks[this.trackId];this.log("Now switching to audio-track index "+newId);var track=tracks[newId];var id=track.id,_track$groupId=track.groupId,groupId=_track$groupId===void 0?'':_track$groupId,name=track.name,type=track.type,url=track.url;this.trackId=newId;this.trackName=name;this.selectDefaultTrack=false;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_SWITCHING,{id:id,groupId:groupId,name:name,type:type,url:url});// Do not reload track unless live
|
|
|
if(track.details&&!track.details.live){return;}var hlsUrlParameters=this.switchParams(track.url,lastTrack===null||lastTrack===void 0?void 0:lastTrack.details);this.loadPlaylist(hlsUrlParameters);};_proto.selectInitialTrack=function selectInitialTrack(){var audioTracks=this.tracksInGroup;console.assert(audioTracks.length,'Initial audio track should be selected when tracks are known');var currentAudioTrackName=this.trackName;var trackId=this.findTrackId(currentAudioTrackName)||this.findTrackId();if(trackId!==-1){this.setAudioTrack(trackId);}else{this.warn("No track found for running audio group-ID: "+this.groupId);this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR,fatal:true});}};_proto.findTrackId=function findTrackId(name){var audioTracks=this.tracksInGroup;for(var i=0;i<audioTracks.length;i++){var track=audioTracks[i];if(!this.selectDefaultTrack||track["default"]){if(!name||name===track.name){return track.id;}}}return-1;};_proto.loadPlaylist=function loadPlaylist(hlsUrlParameters){_BasePlaylistControll.prototype.loadPlaylist.call(this);var audioTrack=this.tracksInGroup[this.trackId];if(this.shouldLoadTrack(audioTrack)){var id=audioTrack.id;var groupId=audioTrack.groupId;var url=audioTrack.url;if(hlsUrlParameters){try{url=hlsUrlParameters.addDirectives(url);}catch(error){this.warn("Could not construct new URL with HLS Delivery Directives: "+error);}}// track not retrieved yet, or live playlist we need to (re)load it
|
|
|
this.log("loading audio-track playlist for id: "+id);this.clearTimer();this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADING,{url:url,id:id,groupId:groupId,deliveryDirectives:hlsUrlParameters||null});}};_createClass(AudioTrackController,[{key:"audioTracks",get:function get(){return this.tracksInGroup;}},{key:"audioTrack",get:function get(){return this.trackId;},set:function set(newId){// If audio track is selected from API then don't choose from the manifest default track
|
|
|
this.selectDefaultTrack=false;this.setAudioTrack(newId);}}]);return AudioTrackController;}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]);/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=AudioTrackController;/***/},/***/"./src/controller/base-playlist-controller.ts":/*!****************************************************!*\
|
|
|
!*** ./src/controller/base-playlist-controller.ts ***!
|
|
|
\****************************************************/ /***/function srcControllerBasePlaylistControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_71818__){"use strict";__nested_webpack_require_71818__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_71818__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */BasePlaylistController);}/* harmony export */});/* harmony import */var _types_level__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_71818__(/*! ../types/level */"./src/types/level.ts");/* harmony import */var _level_helper__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_71818__(/*! ./level-helper */"./src/controller/level-helper.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_71818__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_71818__(/*! ../errors */"./src/errors.ts");var BasePlaylistController=/*#__PURE__*/function(){function BasePlaylistController(hls,logPrefix){this.hls=void 0;this.timer=-1;this.requestScheduled=-1;this.canLoad=false;this.retryCount=0;this.log=void 0;this.warn=void 0;this.log=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,logPrefix+":");this.warn=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,logPrefix+":");this.hls=hls;}var _proto=BasePlaylistController.prototype;_proto.destroy=function destroy(){this.clearTimer();// @ts-ignore
|
|
|
this.hls=this.log=this.warn=null;};_proto.onError=function onError(event,data){if(data.fatal&&(data.type===_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.NETWORK_ERROR||data.type===_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.KEY_SYSTEM_ERROR)){this.stopLoad();}};_proto.clearTimer=function clearTimer(){clearTimeout(this.timer);this.timer=-1;};_proto.startLoad=function startLoad(){this.canLoad=true;this.retryCount=0;this.requestScheduled=-1;this.loadPlaylist();};_proto.stopLoad=function stopLoad(){this.canLoad=false;this.clearTimer();};_proto.switchParams=function switchParams(playlistUri,previous){var renditionReports=previous===null||previous===void 0?void 0:previous.renditionReports;if(renditionReports){for(var i=0;i<renditionReports.length;i++){var attr=renditionReports[i];var uri=void 0;try{uri=new self.URL(attr.URI,previous.url).href;}catch(error){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("Could not construct new URL for Rendition Report: "+error);uri=attr.URI||'';}if(uri===playlistUri.slice(-uri.length)){var msn=parseInt(attr['LAST-MSN'])||(previous===null||previous===void 0?void 0:previous.lastPartSn);var part=parseInt(attr['LAST-PART'])||(previous===null||previous===void 0?void 0:previous.lastPartIndex);if(this.hls.config.lowLatencyMode){var currentGoal=Math.min(previous.age-previous.partTarget,previous.targetduration);if(part>=0&¤tGoal>previous.partTarget){part+=1;}}return new _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsUrlParameters(msn,part>=0?part:undefined,_types_level__WEBPACK_IMPORTED_MODULE_0__.HlsSkip.No);}}}};_proto.loadPlaylist=function loadPlaylist(hlsUrlParameters){if(this.requestScheduled===-1){this.requestScheduled=self.performance.now();}};_proto.shouldLoadTrack=function shouldLoadTrack(track){return this.canLoad&&track&&!!track.url&&(!track.details||track.details.live);};_proto.playlistLoaded=function playlistLoaded(index,data,previousDetails){var _this=this;var details=data.details,stats=data.stats;// Set last updated date-time
|
|
|
var now=self.performance.now();var elapsed=stats.loading.first?Math.max(0,now-stats.loading.first):0;details.advancedDateTime=Date.now()-elapsed;// if current playlist is a live playlist, arm a timer to reload it
|
|
|
if(details.live||previousDetails!==null&&previousDetails!==void 0&&previousDetails.live){details.reloaded(previousDetails);if(previousDetails){this.log("live playlist "+index+" "+(details.advanced?'REFRESHED '+details.lastPartSn+'-'+details.lastPartIndex:'MISSED'));}// Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
|
|
|
if(previousDetails&&details.fragments.length>0){(0,_level_helper__WEBPACK_IMPORTED_MODULE_1__.mergeDetails)(previousDetails,details);}if(!this.canLoad||!details.live){return;}var deliveryDirectives;var msn=undefined;var part=undefined;if(details.canBlockReload&&details.endSN&&details.advanced){// Load level with LL-HLS delivery directives
|
|
|
var lowLatencyMode=this.hls.config.lowLatencyMode;var lastPartSn=details.lastPartSn;var endSn=details.endSN;var lastPartIndex=details.lastPartIndex;var hasParts=lastPartIndex!==-1;var lastPart=lastPartSn===endSn;// When low latency mode is disabled, we'll skip part requests once the last part index is found
|
|
|
var nextSnStartIndex=lowLatencyMode?0:lastPartIndex;if(hasParts){msn=lastPart?endSn+1:lastPartSn;part=lastPart?nextSnStartIndex:lastPartIndex+1;}else{msn=endSn+1;}// Low-Latency CDN Tune-in: "age" header and time since load indicates we're behind by more than one part
|
|
|
// Update directives to obtain the Playlist that has the estimated additional duration of media
|
|
|
var lastAdvanced=details.age;var cdnAge=lastAdvanced+details.ageHeader;var currentGoal=Math.min(cdnAge-details.partTarget,details.targetduration*1.5);if(currentGoal>0){if(previousDetails&¤tGoal>previousDetails.tuneInGoal){// If we attempted to get the next or latest playlist update, but currentGoal increased,
|
|
|
// then we either can't catchup, or the "age" header cannot be trusted.
|
|
|
this.warn("CDN Tune-in goal increased from: "+previousDetails.tuneInGoal+" to: "+currentGoal+" with playlist age: "+details.age);currentGoal=0;}else{var segments=Math.floor(currentGoal/details.targetduration);msn+=segments;if(part!==undefined){var parts=Math.round(currentGoal%details.targetduration/details.partTarget);part+=parts;}this.log("CDN Tune-in age: "+details.ageHeader+"s last advanced "+lastAdvanced.toFixed(2)+"s goal: "+currentGoal+" skip sn "+segments+" to part "+part);}details.tuneInGoal=currentGoal;}deliveryDirectives=this.getDeliveryDirectives(details,data.deliveryDirectives,msn,part);if(lowLatencyMode||!lastPart){this.loadPlaylist(deliveryDirectives);return;}}else{deliveryDirectives=this.getDeliveryDirectives(details,data.deliveryDirectives,msn,part);}var bufferInfo=this.hls.mainForwardBufferInfo;var position=bufferInfo?bufferInfo.end-bufferInfo.len:0;var distanceToLiveEdgeMs=(details.edge-position)*1000;var reloadInterval=(0,_level_helper__WEBPACK_IMPORTED_MODULE_1__.computeReloadInterval)(details,distanceToLiveEdgeMs);if(!details.updated){this.requestScheduled=-1;}else if(now>this.requestScheduled+reloadInterval){this.requestScheduled=stats.loading.start;}if(msn!==undefined&&details.canBlockReload){this.requestScheduled=stats.loading.first+reloadInterval-(details.partTarget*1000||1000);}else{this.requestScheduled=(this.requestScheduled===-1?now:this.requestScheduled)+reloadInterval;}var estimatedTimeUntilUpdate=this.requestScheduled-now;estimatedTimeUntilUpdate=Math.max(0,estimatedTimeUntilUpdate);this.log("reload live playlist "+index+" in "+Math.round(estimatedTimeUntilUpdate)+" ms");// this.log(
|
|
|
// `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
|
|
|
// reload in ${estimatedTimeUntilUpdate / 1000}
|
|
|
// round trip ${(stats.loading.end - stats.loading.start) / 1000}
|
|
|
// diff ${
|
|
|
// (reloadInterval -
|
|
|
// (estimatedTimeUntilUpdate + stats.loading.end - stats.loading.start)) /
|
|
|
// 1000
|
|
|
// }
|
|
|
// reload interval ${reloadInterval / 1000}
|
|
|
// target duration ${details.targetduration}
|
|
|
// distance to edge ${distanceToLiveEdgeMs / 1000}`
|
|
|
// );
|
|
|
this.timer=self.setTimeout(function(){return _this.loadPlaylist(deliveryDirectives);},estimatedTimeUntilUpdate);}else{this.clearTimer();}};_proto.getDeliveryDirectives=function getDeliveryDirectives(details,previousDeliveryDirectives,msn,part){var skip=(0,_types_level__WEBPACK_IMPORTED_MODULE_0__.getSkipValue)(details,msn);if(previousDeliveryDirectives!==null&&previousDeliveryDirectives!==void 0&&previousDeliveryDirectives.skip&&details.deltaUpdateFailed){msn=previousDeliveryDirectives.msn;part=previousDeliveryDirectives.part;skip=_types_level__WEBPACK_IMPORTED_MODULE_0__.HlsSkip.No;}return new _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsUrlParameters(msn,part,skip);};_proto.retryLoadingOrFail=function retryLoadingOrFail(errorEvent){var _this2=this;var config=this.hls.config;var retry=this.retryCount<config.levelLoadingMaxRetry;if(retry){var _errorEvent$context;this.requestScheduled=-1;this.retryCount++;if(errorEvent.details.indexOf('LoadTimeOut')>-1&&(_errorEvent$context=errorEvent.context)!==null&&_errorEvent$context!==void 0&&_errorEvent$context.deliveryDirectives){// The LL-HLS request already timed out so retry immediately
|
|
|
this.warn("retry playlist loading #"+this.retryCount+" after \""+errorEvent.details+"\"");this.loadPlaylist();}else{// exponential backoff capped to max retry timeout
|
|
|
var delay=Math.min(Math.pow(2,this.retryCount)*config.levelLoadingRetryDelay,config.levelLoadingMaxRetryTimeout);// Schedule level/track reload
|
|
|
this.timer=self.setTimeout(function(){return _this2.loadPlaylist();},delay);this.warn("retry playlist loading #"+this.retryCount+" in "+delay+" ms after \""+errorEvent.details+"\"");}}else{this.warn("cannot recover from error \""+errorEvent.details+"\"");// stopping live reloading timer if any
|
|
|
this.clearTimer();// switch error to fatal
|
|
|
errorEvent.fatal=true;}return retry;};return BasePlaylistController;}();/***/},/***/"./src/controller/base-stream-controller.ts":/*!**************************************************!*\
|
|
|
!*** ./src/controller/base-stream-controller.ts ***!
|
|
|
\**************************************************/ /***/function srcControllerBaseStreamControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_81498__){"use strict";__nested_webpack_require_81498__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_81498__.d(__webpack_exports__,{/* harmony export */"State":function State(){return(/* binding */_State);},/* harmony export */"default":function _default(){return(/* binding */BaseStreamController);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_81498__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _task_loop__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_81498__(/*! ../task-loop */"./src/task-loop.ts");/* harmony import */var _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_81498__(/*! ./fragment-tracker */"./src/controller/fragment-tracker.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_81498__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_81498__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_81498__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_81498__(/*! ../errors */"./src/errors.ts");/* harmony import */var _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_81498__(/*! ../types/transmuxer */"./src/types/transmuxer.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_81498__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_81498__(/*! ../utils/discontinuities */"./src/utils/discontinuities.ts");/* harmony import */var _fragment_finders__WEBPACK_IMPORTED_MODULE_10__=__nested_webpack_require_81498__(/*! ./fragment-finders */"./src/controller/fragment-finders.ts");/* harmony import */var _level_helper__WEBPACK_IMPORTED_MODULE_11__=__nested_webpack_require_81498__(/*! ./level-helper */"./src/controller/level-helper.ts");/* harmony import */var _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__=__nested_webpack_require_81498__(/*! ../loader/fragment-loader */"./src/loader/fragment-loader.ts");/* harmony import */var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__=__nested_webpack_require_81498__(/*! ../crypt/decrypter */"./src/crypt/decrypter.ts");/* harmony import */var _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__=__nested_webpack_require_81498__(/*! ../utils/time-ranges */"./src/utils/time-ranges.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_15__=__nested_webpack_require_81498__(/*! ../types/loader */"./src/types/loader.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var _State={STOPPED:'STOPPED',IDLE:'IDLE',KEY_LOADING:'KEY_LOADING',FRAG_LOADING:'FRAG_LOADING',FRAG_LOADING_WAITING_RETRY:'FRAG_LOADING_WAITING_RETRY',WAITING_TRACK:'WAITING_TRACK',PARSING:'PARSING',PARSED:'PARSED',ENDED:'ENDED',ERROR:'ERROR',WAITING_INIT_PTS:'WAITING_INIT_PTS',WAITING_LEVEL:'WAITING_LEVEL'};var BaseStreamController=/*#__PURE__*/function(_TaskLoop){_inheritsLoose(BaseStreamController,_TaskLoop);function BaseStreamController(hls,fragmentTracker,keyLoader,logPrefix){var _this;_this=_TaskLoop.call(this)||this;_this.hls=void 0;_this.fragPrevious=null;_this.fragCurrent=null;_this.fragmentTracker=void 0;_this.transmuxer=null;_this._state=_State.STOPPED;_this.media=null;_this.mediaBuffer=null;_this.config=void 0;_this.bitrateTest=false;_this.lastCurrentTime=0;_this.nextLoadPosition=0;_this.startPosition=0;_this.loadedmetadata=false;_this.fragLoadError=0;_this.retryDate=0;_this.levels=null;_this.fragmentLoader=void 0;_this.keyLoader=void 0;_this.levelLastLoaded=null;_this.startFragRequested=false;_this.decrypter=void 0;_this.initPTS=[];_this.onvseeking=null;_this.onvended=null;_this.logPrefix='';_this.log=void 0;_this.warn=void 0;_this.logPrefix=logPrefix;_this.log=_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger,logPrefix+":");_this.warn=_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger,logPrefix+":");_this.hls=hls;_this.fragmentLoader=new _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__["default"](hls.config);_this.keyLoader=keyLoader;_this.fragmentTracker=fragmentTracker;_this.config=hls.config;_this.decrypter=new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__["default"](hls.config);hls.on(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_SWITCHING,_this.onLevelSwitching,_assertThisInitialized(_this));return _this;}var _proto=BaseStreamController.prototype;_proto.doTick=function doTick(){this.onTickEnd();};_proto.onTickEnd=function onTickEnd(){}// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
;_proto.startLoad=function startLoad(startPosition){};_proto.stopLoad=function stopLoad(){this.fragmentLoader.abort();this.keyLoader.abort();var frag=this.fragCurrent;if(frag){frag.abortRequests();this.fragmentTracker.removeFragment(frag);}this.resetTransmuxer();this.fragCurrent=null;this.fragPrevious=null;this.clearInterval();this.clearNextTick();this.state=_State.STOPPED;};_proto._streamEnded=function _streamEnded(bufferInfo,levelDetails){// If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
|
|
|
// of nothing loading/loaded return false
|
|
|
if(levelDetails.live||bufferInfo.nextStart||!bufferInfo.end||!this.media){return false;}var partList=levelDetails.partList;// Since the last part isn't guaranteed to correspond to the last playlist segment for Low-Latency HLS,
|
|
|
// check instead if the last part is buffered.
|
|
|
if(partList!==null&&partList!==void 0&&partList.length){var lastPart=partList[partList.length-1];// Checking the midpoint of the part for potential margin of error and related issues.
|
|
|
// NOTE: Technically I believe parts could yield content that is < the computed duration (including potential a duration of 0)
|
|
|
// and still be spec-compliant, so there may still be edge cases here. Likewise, there could be issues in end of stream
|
|
|
// part mismatches for independent audio and video playlists/segments.
|
|
|
var lastPartBuffered=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.isBuffered(this.media,lastPart.start+lastPart.duration/2);return lastPartBuffered;}var playlistType=levelDetails.fragments[levelDetails.fragments.length-1].type;return this.fragmentTracker.isEndListAppended(playlistType);};_proto.getLevelDetails=function getLevelDetails(){if(this.levels&&this.levelLastLoaded!==null){var _this$levels$this$lev;return(_this$levels$this$lev=this.levels[this.levelLastLoaded])===null||_this$levels$this$lev===void 0?void 0:_this$levels$this$lev.details;}};_proto.onMediaAttached=function onMediaAttached(event,data){var media=this.media=this.mediaBuffer=data.media;this.onvseeking=this.onMediaSeeking.bind(this);this.onvended=this.onMediaEnded.bind(this);media.addEventListener('seeking',this.onvseeking);media.addEventListener('ended',this.onvended);var config=this.config;if(this.levels&&config.autoStartLoad&&this.state===_State.STOPPED){this.startLoad(config.startPosition);}};_proto.onMediaDetaching=function onMediaDetaching(){var media=this.media;if(media!==null&&media!==void 0&&media.ended){this.log('MSE detaching and video ended, reset startPosition');this.startPosition=this.lastCurrentTime=0;}// remove video listeners
|
|
|
if(media&&this.onvseeking&&this.onvended){media.removeEventListener('seeking',this.onvseeking);media.removeEventListener('ended',this.onvended);this.onvseeking=this.onvended=null;}if(this.keyLoader){this.keyLoader.detach();}this.media=this.mediaBuffer=null;this.loadedmetadata=false;this.fragmentTracker.removeAllFragments();this.stopLoad();};_proto.onMediaSeeking=function onMediaSeeking(){var config=this.config,fragCurrent=this.fragCurrent,media=this.media,mediaBuffer=this.mediaBuffer,state=this.state;var currentTime=media?media.currentTime:0;var bufferInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(mediaBuffer?mediaBuffer:media,currentTime,config.maxBufferHole);this.log("media seeking to "+((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime)?currentTime.toFixed(3):currentTime)+", state: "+state);if(this.state===_State.ENDED){this.resetLoadingState();}else if(fragCurrent){// Seeking while frag load is in progress
|
|
|
var tolerance=config.maxFragLookUpTolerance;var fragStartOffset=fragCurrent.start-tolerance;var fragEndOffset=fragCurrent.start+fragCurrent.duration+tolerance;// if seeking out of buffered range or into new one
|
|
|
if(!bufferInfo.len||fragEndOffset<bufferInfo.start||fragStartOffset>bufferInfo.end){var pastFragment=currentTime>fragEndOffset;// if the seek position is outside the current fragment range
|
|
|
if(currentTime<fragStartOffset||pastFragment){if(pastFragment&&fragCurrent.loader){this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');fragCurrent.abortRequests();}this.resetLoadingState();}}}if(media){this.lastCurrentTime=currentTime;}// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
|
|
if(!this.loadedmetadata&&!bufferInfo.len){this.nextLoadPosition=this.startPosition=currentTime;}// Async tick to speed up processing
|
|
|
this.tickImmediate();};_proto.onMediaEnded=function onMediaEnded(){// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
|
|
this.startPosition=this.lastCurrentTime=0;};_proto.onLevelSwitching=function onLevelSwitching(event,data){this.fragLoadError=0;};_proto.onHandlerDestroying=function onHandlerDestroying(){this.stopLoad();_TaskLoop.prototype.onHandlerDestroying.call(this);};_proto.onHandlerDestroyed=function onHandlerDestroyed(){this.state=_State.STOPPED;this.hls.off(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_SWITCHING,this.onLevelSwitching,this);if(this.fragmentLoader){this.fragmentLoader.destroy();}if(this.keyLoader){this.keyLoader.destroy();}if(this.decrypter){this.decrypter.destroy();}this.hls=this.log=this.warn=this.decrypter=this.keyLoader=this.fragmentLoader=this.fragmentTracker=null;_TaskLoop.prototype.onHandlerDestroyed.call(this);};_proto.loadFragment=function loadFragment(frag,levelDetails,targetBufferTime){this._loadFragForPlayback(frag,levelDetails,targetBufferTime);};_proto._loadFragForPlayback=function _loadFragForPlayback(frag,levelDetails,targetBufferTime){var _this2=this;var progressCallback=function progressCallback(data){if(_this2.fragContextChanged(frag)){_this2.warn("Fragment "+frag.sn+(data.part?' p: '+data.part.index:'')+" of level "+frag.level+" was dropped during download.");_this2.fragmentTracker.removeFragment(frag);return;}frag.stats.chunkCount++;_this2._handleFragmentLoadProgress(data);};this._doFragLoad(frag,levelDetails,targetBufferTime,progressCallback).then(function(data){if(!data){// if we're here we probably needed to backtrack or are waiting for more parts
|
|
|
return;}_this2.fragLoadError=0;var state=_this2.state;if(_this2.fragContextChanged(frag)){if(state===_State.FRAG_LOADING||!_this2.fragCurrent&&state===_State.PARSING){_this2.fragmentTracker.removeFragment(frag);_this2.state=_State.IDLE;}return;}if('payload'in data){_this2.log("Loaded fragment "+frag.sn+" of level "+frag.level);_this2.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADED,data);}// Pass through the whole payload; controllers not implementing progressive loading receive data from this callback
|
|
|
_this2._handleFragmentLoadComplete(data);})["catch"](function(reason){if(_this2.state===_State.STOPPED||_this2.state===_State.ERROR){return;}_this2.warn(reason);_this2.resetFragmentLoading(frag);});};_proto.flushMainBuffer=function flushMainBuffer(startOffset,endOffset,type){if(type===void 0){type=null;}if(!(startOffset-endOffset)){return;}// When alternate audio is playing, the audio-stream-controller is responsible for the audio buffer. Otherwise,
|
|
|
// passing a null type flushes both buffers
|
|
|
var flushScope={startOffset:startOffset,endOffset:endOffset,type:type};// Reset load errors on flush
|
|
|
this.fragLoadError=0;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.BUFFER_FLUSHING,flushScope);};_proto._loadInitSegment=function _loadInitSegment(frag,details){var _this3=this;this._doFragLoad(frag,details).then(function(data){if(!data||_this3.fragContextChanged(frag)||!_this3.levels){throw new Error('init load aborted');}return data;}).then(function(data){var hls=_this3.hls;var payload=data.payload;var decryptData=frag.decryptdata;// check to see if the payload needs to be decrypted
|
|
|
if(payload&&payload.byteLength>0&&decryptData&&decryptData.key&&decryptData.iv&&decryptData.method==='AES-128'){var startTime=self.performance.now();// decrypt the subtitles
|
|
|
return _this3.decrypter.decrypt(new Uint8Array(payload),decryptData.key.buffer,decryptData.iv.buffer).then(function(decryptedData){var endTime=self.performance.now();hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_DECRYPTED,{frag:frag,payload:decryptedData,stats:{tstart:startTime,tdecrypt:endTime}});data.payload=decryptedData;return data;});}return data;}).then(function(data){var fragCurrent=_this3.fragCurrent,hls=_this3.hls,levels=_this3.levels;if(!levels){throw new Error('init load aborted, missing levels');}var details=levels[frag.level].details;console.assert(details,'Level details are defined when init segment is loaded');var stats=frag.stats;_this3.state=_State.IDLE;_this3.fragLoadError=0;frag.data=new Uint8Array(data.payload);stats.parsing.start=stats.buffering.start=self.performance.now();stats.parsing.end=stats.buffering.end=self.performance.now();// Silence FRAG_BUFFERED event if fragCurrent is null
|
|
|
if(data.frag===fragCurrent){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_BUFFERED,{stats:stats,frag:fragCurrent,part:null,id:frag.type});}_this3.tick();})["catch"](function(reason){if(_this3.state===_State.STOPPED||_this3.state===_State.ERROR){return;}_this3.warn(reason);_this3.resetFragmentLoading(frag);});};_proto.fragContextChanged=function fragContextChanged(frag){var fragCurrent=this.fragCurrent;return!frag||!fragCurrent||frag.level!==fragCurrent.level||frag.sn!==fragCurrent.sn||frag.urlId!==fragCurrent.urlId;};_proto.fragBufferedComplete=function fragBufferedComplete(frag,part){var _frag$startPTS,_frag$endPTS,_this$fragCurrent,_this$fragPrevious;var media=this.mediaBuffer?this.mediaBuffer:this.media;this.log("Buffered "+frag.type+" sn: "+frag.sn+(part?' part: '+part.index:'')+" of "+(this.logPrefix==='[stream-controller]'?'level':'track')+" "+frag.level+" (frag:["+((_frag$startPTS=frag.startPTS)!=null?_frag$startPTS:NaN).toFixed(3)+"-"+((_frag$endPTS=frag.endPTS)!=null?_frag$endPTS:NaN).toFixed(3)+"] > buffer:"+(media?_utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__["default"].toString(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.getBuffered(media)):'(detached)')+")");this.state=_State.IDLE;if(!media){return;}if(!this.loadedmetadata&&frag.type==_types_loader__WEBPACK_IMPORTED_MODULE_15__.PlaylistLevelType.MAIN&&media.buffered.length&&((_this$fragCurrent=this.fragCurrent)===null||_this$fragCurrent===void 0?void 0:_this$fragCurrent.sn)===((_this$fragPrevious=this.fragPrevious)===null||_this$fragPrevious===void 0?void 0:_this$fragPrevious.sn)){this.loadedmetadata=true;this.seekToStartPos();}this.tick();};_proto.seekToStartPos=function seekToStartPos(){};_proto._handleFragmentLoadComplete=function _handleFragmentLoadComplete(fragLoadedEndData){var transmuxer=this.transmuxer;if(!transmuxer){return;}var frag=fragLoadedEndData.frag,part=fragLoadedEndData.part,partsLoaded=fragLoadedEndData.partsLoaded;// If we did not load parts, or loaded all parts, we have complete (not partial) fragment data
|
|
|
var complete=!partsLoaded||partsLoaded.length===0||partsLoaded.some(function(fragLoaded){return!fragLoaded;});var chunkMeta=new _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__.ChunkMetadata(frag.level,frag.sn,frag.stats.chunkCount+1,0,part?part.index:-1,!complete);transmuxer.flush(chunkMeta);}// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
;_proto._handleFragmentLoadProgress=function _handleFragmentLoadProgress(frag){};_proto._doFragLoad=function _doFragLoad(frag,details,targetBufferTime,progressCallback){var _frag$decryptdata,_this4=this;if(targetBufferTime===void 0){targetBufferTime=null;}if(!this.levels){throw new Error('frag load aborted, missing levels');}var keyLoadingPromise=null;if(frag.encrypted&&!((_frag$decryptdata=frag.decryptdata)!==null&&_frag$decryptdata!==void 0&&_frag$decryptdata.key)){this.log("Loading key for "+frag.sn+" of ["+details.startSN+"-"+details.endSN+"], "+(this.logPrefix==='[stream-controller]'?'level':'track')+" "+frag.level);this.state=_State.KEY_LOADING;this.fragCurrent=frag;keyLoadingPromise=this.keyLoader.load(frag).then(function(keyLoadedData){if(!_this4.fragContextChanged(keyLoadedData.frag)){_this4.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.KEY_LOADED,keyLoadedData);if(_this4.state===_State.KEY_LOADING){_this4.state=_State.IDLE;}return keyLoadedData;}});this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.KEY_LOADING,{frag:frag});this.throwIfFragContextChanged('KEY_LOADING');}else if(!frag.encrypted&&details.encryptedFragments.length){this.keyLoader.loadClear(frag,details.encryptedFragments);}targetBufferTime=Math.max(frag.start,targetBufferTime||0);if(this.config.lowLatencyMode&&details){var partList=details.partList;if(partList&&progressCallback){if(targetBufferTime>frag.end&&details.fragmentHint){frag=details.fragmentHint;}var partIndex=this.getNextPart(partList,frag,targetBufferTime);if(partIndex>-1){var part=partList[partIndex];this.log("Loading part sn: "+frag.sn+" p: "+part.index+" cc: "+frag.cc+" of playlist ["+details.startSN+"-"+details.endSN+"] parts [0-"+partIndex+"-"+(partList.length-1)+"] "+(this.logPrefix==='[stream-controller]'?'level':'track')+": "+frag.level+", target: "+parseFloat(targetBufferTime.toFixed(3)));this.nextLoadPosition=part.start+part.duration;this.state=_State.FRAG_LOADING;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADING,{frag:frag,part:partList[partIndex],targetBufferTime:targetBufferTime});this.throwIfFragContextChanged('FRAG_LOADING parts');if(keyLoadingPromise){return keyLoadingPromise.then(function(keyLoadedData){if(!keyLoadedData||_this4.fragContextChanged(keyLoadedData.frag)){return null;}return _this4.doFragPartsLoad(frag,partList,partIndex,progressCallback);})["catch"](function(error){return _this4.handleFragLoadError(error);});}return this.doFragPartsLoad(frag,partList,partIndex,progressCallback)["catch"](function(error){return _this4.handleFragLoadError(error);});}else if(!frag.url||this.loadedEndOfParts(partList,targetBufferTime)){// Fragment hint has no parts
|
|
|
return Promise.resolve(null);}}}this.log("Loading fragment "+frag.sn+" cc: "+frag.cc+" "+(details?'of ['+details.startSN+'-'+details.endSN+'] ':'')+(this.logPrefix==='[stream-controller]'?'level':'track')+": "+frag.level+", target: "+parseFloat(targetBufferTime.toFixed(3)));// Don't update nextLoadPosition for fragments which are not buffered
|
|
|
if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.sn)&&!this.bitrateTest){this.nextLoadPosition=frag.start+frag.duration;}this.state=_State.FRAG_LOADING;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADING,{frag:frag,targetBufferTime:targetBufferTime});this.throwIfFragContextChanged('FRAG_LOADING');// Load key before streaming fragment data
|
|
|
var dataOnProgress=this.config.progressive;if(dataOnProgress&&keyLoadingPromise){return keyLoadingPromise.then(function(keyLoadedData){if(!keyLoadedData||_this4.fragContextChanged(keyLoadedData===null||keyLoadedData===void 0?void 0:keyLoadedData.frag)){return null;}return _this4.fragmentLoader.load(frag,progressCallback);})["catch"](function(error){return _this4.handleFragLoadError(error);});}// load unencrypted fragment data with progress event,
|
|
|
// or handle fragment result after key and fragment are finished loading
|
|
|
return Promise.all([this.fragmentLoader.load(frag,dataOnProgress?progressCallback:undefined),keyLoadingPromise]).then(function(_ref){var fragLoadedData=_ref[0];if(!dataOnProgress&&fragLoadedData&&progressCallback){progressCallback(fragLoadedData);}return fragLoadedData;})["catch"](function(error){return _this4.handleFragLoadError(error);});};_proto.throwIfFragContextChanged=function throwIfFragContextChanged(context){// exit if context changed during event loop
|
|
|
if(this.fragCurrent===null){throw new Error("frag load aborted, context changed in "+context);}};_proto.doFragPartsLoad=function doFragPartsLoad(frag,partList,partIndex,progressCallback){var _this5=this;return new Promise(function(resolve,reject){var partsLoaded=[];var loadPartIndex=function loadPartIndex(index){var part=partList[index];_this5.fragmentLoader.loadPart(frag,part,progressCallback).then(function(partLoadedData){partsLoaded[part.index]=partLoadedData;var loadedPart=partLoadedData.part;_this5.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADED,partLoadedData);var nextPart=partList[index+1];if(nextPart&&nextPart.fragment===frag){loadPartIndex(index+1);}else{return resolve({frag:frag,part:loadedPart,partsLoaded:partsLoaded});}})["catch"](reject);};loadPartIndex(partIndex);});};_proto.handleFragLoadError=function handleFragLoadError(error){if('data'in error){var data=error.data;if(error.data&&data.details===_errors__WEBPACK_IMPORTED_MODULE_6__.ErrorDetails.INTERNAL_ABORTED){this.handleFragLoadAborted(data.frag,data.part);}else{this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.ERROR,data);}}else{this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_6__.ErrorTypes.OTHER_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_6__.ErrorDetails.INTERNAL_EXCEPTION,err:error,fatal:true});}return null;};_proto._handleTransmuxerFlush=function _handleTransmuxerFlush(chunkMeta){var context=this.getCurrentContext(chunkMeta);if(!context||this.state!==_State.PARSING){if(!this.fragCurrent&&this.state!==_State.STOPPED&&this.state!==_State.ERROR){this.state=_State.IDLE;}return;}var frag=context.frag,part=context.part,level=context.level;var now=self.performance.now();frag.stats.parsing.end=now;if(part){part.stats.parsing.end=now;}this.updateLevelTiming(frag,part,level,chunkMeta.partial);};_proto.getCurrentContext=function getCurrentContext(chunkMeta){var levels=this.levels;var levelIndex=chunkMeta.level,sn=chunkMeta.sn,partIndex=chunkMeta.part;if(!levels||!levels[levelIndex]){this.warn("Levels object was unset while buffering fragment "+sn+" of level "+levelIndex+". The current chunk will not be buffered.");return null;}var level=levels[levelIndex];var part=partIndex>-1?(0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.getPartWith)(level,sn,partIndex):null;var frag=part?part.fragment:(0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.getFragmentWithSN)(level,sn,this.fragCurrent);if(!frag){return null;}return{frag:frag,part:part,level:level};};_proto.bufferFragmentData=function bufferFragmentData(data,frag,part,chunkMeta){if(!data||this.state!==_State.PARSING){return;}var data1=data.data1,data2=data.data2;var buffer=data1;if(data1&&data2){// Combine the moof + mdat so that we buffer with a single append
|
|
|
buffer=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.appendUint8Array)(data1,data2);}if(!buffer||!buffer.length){return;}var segment={type:data.type,frag:frag,part:part,chunkMeta:chunkMeta,parent:frag.type,data:buffer};this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.BUFFER_APPENDING,segment);if(data.dropped&&data.independent&&!part){// Clear buffer so that we reload previous segments sequentially if required
|
|
|
this.flushBufferGap(frag);}};_proto.flushBufferGap=function flushBufferGap(frag){var media=this.media;if(!media){return;}// If currentTime is not buffered, clear the back buffer so that we can backtrack as much as needed
|
|
|
if(!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.isBuffered(media,media.currentTime)){this.flushMainBuffer(0,frag.start);return;}// Remove back-buffer without interrupting playback to allow back tracking
|
|
|
var currentTime=media.currentTime;var bufferInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(media,currentTime,0);var fragDuration=frag.duration;var segmentFraction=Math.min(this.config.maxFragLookUpTolerance*2,fragDuration*0.25);var start=Math.max(Math.min(frag.start-segmentFraction,bufferInfo.end-segmentFraction),currentTime+segmentFraction);if(frag.start-start>segmentFraction){this.flushMainBuffer(start,frag.start);}};_proto.getFwdBufferInfo=function getFwdBufferInfo(bufferable,type){var config=this.config;var pos=this.getLoadPosition();if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(pos)){return null;}var bufferInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(bufferable,pos,config.maxBufferHole);// Workaround flaw in getting forward buffer when maxBufferHole is smaller than gap at current pos
|
|
|
if(bufferInfo.len===0&&bufferInfo.nextStart!==undefined){var bufferedFragAtPos=this.fragmentTracker.getBufferedFrag(pos,type);if(bufferedFragAtPos&&bufferInfo.nextStart<bufferedFragAtPos.end){return _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(bufferable,pos,Math.max(bufferInfo.nextStart,config.maxBufferHole));}}return bufferInfo;};_proto.getMaxBufferLength=function getMaxBufferLength(levelBitrate){var config=this.config;var maxBufLen;if(levelBitrate){maxBufLen=Math.max(8*config.maxBufferSize/levelBitrate,config.maxBufferLength);}else{maxBufLen=config.maxBufferLength;}return Math.min(maxBufLen,config.maxMaxBufferLength);};_proto.reduceMaxBufferLength=function reduceMaxBufferLength(threshold){var config=this.config;var minLength=threshold||config.maxBufferLength;if(config.maxMaxBufferLength>=minLength){// reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
|
|
|
config.maxMaxBufferLength/=2;this.warn("Reduce max buffer length to "+config.maxMaxBufferLength+"s");return true;}return false;};_proto.getNextFragment=function getNextFragment(pos,levelDetails){var fragments=levelDetails.fragments;var fragLen=fragments.length;if(!fragLen){return null;}// find fragment index, contiguous with end of buffer position
|
|
|
var config=this.config;var start=fragments[0].start;var frag;if(levelDetails.live){var initialLiveManifestSize=config.initialLiveManifestSize;if(fragLen<initialLiveManifestSize){this.warn("Not enough fragments to start playback (have: "+fragLen+", need: "+initialLiveManifestSize+")");return null;}// The real fragment start times for a live stream are only known after the PTS range for that level is known.
|
|
|
// In order to discover the range, we load the best matching fragment for that level and demux it.
|
|
|
// Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that
|
|
|
// we get the fragment matching that start time
|
|
|
if(!levelDetails.PTSKnown&&!this.startFragRequested&&this.startPosition===-1){frag=this.getInitialLiveFragment(levelDetails,fragments);this.startPosition=frag?this.hls.liveSyncPosition||frag.start:pos;}}else if(pos<=start){// VoD playlist: if loadPosition before start of playlist, load first fragment
|
|
|
frag=fragments[0];}// If we haven't run into any special cases already, just load the fragment most closely matching the requested position
|
|
|
if(!frag){var end=config.lowLatencyMode?levelDetails.partEnd:levelDetails.fragmentEnd;frag=this.getFragmentAtPosition(pos,end,levelDetails);}return this.mapToInitFragWhenRequired(frag);};_proto.mapToInitFragWhenRequired=function mapToInitFragWhenRequired(frag){// If an initSegment is present, it must be buffered first
|
|
|
if(frag!==null&&frag!==void 0&&frag.initSegment&&!(frag!==null&&frag!==void 0&&frag.initSegment.data)&&!this.bitrateTest){return frag.initSegment;}return frag;};_proto.getNextPart=function getNextPart(partList,frag,targetBufferTime){var nextPart=-1;var contiguous=false;var independentAttrOmitted=true;for(var i=0,len=partList.length;i<len;i++){var part=partList[i];independentAttrOmitted=independentAttrOmitted&&!part.independent;if(nextPart>-1&&targetBufferTime<part.start){break;}var loaded=part.loaded;if(loaded){nextPart=-1;}else if((contiguous||part.independent||independentAttrOmitted)&&part.fragment===frag){nextPart=i;}contiguous=loaded;}return nextPart;};_proto.loadedEndOfParts=function loadedEndOfParts(partList,targetBufferTime){var lastPart=partList[partList.length-1];return lastPart&&targetBufferTime>lastPart.start&&lastPart.loaded;}/*
|
|
|
This method is used find the best matching first fragment for a live playlist. This fragment is used to calculate the
|
|
|
"sliding" of the playlist, which is its offset from the start of playback. After sliding we can compute the real
|
|
|
start and end times for each fragment in the playlist (after which this method will not need to be called).
|
|
|
*/;_proto.getInitialLiveFragment=function getInitialLiveFragment(levelDetails,fragments){var fragPrevious=this.fragPrevious;var frag=null;if(fragPrevious){if(levelDetails.hasProgramDateTime){// Prefer using PDT, because it can be accurate enough to choose the correct fragment without knowing the level sliding
|
|
|
this.log("Live playlist, switching playlist, load frag with same PDT: "+fragPrevious.programDateTime);frag=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragmentByPDT)(fragments,fragPrevious.endProgramDateTime,this.config.maxFragLookUpTolerance);}if(!frag){// SN does not need to be accurate between renditions, but depending on the packaging it may be so.
|
|
|
var targetSN=fragPrevious.sn+1;if(targetSN>=levelDetails.startSN&&targetSN<=levelDetails.endSN){var fragNext=fragments[targetSN-levelDetails.startSN];// Ensure that we're staying within the continuity range, since PTS resets upon a new range
|
|
|
if(fragPrevious.cc===fragNext.cc){frag=fragNext;this.log("Live playlist, switching playlist, load frag with next SN: "+frag.sn);}}// It's important to stay within the continuity range if available; otherwise the fragments in the playlist
|
|
|
// will have the wrong start times
|
|
|
if(!frag){frag=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragWithCC)(fragments,fragPrevious.cc);if(frag){this.log("Live playlist, switching playlist, load frag with same CC: "+frag.sn);}}}}else{// Find a new start fragment when fragPrevious is null
|
|
|
var liveStart=this.hls.liveSyncPosition;if(liveStart!==null){frag=this.getFragmentAtPosition(liveStart,this.bitrateTest?levelDetails.fragmentEnd:levelDetails.edge,levelDetails);}}return frag;}/*
|
|
|
This method finds the best matching fragment given the provided position.
|
|
|
*/;_proto.getFragmentAtPosition=function getFragmentAtPosition(bufferEnd,end,levelDetails){var config=this.config;var fragPrevious=this.fragPrevious;var fragments=levelDetails.fragments,endSN=levelDetails.endSN;var fragmentHint=levelDetails.fragmentHint;var tolerance=config.maxFragLookUpTolerance;var loadingParts=!!(config.lowLatencyMode&&levelDetails.partList&&fragmentHint);if(loadingParts&&fragmentHint&&!this.bitrateTest){// Include incomplete fragment with parts at end
|
|
|
fragments=fragments.concat(fragmentHint);endSN=fragmentHint.sn;}var frag;if(bufferEnd<end){var lookupTolerance=bufferEnd>end-tolerance?0:tolerance;// Remove the tolerance if it would put the bufferEnd past the actual end of stream
|
|
|
// Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
|
|
|
frag=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragmentByPTS)(fragPrevious,fragments,bufferEnd,lookupTolerance);}else{// reach end of playlist
|
|
|
frag=fragments[fragments.length-1];}if(frag){var curSNIdx=frag.sn-levelDetails.startSN;// Move fragPrevious forward to support forcing the next fragment to load
|
|
|
// when the buffer catches up to a previously buffered range.
|
|
|
if(this.fragmentTracker.getState(frag)===_fragment_tracker__WEBPACK_IMPORTED_MODULE_2__.FragmentState.OK){fragPrevious=frag;}if(fragPrevious&&frag.sn===fragPrevious.sn&&!loadingParts){// Force the next fragment to load if the previous one was already selected. This can occasionally happen with
|
|
|
// non-uniform fragment durations
|
|
|
var sameLevel=fragPrevious&&frag.level===fragPrevious.level;if(sameLevel){var nextFrag=fragments[curSNIdx+1];if(frag.sn<endSN&&this.fragmentTracker.getState(nextFrag)!==_fragment_tracker__WEBPACK_IMPORTED_MODULE_2__.FragmentState.OK){this.log("SN "+frag.sn+" just loaded, load next one: "+nextFrag.sn);frag=nextFrag;}else{frag=null;}}}}return frag;};_proto.synchronizeToLiveEdge=function synchronizeToLiveEdge(levelDetails){var config=this.config,media=this.media;if(!media){return;}var liveSyncPosition=this.hls.liveSyncPosition;var currentTime=media.currentTime;var start=levelDetails.fragments[0].start;var end=levelDetails.edge;var withinSlidingWindow=currentTime>=start-config.maxFragLookUpTolerance&¤tTime<=end;// Continue if we can seek forward to sync position or if current time is outside of sliding window
|
|
|
if(liveSyncPosition!==null&&media.duration>liveSyncPosition&&(currentTime<liveSyncPosition||!withinSlidingWindow)){// Continue if buffer is starving or if current time is behind max latency
|
|
|
var maxLatency=config.liveMaxLatencyDuration!==undefined?config.liveMaxLatencyDuration:config.liveMaxLatencyDurationCount*levelDetails.targetduration;if(!withinSlidingWindow&&media.readyState<4||currentTime<end-maxLatency){if(!this.loadedmetadata){this.nextLoadPosition=liveSyncPosition;}// Only seek if ready and there is not a significant forward buffer available for playback
|
|
|
if(media.readyState){this.warn("Playback: "+currentTime.toFixed(3)+" is located too far from the end of live sliding playlist: "+end+", reset currentTime to : "+liveSyncPosition.toFixed(3));media.currentTime=liveSyncPosition;}}}};_proto.alignPlaylists=function alignPlaylists(details,previousDetails){var levels=this.levels,levelLastLoaded=this.levelLastLoaded,fragPrevious=this.fragPrevious;var lastLevel=levelLastLoaded!==null?levels[levelLastLoaded]:null;// FIXME: If not for `shouldAlignOnDiscontinuities` requiring fragPrevious.cc,
|
|
|
// this could all go in level-helper mergeDetails()
|
|
|
var length=details.fragments.length;if(!length){this.warn("No fragments in live playlist");return 0;}var slidingStart=details.fragments[0].start;var firstLevelLoad=!previousDetails;var aligned=details.alignedSliding&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(slidingStart);if(firstLevelLoad||!aligned&&!slidingStart){(0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__.alignStream)(fragPrevious,lastLevel,details);var alignedSlidingStart=details.fragments[0].start;this.log("Live playlist sliding: "+alignedSlidingStart.toFixed(2)+" start-sn: "+(previousDetails?previousDetails.startSN:'na')+"->"+details.startSN+" prev-sn: "+(fragPrevious?fragPrevious.sn:'na')+" fragments: "+length);return alignedSlidingStart;}return slidingStart;};_proto.waitForCdnTuneIn=function waitForCdnTuneIn(details){// Wait for Low-Latency CDN Tune-in to get an updated playlist
|
|
|
var advancePartLimit=3;return details.live&&details.canBlockReload&&details.partTarget&&details.tuneInGoal>Math.max(details.partHoldBack,details.partTarget*advancePartLimit);};_proto.setStartPosition=function setStartPosition(details,sliding){// compute start position if set to -1. use it straight away if value is defined
|
|
|
var startPosition=this.startPosition;if(startPosition<sliding){startPosition=-1;}if(startPosition===-1||this.lastCurrentTime===-1){// first, check if start time offset has been set in playlist, if yes, use this value
|
|
|
var startTimeOffset=details.startTimeOffset;if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(startTimeOffset)){startPosition=sliding+startTimeOffset;if(startTimeOffset<0){startPosition+=details.totalduration;}startPosition=Math.min(Math.max(sliding,startPosition),sliding+details.totalduration);this.log("Start time offset "+startTimeOffset+" found in playlist, adjust startPosition to "+startPosition);this.startPosition=startPosition;}else if(details.live){// Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has
|
|
|
// not been specified via the config or an as an argument to startLoad (#3736).
|
|
|
startPosition=this.hls.liveSyncPosition||sliding;}else{this.startPosition=startPosition=0;}this.lastCurrentTime=startPosition;}this.nextLoadPosition=startPosition;};_proto.getLoadPosition=function getLoadPosition(){var media=this.media;// if we have not yet loaded any fragment, start loading from start position
|
|
|
var pos=0;if(this.loadedmetadata&&media){pos=media.currentTime;}else if(this.nextLoadPosition){pos=this.nextLoadPosition;}return pos;};_proto.handleFragLoadAborted=function handleFragLoadAborted(frag,part){if(this.transmuxer&&frag.sn!=='initSegment'&&frag.stats.aborted){this.warn("Fragment "+frag.sn+(part?' part'+part.index:'')+" of level "+frag.level+" was aborted");this.resetFragmentLoading(frag);}};_proto.resetFragmentLoading=function resetFragmentLoading(frag){if(!this.fragCurrent||!this.fragContextChanged(frag)&&this.state!==_State.FRAG_LOADING_WAITING_RETRY){this.state=_State.IDLE;}};_proto.onFragmentOrKeyLoadError=function onFragmentOrKeyLoadError(filterType,data){if(data.fatal){this.stopLoad();this.state=_State.ERROR;return;}var config=this.config;if(data.chunkMeta){// Parsing Error: no retries
|
|
|
var context=this.getCurrentContext(data.chunkMeta);if(context){data.frag=context.frag;data.levelRetry=true;this.fragLoadError=config.fragLoadingMaxRetry;}}var frag=data.frag;// Handle frag error related to caller's filterType
|
|
|
if(!frag||frag.type!==filterType){return;}var fragCurrent=this.fragCurrent;console.assert(fragCurrent&&frag.sn===fragCurrent.sn&&frag.level===fragCurrent.level&&frag.urlId===fragCurrent.urlId,'Frag load error must match current frag to retry');// keep retrying until the limit will be reached
|
|
|
if(this.fragLoadError+1<=config.fragLoadingMaxRetry){if(!this.loadedmetadata){this.startFragRequested=false;this.nextLoadPosition=this.startPosition;}// exponential backoff capped to config.fragLoadingMaxRetryTimeout
|
|
|
var delay=Math.min(Math.pow(2,this.fragLoadError)*config.fragLoadingRetryDelay,config.fragLoadingMaxRetryTimeout);this.warn("Fragment "+frag.sn+" of "+filterType+" "+frag.level+" failed to load, retrying in "+delay+"ms");this.retryDate=self.performance.now()+delay;this.fragLoadError++;this.state=_State.FRAG_LOADING_WAITING_RETRY;}else if(data.levelRetry){if(filterType===_types_loader__WEBPACK_IMPORTED_MODULE_15__.PlaylistLevelType.AUDIO){// Reset current fragment since audio track audio is essential and may not have a fail-over track
|
|
|
this.fragCurrent=null;}// Fragment errors that result in a level switch or redundant fail-over
|
|
|
// should reset the stream controller state to idle
|
|
|
this.fragLoadError=0;this.state=_State.IDLE;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.error(data.details+" reaches max retry, redispatch as fatal ...");// switch error to fatal
|
|
|
data.fatal=true;this.hls.stopLoad();this.state=_State.ERROR;}};_proto.afterBufferFlushed=function afterBufferFlushed(media,bufferType,playlistType){if(!media){return;}// After successful buffer flushing, filter flushed fragments from bufferedFrags use mediaBuffered instead of media
|
|
|
// (so that we will check against video.buffered ranges in case of alt audio track)
|
|
|
var bufferedTimeRanges=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.getBuffered(media);this.fragmentTracker.detectEvictedFragments(bufferType,bufferedTimeRanges,playlistType);if(this.state===_State.ENDED){this.resetLoadingState();}};_proto.resetLoadingState=function resetLoadingState(){this.log('Reset loading state');this.fragCurrent=null;this.fragPrevious=null;this.state=_State.IDLE;};_proto.resetStartWhenNotLoaded=function resetStartWhenNotLoaded(level){// if loadedmetadata is not set, it means that first frag request failed
|
|
|
// in that case, reset startFragRequested flag
|
|
|
if(!this.loadedmetadata){this.startFragRequested=false;var details=this.levels?this.levels[level].details:null;if(details!==null&&details!==void 0&&details.live){// Update the start position and return to IDLE to recover live start
|
|
|
this.startPosition=-1;this.setStartPosition(details,0);this.resetLoadingState();}else{this.nextLoadPosition=this.startPosition;}}};_proto.updateLevelTiming=function updateLevelTiming(frag,part,level,partial){var _this6=this;var details=level.details;console.assert(!!details,'level.details must be defined');var parsed=Object.keys(frag.elementaryStreams).reduce(function(result,type){var info=frag.elementaryStreams[type];if(info){var parsedDuration=info.endPTS-info.startPTS;if(parsedDuration<=0){// Destroy the transmuxer after it's next time offset failed to advance because duration was <= 0.
|
|
|
// The new transmuxer will be configured with a time offset matching the next fragment start,
|
|
|
// preventing the timeline from shifting.
|
|
|
_this6.warn("Could not parse fragment "+frag.sn+" "+type+" duration reliably ("+parsedDuration+")");return result||false;}var drift=partial?0:(0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.updateFragPTSDTS)(details,frag,info.startPTS,info.endPTS,info.startDTS,info.endDTS);_this6.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_PTS_UPDATED,{details:details,level:level,drift:drift,type:type,frag:frag,start:info.startPTS,end:info.endPTS});return true;}return result;},false);if(!parsed){this.warn("Found no media in fragment "+frag.sn+" of level "+level.id+" resetting transmuxer to fallback to playlist timing");this.resetTransmuxer();}this.state=_State.PARSED;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_PARSED,{frag:frag,part:part});};_proto.resetTransmuxer=function resetTransmuxer(){if(this.transmuxer){this.transmuxer.destroy();this.transmuxer=null;}};_createClass(BaseStreamController,[{key:"state",get:function get(){return this._state;},set:function set(nextState){var previousState=this._state;if(previousState!==nextState){this._state=nextState;this.log(previousState+"->"+nextState);}}}]);return BaseStreamController;}(_task_loop__WEBPACK_IMPORTED_MODULE_1__["default"]);/***/},/***/"./src/controller/buffer-controller.ts":/*!*********************************************!*\
|
|
|
!*** ./src/controller/buffer-controller.ts ***!
|
|
|
\*********************************************/ /***/function srcControllerBufferControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_125714__){"use strict";__nested_webpack_require_125714__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_125714__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */BufferController);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_125714__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_125714__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_125714__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_125714__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_125714__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_125714__(/*! ../utils/mediasource-helper */"./src/utils/mediasource-helper.ts");/* harmony import */var _loader_fragment__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_125714__(/*! ../loader/fragment */"./src/loader/fragment.ts");/* harmony import */var _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_125714__(/*! ./buffer-operation-queue */"./src/controller/buffer-operation-queue.ts");var MediaSource=(0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__.getMediaSource)();var VIDEO_CODEC_PROFILE_REPACE=/([ha]vc.)(?:\.[^.,]+)+/;var BufferController=/*#__PURE__*/function(){// The level details used to determine duration, target-duration and live
|
|
|
// cache the self generated object url to detect hijack of video tag
|
|
|
// A queue of buffer operations which require the SourceBuffer to not be updating upon execution
|
|
|
// References to event listeners for each SourceBuffer, so that they can be referenced for event removal
|
|
|
// The number of BUFFER_CODEC events received before any sourceBuffers are created
|
|
|
// The total number of BUFFER_CODEC events received
|
|
|
// A reference to the attached media element
|
|
|
// A reference to the active media source
|
|
|
// Last MP3 audio chunk appended
|
|
|
// counters
|
|
|
function BufferController(hls){var _this=this;this.details=null;this._objectUrl=null;this.operationQueue=void 0;this.listeners=void 0;this.hls=void 0;this.bufferCodecEventsExpected=0;this._bufferCodecEventsTotal=0;this.media=null;this.mediaSource=null;this.lastMpegAudioChunk=null;this.appendError=0;this.tracks={};this.pendingTracks={};this.sourceBuffer=void 0;this._onMediaSourceOpen=function(){var media=_this.media,mediaSource=_this.mediaSource;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source opened');if(media){media.removeEventListener('emptied',_this._onMediaEmptied);_this.updateMediaElementDuration();_this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED,{media:media});}if(mediaSource){// once received, don't listen anymore to sourceopen event
|
|
|
mediaSource.removeEventListener('sourceopen',_this._onMediaSourceOpen);}_this.checkPendingTracks();};this._onMediaSourceClose=function(){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source closed');};this._onMediaSourceEnded=function(){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source ended');};this._onMediaEmptied=function(){var media=_this.media,_objectUrl=_this._objectUrl;if(media&&media.src!==_objectUrl){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("Media element src was set while attaching MediaSource ("+_objectUrl+" > "+media.src+")");}};this.hls=hls;this._initSourceBuffer();this.registerListeners();}var _proto=BufferController.prototype;_proto.hasSourceTypes=function hasSourceTypes(){return this.getSourceBufferTypes().length>0||Object.keys(this.pendingTracks).length>0;};_proto.destroy=function destroy(){this.unregisterListeners();this.details=null;this.lastMpegAudioChunk=null;};_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_RESET,this.onBufferReset,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDING,this.onBufferAppending,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CODECS,this.onBufferCodecs,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_EOS,this.onBufferEos,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSED,this.onFragParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_CHANGED,this.onFragChanged,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_RESET,this.onBufferReset,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDING,this.onBufferAppending,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CODECS,this.onBufferCodecs,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_EOS,this.onBufferEos,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSED,this.onFragParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_CHANGED,this.onFragChanged,this);};_proto._initSourceBuffer=function _initSourceBuffer(){this.sourceBuffer={};this.operationQueue=new _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__["default"](this.sourceBuffer);this.listeners={audio:[],video:[],audiovideo:[]};this.lastMpegAudioChunk=null;};_proto.onManifestParsed=function onManifestParsed(event,data){// in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller
|
|
|
// sourcebuffers will be created all at once when the expected nb of tracks will be reached
|
|
|
// in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller
|
|
|
// it will contain the expected nb of source buffers, no need to compute it
|
|
|
var codecEvents=2;if(data.audio&&!data.video||!data.altAudio){codecEvents=1;}this.bufferCodecEventsExpected=this._bufferCodecEventsTotal=codecEvents;this.details=null;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log(this.bufferCodecEventsExpected+" bufferCodec event(s) expected");};_proto.onMediaAttaching=function onMediaAttaching(event,data){var media=this.media=data.media;if(media&&MediaSource){var ms=this.mediaSource=new MediaSource();// MediaSource listeners are arrow functions with a lexical scope, and do not need to be bound
|
|
|
ms.addEventListener('sourceopen',this._onMediaSourceOpen);ms.addEventListener('sourceended',this._onMediaSourceEnded);ms.addEventListener('sourceclose',this._onMediaSourceClose);// link video and media Source
|
|
|
media.src=self.URL.createObjectURL(ms);// cache the locally generated object url
|
|
|
this._objectUrl=media.src;media.addEventListener('emptied',this._onMediaEmptied);}};_proto.onMediaDetaching=function onMediaDetaching(){var media=this.media,mediaSource=this.mediaSource,_objectUrl=this._objectUrl;if(mediaSource){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: media source detaching');if(mediaSource.readyState==='open'){try{// endOfStream could trigger exception if any sourcebuffer is in updating state
|
|
|
// we don't really care about checking sourcebuffer state here,
|
|
|
// as we are anyway detaching the MediaSource
|
|
|
// let's just avoid this exception to propagate
|
|
|
mediaSource.endOfStream();}catch(err){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: onMediaDetaching: "+err.message+" while calling endOfStream");}}// Clean up the SourceBuffers by invoking onBufferReset
|
|
|
this.onBufferReset();mediaSource.removeEventListener('sourceopen',this._onMediaSourceOpen);mediaSource.removeEventListener('sourceended',this._onMediaSourceEnded);mediaSource.removeEventListener('sourceclose',this._onMediaSourceClose);// Detach properly the MediaSource from the HTMLMediaElement as
|
|
|
// suggested in https://github.com/w3c/media-source/issues/53.
|
|
|
if(media){media.removeEventListener('emptied',this._onMediaEmptied);if(_objectUrl){self.URL.revokeObjectURL(_objectUrl);}// clean up video tag src only if it's our own url. some external libraries might
|
|
|
// hijack the video tag and change its 'src' without destroying the Hls instance first
|
|
|
if(media.src===_objectUrl){media.removeAttribute('src');media.load();}else{_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn('[buffer-controller]: media.src was changed by a third party - skip cleanup');}}this.mediaSource=null;this.media=null;this._objectUrl=null;this.bufferCodecEventsExpected=this._bufferCodecEventsTotal;this.pendingTracks={};this.tracks={};}this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHED,undefined);};_proto.onBufferReset=function onBufferReset(){var _this2=this;this.getSourceBufferTypes().forEach(function(type){var sb=_this2.sourceBuffer[type];try{if(sb){_this2.removeBufferListeners(type);if(_this2.mediaSource){_this2.mediaSource.removeSourceBuffer(sb);}// Synchronously remove the SB from the map before the next call in order to prevent an async function from
|
|
|
// accessing it
|
|
|
_this2.sourceBuffer[type]=undefined;}}catch(err){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to reset the "+type+" buffer",err);}});this._initSourceBuffer();};_proto.onBufferCodecs=function onBufferCodecs(event,data){var _this3=this;var sourceBufferCount=this.getSourceBufferTypes().length;Object.keys(data).forEach(function(trackName){if(sourceBufferCount){// check if SourceBuffer codec needs to change
|
|
|
var track=_this3.tracks[trackName];if(track&&typeof track.buffer.changeType==='function'){var _data$trackName=data[trackName],id=_data$trackName.id,codec=_data$trackName.codec,levelCodec=_data$trackName.levelCodec,container=_data$trackName.container,metadata=_data$trackName.metadata;var currentCodec=(track.levelCodec||track.codec).replace(VIDEO_CODEC_PROFILE_REPACE,'$1');var nextCodec=(levelCodec||codec).replace(VIDEO_CODEC_PROFILE_REPACE,'$1');if(currentCodec!==nextCodec){var mimeType=container+";codecs="+(levelCodec||codec);_this3.appendChangeType(trackName,mimeType);_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: switching codec "+currentCodec+" to "+nextCodec);_this3.tracks[trackName]={buffer:track.buffer,codec:codec,container:container,levelCodec:levelCodec,metadata:metadata,id:id};}}}else{// if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks
|
|
|
_this3.pendingTracks[trackName]=data[trackName];}});// if sourcebuffers already created, do nothing ...
|
|
|
if(sourceBufferCount){return;}this.bufferCodecEventsExpected=Math.max(this.bufferCodecEventsExpected-1,0);if(this.mediaSource&&this.mediaSource.readyState==='open'){this.checkPendingTracks();}};_proto.appendChangeType=function appendChangeType(type,mimeType){var _this4=this;var operationQueue=this.operationQueue;var operation={execute:function execute(){var sb=_this4.sourceBuffer[type];if(sb){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: changing "+type+" sourceBuffer type to "+mimeType);sb.changeType(mimeType);}operationQueue.shiftAndExecuteNext(type);},onStart:function onStart(){},onComplete:function onComplete(){},onError:function onError(e){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to change "+type+" SourceBuffer type",e);}};operationQueue.append(operation,type);};_proto.onBufferAppending=function onBufferAppending(event,eventData){var _this5=this;var hls=this.hls,operationQueue=this.operationQueue,tracks=this.tracks;var data=eventData.data,type=eventData.type,frag=eventData.frag,part=eventData.part,chunkMeta=eventData.chunkMeta;var chunkStats=chunkMeta.buffering[type];var bufferAppendingStart=self.performance.now();chunkStats.start=bufferAppendingStart;var fragBuffering=frag.stats.buffering;var partBuffering=part?part.stats.buffering:null;if(fragBuffering.start===0){fragBuffering.start=bufferAppendingStart;}if(partBuffering&&partBuffering.start===0){partBuffering.start=bufferAppendingStart;}// TODO: Only update timestampOffset when audio/mpeg fragment or part is not contiguous with previously appended
|
|
|
// Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended)
|
|
|
// in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset`
|
|
|
// is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos).
|
|
|
// More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486
|
|
|
var audioTrack=tracks.audio;var checkTimestampOffset=false;if(type==='audio'&&(audioTrack===null||audioTrack===void 0?void 0:audioTrack.container)==='audio/mpeg'){checkTimestampOffset=!this.lastMpegAudioChunk||chunkMeta.id===1||this.lastMpegAudioChunk.sn!==chunkMeta.sn;this.lastMpegAudioChunk=chunkMeta;}var fragStart=frag.start;var operation={execute:function execute(){chunkStats.executeStart=self.performance.now();if(checkTimestampOffset){var sb=_this5.sourceBuffer[type];if(sb){var delta=fragStart-sb.timestampOffset;if(Math.abs(delta)>=0.1){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Updating audio SourceBuffer timestampOffset to "+fragStart+" (delta: "+delta+") sn: "+frag.sn+")");sb.timestampOffset=fragStart;}}}_this5.appendExecutor(data,type);},onStart:function onStart(){// logger.debug(`[buffer-controller]: ${type} SourceBuffer updatestart`);
|
|
|
},onComplete:function onComplete(){// logger.debug(`[buffer-controller]: ${type} SourceBuffer updateend`);
|
|
|
var end=self.performance.now();chunkStats.executeEnd=chunkStats.end=end;if(fragBuffering.first===0){fragBuffering.first=end;}if(partBuffering&&partBuffering.first===0){partBuffering.first=end;}var sourceBuffer=_this5.sourceBuffer;var timeRanges={};for(var _type in sourceBuffer){timeRanges[_type]=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(sourceBuffer[_type]);}_this5.appendError=0;_this5.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDED,{type:type,frag:frag,part:part,chunkMeta:chunkMeta,parent:frag.type,timeRanges:timeRanges});},onError:function onError(err){// in case any error occured while appending, put back segment in segments table
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: Error encountered while trying to append to the "+type+" SourceBuffer",err);var event={type:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,parent:frag.type,details:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPEND_ERROR,err:err,fatal:false};if(err.code===DOMException.QUOTA_EXCEEDED_ERR){// QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
|
|
|
// let's stop appending any segments, and report BUFFER_FULL_ERROR error
|
|
|
event.details=_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_FULL_ERROR;}else{_this5.appendError++;event.details=_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPEND_ERROR;/* with UHD content, we could get loop of quota exceeded error until
|
|
|
browser is able to evict some data from sourcebuffer. Retrying can help recover.
|
|
|
*/if(_this5.appendError>hls.config.appendErrorMaxRetry){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: Failed "+hls.config.appendErrorMaxRetry+" times to append segment in sourceBuffer");event.fatal=true;hls.stopLoad();}}hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,event);}};operationQueue.append(operation,type);};_proto.onBufferFlushing=function onBufferFlushing(event,data){var _this6=this;var operationQueue=this.operationQueue;var flushOperation=function flushOperation(type){return{execute:_this6.removeExecutor.bind(_this6,type,data.startOffset,data.endOffset),onStart:function onStart(){// logger.debug(`[buffer-controller]: Started flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`);
|
|
|
},onComplete:function onComplete(){// logger.debug(`[buffer-controller]: Finished flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`);
|
|
|
_this6.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHED,{type:type});},onError:function onError(e){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to remove from "+type+" SourceBuffer",e);}};};if(data.type){operationQueue.append(flushOperation(data.type),data.type);}else{this.getSourceBufferTypes().forEach(function(type){operationQueue.append(flushOperation(type),type);});}};_proto.onFragParsed=function onFragParsed(event,data){var _this7=this;var frag=data.frag,part=data.part;var buffersAppendedTo=[];var elementaryStreams=part?part.elementaryStreams:frag.elementaryStreams;if(elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.AUDIOVIDEO]){buffersAppendedTo.push('audiovideo');}else{if(elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.AUDIO]){buffersAppendedTo.push('audio');}if(elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.VIDEO]){buffersAppendedTo.push('video');}}var onUnblocked=function onUnblocked(){var now=self.performance.now();frag.stats.buffering.end=now;if(part){part.stats.buffering.end=now;}var stats=part?part.stats:frag.stats;_this7.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_BUFFERED,{frag:frag,part:part,stats:stats,id:frag.type});};if(buffersAppendedTo.length===0){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("Fragments must have at least one ElementaryStreamType set. type: "+frag.type+" level: "+frag.level+" sn: "+frag.sn);}this.blockBuffers(onUnblocked,buffersAppendedTo);};_proto.onFragChanged=function onFragChanged(event,data){this.flushBackBuffer();}// on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos()
|
|
|
// an undefined data.type will mark all buffers as EOS.
|
|
|
;_proto.onBufferEos=function onBufferEos(event,data){var _this8=this;var ended=this.getSourceBufferTypes().reduce(function(acc,type){var sb=_this8.sourceBuffer[type];if(sb&&(!data.type||data.type===type)){sb.ending=true;if(!sb.ended){sb.ended=true;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: "+type+" sourceBuffer now EOS");}}return acc&&!!(!sb||sb.ended);},true);if(ended){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Queueing mediaSource.endOfStream()");this.blockBuffers(function(){_this8.getSourceBufferTypes().forEach(function(type){var sb=_this8.sourceBuffer[type];if(sb){sb.ending=false;}});var mediaSource=_this8.mediaSource;if(!mediaSource||mediaSource.readyState!=='open'){if(mediaSource){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.info("[buffer-controller]: Could not call mediaSource.endOfStream(). mediaSource.readyState: "+mediaSource.readyState);}return;}_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Calling mediaSource.endOfStream()");// Allow this to throw and be caught by the enqueueing function
|
|
|
mediaSource.endOfStream();});}};_proto.onLevelUpdated=function onLevelUpdated(event,_ref){var details=_ref.details;if(!details.fragments.length){return;}this.details=details;if(this.getSourceBufferTypes().length){this.blockBuffers(this.updateMediaElementDuration.bind(this));}else{this.updateMediaElementDuration();}};_proto.flushBackBuffer=function flushBackBuffer(){var hls=this.hls,details=this.details,media=this.media,sourceBuffer=this.sourceBuffer;if(!media||details===null){return;}var sourceBufferTypes=this.getSourceBufferTypes();if(!sourceBufferTypes.length){return;}// Support for deprecated liveBackBufferLength
|
|
|
var backBufferLength=details.live&&hls.config.liveBackBufferLength!==null?hls.config.liveBackBufferLength:hls.config.backBufferLength;if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(backBufferLength)||backBufferLength<0){return;}var currentTime=media.currentTime;var targetDuration=details.levelTargetDuration;var maxBackBufferLength=Math.max(backBufferLength,targetDuration);var targetBackBufferPosition=Math.floor(currentTime/targetDuration)*targetDuration-maxBackBufferLength;sourceBufferTypes.forEach(function(type){var sb=sourceBuffer[type];if(sb){var buffered=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(sb);// when target buffer start exceeds actual buffer start
|
|
|
if(buffered.length>0&&targetBackBufferPosition>buffered.start(0)){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BACK_BUFFER_REACHED,{bufferEnd:targetBackBufferPosition});// Support for deprecated event:
|
|
|
if(details.live){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LIVE_BACK_BUFFER_REACHED,{bufferEnd:targetBackBufferPosition});}else if(sb.ended&&buffered.end(buffered.length-1)-currentTime<targetDuration*2){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.info("[buffer-controller]: Cannot flush "+type+" back buffer while SourceBuffer is in ended state");return;}hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,{startOffset:0,endOffset:targetBackBufferPosition,type:type});}}});}/**
|
|
|
* Update Media Source duration to current level duration or override to Infinity if configuration parameter
|
|
|
* 'liveDurationInfinity` is set to `true`
|
|
|
* More details: https://github.com/video-dev/hls.js/issues/355
|
|
|
*/;_proto.updateMediaElementDuration=function updateMediaElementDuration(){if(!this.details||!this.media||!this.mediaSource||this.mediaSource.readyState!=='open'){return;}var details=this.details,hls=this.hls,media=this.media,mediaSource=this.mediaSource;var levelDuration=details.fragments[0].start+details.totalduration;var mediaDuration=media.duration;var msDuration=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaSource.duration)?mediaSource.duration:0;if(details.live&&hls.config.liveDurationInfinity){// Override duration to Infinity
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media Source duration is set to Infinity');mediaSource.duration=Infinity;this.updateSeekableRange(details);}else if(levelDuration>msDuration&&levelDuration>mediaDuration||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaDuration)){// levelDuration was the last value we set.
|
|
|
// not using mediaSource.duration as the browser may tweak this value
|
|
|
// only update Media Source duration if its value increase, this is to avoid
|
|
|
// flushing already buffered portion when switching between quality level
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Updating Media Source duration to "+levelDuration.toFixed(3));mediaSource.duration=levelDuration;}};_proto.updateSeekableRange=function updateSeekableRange(levelDetails){var mediaSource=this.mediaSource;var fragments=levelDetails.fragments;var len=fragments.length;if(len&&levelDetails.live&&mediaSource!==null&&mediaSource!==void 0&&mediaSource.setLiveSeekableRange){var start=Math.max(0,fragments[0].start);var end=Math.max(start,start+levelDetails.totalduration);mediaSource.setLiveSeekableRange(start,end);}};_proto.checkPendingTracks=function checkPendingTracks(){var bufferCodecEventsExpected=this.bufferCodecEventsExpected,operationQueue=this.operationQueue,pendingTracks=this.pendingTracks;// Check if we've received all of the expected bufferCodec events. When none remain, create all the sourceBuffers at once.
|
|
|
// This is important because the MSE spec allows implementations to throw QuotaExceededErrors if creating new sourceBuffers after
|
|
|
// data has been appended to existing ones.
|
|
|
// 2 tracks is the max (one for audio, one for video). If we've reach this max go ahead and create the buffers.
|
|
|
var pendingTracksCount=Object.keys(pendingTracks).length;if(pendingTracksCount&&!bufferCodecEventsExpected||pendingTracksCount===2){// ok, let's create them now !
|
|
|
this.createSourceBuffers(pendingTracks);this.pendingTracks={};// append any pending segments now !
|
|
|
var buffers=this.getSourceBufferTypes();if(buffers.length===0){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_INCOMPATIBLE_CODECS_ERROR,fatal:true,reason:'could not create source buffer for media codec(s)'});return;}buffers.forEach(function(type){operationQueue.executeNext(type);});}};_proto.createSourceBuffers=function createSourceBuffers(tracks){var sourceBuffer=this.sourceBuffer,mediaSource=this.mediaSource;if(!mediaSource){throw Error('createSourceBuffers called when mediaSource was null');}var tracksCreated=0;for(var trackName in tracks){if(!sourceBuffer[trackName]){var track=tracks[trackName];if(!track){throw Error("source buffer exists for track "+trackName+", however track does not");}// use levelCodec as first priority
|
|
|
var codec=track.levelCodec||track.codec;var mimeType=track.container+";codecs="+codec;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: creating sourceBuffer("+mimeType+")");try{var sb=sourceBuffer[trackName]=mediaSource.addSourceBuffer(mimeType);var sbName=trackName;this.addBufferListener(sbName,'updatestart',this._onSBUpdateStart);this.addBufferListener(sbName,'updateend',this._onSBUpdateEnd);this.addBufferListener(sbName,'error',this._onSBUpdateError);this.tracks[trackName]={buffer:sb,codec:codec,container:track.container,levelCodec:track.levelCodec,metadata:track.metadata,id:track.id};tracksCreated++;}catch(err){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: error while trying to add sourceBuffer: "+err.message);this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_ADD_CODEC_ERROR,fatal:false,error:err,mimeType:mimeType});}}}if(tracksCreated){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CREATED,{tracks:this.tracks});}}// Keep as arrow functions so that we can directly reference these functions directly as event listeners
|
|
|
;_proto._onSBUpdateStart=function _onSBUpdateStart(type){var operationQueue=this.operationQueue;var operation=operationQueue.current(type);operation.onStart();};_proto._onSBUpdateEnd=function _onSBUpdateEnd(type){var operationQueue=this.operationQueue;var operation=operationQueue.current(type);operation.onComplete();operationQueue.shiftAndExecuteNext(type);};_proto._onSBUpdateError=function _onSBUpdateError(type,event){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: "+type+" SourceBuffer error",event);// according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error
|
|
|
// SourceBuffer errors are not necessarily fatal; if so, the HTMLMediaElement will fire an error event
|
|
|
this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPENDING_ERROR,fatal:false});// updateend is always fired after error, so we'll allow that to shift the current operation off of the queue
|
|
|
var operation=this.operationQueue.current(type);if(operation){operation.onError(event);}}// This method must result in an updateend event; if remove is not called, _onSBUpdateEnd must be called manually
|
|
|
;_proto.removeExecutor=function removeExecutor(type,startOffset,endOffset){var media=this.media,mediaSource=this.mediaSource,operationQueue=this.operationQueue,sourceBuffer=this.sourceBuffer;var sb=sourceBuffer[type];if(!media||!mediaSource||!sb){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Attempting to remove from the "+type+" SourceBuffer, but it does not exist");operationQueue.shiftAndExecuteNext(type);return;}var mediaDuration=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(media.duration)?media.duration:Infinity;var msDuration=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaSource.duration)?mediaSource.duration:Infinity;var removeStart=Math.max(0,startOffset);var removeEnd=Math.min(endOffset,mediaDuration,msDuration);if(removeEnd>removeStart&&!sb.ending){sb.ended=false;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Removing ["+removeStart+","+removeEnd+"] from the "+type+" SourceBuffer");console.assert(!sb.updating,type+" sourceBuffer must not be updating");sb.remove(removeStart,removeEnd);}else{// Cycle the queue
|
|
|
operationQueue.shiftAndExecuteNext(type);}}// This method must result in an updateend event; if append is not called, _onSBUpdateEnd must be called manually
|
|
|
;_proto.appendExecutor=function appendExecutor(data,type){var operationQueue=this.operationQueue,sourceBuffer=this.sourceBuffer;var sb=sourceBuffer[type];if(!sb){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Attempting to append to the "+type+" SourceBuffer, but it does not exist");operationQueue.shiftAndExecuteNext(type);return;}sb.ended=false;console.assert(!sb.updating,type+" sourceBuffer must not be updating");sb.appendBuffer(data);}// Enqueues an operation to each SourceBuffer queue which, upon execution, resolves a promise. When all promises
|
|
|
// resolve, the onUnblocked function is executed. Functions calling this method do not need to unblock the queue
|
|
|
// upon completion, since we already do it here
|
|
|
;_proto.blockBuffers=function blockBuffers(onUnblocked,buffers){var _this9=this;if(buffers===void 0){buffers=this.getSourceBufferTypes();}if(!buffers.length){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Blocking operation requested, but no SourceBuffers exist');Promise.resolve().then(onUnblocked);return;}var operationQueue=this.operationQueue;// logger.debug(`[buffer-controller]: Blocking ${buffers} SourceBuffer`);
|
|
|
var blockingOperations=buffers.map(function(type){return operationQueue.appendBlocker(type);});Promise.all(blockingOperations).then(function(){// logger.debug(`[buffer-controller]: Blocking operation resolved; unblocking ${buffers} SourceBuffer`);
|
|
|
onUnblocked();buffers.forEach(function(type){var sb=_this9.sourceBuffer[type];// Only cycle the queue if the SB is not updating. There's a bug in Chrome which sets the SB updating flag to
|
|
|
// true when changing the MediaSource duration (https://bugs.chromium.org/p/chromium/issues/detail?id=959359&can=2&q=mediasource%20duration)
|
|
|
// While this is a workaround, it's probably useful to have around
|
|
|
if(!sb||!sb.updating){operationQueue.shiftAndExecuteNext(type);}});});};_proto.getSourceBufferTypes=function getSourceBufferTypes(){return Object.keys(this.sourceBuffer);};_proto.addBufferListener=function addBufferListener(type,event,fn){var buffer=this.sourceBuffer[type];if(!buffer){return;}var listener=fn.bind(this,type);this.listeners[type].push({event:event,listener:listener});buffer.addEventListener(event,listener);};_proto.removeBufferListeners=function removeBufferListeners(type){var buffer=this.sourceBuffer[type];if(!buffer){return;}this.listeners[type].forEach(function(l){buffer.removeEventListener(l.event,l.listener);});};return BufferController;}();/***/},/***/"./src/controller/buffer-operation-queue.ts":/*!**************************************************!*\
|
|
|
!*** ./src/controller/buffer-operation-queue.ts ***!
|
|
|
\**************************************************/ /***/function srcControllerBufferOperationQueueTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_158398__){"use strict";__nested_webpack_require_158398__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_158398__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */BufferOperationQueue);}/* harmony export */});/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_158398__(/*! ../utils/logger */"./src/utils/logger.ts");var BufferOperationQueue=/*#__PURE__*/function(){function BufferOperationQueue(sourceBufferReference){this.buffers=void 0;this.queues={video:[],audio:[],audiovideo:[]};this.buffers=sourceBufferReference;}var _proto=BufferOperationQueue.prototype;_proto.append=function append(operation,type){var queue=this.queues[type];queue.push(operation);if(queue.length===1&&this.buffers[type]){this.executeNext(type);}};_proto.insertAbort=function insertAbort(operation,type){var queue=this.queues[type];queue.unshift(operation);this.executeNext(type);};_proto.appendBlocker=function appendBlocker(type){var execute;var promise=new Promise(function(resolve){execute=resolve;});var operation={execute:execute,onStart:function onStart(){},onComplete:function onComplete(){},onError:function onError(){}};this.append(operation,type);return promise;};_proto.executeNext=function executeNext(type){var buffers=this.buffers,queues=this.queues;var sb=buffers[type];var queue=queues[type];if(queue.length){var operation=queue[0];try{// Operations are expected to result in an 'updateend' event being fired. If not, the queue will lock. Operations
|
|
|
// which do not end with this event must call _onSBUpdateEnd manually
|
|
|
operation.execute();}catch(e){_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn('[buffer-operation-queue]: Unhandled exception executing the current operation');operation.onError(e);// Only shift the current operation off, otherwise the updateend handler will do this for us
|
|
|
if(!sb||!sb.updating){queue.shift();this.executeNext(type);}}}};_proto.shiftAndExecuteNext=function shiftAndExecuteNext(type){this.queues[type].shift();this.executeNext(type);};_proto.current=function current(type){return this.queues[type][0];};return BufferOperationQueue;}();/***/},/***/"./src/controller/cap-level-controller.ts":/*!************************************************!*\
|
|
|
!*** ./src/controller/cap-level-controller.ts ***!
|
|
|
\************************************************/ /***/function srcControllerCapLevelControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_160851__){"use strict";__nested_webpack_require_160851__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_160851__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_160851__(/*! ../events */"./src/events.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}/*
|
|
|
* cap stream level to media size dimension controller
|
|
|
*/var CapLevelController=/*#__PURE__*/function(){function CapLevelController(hls){this.autoLevelCapping=void 0;this.firstLevel=void 0;this.media=void 0;this.restrictedLevels=void 0;this.timer=void 0;this.hls=void 0;this.streamController=void 0;this.clientRect=void 0;this.hls=hls;this.autoLevelCapping=Number.POSITIVE_INFINITY;this.firstLevel=-1;this.media=null;this.restrictedLevels=[];this.timer=undefined;this.clientRect=null;this.registerListeners();}var _proto=CapLevelController.prototype;_proto.setStreamController=function setStreamController(streamController){this.streamController=streamController;};_proto.destroy=function destroy(){this.unregisterListener();if(this.hls.config.capLevelToPlayerSize){this.stopCapping();}this.media=null;this.clientRect=null;// @ts-ignore
|
|
|
this.hls=this.streamController=null;};_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING,this.onFpsDropLevelCapping,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CODECS,this.onBufferCodecs,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);};_proto.unregisterListener=function unregisterListener(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING,this.onFpsDropLevelCapping,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CODECS,this.onBufferCodecs,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);};_proto.onFpsDropLevelCapping=function onFpsDropLevelCapping(event,data){// Don't add a restricted level more than once
|
|
|
if(CapLevelController.isLevelAllowed(data.droppedLevel,this.restrictedLevels)){this.restrictedLevels.push(data.droppedLevel);}};_proto.onMediaAttaching=function onMediaAttaching(event,data){this.media=data.media instanceof HTMLVideoElement?data.media:null;this.clientRect=null;};_proto.onManifestParsed=function onManifestParsed(event,data){var hls=this.hls;this.restrictedLevels=[];this.firstLevel=data.firstLevel;if(hls.config.capLevelToPlayerSize&&data.video){// Start capping immediately if the manifest has signaled video codecs
|
|
|
this.startCapping();}}// Only activate capping when playing a video stream; otherwise, multi-bitrate audio-only streams will be restricted
|
|
|
// to the first level
|
|
|
;_proto.onBufferCodecs=function onBufferCodecs(event,data){var hls=this.hls;if(hls.config.capLevelToPlayerSize&&data.video){// If the manifest did not signal a video codec capping has been deferred until we're certain video is present
|
|
|
this.startCapping();}};_proto.onMediaDetaching=function onMediaDetaching(){this.stopCapping();};_proto.detectPlayerSize=function detectPlayerSize(){if(this.media&&this.mediaHeight>0&&this.mediaWidth>0){var levels=this.hls.levels;if(levels.length){var hls=this.hls;hls.autoLevelCapping=this.getMaxLevel(levels.length-1);if(hls.autoLevelCapping>this.autoLevelCapping&&this.streamController){// if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch
|
|
|
// usually happen when the user go to the fullscreen mode.
|
|
|
this.streamController.nextLevelSwitch();}this.autoLevelCapping=hls.autoLevelCapping;}}}/*
|
|
|
* returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled)
|
|
|
*/;_proto.getMaxLevel=function getMaxLevel(capLevelIndex){var _this=this;var levels=this.hls.levels;if(!levels.length){return-1;}var validLevels=levels.filter(function(level,index){return CapLevelController.isLevelAllowed(index,_this.restrictedLevels)&&index<=capLevelIndex;});this.clientRect=null;return CapLevelController.getMaxLevelByMediaSize(validLevels,this.mediaWidth,this.mediaHeight);};_proto.startCapping=function startCapping(){if(this.timer){// Don't reset capping if started twice; this can happen if the manifest signals a video codec
|
|
|
return;}this.autoLevelCapping=Number.POSITIVE_INFINITY;this.hls.firstLevel=this.getMaxLevel(this.firstLevel);self.clearInterval(this.timer);this.timer=self.setInterval(this.detectPlayerSize.bind(this),1000);this.detectPlayerSize();};_proto.stopCapping=function stopCapping(){this.restrictedLevels=[];this.firstLevel=-1;this.autoLevelCapping=Number.POSITIVE_INFINITY;if(this.timer){self.clearInterval(this.timer);this.timer=undefined;}};_proto.getDimensions=function getDimensions(){if(this.clientRect){return this.clientRect;}var media=this.media;var boundsRect={width:0,height:0};if(media){var clientRect=media.getBoundingClientRect();boundsRect.width=clientRect.width;boundsRect.height=clientRect.height;if(!boundsRect.width&&!boundsRect.height){// When the media element has no width or height (equivalent to not being in the DOM),
|
|
|
// then use its width and height attributes (media.width, media.height)
|
|
|
boundsRect.width=clientRect.right-clientRect.left||media.width||0;boundsRect.height=clientRect.bottom-clientRect.top||media.height||0;}}this.clientRect=boundsRect;return boundsRect;};CapLevelController.isLevelAllowed=function isLevelAllowed(level,restrictedLevels){if(restrictedLevels===void 0){restrictedLevels=[];}return restrictedLevels.indexOf(level)===-1;};CapLevelController.getMaxLevelByMediaSize=function getMaxLevelByMediaSize(levels,width,height){if(!levels||!levels.length){return-1;}// Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next
|
|
|
// to determine whether we've chosen the greatest bandwidth for the media's dimensions
|
|
|
var atGreatestBandwidth=function atGreatestBandwidth(curLevel,nextLevel){if(!nextLevel){return true;}return curLevel.width!==nextLevel.width||curLevel.height!==nextLevel.height;};// If we run through the loop without breaking, the media's dimensions are greater than every level, so default to
|
|
|
// the max level
|
|
|
var maxLevelIndex=levels.length-1;for(var i=0;i<levels.length;i+=1){var level=levels[i];if((level.width>=width||level.height>=height)&&atGreatestBandwidth(level,levels[i+1])){maxLevelIndex=i;break;}}return maxLevelIndex;};_createClass(CapLevelController,[{key:"mediaWidth",get:function get(){return this.getDimensions().width*this.contentScaleFactor;}},{key:"mediaHeight",get:function get(){return this.getDimensions().height*this.contentScaleFactor;}},{key:"contentScaleFactor",get:function get(){var pixelRatio=1;if(!this.hls.config.ignoreDevicePixelRatio){try{pixelRatio=self.devicePixelRatio;}catch(e){/* no-op */}}return pixelRatio;}}]);return CapLevelController;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=CapLevelController;/***/},/***/"./src/controller/cmcd-controller.ts":/*!*******************************************!*\
|
|
|
!*** ./src/controller/cmcd-controller.ts ***!
|
|
|
\*******************************************/ /***/function srcControllerCmcdControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_169568__){"use strict";__nested_webpack_require_169568__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_169568__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */CMCDController);}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_169568__(/*! ../events */"./src/events.ts");/* harmony import */var _types_cmcd__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_169568__(/*! ../types/cmcd */"./src/types/cmcd.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_169568__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_169568__(/*! ../utils/logger */"./src/utils/logger.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _createForOfIteratorHelperLoose(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(it)return(it=it.call(o)).next.bind(it);if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;return function(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]};};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen);}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i];}return arr2;}function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}/**
|
|
|
* Controller to deal with Common Media Client Data (CMCD)
|
|
|
* @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf
|
|
|
*/var CMCDController=/*#__PURE__*/function(){// eslint-disable-line no-restricted-globals
|
|
|
// eslint-disable-line no-restricted-globals
|
|
|
function CMCDController(hls){var _this=this;this.hls=void 0;this.config=void 0;this.media=void 0;this.sid=void 0;this.cid=void 0;this.useHeaders=false;this.initialized=false;this.starved=false;this.buffering=true;this.audioBuffer=void 0;this.videoBuffer=void 0;this.onWaiting=function(){if(_this.initialized){_this.starved=true;}_this.buffering=true;};this.onPlaying=function(){if(!_this.initialized){_this.initialized=true;}_this.buffering=false;};this.applyPlaylistData=function(context){try{_this.apply(context,{ot:_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MANIFEST,su:!_this.initialized});}catch(error){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Could not generate manifest CMCD data.',error);}};this.applyFragmentData=function(context){try{var fragment=context.frag;var level=_this.hls.levels[fragment.level];var ot=_this.getObjectType(fragment);var data={d:fragment.duration*1000,ot:ot};if(ot===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO||ot===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO||ot==_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED){data.br=level.bitrate/1000;data.tb=_this.getTopBandwidth(ot)/1000;data.bl=_this.getBufferLength(ot);}_this.apply(context,data);}catch(error){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Could not generate segment CMCD data.',error);}};this.hls=hls;var config=this.config=hls.config;var cmcd=config.cmcd;if(cmcd!=null){config.pLoader=this.createPlaylistLoader();config.fLoader=this.createFragmentLoader();this.sid=cmcd.sessionId||CMCDController.uuid();this.cid=cmcd.contentId;this.useHeaders=cmcd.useHeaders===true;this.registerListeners();}}var _proto=CMCDController.prototype;_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED,this.onMediaDetached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CREATED,this.onBufferCreated,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED,this.onMediaDetached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CREATED,this.onBufferCreated,this);this.onMediaDetached();};_proto.destroy=function destroy(){this.unregisterListeners();// @ts-ignore
|
|
|
this.hls=this.config=this.audioBuffer=this.videoBuffer=null;};_proto.onMediaAttached=function onMediaAttached(event,data){this.media=data.media;this.media.addEventListener('waiting',this.onWaiting);this.media.addEventListener('playing',this.onPlaying);};_proto.onMediaDetached=function onMediaDetached(){if(!this.media){return;}this.media.removeEventListener('waiting',this.onWaiting);this.media.removeEventListener('playing',this.onPlaying);// @ts-ignore
|
|
|
this.media=null;};_proto.onBufferCreated=function onBufferCreated(event,data){var _data$tracks$audio,_data$tracks$video;this.audioBuffer=(_data$tracks$audio=data.tracks.audio)===null||_data$tracks$audio===void 0?void 0:_data$tracks$audio.buffer;this.videoBuffer=(_data$tracks$video=data.tracks.video)===null||_data$tracks$video===void 0?void 0:_data$tracks$video.buffer;};/**
|
|
|
* Create baseline CMCD data
|
|
|
*/_proto.createData=function createData(){var _this$media;return{v:_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDVersion,sf:_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDStreamingFormat.HLS,sid:this.sid,cid:this.cid,pr:(_this$media=this.media)===null||_this$media===void 0?void 0:_this$media.playbackRate,mtp:this.hls.bandwidthEstimate/1000};}/**
|
|
|
* Apply CMCD data to a request.
|
|
|
*/;_proto.apply=function apply(context,data){if(data===void 0){data={};}// apply baseline data
|
|
|
_extends(data,this.createData());var isVideo=data.ot===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.INIT||data.ot===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO||data.ot===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED;if(this.starved&&isVideo){data.bs=true;data.su=true;this.starved=false;}if(data.su==null){data.su=this.buffering;}// TODO: Implement rtp, nrr, nor, dl
|
|
|
if(this.useHeaders){var headers=CMCDController.toHeaders(data);if(!Object.keys(headers).length){return;}if(!context.headers){context.headers={};}_extends(context.headers,headers);}else{var query=CMCDController.toQuery(data);if(!query){return;}context.url=CMCDController.appendQueryToUri(context.url,query);}}/**
|
|
|
* Apply CMCD data to a manifest request.
|
|
|
*/;/**
|
|
|
* The CMCD object type.
|
|
|
*/_proto.getObjectType=function getObjectType(fragment){var type=fragment.type;if(type==='subtitle'){return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.TIMED_TEXT;}if(fragment.sn==='initSegment'){return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.INIT;}if(type==='audio'){return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO;}if(type==='main'){if(!this.hls.audioTracks.length){return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED;}return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO;}return undefined;}/**
|
|
|
* Get the highest bitrate.
|
|
|
*/;_proto.getTopBandwidth=function getTopBandwidth(type){var bitrate=0;var levels;var hls=this.hls;if(type===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO){levels=hls.audioTracks;}else{var max=hls.maxAutoLevel;var len=max>-1?max+1:hls.levels.length;levels=hls.levels.slice(0,len);}for(var _iterator=_createForOfIteratorHelperLoose(levels),_step;!(_step=_iterator()).done;){var level=_step.value;if(level.bitrate>bitrate){bitrate=level.bitrate;}}return bitrate>0?bitrate:NaN;}/**
|
|
|
* Get the buffer length for a media type in milliseconds
|
|
|
*/;_proto.getBufferLength=function getBufferLength(type){var media=this.hls.media;var buffer=type===_types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO?this.audioBuffer:this.videoBuffer;if(!buffer||!media){return NaN;}var info=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__.BufferHelper.bufferInfo(buffer,media.currentTime,this.config.maxBufferHole);return info.len*1000;}/**
|
|
|
* Create a playlist loader
|
|
|
*/;_proto.createPlaylistLoader=function createPlaylistLoader(){var pLoader=this.config.pLoader;var apply=this.applyPlaylistData;var Ctor=pLoader||this.config.loader;return/*#__PURE__*/function(){function CmcdPlaylistLoader(config){this.loader=void 0;this.loader=new Ctor(config);}var _proto2=CmcdPlaylistLoader.prototype;_proto2.destroy=function destroy(){this.loader.destroy();};_proto2.abort=function abort(){this.loader.abort();};_proto2.load=function load(context,config,callbacks){apply(context);this.loader.load(context,config,callbacks);};_createClass(CmcdPlaylistLoader,[{key:"stats",get:function get(){return this.loader.stats;}},{key:"context",get:function get(){return this.loader.context;}}]);return CmcdPlaylistLoader;}();}/**
|
|
|
* Create a playlist loader
|
|
|
*/;_proto.createFragmentLoader=function createFragmentLoader(){var fLoader=this.config.fLoader;var apply=this.applyFragmentData;var Ctor=fLoader||this.config.loader;return/*#__PURE__*/function(){function CmcdFragmentLoader(config){this.loader=void 0;this.loader=new Ctor(config);}var _proto3=CmcdFragmentLoader.prototype;_proto3.destroy=function destroy(){this.loader.destroy();};_proto3.abort=function abort(){this.loader.abort();};_proto3.load=function load(context,config,callbacks){apply(context);this.loader.load(context,config,callbacks);};_createClass(CmcdFragmentLoader,[{key:"stats",get:function get(){return this.loader.stats;}},{key:"context",get:function get(){return this.loader.context;}}]);return CmcdFragmentLoader;}();}/**
|
|
|
* Generate a random v4 UUI
|
|
|
*
|
|
|
* @returns {string}
|
|
|
*/;CMCDController.uuid=function uuid(){var url=URL.createObjectURL(new Blob());var uuid=url.toString();URL.revokeObjectURL(url);return uuid.slice(uuid.lastIndexOf('/')+1);}/**
|
|
|
* Serialize a CMCD data object according to the rules defined in the
|
|
|
* section 3.2 of
|
|
|
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
|
*/;CMCDController.serialize=function serialize(data){var results=[];var isValid=function isValid(value){return!Number.isNaN(value)&&value!=null&&value!==''&&value!==false;};var toRounded=function toRounded(value){return Math.round(value);};var toHundred=function toHundred(value){return toRounded(value/100)*100;};var toUrlSafe=function toUrlSafe(value){return encodeURIComponent(value);};var formatters={br:toRounded,d:toRounded,bl:toHundred,dl:toHundred,mtp:toHundred,nor:toUrlSafe,rtp:toHundred,tb:toRounded};var keys=Object.keys(data||{}).sort();for(var _iterator2=_createForOfIteratorHelperLoose(keys),_step2;!(_step2=_iterator2()).done;){var key=_step2.value;var value=data[key];// ignore invalid values
|
|
|
if(!isValid(value)){continue;}// Version should only be reported if not equal to 1.
|
|
|
if(key==='v'&&value===1){continue;}// Playback rate should only be sent if not equal to 1.
|
|
|
if(key=='pr'&&value===1){continue;}// Certain values require special formatting
|
|
|
var formatter=formatters[key];if(formatter){value=formatter(value);}// Serialize the key/value pair
|
|
|
var type=_typeof(value);var result=void 0;if(key==='ot'||key==='sf'||key==='st'){result=key+"="+value;}else if(type==='boolean'){result=key;}else if(type==='number'){result=key+"="+value;}else{result=key+"="+JSON.stringify(value);}results.push(result);}return results.join(',');}/**
|
|
|
* Convert a CMCD data object to request headers according to the rules
|
|
|
* defined in the section 2.1 and 3.2 of
|
|
|
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
|
*/;CMCDController.toHeaders=function toHeaders(data){var keys=Object.keys(data);var headers={};var headerNames=['Object','Request','Session','Status'];var headerGroups=[{},{},{},{}];var headerMap={br:0,d:0,ot:0,tb:0,bl:1,dl:1,mtp:1,nor:1,nrr:1,su:1,cid:2,pr:2,sf:2,sid:2,st:2,v:2,bs:3,rtp:3};for(var _i=0,_keys=keys;_i<_keys.length;_i++){var key=_keys[_i];// Unmapped fields are mapped to the Request header
|
|
|
var index=headerMap[key]!=null?headerMap[key]:1;headerGroups[index][key]=data[key];}for(var i=0;i<headerGroups.length;i++){var value=CMCDController.serialize(headerGroups[i]);if(value){headers["CMCD-"+headerNames[i]]=value;}}return headers;}/**
|
|
|
* Convert a CMCD data object to query args according to the rules
|
|
|
* defined in the section 2.2 and 3.2 of
|
|
|
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
|
*/;CMCDController.toQuery=function toQuery(data){return"CMCD="+encodeURIComponent(CMCDController.serialize(data));}/**
|
|
|
* Append query args to a uri.
|
|
|
*/;CMCDController.appendQueryToUri=function appendQueryToUri(uri,query){if(!query){return uri;}var separator=uri.includes('?')?'&':'?';return""+uri+separator+query;};return CMCDController;}();/***/},/***/"./src/controller/eme-controller.ts":/*!******************************************!*\
|
|
|
!*** ./src/controller/eme-controller.ts ***!
|
|
|
\******************************************/ /***/function srcControllerEmeControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_184295__){"use strict";__nested_webpack_require_184295__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_184295__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_184295__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_184295__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_184295__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_184295__(/*! ../utils/mediakeys-helper */"./src/utils/mediakeys-helper.ts");/* harmony import */var _utils_keysystem_util__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_184295__(/*! ../utils/keysystem-util */"./src/utils/keysystem-util.ts");/* harmony import */var _utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_184295__(/*! ../utils/numeric-encoding-utils */"./src/utils/numeric-encoding-utils.ts");/* harmony import */var _loader_level_key__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_184295__(/*! ../loader/level-key */"./src/loader/level-key.ts");/* harmony import */var _utils_hex__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_184295__(/*! ../utils/hex */"./src/utils/hex.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_184295__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_184295__(/*! eventemitter3 */"./node_modules/eventemitter3/index.js");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_9___default=/*#__PURE__*/__nested_webpack_require_184295__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_9__);function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map():undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function");}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper);}function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor);}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class);};return _wrapNativeSuper(Class);}function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct.bind();}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor();if(Class)_setPrototypeOf(instance,Class.prototype);return instance;};}return _construct.apply(null,arguments);}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1;}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}/**
|
|
|
* @author Stephan Hesse <disparat@gmail.com> | <tchakabam@gmail.com>
|
|
|
*
|
|
|
* DRM support for Hls.js
|
|
|
*/var MAX_LICENSE_REQUEST_FAILURES=3;var LOGGER_PREFIX='[eme]';/**
|
|
|
* Controller to deal with encrypted media extensions (EME)
|
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API
|
|
|
*
|
|
|
* @class
|
|
|
* @constructor
|
|
|
*/var EMEController=/*#__PURE__*/function(){function EMEController(hls){this.hls=void 0;this.config=void 0;this.media=null;this.keyFormatPromise=null;this.keySystemAccessPromises={};this._requestLicenseFailureCount=0;this.mediaKeySessions=[];this.keyIdToKeySessionPromise={};this.setMediaKeysQueue=EMEController.CDMCleanupPromise?[EMEController.CDMCleanupPromise]:[];this.onMediaEncrypted=this._onMediaEncrypted.bind(this);this.onWaitingForKey=this._onWaitingForKey.bind(this);this.debug=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.debug.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,LOGGER_PREFIX);this.log=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,LOGGER_PREFIX);this.warn=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,LOGGER_PREFIX);this.error=_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger,LOGGER_PREFIX);this.hls=hls;this.config=hls.config;this.registerListeners();}var _proto=EMEController.prototype;_proto.destroy=function destroy(){this.unregisterListeners();this.onMediaDetached();// @ts-ignore
|
|
|
this.hls=this.onMediaEncrypted=this.onWaitingForKey=this.keyIdToKeySessionPromise=null;};_proto.registerListeners=function registerListeners(){this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED,this.onMediaDetached,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);};_proto.unregisterListeners=function unregisterListeners(){this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED,this.onMediaDetached,this);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);};_proto.getLicenseServerUrl=function getLicenseServerUrl(keySystem){var _this$config=this.config,drmSystems=_this$config.drmSystems,widevineLicenseUrl=_this$config.widevineLicenseUrl;var keySystemConfiguration=drmSystems[keySystem];if(keySystemConfiguration){return keySystemConfiguration.licenseUrl;}// For backward compatibility
|
|
|
if(keySystem===_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.WIDEVINE&&widevineLicenseUrl){return widevineLicenseUrl;}throw new Error("no license server URL configured for key-system \""+keySystem+"\"");};_proto.getServerCertificateUrl=function getServerCertificateUrl(keySystem){var drmSystems=this.config.drmSystems;var keySystemConfiguration=drmSystems[keySystem];if(keySystemConfiguration){return keySystemConfiguration.serverCertificateUrl;}else{this.log("No Server Certificate in config.drmSystems[\""+keySystem+"\"]");}};_proto.attemptKeySystemAccess=function attemptKeySystemAccess(keySystemsToAttempt){var _this=this;var levels=this.hls.levels;var uniqueCodec=function uniqueCodec(value,i,a){return!!value&&a.indexOf(value)===i;};var audioCodecs=levels.map(function(level){return level.audioCodec;}).filter(uniqueCodec);var videoCodecs=levels.map(function(level){return level.videoCodec;}).filter(uniqueCodec);if(audioCodecs.length+videoCodecs.length===0){videoCodecs.push('avc1.42e01e');}return new Promise(function(resolve,reject){var attempt=function attempt(keySystems){var keySystem=keySystems.shift();_this.getMediaKeysPromise(keySystem,audioCodecs,videoCodecs).then(function(mediaKeys){return resolve({keySystem:keySystem,mediaKeys:mediaKeys});})["catch"](function(error){if(keySystems.length){attempt(keySystems);}else if(error instanceof EMEKeyError){reject(error);}else{reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_ACCESS,error:error,fatal:true},error.message));}});};attempt(keySystemsToAttempt);});};_proto.requestMediaKeySystemAccess=function requestMediaKeySystemAccess(keySystem,supportedConfigurations){var requestMediaKeySystemAccessFunc=this.config.requestMediaKeySystemAccessFunc;if(!(typeof requestMediaKeySystemAccessFunc==='function')){var errMessage="Configured requestMediaKeySystemAccess is not a function "+requestMediaKeySystemAccessFunc;if(_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.requestMediaKeySystemAccess===null&&self.location.protocol==='http:'){errMessage="navigator.requestMediaKeySystemAccess is not available over insecure protocol "+location.protocol;}return Promise.reject(new Error(errMessage));}return requestMediaKeySystemAccessFunc(keySystem,supportedConfigurations);};_proto.getMediaKeysPromise=function getMediaKeysPromise(keySystem,audioCodecs,videoCodecs){var _this2=this;// This can throw, but is caught in event handler callpath
|
|
|
var mediaKeySystemConfigs=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getSupportedMediaKeySystemConfigurations)(keySystem,audioCodecs,videoCodecs,this.config.drmSystemOptions);var keySystemAccessPromises=this.keySystemAccessPromises[keySystem];var keySystemAccess=keySystemAccessPromises===null||keySystemAccessPromises===void 0?void 0:keySystemAccessPromises.keySystemAccess;if(!keySystemAccess){this.log("Requesting encrypted media \""+keySystem+"\" key-system access with config: "+JSON.stringify(mediaKeySystemConfigs));keySystemAccess=this.requestMediaKeySystemAccess(keySystem,mediaKeySystemConfigs);var _keySystemAccessPromises=this.keySystemAccessPromises[keySystem]={keySystemAccess:keySystemAccess};keySystemAccess["catch"](function(error){_this2.log("Failed to obtain access to key-system \""+keySystem+"\": "+error);});return keySystemAccess.then(function(mediaKeySystemAccess){_this2.log("Access for key-system \""+mediaKeySystemAccess.keySystem+"\" obtained");var certificateRequest=_this2.fetchServerCertificate(keySystem);_this2.log("Create media-keys for \""+keySystem+"\"");_keySystemAccessPromises.mediaKeys=mediaKeySystemAccess.createMediaKeys().then(function(mediaKeys){_this2.log("Media-keys created for \""+keySystem+"\"");return certificateRequest.then(function(certificate){if(certificate){return _this2.setMediaKeysServerCertificate(mediaKeys,keySystem,certificate);}return mediaKeys;});});_keySystemAccessPromises.mediaKeys["catch"](function(error){_this2.error("Failed to create media-keys for \""+keySystem+"\"}: "+error);});return _keySystemAccessPromises.mediaKeys;});}return keySystemAccess.then(function(){return keySystemAccessPromises.mediaKeys;});};_proto.createMediaKeySessionContext=function createMediaKeySessionContext(_ref){var decryptdata=_ref.decryptdata,keySystem=_ref.keySystem,mediaKeys=_ref.mediaKeys;console.assert(!!mediaKeys,'mediaKeys is defined');this.log("Creating key-system session \""+keySystem+"\" keyId: "+_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId||[]));var mediaKeysSession=mediaKeys.createSession();var mediaKeySessionContext={decryptdata:decryptdata,keySystem:keySystem,mediaKeys:mediaKeys,mediaKeysSession:mediaKeysSession,keyStatus:'status-pending'};this.mediaKeySessions.push(mediaKeySessionContext);return mediaKeySessionContext;};_proto.renewKeySession=function renewKeySession(mediaKeySessionContext){var decryptdata=mediaKeySessionContext.decryptdata;if(decryptdata.pssh){var keySessionContext=this.createMediaKeySessionContext(mediaKeySessionContext);var _keyId=this.getKeyIdString(decryptdata);var scheme='cenc';this.keyIdToKeySessionPromise[_keyId]=this.generateRequestWithPreferredKeySession(keySessionContext,scheme,decryptdata.pssh,'expired');}else{this.warn("Could not renew expired session. Missing pssh initData.");}this.removeSession(mediaKeySessionContext);};_proto.getKeyIdString=function getKeyIdString(decryptdata){if(!decryptdata){throw new Error('Could not read keyId of undefined decryptdata');}if(decryptdata.keyId===null){throw new Error('keyId is null');}return _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId);};_proto.updateKeySession=function updateKeySession(mediaKeySessionContext,data){var _mediaKeySessionConte;var keySession=mediaKeySessionContext.mediaKeysSession;this.log("Updating key-session \""+keySession.sessionId+"\" for keyID "+_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(((_mediaKeySessionConte=mediaKeySessionContext.decryptdata)===null||_mediaKeySessionConte===void 0?void 0:_mediaKeySessionConte.keyId)||[])+"\n } (data length: "+(data?data.byteLength:data)+")");return keySession.update(data);};_proto.selectKeySystemFormat=function selectKeySystemFormat(frag){var keyFormats=Object.keys(frag.levelkeys||{});if(!this.keyFormatPromise){this.log("Selecting key-system from fragment (sn: "+frag.sn+" "+frag.type+": "+frag.level+") key formats "+keyFormats.join(', '));this.keyFormatPromise=this.getKeyFormatPromise(keyFormats);}return this.keyFormatPromise;};_proto.getKeyFormatPromise=function getKeyFormatPromise(keyFormats){var _this3=this;return new Promise(function(resolve,reject){var keySystemsInConfig=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(_this3.config);var keySystemsToAttempt=keyFormats.map(_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemFormatToKeySystemDomain).filter(function(value){return!!value&&keySystemsInConfig.indexOf(value)!==-1;});return _this3.getKeySystemSelectionPromise(keySystemsToAttempt).then(function(_ref2){var keySystem=_ref2.keySystem;var keySystemFormat=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemDomainToKeySystemFormat)(keySystem);if(keySystemFormat){resolve(keySystemFormat);}else{reject(new Error("Unable to find format for key-system \""+keySystem+"\""));}})["catch"](reject);});};_proto.loadKey=function loadKey(data){var _this4=this;var decryptdata=data.keyInfo.decryptdata;var keyId=this.getKeyIdString(decryptdata);var keyDetails="(keyId: "+keyId+" format: \""+decryptdata.keyFormat+"\" method: "+decryptdata.method+" uri: "+decryptdata.uri+")";this.log("Starting session for key "+keyDetails);var keySessionContextPromise=this.keyIdToKeySessionPromise[keyId];if(!keySessionContextPromise){keySessionContextPromise=this.keyIdToKeySessionPromise[keyId]=this.getKeySystemForKeyPromise(decryptdata).then(function(_ref3){var keySystem=_ref3.keySystem,mediaKeys=_ref3.mediaKeys;_this4.throwIfDestroyed();_this4.log("Handle encrypted media sn: "+data.frag.sn+" "+data.frag.type+": "+data.frag.level+" using key "+keyDetails);return _this4.attemptSetMediaKeys(keySystem,mediaKeys).then(function(){_this4.throwIfDestroyed();var keySessionContext=_this4.createMediaKeySessionContext({keySystem:keySystem,mediaKeys:mediaKeys,decryptdata:decryptdata});var scheme='cenc';return _this4.generateRequestWithPreferredKeySession(keySessionContext,scheme,decryptdata.pssh,'playlist-key');});});keySessionContextPromise["catch"](function(error){return _this4.handleError(error);});}return keySessionContextPromise;};_proto.throwIfDestroyed=function throwIfDestroyed(message){if(message===void 0){message='Invalid state';}if(!this.hls){throw new Error('invalid state');}};_proto.handleError=function handleError(error){if(!this.hls){return;}this.error(error.message);if(error instanceof EMEKeyError){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,error.data);}else{this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_KEYS,error:error,fatal:true});}};_proto.getKeySystemForKeyPromise=function getKeySystemForKeyPromise(decryptdata){var keyId=this.getKeyIdString(decryptdata);var mediaKeySessionContext=this.keyIdToKeySessionPromise[keyId];if(!mediaKeySessionContext){var keySystem=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemFormatToKeySystemDomain)(decryptdata.keyFormat);var keySystemsToAttempt=keySystem?[keySystem]:(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(this.config);return this.attemptKeySystemAccess(keySystemsToAttempt);}return mediaKeySessionContext;};_proto.getKeySystemSelectionPromise=function getKeySystemSelectionPromise(keySystemsToAttempt){if(!keySystemsToAttempt.length){keySystemsToAttempt=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(this.config);}if(keySystemsToAttempt.length===0){throw new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_CONFIGURED_LICENSE,fatal:true},"Missing key-system license configuration options "+JSON.stringify({drmSystems:this.config.drmSystems}));}return this.attemptKeySystemAccess(keySystemsToAttempt);};_proto._onMediaEncrypted=function _onMediaEncrypted(event){var _this5=this;var initDataType=event.initDataType,initData=event.initData;this.debug("\""+event.type+"\" event: init data type: \""+initDataType+"\"");// Ignore event when initData is null
|
|
|
if(initData===null){return;}var keyId;var keySystemDomain;if(initDataType==='sinf'&&this.config.drmSystems[_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY]){// Match sinf keyId to playlist skd://keyId=
|
|
|
var json=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.bin2str)(new Uint8Array(initData));try{var sinf=(0,_utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_5__.base64Decode)(JSON.parse(json).sinf);var tenc=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.parseSinf)(new Uint8Array(sinf));if(!tenc){return;}keyId=tenc.subarray(8,24);keySystemDomain=_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY;}catch(error){this.warn('Failed to parse sinf "encrypted" event message initData');return;}}else{// Support clear-lead key-session creation (otherwise depend on playlist keys)
|
|
|
var psshInfo=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.parsePssh)(initData);if(psshInfo===null){return;}if(psshInfo.version===0&&psshInfo.systemId===_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystemIds.WIDEVINE&&psshInfo.data){keyId=psshInfo.data.subarray(8,24);}keySystemDomain=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemIdToKeySystemDomain)(psshInfo.systemId);}if(!keySystemDomain||!keyId){return;}var keyIdHex=_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(keyId);var keyIdToKeySessionPromise=this.keyIdToKeySessionPromise,mediaKeySessions=this.mediaKeySessions;var keySessionContextPromise=keyIdToKeySessionPromise[keyIdHex];var _loop=function _loop(i){// Match playlist key
|
|
|
var keyContext=mediaKeySessions[i];var decryptdata=keyContext.decryptdata;if(decryptdata.pssh||!decryptdata.keyId){return"continue";}var oldKeyIdHex=_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId);if(keyIdHex===oldKeyIdHex||decryptdata.uri.replace(/-/g,'').indexOf(keyIdHex)!==-1){keySessionContextPromise=keyIdToKeySessionPromise[oldKeyIdHex];delete keyIdToKeySessionPromise[oldKeyIdHex];decryptdata.pssh=new Uint8Array(initData);decryptdata.keyId=keyId;keySessionContextPromise=keyIdToKeySessionPromise[keyIdHex]=keySessionContextPromise.then(function(){return _this5.generateRequestWithPreferredKeySession(keyContext,initDataType,initData,'encrypted-event-key-match');});return"break";}};for(var i=0;i<mediaKeySessions.length;i++){var _ret=_loop(i);if(_ret==="continue")continue;if(_ret==="break")break;}if(!keySessionContextPromise){// Clear-lead key (not encountered in playlist)
|
|
|
keySessionContextPromise=keyIdToKeySessionPromise[keyIdHex]=this.getKeySystemSelectionPromise([keySystemDomain]).then(function(_ref4){var _keySystemToKeySystem;var keySystem=_ref4.keySystem,mediaKeys=_ref4.mediaKeys;_this5.throwIfDestroyed();var decryptdata=new _loader_level_key__WEBPACK_IMPORTED_MODULE_6__.LevelKey('ISO-23001-7',keyIdHex,(_keySystemToKeySystem=(0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemDomainToKeySystemFormat)(keySystem))!=null?_keySystemToKeySystem:'');decryptdata.pssh=new Uint8Array(initData);decryptdata.keyId=keyId;return _this5.attemptSetMediaKeys(keySystem,mediaKeys).then(function(){_this5.throwIfDestroyed();var keySessionContext=_this5.createMediaKeySessionContext({decryptdata:decryptdata,keySystem:keySystem,mediaKeys:mediaKeys});return _this5.generateRequestWithPreferredKeySession(keySessionContext,initDataType,initData,'encrypted-event-no-match');});});}keySessionContextPromise["catch"](function(error){return _this5.handleError(error);});};_proto._onWaitingForKey=function _onWaitingForKey(event){this.log("\""+event.type+"\" event");};_proto.attemptSetMediaKeys=function attemptSetMediaKeys(keySystem,mediaKeys){var _this6=this;var queue=this.setMediaKeysQueue.slice();this.log("Setting media-keys for \""+keySystem+"\"");// Only one setMediaKeys() can run at one time, and multiple setMediaKeys() operations
|
|
|
// can be queued for execution for multiple key sessions.
|
|
|
var setMediaKeysPromise=Promise.all(queue).then(function(){if(!_this6.media){throw new Error('Attempted to set mediaKeys without media element attached');}return _this6.media.setMediaKeys(mediaKeys);});this.setMediaKeysQueue.push(setMediaKeysPromise);return setMediaKeysPromise.then(function(){_this6.log("Media-keys set for \""+keySystem+"\"");queue.push(setMediaKeysPromise);_this6.setMediaKeysQueue=_this6.setMediaKeysQueue.filter(function(p){return queue.indexOf(p)===-1;});});};_proto.generateRequestWithPreferredKeySession=function generateRequestWithPreferredKeySession(context,initDataType,initData,reason){var _this$config$drmSyste,_this$config$drmSyste2,_this7=this;var generateRequestFilter=(_this$config$drmSyste=this.config.drmSystems)===null||_this$config$drmSyste===void 0?void 0:(_this$config$drmSyste2=_this$config$drmSyste[context.keySystem])===null||_this$config$drmSyste2===void 0?void 0:_this$config$drmSyste2.generateRequest;if(generateRequestFilter){try{var mappedInitData=generateRequestFilter.call(this.hls,initDataType,initData,context);if(!mappedInitData){throw new Error('Invalid response from configured generateRequest filter');}initDataType=mappedInitData.initDataType;initData=context.decryptdata.pssh=mappedInitData.initData?new Uint8Array(mappedInitData.initData):null;}catch(error){var _this$hls;this.warn(error.message);if((_this$hls=this.hls)!==null&&_this$hls!==void 0&&_this$hls.config.debug){throw error;}}}if(initData===null){this.log("Skipping key-session request for \""+reason+"\" (no initData)");return Promise.resolve(context);}var keyId=this.getKeyIdString(context.decryptdata);this.log("Generating key-session request for \""+reason+"\": "+keyId+" (init data type: "+initDataType+" length: "+(initData?initData.byteLength:null)+")");var licenseStatus=new(eventemitter3__WEBPACK_IMPORTED_MODULE_9___default())();context.mediaKeysSession.onmessage=function(event){var keySession=context.mediaKeysSession;if(!keySession){licenseStatus.emit('error',new Error('invalid state'));return;}var messageType=event.messageType,message=event.message;_this7.log("\""+messageType+"\" message event for session \""+keySession.sessionId+"\" message size: "+message.byteLength);if(messageType==='license-request'||messageType==='license-renewal'){_this7.renewLicense(context,message)["catch"](function(error){_this7.handleError(error);licenseStatus.emit('error',error);});}else if(messageType==='license-release'){if(context.keySystem===_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY){_this7.updateKeySession(context,(0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_4__.strToUtf8array)('acknowledged'));_this7.removeSession(context);}}else{_this7.warn("unhandled media key message type \""+messageType+"\"");}};context.mediaKeysSession.onkeystatuseschange=function(event){var keySession=context.mediaKeysSession;if(!keySession){licenseStatus.emit('error',new Error('invalid state'));return;}_this7.onKeyStatusChange(context);var keyStatus=context.keyStatus;licenseStatus.emit('keyStatus',keyStatus);if(keyStatus==='expired'){_this7.warn(context.keySystem+" expired for key "+keyId);_this7.renewKeySession(context);}};var keyUsablePromise=new Promise(function(resolve,reject){licenseStatus.on('error',reject);licenseStatus.on('keyStatus',function(keyStatus){if(keyStatus.startsWith('usable')){resolve();}else if(keyStatus==='output-restricted'){reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED,fatal:false},'HDCP level output restricted'));}else if(keyStatus==='internal-error'){reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_STATUS_INTERNAL_ERROR,fatal:true},"key status changed to \""+keyStatus+"\""));}else if(keyStatus==='expired'){reject(new Error('key expired while generating request'));}else{_this7.warn("unhandled key status change \""+keyStatus+"\"");}});});return context.mediaKeysSession.generateRequest(initDataType,initData).then(function(){var _context$mediaKeysSes;_this7.log("Request generated for key-session \""+((_context$mediaKeysSes=context.mediaKeysSession)===null||_context$mediaKeysSes===void 0?void 0:_context$mediaKeysSes.sessionId)+"\" keyId: "+keyId);})["catch"](function(error){throw new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_SESSION,error:error,fatal:false},"Error generating key-session request: "+error);}).then(function(){return keyUsablePromise;})["catch"](function(error){licenseStatus.removeAllListeners();_this7.removeSession(context);throw error;}).then(function(){licenseStatus.removeAllListeners();return context;});};_proto.onKeyStatusChange=function onKeyStatusChange(mediaKeySessionContext){var _this8=this;mediaKeySessionContext.mediaKeysSession.keyStatuses.forEach(function(status,keyId){_this8.log("key status change \""+status+"\" for keyStatuses keyId: "+_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump('buffer'in keyId?new Uint8Array(keyId.buffer,keyId.byteOffset,keyId.byteLength):new Uint8Array(keyId))+" session keyId: "+_utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(new Uint8Array(mediaKeySessionContext.decryptdata.keyId||[]))+" uri: "+mediaKeySessionContext.decryptdata.uri);mediaKeySessionContext.keyStatus=status;});};_proto.fetchServerCertificate=function fetchServerCertificate(keySystem){var _this9=this;return new Promise(function(resolve,reject){var url=_this9.getServerCertificateUrl(keySystem);if(!url){return resolve();}_this9.log("Fetching serverCertificate for \""+keySystem+"\"");var xhr=new XMLHttpRequest();xhr.open('GET',url,true);xhr.responseType='arraybuffer';xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE){if(xhr.status===200){resolve(xhr.response);}else{reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED,fatal:true,networkDetails:xhr},"\""+keySystem+"\" certificate request XHR failed ("+url+"). Status: "+xhr.status+" ("+xhr.statusText+")"));}}};xhr.send();});};_proto.setMediaKeysServerCertificate=function setMediaKeysServerCertificate(mediaKeys,keySystem,cert){var _this10=this;return new Promise(function(resolve,reject){mediaKeys.setServerCertificate(cert).then(function(success){_this10.log("setServerCertificate "+(success?'success':'not supported by CDM')+" ("+(cert===null||cert===void 0?void 0:cert.byteLength)+") on \""+keySystem+"\"");resolve(mediaKeys);})["catch"](function(error){reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED,error:error,fatal:true},error.message));});});};_proto.renewLicense=function renewLicense(context,keyMessage){var _this11=this;return this.requestLicense(context,new Uint8Array(keyMessage)).then(function(data){return _this11.updateKeySession(context,new Uint8Array(data))["catch"](function(error){throw new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SESSION_UPDATE_FAILED,error:error,fatal:true},error.message);});});};_proto.setupLicenseXHR=function setupLicenseXHR(xhr,url,keysListItem,licenseChallenge){var _this12=this;var licenseXhrSetup=this.config.licenseXhrSetup;if(!licenseXhrSetup){xhr.open('POST',url,true);return Promise.resolve({xhr:xhr,licenseChallenge:licenseChallenge});}return Promise.resolve().then(function(){if(!keysListItem.decryptdata){throw new Error('Key removed');}return licenseXhrSetup.call(_this12.hls,xhr,url,keysListItem,licenseChallenge);})["catch"](function(error){if(!keysListItem.decryptdata){// Key session removed. Cancel license request.
|
|
|
throw error;}// let's try to open before running setup
|
|
|
xhr.open('POST',url,true);return licenseXhrSetup.call(_this12.hls,xhr,url,keysListItem,licenseChallenge);}).then(function(licenseXhrSetupResult){// if licenseXhrSetup did not yet call open, let's do it now
|
|
|
if(!xhr.readyState){xhr.open('POST',url,true);}var finalLicenseChallenge=licenseXhrSetupResult?licenseXhrSetupResult:licenseChallenge;return{xhr:xhr,licenseChallenge:finalLicenseChallenge};});};_proto.requestLicense=function requestLicense(keySessionContext,licenseChallenge){var _this13=this;return new Promise(function(resolve,reject){var url=_this13.getLicenseServerUrl(keySessionContext.keySystem);_this13.log("Sending license request to URL: "+url);var xhr=new XMLHttpRequest();xhr.responseType='arraybuffer';xhr.onreadystatechange=function(){if(!_this13.hls||!keySessionContext.mediaKeysSession){return reject(new Error('invalid state'));}if(xhr.readyState===4){if(xhr.status===200){_this13._requestLicenseFailureCount=0;var data=xhr.response;_this13.log("License received "+(data instanceof ArrayBuffer?data.byteLength:data));var licenseResponseCallback=_this13.config.licenseResponseCallback;if(licenseResponseCallback){try{data=licenseResponseCallback.call(_this13.hls,xhr,url,keySessionContext);}catch(error){_this13.error(error);}}resolve(data);}else{_this13._requestLicenseFailureCount++;if(_this13._requestLicenseFailureCount>MAX_LICENSE_REQUEST_FAILURES||xhr.status>=400&&xhr.status<500){reject(new EMEKeyError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED,fatal:true,networkDetails:xhr},"License Request XHR failed ("+url+"). Status: "+xhr.status+" ("+xhr.statusText+")"));}else{var attemptsLeft=MAX_LICENSE_REQUEST_FAILURES-_this13._requestLicenseFailureCount+1;_this13.warn("Retrying license request, "+attemptsLeft+" attempts left");_this13.requestLicense(keySessionContext,licenseChallenge).then(resolve,reject);}}}};if(keySessionContext.licenseXhr&&keySessionContext.licenseXhr.readyState!==XMLHttpRequest.DONE){keySessionContext.licenseXhr.abort();}keySessionContext.licenseXhr=xhr;_this13.setupLicenseXHR(xhr,url,keySessionContext,licenseChallenge).then(function(_ref5){var xhr=_ref5.xhr,licenseChallenge=_ref5.licenseChallenge;xhr.send(licenseChallenge);});});};_proto.onMediaAttached=function onMediaAttached(event,data){if(!this.config.emeEnabled){return;}var media=data.media;// keep reference of media
|
|
|
this.media=media;media.addEventListener('encrypted',this.onMediaEncrypted);media.addEventListener('waitingforkey',this.onWaitingForKey);};_proto.onMediaDetached=function onMediaDetached(){var _this14=this;var media=this.media;var mediaKeysList=this.mediaKeySessions;if(media){media.removeEventListener('encrypted',this.onMediaEncrypted);media.removeEventListener('waitingforkey',this.onWaitingForKey);this.media=null;}this._requestLicenseFailureCount=0;this.setMediaKeysQueue=[];this.mediaKeySessions=[];this.keyIdToKeySessionPromise={};_loader_level_key__WEBPACK_IMPORTED_MODULE_6__.LevelKey.clearKeyUriToKeyIdMap();// Close all sessions and remove media keys from the video element.
|
|
|
var keySessionCount=mediaKeysList.length;EMEController.CDMCleanupPromise=Promise.all(mediaKeysList.map(function(mediaKeySessionContext){return _this14.removeSession(mediaKeySessionContext);}).concat(media===null||media===void 0?void 0:media.setMediaKeys(null)["catch"](function(error){_this14.log("Could not clear media keys: "+error+". media.src: "+(media===null||media===void 0?void 0:media.src));}))).then(function(){if(keySessionCount){_this14.log('finished closing key sessions and clearing media keys');mediaKeysList.length=0;}})["catch"](function(error){_this14.log("Could not close sessions and clear media keys: "+error+". media.src: "+(media===null||media===void 0?void 0:media.src));});};_proto.onManifestLoaded=function onManifestLoaded(event,_ref6){var sessionKeys=_ref6.sessionKeys;if(!sessionKeys||!this.config.emeEnabled){return;}if(!this.keyFormatPromise){var keyFormats=sessionKeys.reduce(function(formats,sessionKey){if(formats.indexOf(sessionKey.keyFormat)===-1){formats.push(sessionKey.keyFormat);}return formats;},[]);this.log("Selecting key-system from session-keys "+keyFormats.join(', '));this.keyFormatPromise=this.getKeyFormatPromise(keyFormats);}};_proto.removeSession=function removeSession(mediaKeySessionContext){var _this15=this;var mediaKeysSession=mediaKeySessionContext.mediaKeysSession,licenseXhr=mediaKeySessionContext.licenseXhr;if(mediaKeysSession){this.log("Remove licenses and keys and close session "+mediaKeysSession.sessionId);mediaKeysSession.onmessage=null;mediaKeysSession.onkeystatuseschange=null;if(licenseXhr&&licenseXhr.readyState!==XMLHttpRequest.DONE){licenseXhr.abort();}mediaKeySessionContext.mediaKeysSession=mediaKeySessionContext.decryptdata=mediaKeySessionContext.licenseXhr=undefined;var index=this.mediaKeySessions.indexOf(mediaKeySessionContext);if(index>-1){this.mediaKeySessions.splice(index,1);}return mediaKeysSession.remove()["catch"](function(error){_this15.log("Could not remove session: "+error);}).then(function(){return mediaKeysSession.close();})["catch"](function(error){_this15.log("Could not close session: "+error);});}};return EMEController;}();EMEController.CDMCleanupPromise=void 0;var EMEKeyError=/*#__PURE__*/function(_Error){_inheritsLoose(EMEKeyError,_Error);function EMEKeyError(data,message){var _this16;_this16=_Error.call(this,message)||this;_this16.data=void 0;_this16.data=data;data.err=data.error;return _this16;}return EMEKeyError;}(/*#__PURE__*/_wrapNativeSuper(Error));/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=EMEController;/***/},/***/"./src/controller/fps-controller.ts":/*!******************************************!*\
|
|
|
!*** ./src/controller/fps-controller.ts ***!
|
|
|
\******************************************/ /***/function srcControllerFpsControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_219574__){"use strict";__nested_webpack_require_219574__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_219574__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_219574__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_219574__(/*! ../utils/logger */"./src/utils/logger.ts");var FPSController=/*#__PURE__*/function(){// stream controller must be provided as a dependency!
|
|
|
function FPSController(hls){this.hls=void 0;this.isVideoPlaybackQualityAvailable=false;this.timer=void 0;this.media=null;this.lastTime=void 0;this.lastDroppedFrames=0;this.lastDecodedFrames=0;this.streamController=void 0;this.hls=hls;this.registerListeners();}var _proto=FPSController.prototype;_proto.setStreamController=function setStreamController(streamController){this.streamController=streamController;};_proto.registerListeners=function registerListeners(){this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);};_proto.unregisterListeners=function unregisterListeners(){this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING,this.onMediaAttaching);};_proto.destroy=function destroy(){if(this.timer){clearInterval(this.timer);}this.unregisterListeners();this.isVideoPlaybackQualityAvailable=false;this.media=null;};_proto.onMediaAttaching=function onMediaAttaching(event,data){var config=this.hls.config;if(config.capLevelOnFPSDrop){var media=data.media instanceof self.HTMLVideoElement?data.media:null;this.media=media;if(media&&typeof media.getVideoPlaybackQuality==='function'){this.isVideoPlaybackQualityAvailable=true;}self.clearInterval(this.timer);this.timer=self.setInterval(this.checkFPSInterval.bind(this),config.fpsDroppedMonitoringPeriod);}};_proto.checkFPS=function checkFPS(video,decodedFrames,droppedFrames){var currentTime=performance.now();if(decodedFrames){if(this.lastTime){var currentPeriod=currentTime-this.lastTime;var currentDropped=droppedFrames-this.lastDroppedFrames;var currentDecoded=decodedFrames-this.lastDecodedFrames;var droppedFPS=1000*currentDropped/currentPeriod;var hls=this.hls;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP,{currentDropped:currentDropped,currentDecoded:currentDecoded,totalDroppedFrames:droppedFrames});if(droppedFPS>0){// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
|
|
if(currentDropped>hls.config.fpsDroppedMonitoringThreshold*currentDecoded){var currentLevel=hls.currentLevel;_utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('drop FPS ratio greater than max allowed value for currentLevel: '+currentLevel);if(currentLevel>0&&(hls.autoLevelCapping===-1||hls.autoLevelCapping>=currentLevel)){currentLevel=currentLevel-1;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING,{level:currentLevel,droppedLevel:hls.currentLevel});hls.autoLevelCapping=currentLevel;this.streamController.nextLevelSwitch();}}}}this.lastTime=currentTime;this.lastDroppedFrames=droppedFrames;this.lastDecodedFrames=decodedFrames;}};_proto.checkFPSInterval=function checkFPSInterval(){var video=this.media;if(video){if(this.isVideoPlaybackQualityAvailable){var videoPlaybackQuality=video.getVideoPlaybackQuality();this.checkFPS(video,videoPlaybackQuality.totalVideoFrames,videoPlaybackQuality.droppedVideoFrames);}else{// HTMLVideoElement doesn't include the webkit types
|
|
|
this.checkFPS(video,video.webkitDecodedFrameCount,video.webkitDroppedFrameCount);}}};return FPSController;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=FPSController;/***/},/***/"./src/controller/fragment-finders.ts":/*!********************************************!*\
|
|
|
!*** ./src/controller/fragment-finders.ts ***!
|
|
|
\********************************************/ /***/function srcControllerFragmentFindersTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_223618__){"use strict";__nested_webpack_require_223618__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_223618__.d(__webpack_exports__,{/* harmony export */"findFragWithCC":function findFragWithCC(){return(/* binding */_findFragWithCC);},/* harmony export */"findFragmentByPDT":function findFragmentByPDT(){return(/* binding */_findFragmentByPDT);},/* harmony export */"findFragmentByPTS":function findFragmentByPTS(){return(/* binding */_findFragmentByPTS);},/* harmony export */"fragmentWithinToleranceTest":function fragmentWithinToleranceTest(){return(/* binding */_fragmentWithinToleranceTest);},/* harmony export */"pdtWithinToleranceTest":function pdtWithinToleranceTest(){return(/* binding */_pdtWithinToleranceTest);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_223618__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_223618__(/*! ../utils/binary-search */"./src/utils/binary-search.ts");/**
|
|
|
* Returns first fragment whose endPdt value exceeds the given PDT.
|
|
|
* @param {Array<Fragment>} fragments - The array of candidate fragments
|
|
|
* @param {number|null} [PDTValue = null] - The PDT value which must be exceeded
|
|
|
* @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start/end can be within in order to be considered contiguous
|
|
|
* @returns {*|null} fragment - The best matching fragment
|
|
|
*/function _findFragmentByPDT(fragments,PDTValue,maxFragLookUpTolerance){if(PDTValue===null||!Array.isArray(fragments)||!fragments.length||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(PDTValue)){return null;}// if less than start
|
|
|
var startPDT=fragments[0].programDateTime;if(PDTValue<(startPDT||0)){return null;}var endPDT=fragments[fragments.length-1].endProgramDateTime;if(PDTValue>=(endPDT||0)){return null;}maxFragLookUpTolerance=maxFragLookUpTolerance||0;for(var seg=0;seg<fragments.length;++seg){var frag=fragments[seg];if(_pdtWithinToleranceTest(PDTValue,maxFragLookUpTolerance,frag)){return frag;}}return null;}/**
|
|
|
* Finds a fragment based on the SN of the previous fragment; or based on the needs of the current buffer.
|
|
|
* This method compensates for small buffer gaps by applying a tolerance to the start of any candidate fragment, thus
|
|
|
* breaking any traps which would cause the same fragment to be continuously selected within a small range.
|
|
|
* @param {*} fragPrevious - The last frag successfully appended
|
|
|
* @param {Array} fragments - The array of candidate fragments
|
|
|
* @param {number} [bufferEnd = 0] - The end of the contiguous buffered range the playhead is currently within
|
|
|
* @param {number} maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous
|
|
|
* @returns {*} foundFrag - The best matching fragment
|
|
|
*/function _findFragmentByPTS(fragPrevious,fragments,bufferEnd,maxFragLookUpTolerance){if(bufferEnd===void 0){bufferEnd=0;}if(maxFragLookUpTolerance===void 0){maxFragLookUpTolerance=0;}var fragNext=null;if(fragPrevious){fragNext=fragments[fragPrevious.sn-fragments[0].sn+1]||null;}else if(bufferEnd===0&&fragments[0].start===0){fragNext=fragments[0];}// Prefer the next fragment if it's within tolerance
|
|
|
if(fragNext&&_fragmentWithinToleranceTest(bufferEnd,maxFragLookUpTolerance,fragNext)===0){return fragNext;}// We might be seeking past the tolerance so find the best match
|
|
|
var foundFragment=_utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments,_fragmentWithinToleranceTest.bind(null,bufferEnd,maxFragLookUpTolerance));if(foundFragment&&(foundFragment!==fragPrevious||!fragNext)){return foundFragment;}// If no match was found return the next fragment after fragPrevious, or null
|
|
|
return fragNext;}/**
|
|
|
* The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions.
|
|
|
* @param {*} candidate - The fragment to test
|
|
|
* @param {number} [bufferEnd = 0] - The end of the current buffered range the playhead is currently within
|
|
|
* @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
|
|
|
* @returns {number} - 0 if it matches, 1 if too low, -1 if too high
|
|
|
*/function _fragmentWithinToleranceTest(bufferEnd,maxFragLookUpTolerance,candidate){if(bufferEnd===void 0){bufferEnd=0;}if(maxFragLookUpTolerance===void 0){maxFragLookUpTolerance=0;}// eagerly accept an accurate match (no tolerance)
|
|
|
if(candidate.start<=bufferEnd&&candidate.start+candidate.duration>bufferEnd){return 0;}// offset should be within fragment boundary - config.maxFragLookUpTolerance
|
|
|
// this is to cope with situations like
|
|
|
// bufferEnd = 9.991
|
|
|
// frag[Ø] : [0,10]
|
|
|
// frag[1] : [10,20]
|
|
|
// bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here
|
|
|
// frag start frag start+duration
|
|
|
// |-----------------------------|
|
|
|
// <---> <--->
|
|
|
// ...--------><-----------------------------><---------....
|
|
|
// previous frag matching fragment next frag
|
|
|
// return -1 return 0 return 1
|
|
|
// logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`);
|
|
|
// Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
|
|
|
var candidateLookupTolerance=Math.min(maxFragLookUpTolerance,candidate.duration+(candidate.deltaPTS?candidate.deltaPTS:0));if(candidate.start+candidate.duration-candidateLookupTolerance<=bufferEnd){return 1;}else if(candidate.start-candidateLookupTolerance>bufferEnd&&candidate.start){// if maxFragLookUpTolerance will have negative value then don't return -1 for first element
|
|
|
return-1;}return 0;}/**
|
|
|
* The test function used by the findFragmentByPdt's BinarySearch to look for the best match to the current buffer conditions.
|
|
|
* This function tests the candidate's program date time values, as represented in Unix time
|
|
|
* @param {*} candidate - The fragment to test
|
|
|
* @param {number} [pdtBufferEnd = 0] - The Unix time representing the end of the current buffered range
|
|
|
* @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
|
|
|
* @returns {boolean} True if contiguous, false otherwise
|
|
|
*/function _pdtWithinToleranceTest(pdtBufferEnd,maxFragLookUpTolerance,candidate){var candidateLookupTolerance=Math.min(maxFragLookUpTolerance,candidate.duration+(candidate.deltaPTS?candidate.deltaPTS:0))*1000;// endProgramDateTime can be null, default to zero
|
|
|
var endProgramDateTime=candidate.endProgramDateTime||0;return endProgramDateTime-candidateLookupTolerance>pdtBufferEnd;}function _findFragWithCC(fragments,cc){return _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments,function(candidate){if(candidate.cc<cc){return 1;}else if(candidate.cc>cc){return-1;}else{return 0;}});}/***/},/***/"./src/controller/fragment-tracker.ts":/*!********************************************!*\
|
|
|
!*** ./src/controller/fragment-tracker.ts ***!
|
|
|
\********************************************/ /***/function srcControllerFragmentTrackerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_231104__){"use strict";__nested_webpack_require_231104__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_231104__.d(__webpack_exports__,{/* harmony export */"FragmentState":function FragmentState(){return(/* binding */_FragmentState);},/* harmony export */"FragmentTracker":function FragmentTracker(){return(/* binding */_FragmentTracker);}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_231104__(/*! ../events */"./src/events.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_231104__(/*! ../types/loader */"./src/types/loader.ts");var _FragmentState;(function(FragmentState){FragmentState["NOT_LOADED"]="NOT_LOADED";FragmentState["APPENDING"]="APPENDING";FragmentState["PARTIAL"]="PARTIAL";FragmentState["OK"]="OK";})(_FragmentState||(_FragmentState={}));var _FragmentTracker=/*#__PURE__*/function(){function FragmentTracker(hls){this.activeFragment=null;this.activeParts=null;this.endListFragments=Object.create(null);this.fragments=Object.create(null);this.timeRanges=Object.create(null);this.bufferPadding=0.2;this.hls=void 0;this.hls=hls;this._registerListeners();}var _proto=FragmentTracker.prototype;_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_APPENDED,this.onBufferAppended,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED,this.onFragBuffered,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_LOADED,this.onFragLoaded,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_APPENDED,this.onBufferAppended,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED,this.onFragBuffered,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_LOADED,this.onFragLoaded,this);};_proto.destroy=function destroy(){this._unregisterListeners();// @ts-ignore
|
|
|
this.fragments=// @ts-ignore
|
|
|
this.endListFragments=this.timeRanges=this.activeFragment=this.activeParts=null;}/**
|
|
|
* Return a Fragment with an appended range that matches the position and levelType.
|
|
|
* If not found any Fragment, return null
|
|
|
*/;_proto.getAppendedFrag=function getAppendedFrag(position,levelType){if(levelType===_types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN){var activeFragment=this.activeFragment,activeParts=this.activeParts;if(!activeFragment){return null;}if(activeParts){for(var i=activeParts.length;i--;){var activePart=activeParts[i];var appendedPTS=activePart?activePart.end:activeFragment.appendedPTS;if(activePart.start<=position&&appendedPTS!==undefined&&position<=appendedPTS){// 9 is a magic number. remove parts from lookup after a match but keep some short seeks back.
|
|
|
if(i>9){this.activeParts=activeParts.slice(i-9);}return activePart;}}}else if(activeFragment.start<=position&&activeFragment.appendedPTS!==undefined&&position<=activeFragment.appendedPTS){return activeFragment;}}return this.getBufferedFrag(position,levelType);}/**
|
|
|
* Return a buffered Fragment that matches the position and levelType.
|
|
|
* A buffered Fragment is one whose loading, parsing and appending is done (completed or "partial" meaning aborted).
|
|
|
* If not found any Fragment, return null
|
|
|
*/;_proto.getBufferedFrag=function getBufferedFrag(position,levelType){var fragments=this.fragments;var keys=Object.keys(fragments);for(var i=keys.length;i--;){var fragmentEntity=fragments[keys[i]];if((fragmentEntity===null||fragmentEntity===void 0?void 0:fragmentEntity.body.type)===levelType&&fragmentEntity.buffered){var frag=fragmentEntity.body;if(frag.start<=position&&position<=frag.end){return frag;}}}return null;}/**
|
|
|
* Partial fragments effected by coded frame eviction will be removed
|
|
|
* The browser will unload parts of the buffer to free up memory for new buffer data
|
|
|
* Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable)
|
|
|
*/;_proto.detectEvictedFragments=function detectEvictedFragments(elementaryStream,timeRange,playlistType){var _this=this;if(this.timeRanges){this.timeRanges[elementaryStream]=timeRange;}// Check if any flagged fragments have been unloaded
|
|
|
Object.keys(this.fragments).forEach(function(key){var fragmentEntity=_this.fragments[key];if(!fragmentEntity){return;}if(!fragmentEntity.buffered&&!fragmentEntity.loaded){if(fragmentEntity.body.type===playlistType){_this.removeFragment(fragmentEntity.body);}return;}var esData=fragmentEntity.range[elementaryStream];if(!esData){return;}esData.time.some(function(time){var isNotBuffered=!_this.isTimeBuffered(time.startPTS,time.endPTS,timeRange);if(isNotBuffered){// Unregister partial fragment as it needs to load again to be reused
|
|
|
_this.removeFragment(fragmentEntity.body);}return isNotBuffered;});});}/**
|
|
|
* Checks if the fragment passed in is loaded in the buffer properly
|
|
|
* Partially loaded fragments will be registered as a partial fragment
|
|
|
*/;_proto.detectPartialFragments=function detectPartialFragments(data){var _this2=this;var timeRanges=this.timeRanges;var frag=data.frag,part=data.part;if(!timeRanges||frag.sn==='initSegment'){return;}var fragKey=getFragmentKey(frag);var fragmentEntity=this.fragments[fragKey];if(!fragmentEntity){return;}Object.keys(timeRanges).forEach(function(elementaryStream){var streamInfo=frag.elementaryStreams[elementaryStream];if(!streamInfo){return;}var timeRange=timeRanges[elementaryStream];var partial=part!==null||streamInfo.partial===true;fragmentEntity.range[elementaryStream]=_this2.getBufferedTimes(frag,part,partial,timeRange);});fragmentEntity.loaded=null;if(Object.keys(fragmentEntity.range).length){fragmentEntity.buffered=true;if(fragmentEntity.body.endList){this.endListFragments[fragmentEntity.body.type]=fragmentEntity;}}else{// remove fragment if nothing was appended
|
|
|
this.removeFragment(fragmentEntity.body);}};_proto.fragBuffered=function fragBuffered(frag){var fragKey=getFragmentKey(frag);var fragmentEntity=this.fragments[fragKey];if(fragmentEntity){fragmentEntity.loaded=null;fragmentEntity.buffered=true;}};_proto.getBufferedTimes=function getBufferedTimes(fragment,part,partial,timeRange){var buffered={time:[],partial:partial};var startPTS=part?part.start:fragment.start;var endPTS=part?part.end:fragment.end;var minEndPTS=fragment.minEndPTS||endPTS;var maxStartPTS=fragment.maxStartPTS||startPTS;for(var i=0;i<timeRange.length;i++){var startTime=timeRange.start(i)-this.bufferPadding;var endTime=timeRange.end(i)+this.bufferPadding;if(maxStartPTS>=startTime&&minEndPTS<=endTime){// Fragment is entirely contained in buffer
|
|
|
// No need to check the other timeRange times since it's completely playable
|
|
|
buffered.time.push({startPTS:Math.max(startPTS,timeRange.start(i)),endPTS:Math.min(endPTS,timeRange.end(i))});break;}else if(startPTS<endTime&&endPTS>startTime){buffered.partial=true;// Check for intersection with buffer
|
|
|
// Get playable sections of the fragment
|
|
|
buffered.time.push({startPTS:Math.max(startPTS,timeRange.start(i)),endPTS:Math.min(endPTS,timeRange.end(i))});}else if(endPTS<=startTime){// No need to check the rest of the timeRange as it is in order
|
|
|
break;}}return buffered;}/**
|
|
|
* Gets the partial fragment for a certain time
|
|
|
*/;_proto.getPartialFragment=function getPartialFragment(time){var bestFragment=null;var timePadding;var startTime;var endTime;var bestOverlap=0;var bufferPadding=this.bufferPadding,fragments=this.fragments;Object.keys(fragments).forEach(function(key){var fragmentEntity=fragments[key];if(!fragmentEntity){return;}if(isPartial(fragmentEntity)){startTime=fragmentEntity.body.start-bufferPadding;endTime=fragmentEntity.body.end+bufferPadding;if(time>=startTime&&time<=endTime){// Use the fragment that has the most padding from start and end time
|
|
|
timePadding=Math.min(time-startTime,endTime-time);if(bestOverlap<=timePadding){bestFragment=fragmentEntity.body;bestOverlap=timePadding;}}}});return bestFragment;};_proto.isEndListAppended=function isEndListAppended(type){var lastFragmentEntity=this.endListFragments[type];return lastFragmentEntity!==undefined&&(lastFragmentEntity.buffered||isPartial(lastFragmentEntity));};_proto.getState=function getState(fragment){var fragKey=getFragmentKey(fragment);var fragmentEntity=this.fragments[fragKey];if(fragmentEntity){if(!fragmentEntity.buffered){return _FragmentState.APPENDING;}else if(isPartial(fragmentEntity)){return _FragmentState.PARTIAL;}else{return _FragmentState.OK;}}return _FragmentState.NOT_LOADED;};_proto.isTimeBuffered=function isTimeBuffered(startPTS,endPTS,timeRange){var startTime;var endTime;for(var i=0;i<timeRange.length;i++){startTime=timeRange.start(i)-this.bufferPadding;endTime=timeRange.end(i)+this.bufferPadding;if(startPTS>=startTime&&endPTS<=endTime){return true;}if(endPTS<=startTime){// No need to check the rest of the timeRange as it is in order
|
|
|
return false;}}return false;};_proto.onFragLoaded=function onFragLoaded(event,data){var frag=data.frag,part=data.part;// don't track initsegment (for which sn is not a number)
|
|
|
// don't track frags used for bitrateTest, they're irrelevant.
|
|
|
// don't track parts for memory efficiency
|
|
|
if(frag.sn==='initSegment'||frag.bitrateTest||part){return;}var fragKey=getFragmentKey(frag);this.fragments[fragKey]={body:frag,loaded:data,buffered:false,range:Object.create(null)};};_proto.onBufferAppended=function onBufferAppended(event,data){var _this3=this;var frag=data.frag,part=data.part,timeRanges=data.timeRanges;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN){if(this.activeFragment!==frag){this.activeFragment=frag;frag.appendedPTS=undefined;}if(part){var activeParts=this.activeParts;if(!activeParts){this.activeParts=activeParts=[];}activeParts.push(part);}else{this.activeParts=null;}}// Store the latest timeRanges loaded in the buffer
|
|
|
this.timeRanges=timeRanges;Object.keys(timeRanges).forEach(function(elementaryStream){var timeRange=timeRanges[elementaryStream];_this3.detectEvictedFragments(elementaryStream,timeRange);if(!part&&frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN){var streamInfo=frag.elementaryStreams[elementaryStream];if(!streamInfo){return;}for(var i=0;i<timeRange.length;i++){var rangeEnd=timeRange.end(i);if(rangeEnd<=streamInfo.endPTS&&rangeEnd>streamInfo.startPTS){frag.appendedPTS=Math.max(rangeEnd,frag.appendedPTS||0);}else{frag.appendedPTS=streamInfo.endPTS;}}}});};_proto.onFragBuffered=function onFragBuffered(event,data){this.detectPartialFragments(data);};_proto.hasFragment=function hasFragment(fragment){var fragKey=getFragmentKey(fragment);return!!this.fragments[fragKey];};_proto.removeFragmentsInRange=function removeFragmentsInRange(start,end,playlistType){var _this4=this;Object.keys(this.fragments).forEach(function(key){var fragmentEntity=_this4.fragments[key];if(!fragmentEntity){return;}if(fragmentEntity.buffered){var frag=fragmentEntity.body;if(frag.type===playlistType&&frag.start<end&&frag.end>start){_this4.removeFragment(frag);}}});};_proto.removeFragment=function removeFragment(fragment){var fragKey=getFragmentKey(fragment);fragment.stats.loaded=0;fragment.clearElementaryStreamInfo();fragment.appendedPTS=undefined;delete this.fragments[fragKey];if(fragment.endList){delete this.endListFragments[fragment.type];}};_proto.removeAllFragments=function removeAllFragments(){this.fragments=Object.create(null);this.endListFragments=Object.create(null);this.activeFragment=null;this.activeParts=null;};return FragmentTracker;}();function isPartial(fragmentEntity){var _fragmentEntity$range,_fragmentEntity$range2;return fragmentEntity.buffered&&(((_fragmentEntity$range=fragmentEntity.range.video)===null||_fragmentEntity$range===void 0?void 0:_fragmentEntity$range.partial)||((_fragmentEntity$range2=fragmentEntity.range.audio)===null||_fragmentEntity$range2===void 0?void 0:_fragmentEntity$range2.partial));}function getFragmentKey(fragment){return fragment.type+"_"+fragment.level+"_"+fragment.urlId+"_"+fragment.sn;}/***/},/***/"./src/controller/gap-controller.ts":/*!******************************************!*\
|
|
|
!*** ./src/controller/gap-controller.ts ***!
|
|
|
\******************************************/ /***/function srcControllerGapControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_243461__){"use strict";__nested_webpack_require_243461__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_243461__.d(__webpack_exports__,{/* harmony export */"MAX_START_GAP_JUMP":function MAX_START_GAP_JUMP(){return(/* binding */_MAX_START_GAP_JUMP);},/* harmony export */"SKIP_BUFFER_HOLE_STEP_SECONDS":function SKIP_BUFFER_HOLE_STEP_SECONDS(){return(/* binding */_SKIP_BUFFER_HOLE_STEP_SECONDS);},/* harmony export */"SKIP_BUFFER_RANGE_START":function SKIP_BUFFER_RANGE_START(){return(/* binding */_SKIP_BUFFER_RANGE_START);},/* harmony export */"STALL_MINIMUM_DURATION_MS":function STALL_MINIMUM_DURATION_MS(){return(/* binding */_STALL_MINIMUM_DURATION_MS);},/* harmony export */"default":function _default(){return(/* binding */GapController);}/* harmony export */});/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_243461__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_243461__(/*! ../errors */"./src/errors.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_243461__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_243461__(/*! ../utils/logger */"./src/utils/logger.ts");var _STALL_MINIMUM_DURATION_MS=250;var _MAX_START_GAP_JUMP=2.0;var _SKIP_BUFFER_HOLE_STEP_SECONDS=0.1;var _SKIP_BUFFER_RANGE_START=0.05;var GapController=/*#__PURE__*/function(){function GapController(config,media,fragmentTracker,hls){this.config=void 0;this.media=null;this.fragmentTracker=void 0;this.hls=void 0;this.nudgeRetry=0;this.stallReported=false;this.stalled=null;this.moved=false;this.seeking=false;this.config=config;this.media=media;this.fragmentTracker=fragmentTracker;this.hls=hls;}var _proto=GapController.prototype;_proto.destroy=function destroy(){this.media=null;// @ts-ignore
|
|
|
this.hls=this.fragmentTracker=null;}/**
|
|
|
* Checks if the playhead is stuck within a gap, and if so, attempts to free it.
|
|
|
* A gap is an unbuffered range between two buffered ranges (or the start and the first buffered range).
|
|
|
*
|
|
|
* @param {number} lastCurrentTime Previously read playhead position
|
|
|
*/;_proto.poll=function poll(lastCurrentTime,activeFrag){var config=this.config,media=this.media,stalled=this.stalled;if(media===null){return;}var currentTime=media.currentTime,seeking=media.seeking;var seeked=this.seeking&&!seeking;var beginSeek=!this.seeking&&seeking;this.seeking=seeking;// The playhead is moving, no-op
|
|
|
if(currentTime!==lastCurrentTime){this.moved=true;if(stalled!==null){// The playhead is now moving, but was previously stalled
|
|
|
if(this.stallReported){var _stalledDuration=self.performance.now()-stalled;_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("playback not stuck anymore @"+currentTime+", after "+Math.round(_stalledDuration)+"ms");this.stallReported=false;}this.stalled=null;this.nudgeRetry=0;}return;}// Clear stalled state when beginning or finishing seeking so that we don't report stalls coming out of a seek
|
|
|
if(beginSeek||seeked){this.stalled=null;}// The playhead should not be moving
|
|
|
if(media.paused&&!seeking||media.ended||media.playbackRate===0||!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.getBuffered(media).length){return;}var bufferInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.bufferInfo(media,currentTime,0);var isBuffered=bufferInfo.len>0;var nextStart=bufferInfo.nextStart||0;// There is no playable buffer (seeked, waiting for buffer)
|
|
|
if(!isBuffered&&!nextStart){return;}if(seeking){// Waiting for seeking in a buffered range to complete
|
|
|
var hasEnoughBuffer=bufferInfo.len>_MAX_START_GAP_JUMP;// Next buffered range is too far ahead to jump to while still seeking
|
|
|
var noBufferGap=!nextStart||activeFrag&&activeFrag.start<=currentTime||nextStart-currentTime>_MAX_START_GAP_JUMP&&!this.fragmentTracker.getPartialFragment(currentTime);if(hasEnoughBuffer||noBufferGap){return;}// Reset moved state when seeking to a point in or before a gap
|
|
|
this.moved=false;}// Skip start gaps if we haven't played, but the last poll detected the start of a stall
|
|
|
// The addition poll gives the browser a chance to jump the gap for us
|
|
|
if(!this.moved&&this.stalled!==null){var _level$details;// Jump start gaps within jump threshold
|
|
|
var startJump=Math.max(nextStart,bufferInfo.start||0)-currentTime;// When joining a live stream with audio tracks, account for live playlist window sliding by allowing
|
|
|
// a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment
|
|
|
// that begins over 1 target duration after the video start position.
|
|
|
var level=this.hls.levels?this.hls.levels[this.hls.currentLevel]:null;var isLive=level===null||level===void 0?void 0:(_level$details=level.details)===null||_level$details===void 0?void 0:_level$details.live;var maxStartGapJump=isLive?level.details.targetduration*2:_MAX_START_GAP_JUMP;if(startJump>0&&startJump<=maxStartGapJump){this._trySkipBufferHole(null);return;}}// Start tracking stall time
|
|
|
var tnow=self.performance.now();if(stalled===null){this.stalled=tnow;return;}var stalledDuration=tnow-stalled;if(!seeking&&stalledDuration>=_STALL_MINIMUM_DURATION_MS){// Report stalling after trying to fix
|
|
|
this._reportStall(bufferInfo);if(!this.media){return;}}var bufferedWithHoles=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.bufferInfo(media,currentTime,config.maxBufferHole);this._tryFixBufferStall(bufferedWithHoles,stalledDuration);}/**
|
|
|
* Detects and attempts to fix known buffer stalling issues.
|
|
|
* @param bufferInfo - The properties of the current buffer.
|
|
|
* @param stalledDurationMs - The amount of time Hls.js has been stalling for.
|
|
|
* @private
|
|
|
*/;_proto._tryFixBufferStall=function _tryFixBufferStall(bufferInfo,stalledDurationMs){var config=this.config,fragmentTracker=this.fragmentTracker,media=this.media;if(media===null){return;}var currentTime=media.currentTime;var partial=fragmentTracker.getPartialFragment(currentTime);if(partial){// Try to skip over the buffer hole caused by a partial fragment
|
|
|
// This method isn't limited by the size of the gap between buffered ranges
|
|
|
var targetTime=this._trySkipBufferHole(partial);// we return here in this case, meaning
|
|
|
// the branch below only executes when we don't handle a partial fragment
|
|
|
if(targetTime||!this.media){return;}}// if we haven't had to skip over a buffer hole of a partial fragment
|
|
|
// we may just have to "nudge" the playlist as the browser decoding/rendering engine
|
|
|
// needs to cross some sort of threshold covering all source-buffers content
|
|
|
// to start playing properly.
|
|
|
if(bufferInfo.len>config.maxBufferHole&&stalledDurationMs>config.highBufferWatchdogPeriod*1000){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Trying to nudge playhead over buffer-hole');// Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
|
|
|
// We only try to jump the hole if it's under the configured size
|
|
|
// Reset stalled so to rearm watchdog timer
|
|
|
this.stalled=null;this._tryNudgeBuffer();}}/**
|
|
|
* Triggers a BUFFER_STALLED_ERROR event, but only once per stall period.
|
|
|
* @param bufferLen - The playhead distance from the end of the current buffer segment.
|
|
|
* @private
|
|
|
*/;_proto._reportStall=function _reportStall(bufferInfo){var hls=this.hls,media=this.media,stallReported=this.stallReported;if(!stallReported&&media){// Report stalled error once
|
|
|
this.stallReported=true;_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("Playback stalling at @"+media.currentTime+" due to low buffer ("+JSON.stringify(bufferInfo)+")");hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_STALLED_ERROR,fatal:false,buffer:bufferInfo.len});}}/**
|
|
|
* Attempts to fix buffer stalls by jumping over known gaps caused by partial fragments
|
|
|
* @param partial - The partial fragment found at the current time (where playback is stalling).
|
|
|
* @private
|
|
|
*/;_proto._trySkipBufferHole=function _trySkipBufferHole(partial){var config=this.config,hls=this.hls,media=this.media;if(media===null){return 0;}var currentTime=media.currentTime;var lastEndTime=0;// Check if currentTime is between unbuffered regions of partial fragments
|
|
|
var buffered=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.getBuffered(media);for(var i=0;i<buffered.length;i++){var startTime=buffered.start(i);if(currentTime+config.maxBufferHole>=lastEndTime&¤tTime<startTime){var targetTime=Math.max(startTime+_SKIP_BUFFER_RANGE_START,media.currentTime+_SKIP_BUFFER_HOLE_STEP_SECONDS);_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("skipping hole, adjusting currentTime from "+currentTime+" to "+targetTime);this.moved=true;this.stalled=null;media.currentTime=targetTime;if(partial){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_SEEK_OVER_HOLE,fatal:false,reason:"fragment loaded with buffer holes, seeking from "+currentTime+" to "+targetTime,frag:partial});}return targetTime;}lastEndTime=buffered.end(i);}return 0;}/**
|
|
|
* Attempts to fix buffer stalls by advancing the mediaElement's current time by a small amount.
|
|
|
* @private
|
|
|
*/;_proto._tryNudgeBuffer=function _tryNudgeBuffer(){var config=this.config,hls=this.hls,media=this.media,nudgeRetry=this.nudgeRetry;if(media===null){return;}var currentTime=media.currentTime;this.nudgeRetry++;if(nudgeRetry<config.nudgeMaxRetry){var targetTime=currentTime+(nudgeRetry+1)*config.nudgeOffset;// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("Nudging 'currentTime' from "+currentTime+" to "+targetTime);media.currentTime=targetTime;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_NUDGE_ON_STALL,fatal:false});}else{_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error("Playhead still not moving while enough data buffered @"+currentTime+" after "+config.nudgeMaxRetry+" nudges");hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_STALLED_ERROR,fatal:true});}};return GapController;}();/***/},/***/"./src/controller/id3-track-controller.ts":/*!************************************************!*\
|
|
|
!*** ./src/controller/id3-track-controller.ts ***!
|
|
|
\************************************************/ /***/function srcControllerId3TrackControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_254359__){"use strict";__nested_webpack_require_254359__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_254359__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_254359__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_254359__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_254359__(/*! ../utils/texttrack-utils */"./src/utils/texttrack-utils.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_254359__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _loader_date_range__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_254359__(/*! ../loader/date-range */"./src/loader/date-range.ts");/* harmony import */var _types_demuxer__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_254359__(/*! ../types/demuxer */"./src/types/demuxer.ts");var MIN_CUE_DURATION=0.25;function getCueClass(){// Attempt to recreate Safari functionality by creating
|
|
|
// WebKitDataCue objects when available and store the decoded
|
|
|
// ID3 data in the value property of the cue
|
|
|
return self.WebKitDataCue||self.VTTCue||self.TextTrackCue;}// VTTCue latest draft allows an infinite duration, fallback
|
|
|
// to MAX_VALUE if necessary
|
|
|
var MAX_CUE_ENDTIME=function(){var Cue=getCueClass();try{new Cue(0,Number.POSITIVE_INFINITY,'');}catch(e){return Number.MAX_VALUE;}return Number.POSITIVE_INFINITY;}();function dateRangeDateToTimelineSeconds(date,offset){return date.getTime()/1000-offset;}function hexToArrayBuffer(str){return Uint8Array.from(str.replace(/^0x/,'').replace(/([\da-fA-F]{2}) ?/g,'0x$1 ').replace(/ +$/,'').split(' ')).buffer;}var ID3TrackController=/*#__PURE__*/function(){function ID3TrackController(hls){this.hls=void 0;this.id3Track=null;this.media=null;this.dateRangeCuesAppended={};this.hls=hls;this._registerListeners();}var _proto=ID3TrackController.prototype;_proto.destroy=function destroy(){this._unregisterListeners();this.id3Track=null;this.media=null;this.dateRangeCuesAppended={};// @ts-ignore
|
|
|
this.hls=null;};_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_METADATA,this.onFragParsingMetadata,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_METADATA,this.onFragParsingMetadata,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated,this);}// Add ID3 metatadata text track.
|
|
|
;_proto.onMediaAttached=function onMediaAttached(event,data){this.media=data.media;};_proto.onMediaDetaching=function onMediaDetaching(){if(!this.id3Track){return;}(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.clearCurrentCues)(this.id3Track);this.id3Track=null;this.media=null;this.dateRangeCuesAppended={};};_proto.onManifestLoading=function onManifestLoading(){this.dateRangeCuesAppended={};};_proto.createTrack=function createTrack(media){var track=this.getID3Track(media.textTracks);track.mode='hidden';return track;};_proto.getID3Track=function getID3Track(textTracks){if(!this.media){return;}for(var i=0;i<textTracks.length;i++){var textTrack=textTracks[i];if(textTrack.kind==='metadata'&&textTrack.label==='id3'){// send 'addtrack' when reusing the textTrack for metadata,
|
|
|
// same as what we do for captions
|
|
|
(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.sendAddTrackEvent)(textTrack,this.media);return textTrack;}}return this.media.addTextTrack('metadata','id3');};_proto.onFragParsingMetadata=function onFragParsingMetadata(event,data){if(!this.media){return;}var _this$hls$config=this.hls.config,enableEmsgMetadataCues=_this$hls$config.enableEmsgMetadataCues,enableID3MetadataCues=_this$hls$config.enableID3MetadataCues;if(!enableEmsgMetadataCues&&!enableID3MetadataCues){return;}var samples=data.samples;// create track dynamically
|
|
|
if(!this.id3Track){this.id3Track=this.createTrack(this.media);}var Cue=getCueClass();for(var i=0;i<samples.length;i++){var type=samples[i].type;if(type===_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg&&!enableEmsgMetadataCues||!enableID3MetadataCues){continue;}var frames=_demux_id3__WEBPACK_IMPORTED_MODULE_3__.getID3Frames(samples[i].data);if(frames){var startTime=samples[i].pts;var endTime=startTime+samples[i].duration;if(endTime>MAX_CUE_ENDTIME){endTime=MAX_CUE_ENDTIME;}var timeDiff=endTime-startTime;if(timeDiff<=0){endTime=startTime+MIN_CUE_DURATION;}for(var j=0;j<frames.length;j++){var frame=frames[j];// Safari doesn't put the timestamp frame in the TextTrack
|
|
|
if(!_demux_id3__WEBPACK_IMPORTED_MODULE_3__.isTimeStampFrame(frame)){// add a bounds to any unbounded cues
|
|
|
this.updateId3CueEnds(startTime);var cue=new Cue(startTime,endTime,'');cue.value=frame;if(type){cue.type=type;}this.id3Track.addCue(cue);}}}}};_proto.updateId3CueEnds=function updateId3CueEnds(startTime){var _this$id3Track;var cues=(_this$id3Track=this.id3Track)===null||_this$id3Track===void 0?void 0:_this$id3Track.cues;if(cues){for(var i=cues.length;i--;){var cue=cues[i];if(cue.startTime<startTime&&cue.endTime===MAX_CUE_ENDTIME){cue.endTime=startTime;}}}};_proto.onBufferFlushing=function onBufferFlushing(event,_ref){var startOffset=_ref.startOffset,endOffset=_ref.endOffset,type=_ref.type;var id3Track=this.id3Track,hls=this.hls;if(!hls){return;}var _hls$config=hls.config,enableEmsgMetadataCues=_hls$config.enableEmsgMetadataCues,enableID3MetadataCues=_hls$config.enableID3MetadataCues;if(id3Track&&(enableEmsgMetadataCues||enableID3MetadataCues)){var predicate;if(type==='audio'){predicate=function predicate(cue){return cue.type===_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.audioId3&&enableID3MetadataCues;};}else if(type==='video'){predicate=function predicate(cue){return cue.type===_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg&&enableEmsgMetadataCues;};}else{predicate=function predicate(cue){return cue.type===_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.audioId3&&enableID3MetadataCues||cue.type===_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg&&enableEmsgMetadataCues;};}(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.removeCuesInRange)(id3Track,startOffset,endOffset,predicate);}};_proto.onLevelUpdated=function onLevelUpdated(event,_ref2){var _this=this;var details=_ref2.details;if(!this.media||!details.hasProgramDateTime||!this.hls.config.enableDateRangeMetadataCues){return;}var dateRangeCuesAppended=this.dateRangeCuesAppended,id3Track=this.id3Track;var dateRanges=details.dateRanges;var ids=Object.keys(dateRanges);// Remove cues from track not found in details.dateRanges
|
|
|
if(id3Track){var idsToRemove=Object.keys(dateRangeCuesAppended).filter(function(id){return!ids.includes(id);});var _loop=function _loop(i){var id=idsToRemove[i];Object.keys(dateRangeCuesAppended[id].cues).forEach(function(key){id3Track.removeCue(dateRangeCuesAppended[id].cues[key]);});delete dateRangeCuesAppended[id];};for(var i=idsToRemove.length;i--;){_loop(i);}}// Exit if the playlist does not have Date Ranges or does not have Program Date Time
|
|
|
var lastFragment=details.fragments[details.fragments.length-1];if(ids.length===0||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(lastFragment===null||lastFragment===void 0?void 0:lastFragment.programDateTime)){return;}if(!this.id3Track){this.id3Track=this.createTrack(this.media);}var dateTimeOffset=lastFragment.programDateTime/1000-lastFragment.start;var Cue=getCueClass();var _loop2=function _loop2(_i){var id=ids[_i];var dateRange=dateRanges[id];var appendedDateRangeCues=dateRangeCuesAppended[id];var cues=(appendedDateRangeCues===null||appendedDateRangeCues===void 0?void 0:appendedDateRangeCues.cues)||{};var durationKnown=(appendedDateRangeCues===null||appendedDateRangeCues===void 0?void 0:appendedDateRangeCues.durationKnown)||false;var startTime=dateRangeDateToTimelineSeconds(dateRange.startDate,dateTimeOffset);var endTime=MAX_CUE_ENDTIME;var endDate=dateRange.endDate;if(endDate){endTime=dateRangeDateToTimelineSeconds(endDate,dateTimeOffset);durationKnown=true;}else if(dateRange.endOnNext&&!durationKnown){var nextDateRangeWithSameClass=ids.reduce(function(filterMapArray,id){var candidate=dateRanges[id];if(candidate["class"]===dateRange["class"]&&candidate.id!==id&&candidate.startDate>dateRange.startDate){filterMapArray.push(candidate);}return filterMapArray;},[]).sort(function(a,b){return a.startDate.getTime()-b.startDate.getTime();})[0];if(nextDateRangeWithSameClass){endTime=dateRangeDateToTimelineSeconds(nextDateRangeWithSameClass.startDate,dateTimeOffset);durationKnown=true;}}var attributes=Object.keys(dateRange.attr);for(var j=0;j<attributes.length;j++){var key=attributes[j];if(key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.ID||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.CLASS||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.START_DATE||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.DURATION||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.END_DATE||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.END_ON_NEXT){continue;}var cue=cues[key];if(cue){if(durationKnown&&!appendedDateRangeCues.durationKnown){cue.endTime=endTime;}}else{var data=dateRange.attr[key];cue=new Cue(startTime,endTime,'');if(key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.SCTE35_OUT||key===_loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.SCTE35_IN){data=hexToArrayBuffer(data);}cue.value={key:key,data:data};cue.type=_types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.dateRange;_this.id3Track.addCue(cue);cues[key]=cue;}}dateRangeCuesAppended[id]={cues:cues,dateRange:dateRange,durationKnown:durationKnown};};for(var _i=0;_i<ids.length;_i++){_loop2(_i);}};return ID3TrackController;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=ID3TrackController;/***/},/***/"./src/controller/latency-controller.ts":/*!**********************************************!*\
|
|
|
!*** ./src/controller/latency-controller.ts ***!
|
|
|
\**********************************************/ /***/function srcControllerLatencyControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_265807__){"use strict";__nested_webpack_require_265807__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_265807__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */LatencyController);}/* harmony export */});/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_265807__(/*! ../errors */"./src/errors.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_265807__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_265807__(/*! ../utils/logger */"./src/utils/logger.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var LatencyController=/*#__PURE__*/function(){function LatencyController(hls){var _this=this;this.hls=void 0;this.config=void 0;this.media=null;this.levelDetails=null;this.currentTime=0;this.stallCount=0;this._latency=null;this.timeupdateHandler=function(){return _this.timeupdate();};this.hls=hls;this.config=hls.config;this.registerListeners();}var _proto=LatencyController.prototype;_proto.destroy=function destroy(){this.unregisterListeners();this.onMediaDetaching();this.levelDetails=null;// @ts-ignore
|
|
|
this.hls=this.timeupdateHandler=null;};_proto.registerListeners=function registerListeners(){this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated,this);this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,this.onError,this);};_proto.unregisterListeners=function unregisterListeners(){this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED,this.onMediaAttached);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED,this.onLevelUpdated);this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,this.onError);};_proto.onMediaAttached=function onMediaAttached(event,data){this.media=data.media;this.media.addEventListener('timeupdate',this.timeupdateHandler);};_proto.onMediaDetaching=function onMediaDetaching(){if(this.media){this.media.removeEventListener('timeupdate',this.timeupdateHandler);this.media=null;}};_proto.onManifestLoading=function onManifestLoading(){this.levelDetails=null;this._latency=null;this.stallCount=0;};_proto.onLevelUpdated=function onLevelUpdated(event,_ref){var details=_ref.details;this.levelDetails=details;if(details.advanced){this.timeupdate();}if(!details.live&&this.media){this.media.removeEventListener('timeupdate',this.timeupdateHandler);}};_proto.onError=function onError(event,data){if(data.details!==_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.BUFFER_STALLED_ERROR){return;}this.stallCount++;_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');};_proto.timeupdate=function timeupdate(){var media=this.media,levelDetails=this.levelDetails;if(!media||!levelDetails){return;}this.currentTime=media.currentTime;var latency=this.computeLatency();if(latency===null){return;}this._latency=latency;// Adapt playbackRate to meet target latency in low-latency mode
|
|
|
var _this$config=this.config,lowLatencyMode=_this$config.lowLatencyMode,maxLiveSyncPlaybackRate=_this$config.maxLiveSyncPlaybackRate;if(!lowLatencyMode||maxLiveSyncPlaybackRate===1){return;}var targetLatency=this.targetLatency;if(targetLatency===null){return;}var distanceFromTarget=latency-targetLatency;// Only adjust playbackRate when within one target duration of targetLatency
|
|
|
// and more than one second from under-buffering.
|
|
|
// Playback further than one target duration from target can be considered DVR playback.
|
|
|
var liveMinLatencyDuration=Math.min(this.maxLatency,targetLatency+levelDetails.targetduration);var inLiveRange=distanceFromTarget<liveMinLatencyDuration;if(levelDetails.live&&inLiveRange&&distanceFromTarget>0.05&&this.forwardBufferLength>1){var max=Math.min(2,Math.max(1.0,maxLiveSyncPlaybackRate));var rate=Math.round(2/(1+Math.exp(-0.75*distanceFromTarget-this.edgeStalled))*20)/20;media.playbackRate=Math.min(max,Math.max(1,rate));}else if(media.playbackRate!==1&&media.playbackRate!==0){media.playbackRate=1;}};_proto.estimateLiveEdge=function estimateLiveEdge(){var levelDetails=this.levelDetails;if(levelDetails===null){return null;}return levelDetails.edge+levelDetails.age;};_proto.computeLatency=function computeLatency(){var liveEdge=this.estimateLiveEdge();if(liveEdge===null){return null;}return liveEdge-this.currentTime;};_createClass(LatencyController,[{key:"latency",get:function get(){return this._latency||0;}},{key:"maxLatency",get:function get(){var config=this.config,levelDetails=this.levelDetails;if(config.liveMaxLatencyDuration!==undefined){return config.liveMaxLatencyDuration;}return levelDetails?config.liveMaxLatencyDurationCount*levelDetails.targetduration:0;}},{key:"targetLatency",get:function get(){var levelDetails=this.levelDetails;if(levelDetails===null){return null;}var holdBack=levelDetails.holdBack,partHoldBack=levelDetails.partHoldBack,targetduration=levelDetails.targetduration;var _this$config2=this.config,liveSyncDuration=_this$config2.liveSyncDuration,liveSyncDurationCount=_this$config2.liveSyncDurationCount,lowLatencyMode=_this$config2.lowLatencyMode;var userConfig=this.hls.userConfig;var targetLatency=lowLatencyMode?partHoldBack||holdBack:holdBack;if(userConfig.liveSyncDuration||userConfig.liveSyncDurationCount||targetLatency===0){targetLatency=liveSyncDuration!==undefined?liveSyncDuration:liveSyncDurationCount*targetduration;}var maxLiveSyncOnStallIncrease=targetduration;var liveSyncOnStallIncrease=1.0;return targetLatency+Math.min(this.stallCount*liveSyncOnStallIncrease,maxLiveSyncOnStallIncrease);}},{key:"liveSyncPosition",get:function get(){var liveEdge=this.estimateLiveEdge();var targetLatency=this.targetLatency;var levelDetails=this.levelDetails;if(liveEdge===null||targetLatency===null||levelDetails===null){return null;}var edge=levelDetails.edge;var syncPosition=liveEdge-targetLatency-this.edgeStalled;var min=edge-levelDetails.totalduration;var max=edge-(this.config.lowLatencyMode&&levelDetails.partTarget||levelDetails.targetduration);return Math.min(Math.max(min,syncPosition),max);}},{key:"drift",get:function get(){var levelDetails=this.levelDetails;if(levelDetails===null){return 1;}return levelDetails.drift;}},{key:"edgeStalled",get:function get(){var levelDetails=this.levelDetails;if(levelDetails===null){return 0;}var maxLevelUpdateAge=(this.config.lowLatencyMode&&levelDetails.partTarget||levelDetails.targetduration)*3;return Math.max(levelDetails.age-maxLevelUpdateAge,0);}},{key:"forwardBufferLength",get:function get(){var media=this.media,levelDetails=this.levelDetails;if(!media||!levelDetails){return 0;}var bufferedRanges=media.buffered.length;return(bufferedRanges?media.buffered.end(bufferedRanges-1):levelDetails.edge)-this.currentTime;}}]);return LatencyController;}();/***/},/***/"./src/controller/level-controller.ts":/*!********************************************!*\
|
|
|
!*** ./src/controller/level-controller.ts ***!
|
|
|
\********************************************/ /***/function srcControllerLevelControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_274385__){"use strict";__nested_webpack_require_274385__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_274385__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */LevelController);}/* harmony export */});/* harmony import */var _types_level__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_274385__(/*! ../types/level */"./src/types/level.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_274385__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_274385__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_codecs__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_274385__(/*! ../utils/codecs */"./src/utils/codecs.ts");/* harmony import */var _level_helper__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_274385__(/*! ./level-helper */"./src/controller/level-helper.ts");/* harmony import */var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_274385__(/*! ./base-playlist-controller */"./src/controller/base-playlist-controller.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_274385__(/*! ../types/loader */"./src/types/loader.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}/*
|
|
|
* Level Controller
|
|
|
*/var chromeOrFirefox=/chrome|firefox/.test(navigator.userAgent.toLowerCase());var LevelController=/*#__PURE__*/function(_BasePlaylistControll){_inheritsLoose(LevelController,_BasePlaylistControll);function LevelController(hls){var _this;_this=_BasePlaylistControll.call(this,hls,'[level-controller]')||this;_this._levels=[];_this._firstLevel=-1;_this._startLevel=void 0;_this.currentLevelIndex=-1;_this.manualLevelIndex=-1;_this.onParsedComplete=void 0;_this._registerListeners();return _this;}var _proto=LevelController.prototype;_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_SWITCHED,this.onAudioTrackSwitched,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,this.onError,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_SWITCHED,this.onAudioTrackSwitched,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,this.onError,this);};_proto.destroy=function destroy(){this._unregisterListeners();this.manualLevelIndex=-1;this._levels.length=0;_BasePlaylistControll.prototype.destroy.call(this);};_proto.startLoad=function startLoad(){var levels=this._levels;// clean up live level details to force reload them, and reset load errors
|
|
|
levels.forEach(function(level){level.loadError=0;});_BasePlaylistControll.prototype.startLoad.call(this);};_proto.onManifestLoaded=function onManifestLoaded(event,data){var levels=[];var audioTracks=[];var subtitleTracks=[];var bitrateStart;var levelSet={};var levelFromSet;var resolutionFound=false;var videoCodecFound=false;var audioCodecFound=false;// regroup redundant levels together
|
|
|
data.levels.forEach(function(levelParsed){var attributes=levelParsed.attrs;resolutionFound=resolutionFound||!!(levelParsed.width&&levelParsed.height);videoCodecFound=videoCodecFound||!!levelParsed.videoCodec;audioCodecFound=audioCodecFound||!!levelParsed.audioCodec;// erase audio codec info if browser does not support mp4a.40.34.
|
|
|
// demuxer will autodetect codec and fallback to mpeg/audio
|
|
|
if(chromeOrFirefox&&levelParsed.audioCodec&&levelParsed.audioCodec.indexOf('mp4a.40.34')!==-1){levelParsed.audioCodec=undefined;}var levelKey=levelParsed.bitrate+"-"+levelParsed.attrs.RESOLUTION+"-"+levelParsed.attrs.CODECS;levelFromSet=levelSet[levelKey];if(!levelFromSet){levelFromSet=new _types_level__WEBPACK_IMPORTED_MODULE_0__.Level(levelParsed);levelSet[levelKey]=levelFromSet;levels.push(levelFromSet);}else{levelFromSet.url.push(levelParsed.url);}if(attributes){if(attributes.AUDIO){(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addGroupId)(levelFromSet,'audio',attributes.AUDIO);}if(attributes.SUBTITLES){(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addGroupId)(levelFromSet,'text',attributes.SUBTITLES);}}});// remove audio-only level if we also have levels with video codecs or RESOLUTION signalled
|
|
|
if((resolutionFound||videoCodecFound)&&audioCodecFound){levels=levels.filter(function(_ref){var videoCodec=_ref.videoCodec,width=_ref.width,height=_ref.height;return!!videoCodec||!!(width&&height);});}// only keep levels with supported audio/video codecs
|
|
|
levels=levels.filter(function(_ref2){var audioCodec=_ref2.audioCodec,videoCodec=_ref2.videoCodec;return(!audioCodec||(0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(audioCodec,'audio'))&&(!videoCodec||(0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(videoCodec,'video'));});if(data.audioTracks){audioTracks=data.audioTracks.filter(function(track){return!track.audioCodec||(0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(track.audioCodec,'audio');});// Assign ids after filtering as array indices by group-id
|
|
|
(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.assignTrackIdsByGroup)(audioTracks);}if(data.subtitles){subtitleTracks=data.subtitles;(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.assignTrackIdsByGroup)(subtitleTracks);}if(levels.length>0){// start bitrate is the first bitrate of the manifest
|
|
|
bitrateStart=levels[0].bitrate;// sort levels from lowest to highest
|
|
|
levels.sort(function(a,b){if(a.attrs['HDCP-LEVEL']!==b.attrs['HDCP-LEVEL']){return(a.attrs['HDCP-LEVEL']||'')>(b.attrs['HDCP-LEVEL']||'')?1:-1;}if(a.bitrate!==b.bitrate){return a.bitrate-b.bitrate;}if(a.attrs.SCORE!==b.attrs.SCORE){return a.attrs.decimalFloatingPoint('SCORE')-b.attrs.decimalFloatingPoint('SCORE');}if(resolutionFound&&a.height!==b.height){return a.height-b.height;}return 0;});this._levels=levels;// find index of first level in sorted levels
|
|
|
for(var i=0;i<levels.length;i++){if(levels[i].bitrate===bitrateStart){this._firstLevel=i;this.log("manifest loaded, "+levels.length+" level(s) found, first bitrate: "+bitrateStart);break;}}// Audio is only alternate if manifest include a URI along with the audio group tag,
|
|
|
// and this is not an audio-only stream where levels contain audio-only
|
|
|
var audioOnly=audioCodecFound&&!videoCodecFound;var edata={levels:levels,audioTracks:audioTracks,subtitleTracks:subtitleTracks,sessionData:data.sessionData,sessionKeys:data.sessionKeys,firstLevel:this._firstLevel,stats:data.stats,audio:audioCodecFound,video:videoCodecFound,altAudio:!audioOnly&&audioTracks.some(function(t){return!!t.url;})};this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED,edata);// Initiate loading after all controllers have received MANIFEST_PARSED
|
|
|
if(this.hls.config.autoStartLoad||this.hls.forceStartLoad){this.hls.startLoad(this.hls.config.startPosition);}}else{this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR,fatal:true,url:data.url,reason:'no level with compatible codecs found in manifest'});}};_proto.onError=function onError(event,data){var _data$frag,_data$level;_BasePlaylistControll.prototype.onError.call(this,event,data);if(data.fatal){return;}// Switch to redundant level when track fails to load
|
|
|
var context=data.context;var level=this._levels[this.currentLevelIndex];if(context&&(context.type===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistContextType.AUDIO_TRACK&&level.audioGroupIds&&context.groupId===level.audioGroupIds[level.urlId]||context.type===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistContextType.SUBTITLE_TRACK&&level.textGroupIds&&context.groupId===level.textGroupIds[level.urlId])){this.redundantFailover(this.currentLevelIndex);return;}var levelError=false;var levelSwitch=true;var levelIndex;// try to recover not fatal errors
|
|
|
switch(data.details){case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_LOAD_TIMEOUT:case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_LOAD_TIMEOUT:if(data.frag){// Share fragment error count accross media options (main, audio, subs)
|
|
|
// This allows for level based rendition switching when media option assets fail
|
|
|
var variantLevelIndex=data.frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN?data.frag.level:this.currentLevelIndex;var _level=this._levels[variantLevelIndex];// Set levelIndex when we're out of fragment retries
|
|
|
if(_level){_level.fragmentError++;if(_level.fragmentError>this.hls.config.fragLoadingMaxRetry){levelIndex=variantLevelIndex;}}else{levelIndex=variantLevelIndex;}}break;case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED:{var restrictedHdcpLevel=level.attrs['HDCP-LEVEL'];if(restrictedHdcpLevel){this.hls.maxHdcpLevel=_types_level__WEBPACK_IMPORTED_MODULE_0__.HdcpLevels[_types_level__WEBPACK_IMPORTED_MODULE_0__.HdcpLevels.indexOf(restrictedHdcpLevel)-1];this.warn("Restricting playback to HDCP-LEVEL of \""+this.hls.maxHdcpLevel+"\" or lower");}}// eslint-disable-next-line no-fallthrough
|
|
|
case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_PARSING_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_SYSTEM_NO_SESSION:levelIndex=((_data$frag=data.frag)===null||_data$frag===void 0?void 0:_data$frag.type)===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN?data.frag.level:this.currentLevelIndex;// Do not retry level. Escalate to fatal if switching levels fails.
|
|
|
data.levelRetry=false;break;case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_TIMEOUT:// Do not perform level switch if an error occurred using delivery directives
|
|
|
// Attempt to reload level without directives first
|
|
|
if(context){if(context.deliveryDirectives){levelSwitch=false;}levelIndex=context.level;}levelError=true;break;case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.REMUX_ALLOC_ERROR:levelIndex=(_data$level=data.level)!=null?_data$level:this.currentLevelIndex;levelError=true;break;}if(levelIndex!==undefined){this.recoverLevel(data,levelIndex,levelError,levelSwitch);}}/**
|
|
|
* Switch to a redundant stream if any available.
|
|
|
* If redundant stream is not available, emergency switch down if ABR mode is enabled.
|
|
|
*/;_proto.recoverLevel=function recoverLevel(errorEvent,levelIndex,levelError,levelSwitch){var errorDetails=errorEvent.details;var level=this._levels[levelIndex];level.loadError++;if(levelError){var retrying=this.retryLoadingOrFail(errorEvent);if(retrying){// boolean used to inform stream controller not to switch back to IDLE on non fatal error
|
|
|
errorEvent.levelRetry=true;}else{this.currentLevelIndex=-1;return;}}if(levelSwitch){var redundantLevels=level.url.length;// Try redundant fail-over until level.loadError reaches redundantLevels
|
|
|
if(redundantLevels>1&&level.loadError<redundantLevels){errorEvent.levelRetry=true;this.redundantFailover(levelIndex);}else if(this.manualLevelIndex===-1){// Search for next level to retry
|
|
|
var nextLevel=-1;var levels=this._levels;for(var i=levels.length;i--;){var candidate=(i+this.currentLevelIndex)%levels.length;if(candidate!==this.currentLevelIndex&&levels[candidate].loadError===0){nextLevel=candidate;break;}}if(nextLevel>-1&&this.currentLevelIndex!==nextLevel){this.warn(errorDetails+": switch to "+nextLevel);errorEvent.levelRetry=true;this.hls.nextAutoLevel=nextLevel;}else if(errorEvent.levelRetry===false){// No levels to switch to and no more retries
|
|
|
errorEvent.fatal=true;}}}};_proto.redundantFailover=function redundantFailover(levelIndex){var level=this._levels[levelIndex];var redundantLevels=level.url.length;if(redundantLevels>1){// Update the url id of all levels so that we stay on the same set of variants when level switching
|
|
|
var newUrlId=(level.urlId+1)%redundantLevels;this.warn("Switching to redundant URL-id "+newUrlId);this._levels.forEach(function(level){level.urlId=newUrlId;});this.level=levelIndex;}}// reset errors on the successful load of a fragment
|
|
|
;_proto.onFragLoaded=function onFragLoaded(event,_ref3){var frag=_ref3.frag;if(frag!==undefined&&frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN){var level=this._levels[frag.level];if(level!==undefined){level.fragmentError=0;level.loadError=0;}}};_proto.onLevelLoaded=function onLevelLoaded(event,data){var _data$deliveryDirecti2;var level=data.level,details=data.details;var curLevel=this._levels[level];if(!curLevel){var _data$deliveryDirecti;this.warn("Invalid level index "+level);if((_data$deliveryDirecti=data.deliveryDirectives)!==null&&_data$deliveryDirecti!==void 0&&_data$deliveryDirecti.skip){details.deltaUpdateFailed=true;}return;}// only process level loaded events matching with expected level
|
|
|
if(level===this.currentLevelIndex){// reset level load error counter on successful level loaded only if there is no issues with fragments
|
|
|
if(curLevel.fragmentError===0){curLevel.loadError=0;this.retryCount=0;}this.playlistLoaded(level,data,curLevel.details);}else if((_data$deliveryDirecti2=data.deliveryDirectives)!==null&&_data$deliveryDirecti2!==void 0&&_data$deliveryDirecti2.skip){// received a delta playlist update that cannot be merged
|
|
|
details.deltaUpdateFailed=true;}};_proto.onAudioTrackSwitched=function onAudioTrackSwitched(event,data){var currentLevel=this.hls.levels[this.currentLevelIndex];if(!currentLevel){return;}if(currentLevel.audioGroupIds){var urlId=-1;var audioGroupId=this.hls.audioTracks[data.id].groupId;for(var i=0;i<currentLevel.audioGroupIds.length;i++){if(currentLevel.audioGroupIds[i]===audioGroupId){urlId=i;break;}}if(urlId!==currentLevel.urlId){currentLevel.urlId=urlId;this.startLoad();}}};_proto.loadPlaylist=function loadPlaylist(hlsUrlParameters){_BasePlaylistControll.prototype.loadPlaylist.call(this);var level=this.currentLevelIndex;var currentLevel=this._levels[level];if(this.canLoad&¤tLevel&¤tLevel.url.length>0){var id=currentLevel.urlId;var url=currentLevel.url[id];if(hlsUrlParameters){try{url=hlsUrlParameters.addDirectives(url);}catch(error){this.warn("Could not construct new URL with HLS Delivery Directives: "+error);}}this.log("Attempt loading level index "+level+((hlsUrlParameters===null||hlsUrlParameters===void 0?void 0:hlsUrlParameters.msn)!==undefined?' at sn '+hlsUrlParameters.msn+' part '+hlsUrlParameters.part:'')+" with URL-id "+id+" "+url);// console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
|
|
|
// console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
|
|
|
this.clearTimer();this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING,{url:url,level:level,id:id,deliveryDirectives:hlsUrlParameters||null});}};_proto.removeLevel=function removeLevel(levelIndex,urlId){var filterLevelAndGroupByIdIndex=function filterLevelAndGroupByIdIndex(url,id){return id!==urlId;};var levels=this._levels.filter(function(level,index){if(index!==levelIndex){return true;}if(level.url.length>1&&urlId!==undefined){level.url=level.url.filter(filterLevelAndGroupByIdIndex);if(level.audioGroupIds){level.audioGroupIds=level.audioGroupIds.filter(filterLevelAndGroupByIdIndex);}if(level.textGroupIds){level.textGroupIds=level.textGroupIds.filter(filterLevelAndGroupByIdIndex);}level.urlId=0;return true;}return false;}).map(function(level,index){var details=level.details;if(details!==null&&details!==void 0&&details.fragments){details.fragments.forEach(function(fragment){fragment.level=index;});}return level;});this._levels=levels;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVELS_UPDATED,{levels:levels});};_createClass(LevelController,[{key:"levels",get:function get(){if(this._levels.length===0){return null;}return this._levels;}},{key:"level",get:function get(){return this.currentLevelIndex;},set:function set(newLevel){var _levels$newLevel;var levels=this._levels;if(levels.length===0){return;}if(this.currentLevelIndex===newLevel&&(_levels$newLevel=levels[newLevel])!==null&&_levels$newLevel!==void 0&&_levels$newLevel.details){return;}// check if level idx is valid
|
|
|
if(newLevel<0||newLevel>=levels.length){// invalid level id given, trigger error
|
|
|
var fatal=newLevel<0;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.OTHER_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_SWITCH_ERROR,level:newLevel,fatal:fatal,reason:'invalid level idx'});if(fatal){return;}newLevel=Math.min(newLevel,levels.length-1);}// stopping live reloading timer if any
|
|
|
this.clearTimer();var lastLevelIndex=this.currentLevelIndex;var lastLevel=levels[lastLevelIndex];var level=levels[newLevel];this.log("switching to level "+newLevel+" from "+lastLevelIndex);this.currentLevelIndex=newLevel;var levelSwitchingData=_extends({},level,{level:newLevel,maxBitrate:level.maxBitrate,uri:level.uri,urlId:level.urlId});// @ts-ignore
|
|
|
delete levelSwitchingData._urlId;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_SWITCHING,levelSwitchingData);// check if we need to load playlist for this level
|
|
|
var levelDetails=level.details;if(!levelDetails||levelDetails.live){// level not retrieved yet, or live playlist we need to (re)load it
|
|
|
var hlsUrlParameters=this.switchParams(level.uri,lastLevel===null||lastLevel===void 0?void 0:lastLevel.details);this.loadPlaylist(hlsUrlParameters);}}},{key:"manualLevel",get:function get(){return this.manualLevelIndex;},set:function set(newLevel){this.manualLevelIndex=newLevel;if(this._startLevel===undefined){this._startLevel=newLevel;}if(newLevel!==-1){this.level=newLevel;}}},{key:"firstLevel",get:function get(){return this._firstLevel;},set:function set(newLevel){this._firstLevel=newLevel;}},{key:"startLevel",get:function get(){// hls.startLevel takes precedence over config.startLevel
|
|
|
// if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest)
|
|
|
if(this._startLevel===undefined){var configStartLevel=this.hls.config.startLevel;if(configStartLevel!==undefined){return configStartLevel;}else{return this._firstLevel;}}else{return this._startLevel;}},set:function set(newLevel){this._startLevel=newLevel;}},{key:"nextLoadLevel",get:function get(){if(this.manualLevelIndex!==-1){return this.manualLevelIndex;}else{return this.hls.nextAutoLevel;}},set:function set(nextLevel){this.level=nextLevel;if(this.manualLevelIndex===-1){this.hls.nextAutoLevel=nextLevel;}}}]);return LevelController;}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__["default"]);/***/},/***/"./src/controller/level-helper.ts":/*!****************************************!*\
|
|
|
!*** ./src/controller/level-helper.ts ***!
|
|
|
\****************************************/ /***/function srcControllerLevelHelperTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_295586__){"use strict";__nested_webpack_require_295586__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_295586__.d(__webpack_exports__,{/* harmony export */"addGroupId":function addGroupId(){return(/* binding */_addGroupId);},/* harmony export */"addSliding":function addSliding(){return(/* binding */_addSliding);},/* harmony export */"adjustSliding":function adjustSliding(){return(/* binding */_adjustSliding);},/* harmony export */"assignTrackIdsByGroup":function assignTrackIdsByGroup(){return(/* binding */_assignTrackIdsByGroup);},/* harmony export */"computeReloadInterval":function computeReloadInterval(){return(/* binding */_computeReloadInterval);},/* harmony export */"getFragmentWithSN":function getFragmentWithSN(){return(/* binding */_getFragmentWithSN);},/* harmony export */"getPartWith":function getPartWith(){return(/* binding */_getPartWith);},/* harmony export */"mapFragmentIntersection":function mapFragmentIntersection(){return(/* binding */_mapFragmentIntersection);},/* harmony export */"mapPartIntersection":function mapPartIntersection(){return(/* binding */_mapPartIntersection);},/* harmony export */"mergeDetails":function mergeDetails(){return(/* binding */_mergeDetails);},/* harmony export */"updateFragPTSDTS":function updateFragPTSDTS(){return(/* binding */_updateFragPTSDTS);},/* harmony export */"updatePTS":function updatePTS(){return(/* binding */_updatePTS);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_295586__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_295586__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _loader_date_range__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_295586__(/*! ../loader/date-range */"./src/loader/date-range.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}/**
|
|
|
* @module LevelHelper
|
|
|
* Providing methods dealing with playlist sliding and drift
|
|
|
* */function _addGroupId(level,type,id){switch(type){case'audio':if(!level.audioGroupIds){level.audioGroupIds=[];}level.audioGroupIds.push(id);break;case'text':if(!level.textGroupIds){level.textGroupIds=[];}level.textGroupIds.push(id);break;}}function _assignTrackIdsByGroup(tracks){var groups={};tracks.forEach(function(track){var groupId=track.groupId||'';track.id=groups[groupId]=groups[groupId]||0;groups[groupId]++;});}function _updatePTS(fragments,fromIdx,toIdx){var fragFrom=fragments[fromIdx];var fragTo=fragments[toIdx];updateFromToPTS(fragFrom,fragTo);}function updateFromToPTS(fragFrom,fragTo){var fragToPTS=fragTo.startPTS;// if we know startPTS[toIdx]
|
|
|
if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fragToPTS)){// update fragment duration.
|
|
|
// it helps to fix drifts between playlist reported duration and fragment real duration
|
|
|
var duration=0;var frag;if(fragTo.sn>fragFrom.sn){duration=fragToPTS-fragFrom.start;frag=fragFrom;}else{duration=fragFrom.start-fragToPTS;frag=fragTo;}// TODO? Drift can go either way, or the playlist could be completely accurate
|
|
|
// console.assert(duration > 0,
|
|
|
// `duration of ${duration} computed for frag ${frag.sn}, level ${frag.level}, there should be some duration drift between playlist and fragment!`);
|
|
|
if(frag.duration!==duration){frag.duration=duration;}// we dont know startPTS[toIdx]
|
|
|
}else if(fragTo.sn>fragFrom.sn){var contiguous=fragFrom.cc===fragTo.cc;// TODO: With part-loading end/durations we need to confirm the whole fragment is loaded before using (or setting) minEndPTS
|
|
|
if(contiguous&&fragFrom.minEndPTS){fragTo.start=fragFrom.start+(fragFrom.minEndPTS-fragFrom.start);}else{fragTo.start=fragFrom.start+fragFrom.duration;}}else{fragTo.start=Math.max(fragFrom.start-fragTo.duration,0);}}function _updateFragPTSDTS(details,frag,startPTS,endPTS,startDTS,endDTS){var parsedMediaDuration=endPTS-startPTS;if(parsedMediaDuration<=0){_utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('Fragment should have a positive duration',frag);endPTS=startPTS+frag.duration;endDTS=startDTS+frag.duration;}var maxStartPTS=startPTS;var minEndPTS=endPTS;var fragStartPts=frag.startPTS;var fragEndPts=frag.endPTS;if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fragStartPts)){// delta PTS between audio and video
|
|
|
var deltaPTS=Math.abs(fragStartPts-startPTS);if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.deltaPTS)){frag.deltaPTS=deltaPTS;}else{frag.deltaPTS=Math.max(deltaPTS,frag.deltaPTS);}maxStartPTS=Math.max(startPTS,fragStartPts);startPTS=Math.min(startPTS,fragStartPts);startDTS=Math.min(startDTS,frag.startDTS);minEndPTS=Math.min(endPTS,fragEndPts);endPTS=Math.max(endPTS,fragEndPts);endDTS=Math.max(endDTS,frag.endDTS);}frag.duration=endPTS-startPTS;var drift=startPTS-frag.start;frag.start=frag.startPTS=startPTS;frag.maxStartPTS=maxStartPTS;frag.startDTS=startDTS;frag.endPTS=endPTS;frag.minEndPTS=minEndPTS;frag.endDTS=endDTS;var sn=frag.sn;// 'initSegment'
|
|
|
// exit if sn out of range
|
|
|
if(!details||sn<details.startSN||sn>details.endSN){return 0;}var i;var fragIdx=sn-details.startSN;var fragments=details.fragments;// update frag reference in fragments array
|
|
|
// rationale is that fragments array might not contain this frag object.
|
|
|
// this will happen if playlist has been refreshed between frag loading and call to updateFragPTSDTS()
|
|
|
// if we don't update frag, we won't be able to propagate PTS info on the playlist
|
|
|
// resulting in invalid sliding computation
|
|
|
fragments[fragIdx]=frag;// adjust fragment PTS/duration from seqnum-1 to frag 0
|
|
|
for(i=fragIdx;i>0;i--){updateFromToPTS(fragments[i],fragments[i-1]);}// adjust fragment PTS/duration from seqnum to last frag
|
|
|
for(i=fragIdx;i<fragments.length-1;i++){updateFromToPTS(fragments[i],fragments[i+1]);}if(details.fragmentHint){updateFromToPTS(fragments[fragments.length-1],details.fragmentHint);}details.PTSKnown=details.alignedSliding=true;return drift;}function _mergeDetails(oldDetails,newDetails){// Track the last initSegment processed. Initialize it to the last one on the timeline.
|
|
|
var currentInitSegment=null;var oldFragments=oldDetails.fragments;for(var i=oldFragments.length-1;i>=0;i--){var oldInit=oldFragments[i].initSegment;if(oldInit){currentInitSegment=oldInit;break;}}if(oldDetails.fragmentHint){// prevent PTS and duration from being adjusted on the next hint
|
|
|
delete oldDetails.fragmentHint.endPTS;}// check if old/new playlists have fragments in common
|
|
|
// loop through overlapping SN and update startPTS , cc, and duration if any found
|
|
|
var ccOffset=0;var PTSFrag;_mapFragmentIntersection(oldDetails,newDetails,function(oldFrag,newFrag){if(oldFrag.relurl){// Do not compare CC if the old fragment has no url. This is a level.fragmentHint used by LL-HLS parts.
|
|
|
// It maybe be off by 1 if it was created before any parts or discontinuity tags were appended to the end
|
|
|
// of the playlist.
|
|
|
ccOffset=oldFrag.cc-newFrag.cc;}if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(oldFrag.startPTS)&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(oldFrag.endPTS)){newFrag.start=newFrag.startPTS=oldFrag.startPTS;newFrag.startDTS=oldFrag.startDTS;newFrag.appendedPTS=oldFrag.appendedPTS;newFrag.maxStartPTS=oldFrag.maxStartPTS;newFrag.endPTS=oldFrag.endPTS;newFrag.endDTS=oldFrag.endDTS;newFrag.minEndPTS=oldFrag.minEndPTS;newFrag.duration=oldFrag.endPTS-oldFrag.startPTS;if(newFrag.duration){PTSFrag=newFrag;}// PTS is known when any segment has startPTS and endPTS
|
|
|
newDetails.PTSKnown=newDetails.alignedSliding=true;}newFrag.elementaryStreams=oldFrag.elementaryStreams;newFrag.loader=oldFrag.loader;newFrag.stats=oldFrag.stats;newFrag.urlId=oldFrag.urlId;if(oldFrag.initSegment){newFrag.initSegment=oldFrag.initSegment;currentInitSegment=oldFrag.initSegment;}});if(currentInitSegment){var fragmentsToCheck=newDetails.fragmentHint?newDetails.fragments.concat(newDetails.fragmentHint):newDetails.fragments;fragmentsToCheck.forEach(function(frag){var _currentInitSegment;if(!frag.initSegment||frag.initSegment.relurl===((_currentInitSegment=currentInitSegment)===null||_currentInitSegment===void 0?void 0:_currentInitSegment.relurl)){frag.initSegment=currentInitSegment;}});}if(newDetails.skippedSegments){newDetails.deltaUpdateFailed=newDetails.fragments.some(function(frag){return!frag;});if(newDetails.deltaUpdateFailed){_utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('[level-helper] Previous playlist missing segments skipped in delta playlist');for(var _i=newDetails.skippedSegments;_i--;){newDetails.fragments.shift();}newDetails.startSN=newDetails.fragments[0].sn;newDetails.startCC=newDetails.fragments[0].cc;}else if(newDetails.canSkipDateRanges){newDetails.dateRanges=mergeDateRanges(oldDetails.dateRanges,newDetails.dateRanges,newDetails.recentlyRemovedDateranges);}}var newFragments=newDetails.fragments;if(ccOffset){_utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('discontinuity sliding from playlist, take drift into account');for(var _i2=0;_i2<newFragments.length;_i2++){newFragments[_i2].cc+=ccOffset;}}if(newDetails.skippedSegments){newDetails.startCC=newDetails.fragments[0].cc;}// Merge parts
|
|
|
_mapPartIntersection(oldDetails.partList,newDetails.partList,function(oldPart,newPart){newPart.elementaryStreams=oldPart.elementaryStreams;newPart.stats=oldPart.stats;});// if at least one fragment contains PTS info, recompute PTS information for all fragments
|
|
|
if(PTSFrag){_updateFragPTSDTS(newDetails,PTSFrag,PTSFrag.startPTS,PTSFrag.endPTS,PTSFrag.startDTS,PTSFrag.endDTS);}else{// ensure that delta is within oldFragments range
|
|
|
// also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
|
|
|
// in that case we also need to adjust start offset of all fragments
|
|
|
_adjustSliding(oldDetails,newDetails);}if(newFragments.length){newDetails.totalduration=newDetails.edge-newFragments[0].start;}newDetails.driftStartTime=oldDetails.driftStartTime;newDetails.driftStart=oldDetails.driftStart;var advancedDateTime=newDetails.advancedDateTime;if(newDetails.advanced&&advancedDateTime){var edge=newDetails.edge;if(!newDetails.driftStart){newDetails.driftStartTime=advancedDateTime;newDetails.driftStart=edge;}newDetails.driftEndTime=advancedDateTime;newDetails.driftEnd=edge;}else{newDetails.driftEndTime=oldDetails.driftEndTime;newDetails.driftEnd=oldDetails.driftEnd;newDetails.advancedDateTime=oldDetails.advancedDateTime;}}function mergeDateRanges(oldDateRanges,deltaDateRanges,recentlyRemovedDateranges){var dateRanges=_extends({},oldDateRanges);if(recentlyRemovedDateranges){recentlyRemovedDateranges.forEach(function(id){delete dateRanges[id];});}Object.keys(deltaDateRanges).forEach(function(id){var dateRange=new _loader_date_range__WEBPACK_IMPORTED_MODULE_2__.DateRange(deltaDateRanges[id].attr,dateRanges[id]);if(dateRange.isValid){dateRanges[id]=dateRange;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn("Ignoring invalid Playlist Delta Update DATERANGE tag: \""+JSON.stringify(deltaDateRanges[id].attr)+"\"");}});return dateRanges;}function _mapPartIntersection(oldParts,newParts,intersectionFn){if(oldParts&&newParts){var delta=0;for(var i=0,len=oldParts.length;i<=len;i++){var _oldPart=oldParts[i];var _newPart=newParts[i+delta];if(_oldPart&&_newPart&&_oldPart.index===_newPart.index&&_oldPart.fragment.sn===_newPart.fragment.sn){intersectionFn(_oldPart,_newPart);}else{delta--;}}}}function _mapFragmentIntersection(oldDetails,newDetails,intersectionFn){var skippedSegments=newDetails.skippedSegments;var start=Math.max(oldDetails.startSN,newDetails.startSN)-newDetails.startSN;var end=(oldDetails.fragmentHint?1:0)+(skippedSegments?newDetails.endSN:Math.min(oldDetails.endSN,newDetails.endSN))-newDetails.startSN;var delta=newDetails.startSN-oldDetails.startSN;var newFrags=newDetails.fragmentHint?newDetails.fragments.concat(newDetails.fragmentHint):newDetails.fragments;var oldFrags=oldDetails.fragmentHint?oldDetails.fragments.concat(oldDetails.fragmentHint):oldDetails.fragments;for(var i=start;i<=end;i++){var _oldFrag=oldFrags[delta+i];var _newFrag=newFrags[i];if(skippedSegments&&!_newFrag&&i<skippedSegments){// Fill in skipped segments in delta playlist
|
|
|
_newFrag=newDetails.fragments[i]=_oldFrag;}if(_oldFrag&&_newFrag){intersectionFn(_oldFrag,_newFrag);}}}function _adjustSliding(oldDetails,newDetails){var delta=newDetails.startSN+newDetails.skippedSegments-oldDetails.startSN;var oldFragments=oldDetails.fragments;if(delta<0||delta>=oldFragments.length){return;}_addSliding(newDetails,oldFragments[delta].start);}function _addSliding(details,start){if(start){var fragments=details.fragments;for(var i=details.skippedSegments;i<fragments.length;i++){fragments[i].start+=start;}if(details.fragmentHint){details.fragmentHint.start+=start;}}}function _computeReloadInterval(newDetails,distanceToLiveEdgeMs){if(distanceToLiveEdgeMs===void 0){distanceToLiveEdgeMs=Infinity;}var reloadInterval=1000*newDetails.targetduration;if(newDetails.updated){// Use last segment duration when shorter than target duration and near live edge
|
|
|
var fragments=newDetails.fragments;var liveEdgeMaxTargetDurations=4;if(fragments.length&&reloadInterval*liveEdgeMaxTargetDurations>distanceToLiveEdgeMs){var lastSegmentDuration=fragments[fragments.length-1].duration*1000;if(lastSegmentDuration<reloadInterval){reloadInterval=lastSegmentDuration;}}}else{// estimate = 'miss half average';
|
|
|
// follow HLS Spec, If the client reloads a Playlist file and finds that it has not
|
|
|
// changed then it MUST wait for a period of one-half the target
|
|
|
// duration before retrying.
|
|
|
reloadInterval/=2;}return Math.round(reloadInterval);}function _getFragmentWithSN(level,sn,fragCurrent){if(!level||!level.details){return null;}var levelDetails=level.details;var fragment=levelDetails.fragments[sn-levelDetails.startSN];if(fragment){return fragment;}fragment=levelDetails.fragmentHint;if(fragment&&fragment.sn===sn){return fragment;}if(sn<levelDetails.startSN&&fragCurrent&&fragCurrent.sn===sn){return fragCurrent;}return null;}function _getPartWith(level,sn,partIndex){if(!level||!level.details){return null;}var partList=level.details.partList;if(partList){for(var i=partList.length;i--;){var part=partList[i];if(part.index===partIndex&&part.fragment.sn===sn){return part;}}}return null;}/***/},/***/"./src/controller/stream-controller.ts":/*!*********************************************!*\
|
|
|
!*** ./src/controller/stream-controller.ts ***!
|
|
|
\*********************************************/ /***/function srcControllerStreamControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_310592__){"use strict";__nested_webpack_require_310592__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_310592__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */StreamController);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_310592__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_310592__(/*! ./base-stream-controller */"./src/controller/base-stream-controller.ts");/* harmony import */var _is_supported__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_310592__(/*! ../is-supported */"./src/is-supported.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_310592__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_310592__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_310592__(/*! ./fragment-tracker */"./src/controller/fragment-tracker.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_310592__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_310592__(/*! ../loader/fragment */"./src/loader/fragment.ts");/* harmony import */var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_310592__(/*! ../demux/transmuxer-interface */"./src/demux/transmuxer-interface.ts");/* harmony import */var _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_310592__(/*! ../types/transmuxer */"./src/types/transmuxer.ts");/* harmony import */var _gap_controller__WEBPACK_IMPORTED_MODULE_10__=__nested_webpack_require_310592__(/*! ./gap-controller */"./src/controller/gap-controller.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_11__=__nested_webpack_require_310592__(/*! ../errors */"./src/errors.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var TICK_INTERVAL=100;// how often to tick in ms
|
|
|
var StreamController=/*#__PURE__*/function(_BaseStreamController){_inheritsLoose(StreamController,_BaseStreamController);function StreamController(hls,fragmentTracker,keyLoader){var _this;_this=_BaseStreamController.call(this,hls,fragmentTracker,keyLoader,'[stream-controller]')||this;_this.audioCodecSwap=false;_this.gapController=null;_this.level=-1;_this._forceStartLoad=false;_this.altAudio=false;_this.audioOnly=false;_this.fragPlaying=null;_this.onvplaying=null;_this.onvseeked=null;_this.fragLastKbps=0;_this.couldBacktrack=false;_this.backtrackFragment=null;_this.audioCodecSwitch=false;_this.videoBuffer=null;_this._registerListeners();return _this;}var _proto=StreamController.prototype;_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOAD_EMERGENCY_ABORTED,this.onFragLoadEmergencyAborted,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,this.onError,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHING,this.onAudioTrackSwitching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED,this.onAudioTrackSwitched,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CREATED,this.onBufferCreated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHED,this.onBufferFlushed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVELS_UPDATED,this.onLevelsUpdated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_BUFFERED,this.onFragBuffered,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOAD_EMERGENCY_ABORTED,this.onFragLoadEmergencyAborted,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,this.onError,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHING,this.onAudioTrackSwitching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED,this.onAudioTrackSwitched,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CREATED,this.onBufferCreated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHED,this.onBufferFlushed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVELS_UPDATED,this.onLevelsUpdated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_BUFFERED,this.onFragBuffered,this);};_proto.onHandlerDestroying=function onHandlerDestroying(){this._unregisterListeners();this.onMediaDetaching();};_proto.startLoad=function startLoad(startPosition){if(this.levels){var lastCurrentTime=this.lastCurrentTime,hls=this.hls;this.stopLoad();this.setInterval(TICK_INTERVAL);this.level=-1;this.fragLoadError=0;if(!this.startFragRequested){// determine load level
|
|
|
var startLevel=hls.startLevel;if(startLevel===-1){if(hls.config.testBandwidth&&this.levels.length>1){// -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level
|
|
|
startLevel=0;this.bitrateTest=true;}else{startLevel=hls.nextAutoLevel;}}// set new level to playlist loader : this will trigger start level load
|
|
|
// hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
|
|
|
this.level=hls.nextLoadLevel=startLevel;this.loadedmetadata=false;}// if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
|
|
|
if(lastCurrentTime>0&&startPosition===-1){this.log("Override startPosition with lastCurrentTime @"+lastCurrentTime.toFixed(3));startPosition=lastCurrentTime;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;this.nextLoadPosition=this.startPosition=this.lastCurrentTime=startPosition;this.tick();}else{this._forceStartLoad=true;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;}};_proto.stopLoad=function stopLoad(){this._forceStartLoad=false;_BaseStreamController.prototype.stopLoad.call(this);};_proto.doTick=function doTick(){switch(this.state){case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE:this.doTickIdle();break;case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL:{var _levels$level;var levels=this.levels,level=this.level;var details=levels===null||levels===void 0?void 0:(_levels$level=levels[level])===null||_levels$level===void 0?void 0:_levels$level.details;if(details&&(!details.live||this.levelLastLoaded===this.level)){if(this.waitForCdnTuneIn(details)){break;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;break;}break;}case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:{var _this$media;var now=self.performance.now();var retryDate=this.retryDate;// if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
|
|
|
if(!retryDate||now>=retryDate||(_this$media=this.media)!==null&&_this$media!==void 0&&_this$media.seeking){this.log('retryDate reached, switch back to IDLE state');this.resetStartWhenNotLoaded(this.level);this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}}break;default:break;}// check buffer
|
|
|
// check/update current fragment
|
|
|
this.onTickEnd();};_proto.onTickEnd=function onTickEnd(){_BaseStreamController.prototype.onTickEnd.call(this);this.checkBuffer();this.checkFragmentChanged();};_proto.doTickIdle=function doTickIdle(){var hls=this.hls,levelLastLoaded=this.levelLastLoaded,levels=this.levels,media=this.media;var config=hls.config,level=hls.nextLoadLevel;// if start level not parsed yet OR
|
|
|
// if video not attached AND start fragment already requested OR start frag prefetch not enabled
|
|
|
// exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment
|
|
|
if(levelLastLoaded===null||!media&&(this.startFragRequested||!config.startFragPrefetch)){return;}// If the "main" level is audio-only but we are loading an alternate track in the same group, do not load anything
|
|
|
if(this.altAudio&&this.audioOnly){return;}if(!levels||!levels[level]){return;}var levelInfo=levels[level];// if buffer length is less than maxBufLen try to load a new fragment
|
|
|
var bufferInfo=this.getMainFwdBufferInfo();if(bufferInfo===null){return;}var lastDetails=this.getLevelDetails();if(lastDetails&&this._streamEnded(bufferInfo,lastDetails)){var data={};if(this.altAudio){data.type='video';}this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_EOS,data);this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED;return;}// set next load level : this will trigger a playlist load if needed
|
|
|
this.level=hls.nextLoadLevel=level;var levelDetails=levelInfo.details;// if level info not retrieved yet, switch state and wait for level retrieval
|
|
|
// if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
|
|
|
// a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
|
|
|
if(!levelDetails||this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL||levelDetails.live&&this.levelLastLoaded!==level){this.level=level;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL;return;}var bufferLen=bufferInfo.len;// compute max Buffer Length that we could get from this load level, based on level bitrate. don't buffer more than 60 MB and more than 30s
|
|
|
var maxBufLen=this.getMaxBufferLength(levelInfo.maxBitrate);// Stay idle if we are still with buffer margins
|
|
|
if(bufferLen>=maxBufLen){return;}if(this.backtrackFragment&&this.backtrackFragment.start>bufferInfo.end){this.backtrackFragment=null;}var targetBufferTime=this.backtrackFragment?this.backtrackFragment.start:bufferInfo.end;var frag=this.getNextFragment(targetBufferTime,levelDetails);// Avoid backtracking by loading an earlier segment in streams with segments that do not start with a key frame (flagged by `couldBacktrack`)
|
|
|
if(this.couldBacktrack&&!this.fragPrevious&&frag&&frag.sn!=='initSegment'&&this.fragmentTracker.getState(frag)!==_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.OK){var _this$backtrackFragme;var backtrackSn=((_this$backtrackFragme=this.backtrackFragment)!=null?_this$backtrackFragme:frag).sn;var fragIdx=backtrackSn-levelDetails.startSN;var backtrackFrag=levelDetails.fragments[fragIdx-1];if(backtrackFrag&&frag.cc===backtrackFrag.cc){frag=backtrackFrag;this.fragmentTracker.removeFragment(backtrackFrag);}}else if(this.backtrackFragment&&bufferInfo.len){this.backtrackFragment=null;}// Avoid loop loading by using nextLoadPosition set for backtracking
|
|
|
if(frag&&this.fragmentTracker.getState(frag)===_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.OK&&this.nextLoadPosition>targetBufferTime){// Cleanup the fragment tracker before trying to find the next unbuffered fragment
|
|
|
var type=this.audioOnly&&!this.altAudio?_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO:_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO;var mediaBuffer=(type===_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO?this.videoBuffer:this.mediaBuffer)||this.media;if(mediaBuffer){this.afterBufferFlushed(mediaBuffer,type,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);}frag=this.getNextFragment(this.nextLoadPosition,levelDetails);}if(!frag){return;}if(frag.initSegment&&!frag.initSegment.data&&!this.bitrateTest){frag=frag.initSegment;}this.loadFragment(frag,levelDetails,targetBufferTime);};_proto.loadFragment=function loadFragment(frag,levelDetails,targetBufferTime){var _this$media2;// Check if fragment is not loaded
|
|
|
var fragState=this.fragmentTracker.getState(frag);this.fragCurrent=frag;if(fragState===_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.NOT_LOADED){if(frag.sn==='initSegment'){this._loadInitSegment(frag,levelDetails);}else if(this.bitrateTest){this.log("Fragment "+frag.sn+" of level "+frag.level+" is being downloaded to test bitrate and will not be buffered");this._loadBitrateTestFrag(frag,levelDetails);}else{this.startFragRequested=true;_BaseStreamController.prototype.loadFragment.call(this,frag,levelDetails,targetBufferTime);}}else if(fragState===_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.APPENDING){// Lower the buffer size and try again
|
|
|
if(this.reduceMaxBufferLength(frag.duration)){this.fragmentTracker.removeFragment(frag);}}else if(((_this$media2=this.media)===null||_this$media2===void 0?void 0:_this$media2.buffered.length)===0){// Stop gap for bad tracker / buffer flush behavior
|
|
|
this.fragmentTracker.removeAllFragments();}};_proto.getAppendedFrag=function getAppendedFrag(position){var fragOrPart=this.fragmentTracker.getAppendedFrag(position,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);if(fragOrPart&&'fragment'in fragOrPart){return fragOrPart.fragment;}return fragOrPart;};_proto.getBufferedFrag=function getBufferedFrag(position){return this.fragmentTracker.getBufferedFrag(position,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);};_proto.followingBufferedFrag=function followingBufferedFrag(frag){if(frag){// try to get range of next fragment (500ms after this range)
|
|
|
return this.getBufferedFrag(frag.end+0.5);}return null;}/*
|
|
|
on immediate level switch :
|
|
|
- pause playback if playing
|
|
|
- cancel any pending load request
|
|
|
- and trigger a buffer flush
|
|
|
*/;_proto.immediateLevelSwitch=function immediateLevelSwitch(){this.abortCurrentFrag();this.flushMainBuffer(0,Number.POSITIVE_INFINITY);}/**
|
|
|
* try to switch ASAP without breaking video playback:
|
|
|
* in order to ensure smooth but quick level switching,
|
|
|
* we need to find the next flushable buffer range
|
|
|
* we should take into account new segment fetch time
|
|
|
*/;_proto.nextLevelSwitch=function nextLevelSwitch(){var levels=this.levels,media=this.media;// ensure that media is defined and that metadata are available (to retrieve currentTime)
|
|
|
if(media!==null&&media!==void 0&&media.readyState){var fetchdelay;var fragPlayingCurrent=this.getAppendedFrag(media.currentTime);if(fragPlayingCurrent&&fragPlayingCurrent.start>1){// flush buffer preceding current fragment (flush until current fragment start offset)
|
|
|
// minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ...
|
|
|
this.flushMainBuffer(0,fragPlayingCurrent.start-1);}if(!media.paused&&levels){// add a safety delay of 1s
|
|
|
var nextLevelId=this.hls.nextLoadLevel;var nextLevel=levels[nextLevelId];var fragLastKbps=this.fragLastKbps;if(fragLastKbps&&this.fragCurrent){fetchdelay=this.fragCurrent.duration*nextLevel.maxBitrate/(1000*fragLastKbps)+1;}else{fetchdelay=0;}}else{fetchdelay=0;}// this.log('fetchdelay:'+fetchdelay);
|
|
|
// find buffer range that will be reached once new fragment will be fetched
|
|
|
var bufferedFrag=this.getBufferedFrag(media.currentTime+fetchdelay);if(bufferedFrag){// we can flush buffer range following this one without stalling playback
|
|
|
var nextBufferedFrag=this.followingBufferedFrag(bufferedFrag);if(nextBufferedFrag){// if we are here, we can also cancel any loading/demuxing in progress, as they are useless
|
|
|
this.abortCurrentFrag();// start flush position is in next buffered frag. Leave some padding for non-independent segments and smoother playback.
|
|
|
var maxStart=nextBufferedFrag.maxStartPTS?nextBufferedFrag.maxStartPTS:nextBufferedFrag.start;var fragDuration=nextBufferedFrag.duration;var startPts=Math.max(bufferedFrag.end,maxStart+Math.min(Math.max(fragDuration-this.config.maxFragLookUpTolerance,fragDuration*0.5),fragDuration*0.75));this.flushMainBuffer(startPts,Number.POSITIVE_INFINITY);}}}};_proto.abortCurrentFrag=function abortCurrentFrag(){var fragCurrent=this.fragCurrent;this.fragCurrent=null;this.backtrackFragment=null;if(fragCurrent){fragCurrent.abortRequests();}switch(this.state){case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.KEY_LOADING:case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING:case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING:case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED:this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;break;}this.nextLoadPosition=this.getLoadPosition();};_proto.flushMainBuffer=function flushMainBuffer(startOffset,endOffset){_BaseStreamController.prototype.flushMainBuffer.call(this,startOffset,endOffset,this.altAudio?'video':null);};_proto.onMediaAttached=function onMediaAttached(event,data){_BaseStreamController.prototype.onMediaAttached.call(this,event,data);var media=data.media;this.onvplaying=this.onMediaPlaying.bind(this);this.onvseeked=this.onMediaSeeked.bind(this);media.addEventListener('playing',this.onvplaying);media.addEventListener('seeked',this.onvseeked);this.gapController=new _gap_controller__WEBPACK_IMPORTED_MODULE_10__["default"](this.config,media,this.fragmentTracker,this.hls);};_proto.onMediaDetaching=function onMediaDetaching(){var media=this.media;if(media&&this.onvplaying&&this.onvseeked){media.removeEventListener('playing',this.onvplaying);media.removeEventListener('seeked',this.onvseeked);this.onvplaying=this.onvseeked=null;this.videoBuffer=null;}this.fragPlaying=null;if(this.gapController){this.gapController.destroy();this.gapController=null;}_BaseStreamController.prototype.onMediaDetaching.call(this);};_proto.onMediaPlaying=function onMediaPlaying(){// tick to speed up FRAG_CHANGED triggering
|
|
|
this.tick();};_proto.onMediaSeeked=function onMediaSeeked(){var media=this.media;var currentTime=media?media.currentTime:null;if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime)){this.log("Media seeked to "+currentTime.toFixed(3));}// tick to speed up FRAG_CHANGED triggering
|
|
|
this.tick();};_proto.onManifestLoading=function onManifestLoading(){// reset buffer on manifest loading
|
|
|
this.log('Trigger BUFFER_RESET');this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_RESET,undefined);this.fragmentTracker.removeAllFragments();this.couldBacktrack=false;this.startPosition=this.lastCurrentTime=0;this.fragPlaying=null;this.backtrackFragment=null;};_proto.onManifestParsed=function onManifestParsed(event,data){var aac=false;var heaac=false;var codec;data.levels.forEach(function(level){// detect if we have different kind of audio codecs used amongst playlists
|
|
|
codec=level.audioCodec;if(codec){if(codec.indexOf('mp4a.40.2')!==-1){aac=true;}if(codec.indexOf('mp4a.40.5')!==-1){heaac=true;}}});this.audioCodecSwitch=aac&&heaac&&!(0,_is_supported__WEBPACK_IMPORTED_MODULE_2__.changeTypeSupported)();if(this.audioCodecSwitch){this.log('Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC');}this.levels=data.levels;this.startFragRequested=false;};_proto.onLevelLoading=function onLevelLoading(event,data){var levels=this.levels;if(!levels||this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE){return;}var level=levels[data.level];if(!level.details||level.details.live&&this.levelLastLoaded!==data.level||this.waitForCdnTuneIn(level.details)){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL;}};_proto.onLevelLoaded=function onLevelLoaded(event,data){var _curLevel$details;var levels=this.levels;var newLevelId=data.level;var newDetails=data.details;var duration=newDetails.totalduration;if(!levels){this.warn("Levels were reset while loading level "+newLevelId);return;}this.log("Level "+newLevelId+" loaded ["+newDetails.startSN+","+newDetails.endSN+"], cc ["+newDetails.startCC+", "+newDetails.endCC+"] duration:"+duration);var fragCurrent=this.fragCurrent;if(fragCurrent&&(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING||this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY)){if(fragCurrent.level!==data.level&&fragCurrent.loader){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;this.backtrackFragment=null;fragCurrent.abortRequests();}}var curLevel=levels[newLevelId];var sliding=0;if(newDetails.live||(_curLevel$details=curLevel.details)!==null&&_curLevel$details!==void 0&&_curLevel$details.live){if(!newDetails.fragments[0]){newDetails.deltaUpdateFailed=true;}if(newDetails.deltaUpdateFailed){return;}sliding=this.alignPlaylists(newDetails,curLevel.details);}// override level info
|
|
|
curLevel.details=newDetails;this.levelLastLoaded=newLevelId;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_UPDATED,{details:newDetails,level:newLevelId});// only switch back to IDLE state if we were waiting for level to start downloading a new fragment
|
|
|
if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL){if(this.waitForCdnTuneIn(newDetails)){// Wait for Low-Latency CDN Tune-in
|
|
|
return;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}if(!this.startFragRequested){this.setStartPosition(newDetails,sliding);}else if(newDetails.live){this.synchronizeToLiveEdge(newDetails);}// trigger handler right now
|
|
|
this.tick();};_proto._handleFragmentLoadProgress=function _handleFragmentLoadProgress(data){var _frag$initSegment;var frag=data.frag,part=data.part,payload=data.payload;var levels=this.levels;if(!levels){this.warn("Levels were reset while fragment load was in progress. Fragment "+frag.sn+" of level "+frag.level+" will not be buffered");return;}var currentLevel=levels[frag.level];var details=currentLevel.details;if(!details){this.warn("Dropping fragment "+frag.sn+" of level "+frag.level+" after level details were reset");return;}var videoCodec=currentLevel.videoCodec;// time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
|
|
|
var accurateTimeOffset=details.PTSKnown||!details.live;var initSegmentData=(_frag$initSegment=frag.initSegment)===null||_frag$initSegment===void 0?void 0:_frag$initSegment.data;var audioCodec=this._getAudioCodec(currentLevel);// transmux the MPEG-TS data to ISO-BMFF segments
|
|
|
// this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`);
|
|
|
var transmuxer=this.transmuxer=this.transmuxer||new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](this.hls,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN,this._handleTransmuxComplete.bind(this),this._handleTransmuxerFlush.bind(this));var partIndex=part?part.index:-1;var partial=partIndex!==-1;var chunkMeta=new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__.ChunkMetadata(frag.level,frag.sn,frag.stats.chunkCount,payload.byteLength,partIndex,partial);var initPTS=this.initPTS[frag.cc];transmuxer.push(payload,initSegmentData,audioCodec,videoCodec,frag,part,details.totalduration,accurateTimeOffset,chunkMeta,initPTS);};_proto.onAudioTrackSwitching=function onAudioTrackSwitching(event,data){// if any URL found on new audio track, it is an alternate audio track
|
|
|
var fromAltAudio=this.altAudio;var altAudio=!!data.url;var trackId=data.id;// if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered
|
|
|
// don't do anything if we switch to alt audio: audio stream controller is handling it.
|
|
|
// we will just have to change buffer scheduling on audioTrackSwitched
|
|
|
if(!altAudio){if(this.mediaBuffer!==this.media){this.log('Switching on main audio, use media.buffered to schedule main fragment loading');this.mediaBuffer=this.media;var fragCurrent=this.fragCurrent;// we need to refill audio buffer from main: cancel any frag loading to speed up audio switch
|
|
|
if(fragCurrent){this.log('Switching to main audio track, cancel main fragment load');fragCurrent.abortRequests();}// destroy transmuxer to force init segment generation (following audio switch)
|
|
|
this.resetTransmuxer();// switch to IDLE state to load new fragment
|
|
|
this.resetLoadingState();}else if(this.audioOnly){// Reset audio transmuxer so when switching back to main audio we're not still appending where we left off
|
|
|
this.resetTransmuxer();}var hls=this.hls;// If switching from alt to main audio, flush all audio and trigger track switched
|
|
|
if(fromAltAudio){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHING,{startOffset:0,endOffset:Number.POSITIVE_INFINITY,type:'audio'});}hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED,{id:trackId});}};_proto.onAudioTrackSwitched=function onAudioTrackSwitched(event,data){var trackId=data.id;var altAudio=!!this.hls.audioTracks[trackId].url;if(altAudio){var videoBuffer=this.videoBuffer;// if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered
|
|
|
if(videoBuffer&&this.mediaBuffer!==videoBuffer){this.log('Switching on alternate audio, use video.buffered to schedule main fragment loading');this.mediaBuffer=videoBuffer;}}this.altAudio=altAudio;this.tick();};_proto.onBufferCreated=function onBufferCreated(event,data){var tracks=data.tracks;var mediaTrack;var name;var alternate=false;for(var type in tracks){var track=tracks[type];if(track.id==='main'){name=type;mediaTrack=track;// keep video source buffer reference
|
|
|
if(type==='video'){var videoTrack=tracks[type];if(videoTrack){this.videoBuffer=videoTrack.buffer;}}}else{alternate=true;}}if(alternate&&mediaTrack){this.log("Alternate track found, use "+name+".buffered to schedule main fragment loading");this.mediaBuffer=mediaTrack.buffer;}else{this.mediaBuffer=this.media;}};_proto.onFragBuffered=function onFragBuffered(event,data){var frag=data.frag,part=data.part;if(frag&&frag.type!==_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN){return;}if(this.fragContextChanged(frag)){// If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion
|
|
|
// Avoid setting state back to IDLE, since that will interfere with a level switch
|
|
|
this.warn("Fragment "+frag.sn+(part?' p: '+part.index:'')+" of level "+frag.level+" finished buffering, but was aborted. state: "+this.state);if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}return;}var stats=part?part.stats:frag.stats;this.fragLastKbps=Math.round(8*stats.total/(stats.buffering.end-stats.loading.first));if(frag.sn!=='initSegment'){this.fragPrevious=frag;}this.fragBufferedComplete(frag,part);};_proto.onError=function onError(event,data){if(data.type===_errors__WEBPACK_IMPORTED_MODULE_11__.ErrorTypes.KEY_SYSTEM_ERROR){this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN,data);return;}switch(data.details){case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_LOAD_TIMEOUT:case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_PARSING_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.KEY_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.KEY_LOAD_TIMEOUT:this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN,data);break;case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.LEVEL_LOAD_ERROR:case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.LEVEL_LOAD_TIMEOUT:if(this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR){if(data.fatal){// if fatal error, stop processing
|
|
|
this.warn(""+data.details);this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR;}else{// in case of non fatal error while loading level, if level controller is not retrying to load level , switch back to IDLE
|
|
|
if(!data.levelRetry&&this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;}}}break;case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.BUFFER_FULL_ERROR:// if in appending state
|
|
|
if(data.parent==='main'&&(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING||this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED)){var flushBuffer=true;var bufferedInfo=this.getFwdBufferInfo(this.media,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);// 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
|
|
|
// reduce max buf len if current position is buffered
|
|
|
if(bufferedInfo&&bufferedInfo.len>0.5){flushBuffer=!this.reduceMaxBufferLength(bufferedInfo.len);}if(flushBuffer){// current position is not buffered, but browser is still complaining about buffer full error
|
|
|
// this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
|
|
|
// in that case flush the whole buffer to recover
|
|
|
this.warn('buffer full error also media.currentTime is not buffered, flush main');// flush main buffer
|
|
|
this.immediateLevelSwitch();}this.resetLoadingState();}break;default:break;}}// Checks the health of the buffer and attempts to resolve playback stalls.
|
|
|
;_proto.checkBuffer=function checkBuffer(){var media=this.media,gapController=this.gapController;if(!media||!gapController||!media.readyState){// Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0)
|
|
|
return;}if(this.loadedmetadata||!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(media).length){// Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers
|
|
|
var activeFrag=this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE?this.fragCurrent:null;gapController.poll(this.lastCurrentTime,activeFrag);}this.lastCurrentTime=media.currentTime;};_proto.onFragLoadEmergencyAborted=function onFragLoadEmergencyAborted(){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;// if loadedmetadata is not set, it means that we are emergency switch down on first frag
|
|
|
// in that case, reset startFragRequested flag
|
|
|
if(!this.loadedmetadata){this.startFragRequested=false;this.nextLoadPosition=this.startPosition;}this.tickImmediate();};_proto.onBufferFlushed=function onBufferFlushed(event,_ref){var type=_ref.type;if(type!==_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO||this.audioOnly&&!this.altAudio){var mediaBuffer=(type===_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO?this.videoBuffer:this.mediaBuffer)||this.media;this.afterBufferFlushed(mediaBuffer,type,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);}};_proto.onLevelsUpdated=function onLevelsUpdated(event,data){this.levels=data.levels;};_proto.swapAudioCodec=function swapAudioCodec(){this.audioCodecSwap=!this.audioCodecSwap;}/**
|
|
|
* Seeks to the set startPosition if not equal to the mediaElement's current time.
|
|
|
*/;_proto.seekToStartPos=function seekToStartPos(){var media=this.media;if(!media){return;}var currentTime=media.currentTime;var startPosition=this.startPosition;// only adjust currentTime if different from startPosition or if startPosition not buffered
|
|
|
// at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered
|
|
|
if(startPosition>=0&¤tTime<startPosition){if(media.seeking){this.log("could not seek to "+startPosition+", already seeking at "+currentTime);return;}var buffered=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(media);var bufferStart=buffered.length?buffered.start(0):0;var delta=bufferStart-startPosition;if(delta>0&&(delta<this.config.maxBufferHole||delta<this.config.maxFragLookUpTolerance)){this.log("adjusting start position by "+delta+" to match buffer start");startPosition+=delta;this.startPosition=startPosition;}this.log("seek to target start position "+startPosition+" from current time "+currentTime);media.currentTime=startPosition;}};_proto._getAudioCodec=function _getAudioCodec(currentLevel){var audioCodec=this.config.defaultAudioCodec||currentLevel.audioCodec;if(this.audioCodecSwap&&audioCodec){this.log('Swapping audio codec');if(audioCodec.indexOf('mp4a.40.5')!==-1){audioCodec='mp4a.40.2';}else{audioCodec='mp4a.40.5';}}return audioCodec;};_proto._loadBitrateTestFrag=function _loadBitrateTestFrag(frag,levelDetails){var _this2=this;frag.bitrateTest=true;this._doFragLoad(frag,levelDetails).then(function(data){var hls=_this2.hls;if(!data||_this2.fragContextChanged(frag)){return;}_this2.fragLoadError=0;_this2.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;_this2.startFragRequested=false;_this2.bitrateTest=false;var stats=frag.stats;// Bitrate tests fragments are neither parsed nor buffered
|
|
|
stats.parsing.start=stats.parsing.end=stats.buffering.start=stats.buffering.end=self.performance.now();hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOADED,data);frag.bitrateTest=false;});};_proto._handleTransmuxComplete=function _handleTransmuxComplete(transmuxResult){var _id3$samples;var id='main';var hls=this.hls;var remuxResult=transmuxResult.remuxResult,chunkMeta=transmuxResult.chunkMeta;var context=this.getCurrentContext(chunkMeta);if(!context){this.warn("The loading context changed while buffering fragment "+chunkMeta.sn+" of level "+chunkMeta.level+". This chunk will not be buffered.");this.resetStartWhenNotLoaded(chunkMeta.level);return;}var frag=context.frag,part=context.part,level=context.level;var video=remuxResult.video,text=remuxResult.text,id3=remuxResult.id3,initSegment=remuxResult.initSegment;var details=level.details;// The audio-stream-controller handles audio buffering if Hls.js is playing an alternate audio track
|
|
|
var audio=this.altAudio?undefined:remuxResult.audio;// Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level.
|
|
|
// If we are, subsequently check if the currently loading fragment (fragCurrent) has changed.
|
|
|
if(this.fragContextChanged(frag)){return;}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING;if(initSegment){if(initSegment.tracks){this._bufferInitSegment(level,initSegment.tracks,frag,chunkMeta);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_INIT_SEGMENT,{frag:frag,id:id,tracks:initSegment.tracks});}// This would be nice if Number.isFinite acted as a typeguard, but it doesn't. See: https://github.com/Microsoft/TypeScript/issues/10038
|
|
|
var initPTS=initSegment.initPTS;var timescale=initSegment.timescale;if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS)){this.initPTS[frag.cc]=initPTS;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.INIT_PTS_FOUND,{frag:frag,id:id,initPTS:initPTS,timescale:timescale});}}// Avoid buffering if backtracking this fragment
|
|
|
if(video&&remuxResult.independent!==false){if(details){var startPTS=video.startPTS,endPTS=video.endPTS,startDTS=video.startDTS,endDTS=video.endDTS;if(part){part.elementaryStreams[video.type]={startPTS:startPTS,endPTS:endPTS,startDTS:startDTS,endDTS:endDTS};}else{if(video.firstKeyFrame&&video.independent&&chunkMeta.id===1){this.couldBacktrack=true;}if(video.dropped&&video.independent){// Backtrack if dropped frames create a gap after currentTime
|
|
|
var bufferInfo=this.getMainFwdBufferInfo();var targetBufferTime=(bufferInfo?bufferInfo.end:this.getLoadPosition())+this.config.maxBufferHole;var startTime=video.firstKeyFramePTS?video.firstKeyFramePTS:startPTS;if(targetBufferTime<startTime-this.config.maxBufferHole){this.backtrack(frag);return;}// Set video stream start to fragment start so that truncated samples do not distort the timeline, and mark it partial
|
|
|
frag.setElementaryStreamInfo(video.type,frag.start,endPTS,frag.start,endDTS,true);}}frag.setElementaryStreamInfo(video.type,startPTS,endPTS,startDTS,endDTS);if(this.backtrackFragment){this.backtrackFragment=frag;}this.bufferFragmentData(video,frag,part,chunkMeta);}}else if(remuxResult.independent===false){this.backtrack(frag);return;}if(audio){var _startPTS=audio.startPTS,_endPTS=audio.endPTS,_startDTS=audio.startDTS,_endDTS=audio.endDTS;if(part){part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO]={startPTS:_startPTS,endPTS:_endPTS,startDTS:_startDTS,endDTS:_endDTS};}frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO,_startPTS,_endPTS,_startDTS,_endDTS);this.bufferFragmentData(audio,frag,part,chunkMeta);}if(details&&id3!==null&&id3!==void 0&&(_id3$samples=id3.samples)!==null&&_id3$samples!==void 0&&_id3$samples.length){var emittedID3={id:id,frag:frag,details:details,samples:id3.samples};hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_METADATA,emittedID3);}if(details&&text){var emittedText={id:id,frag:frag,details:details,samples:text.samples};hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_USERDATA,emittedText);}};_proto._bufferInitSegment=function _bufferInitSegment(currentLevel,tracks,frag,chunkMeta){var _this3=this;if(this.state!==_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING){return;}this.audioOnly=!!tracks.audio&&!tracks.video;// if audio track is expected to come from audio stream controller, discard any coming from main
|
|
|
if(this.altAudio&&!this.audioOnly){delete tracks.audio;}// include levelCodec in audio and video tracks
|
|
|
var audio=tracks.audio,video=tracks.video,audiovideo=tracks.audiovideo;if(audio){var audioCodec=currentLevel.audioCodec;var ua=navigator.userAgent.toLowerCase();if(this.audioCodecSwitch){if(audioCodec){if(audioCodec.indexOf('mp4a.40.5')!==-1){audioCodec='mp4a.40.2';}else{audioCodec='mp4a.40.5';}}// In the case that AAC and HE-AAC audio codecs are signalled in manifest,
|
|
|
// force HE-AAC, as it seems that most browsers prefers it.
|
|
|
// don't force HE-AAC if mono stream, or in Firefox
|
|
|
if(audio.metadata.channelCount!==1&&ua.indexOf('firefox')===-1){audioCodec='mp4a.40.5';}}// HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise
|
|
|
if(ua.indexOf('android')!==-1&&audio.container!=='audio/mpeg'){// Exclude mpeg audio
|
|
|
audioCodec='mp4a.40.2';this.log("Android: force audio codec to "+audioCodec);}if(currentLevel.audioCodec&¤tLevel.audioCodec!==audioCodec){this.log("Swapping manifest audio codec \""+currentLevel.audioCodec+"\" for \""+audioCodec+"\"");}audio.levelCodec=audioCodec;audio.id='main';this.log("Init audio buffer, container:"+audio.container+", codecs[selected/level/parsed]=["+(audioCodec||'')+"/"+(currentLevel.audioCodec||'')+"/"+audio.codec+"]");}if(video){video.levelCodec=currentLevel.videoCodec;video.id='main';this.log("Init video buffer, container:"+video.container+", codecs[level/parsed]=["+(currentLevel.videoCodec||'')+"/"+video.codec+"]");}if(audiovideo){this.log("Init audiovideo buffer, container:"+audiovideo.container+", codecs[level/parsed]=["+(currentLevel.attrs.CODECS||'')+"/"+audiovideo.codec+"]");}this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CODECS,tracks);// loop through tracks that are going to be provided to bufferController
|
|
|
Object.keys(tracks).forEach(function(trackName){var track=tracks[trackName];var initSegment=track.initSegment;if(initSegment!==null&&initSegment!==void 0&&initSegment.byteLength){_this3.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_APPENDING,{type:trackName,data:initSegment,frag:frag,part:null,chunkMeta:chunkMeta,parent:frag.type});}});// trigger handler right now
|
|
|
this.tick();};_proto.getMainFwdBufferInfo=function getMainFwdBufferInfo(){return this.getFwdBufferInfo(this.mediaBuffer?this.mediaBuffer:this.media,_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);};_proto.backtrack=function backtrack(frag){this.couldBacktrack=true;// Causes findFragments to backtrack through fragments to find the keyframe
|
|
|
this.backtrackFragment=frag;this.resetTransmuxer();this.flushBufferGap(frag);this.fragmentTracker.removeFragment(frag);this.fragPrevious=null;this.nextLoadPosition=frag.start;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;};_proto.checkFragmentChanged=function checkFragmentChanged(){var video=this.media;var fragPlayingCurrent=null;if(video&&video.readyState>1&&video.seeking===false){var currentTime=video.currentTime;/* if video element is in seeked state, currentTime can only increase.
|
|
|
(assuming that playback rate is positive ...)
|
|
|
As sometimes currentTime jumps back to zero after a
|
|
|
media decode error, check this, to avoid seeking back to
|
|
|
wrong position after a media decode error
|
|
|
*/if(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.isBuffered(video,currentTime)){fragPlayingCurrent=this.getAppendedFrag(currentTime);}else if(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.isBuffered(video,currentTime+0.1)){/* ensure that FRAG_CHANGED event is triggered at startup,
|
|
|
when first video frame is displayed and playback is paused.
|
|
|
add a tolerance of 100ms, in case current position is not buffered,
|
|
|
check if current pos+100ms is buffered and use that buffer range
|
|
|
for FRAG_CHANGED event reporting */fragPlayingCurrent=this.getAppendedFrag(currentTime+0.1);}if(fragPlayingCurrent){this.backtrackFragment=null;var fragPlaying=this.fragPlaying;var fragCurrentLevel=fragPlayingCurrent.level;if(!fragPlaying||fragPlayingCurrent.sn!==fragPlaying.sn||fragPlaying.level!==fragCurrentLevel||fragPlayingCurrent.urlId!==fragPlaying.urlId){this.fragPlaying=fragPlayingCurrent;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_CHANGED,{frag:fragPlayingCurrent});if(!fragPlaying||fragPlaying.level!==fragCurrentLevel){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_SWITCHED,{level:fragCurrentLevel});}}}}};_createClass(StreamController,[{key:"nextLevel",get:function get(){var frag=this.nextBufferedFrag;if(frag){return frag.level;}return-1;}},{key:"currentFrag",get:function get(){var media=this.media;if(media){return this.fragPlaying||this.getAppendedFrag(media.currentTime);}return null;}},{key:"currentProgramDateTime",get:function get(){var media=this.media;if(media){var currentTime=media.currentTime;var frag=this.currentFrag;if(frag&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime)&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.programDateTime)){var epocMs=frag.programDateTime+(currentTime-frag.start)*1000;return new Date(epocMs);}}return null;}},{key:"currentLevel",get:function get(){var frag=this.currentFrag;if(frag){return frag.level;}return-1;}},{key:"nextBufferedFrag",get:function get(){var frag=this.currentFrag;if(frag){return this.followingBufferedFrag(frag);}return null;}},{key:"forceStartLoad",get:function get(){return this._forceStartLoad;}}]);return StreamController;}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]);/***/},/***/"./src/controller/subtitle-stream-controller.ts":/*!******************************************************!*\
|
|
|
!*** ./src/controller/subtitle-stream-controller.ts ***!
|
|
|
\******************************************************/ /***/function srcControllerSubtitleStreamControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_356468__){"use strict";__nested_webpack_require_356468__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_356468__.d(__webpack_exports__,{/* harmony export */"SubtitleStreamController":function SubtitleStreamController(){return(/* binding */_SubtitleStreamController);}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_356468__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_356468__(/*! ../utils/buffer-helper */"./src/utils/buffer-helper.ts");/* harmony import */var _fragment_finders__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_356468__(/*! ./fragment-finders */"./src/controller/fragment-finders.ts");/* harmony import */var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_356468__(/*! ../utils/discontinuities */"./src/utils/discontinuities.ts");/* harmony import */var _level_helper__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_356468__(/*! ./level-helper */"./src/controller/level-helper.ts");/* harmony import */var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_356468__(/*! ./fragment-tracker */"./src/controller/fragment-tracker.ts");/* harmony import */var _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_356468__(/*! ./base-stream-controller */"./src/controller/base-stream-controller.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_356468__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _types_level__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_356468__(/*! ../types/level */"./src/types/level.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var TICK_INTERVAL=500;// how often to tick in ms
|
|
|
var _SubtitleStreamController=/*#__PURE__*/function(_BaseStreamController){_inheritsLoose(SubtitleStreamController,_BaseStreamController);function SubtitleStreamController(hls,fragmentTracker,keyLoader){var _this;_this=_BaseStreamController.call(this,hls,fragmentTracker,keyLoader,'[subtitle-stream-controller]')||this;_this.levels=[];_this.currentTrackId=-1;_this.tracksBuffered=[];_this.mainDetails=null;_this._registerListeners();return _this;}var _proto=SubtitleStreamController.prototype;_proto.onHandlerDestroying=function onHandlerDestroying(){this._unregisterListeners();this.mainDetails=null;};_proto._registerListeners=function _registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED,this.onSubtitleTracksUpdated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH,this.onSubtitleTrackSwitch,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED,this.onSubtitleTrackLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_FRAG_PROCESSED,this.onSubtitleFragProcessed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED,this.onFragBuffered,this);};_proto._unregisterListeners=function _unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADED,this.onLevelLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED,this.onSubtitleTracksUpdated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH,this.onSubtitleTrackSwitch,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED,this.onSubtitleTrackLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_FRAG_PROCESSED,this.onSubtitleFragProcessed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED,this.onFragBuffered,this);};_proto.startLoad=function startLoad(startPosition){this.stopLoad();this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;this.setInterval(TICK_INTERVAL);this.nextLoadPosition=this.startPosition=this.lastCurrentTime=startPosition;this.tick();};_proto.onManifestLoading=function onManifestLoading(){this.mainDetails=null;this.fragmentTracker.removeAllFragments();};_proto.onLevelLoaded=function onLevelLoaded(event,data){this.mainDetails=data.details;};_proto.onSubtitleFragProcessed=function onSubtitleFragProcessed(event,data){var frag=data.frag,success=data.success;this.fragPrevious=frag;this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;if(!success){return;}var buffered=this.tracksBuffered[this.currentTrackId];if(!buffered){return;}// Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo
|
|
|
// so we can re-use the logic used to detect how much has been buffered
|
|
|
var timeRange;var fragStart=frag.start;for(var i=0;i<buffered.length;i++){if(fragStart>=buffered[i].start&&fragStart<=buffered[i].end){timeRange=buffered[i];break;}}var fragEnd=frag.start+frag.duration;if(timeRange){timeRange.end=fragEnd;}else{timeRange={start:fragStart,end:fragEnd};buffered.push(timeRange);}this.fragmentTracker.fragBuffered(frag);};_proto.onBufferFlushing=function onBufferFlushing(event,data){var startOffset=data.startOffset,endOffset=data.endOffset;if(startOffset===0&&endOffset!==Number.POSITIVE_INFINITY){var currentTrackId=this.currentTrackId,levels=this.levels;if(!levels.length||!levels[currentTrackId]||!levels[currentTrackId].details){return;}var trackDetails=levels[currentTrackId].details;var targetDuration=trackDetails.targetduration;var endOffsetSubtitles=endOffset-targetDuration;if(endOffsetSubtitles<=0){return;}data.endOffsetSubtitles=Math.max(0,endOffsetSubtitles);this.tracksBuffered.forEach(function(buffered){for(var i=0;i<buffered.length;){if(buffered[i].end<=endOffsetSubtitles){buffered.shift();continue;}else if(buffered[i].start<endOffsetSubtitles){buffered[i].start=endOffsetSubtitles;}else{break;}i++;}});this.fragmentTracker.removeFragmentsInRange(startOffset,endOffsetSubtitles,_types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.SUBTITLE);}};_proto.onFragBuffered=function onFragBuffered(event,data){if(!this.loadedmetadata&&data.frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.MAIN){var _this$media;if((_this$media=this.media)!==null&&_this$media!==void 0&&_this$media.buffered.length){this.loadedmetadata=true;}}}// If something goes wrong, proceed to next frag, if we were processing one.
|
|
|
;_proto.onError=function onError(event,data){var frag=data.frag;// don't handle error not related to subtitle fragment
|
|
|
if(!frag||frag.type!==_types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.SUBTITLE){return;}if(this.fragCurrent){this.fragCurrent.abortRequests();}this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;}// Got all new subtitle levels.
|
|
|
;_proto.onSubtitleTracksUpdated=function onSubtitleTracksUpdated(event,_ref){var _this2=this;var subtitleTracks=_ref.subtitleTracks;this.tracksBuffered=[];this.levels=subtitleTracks.map(function(mediaPlaylist){return new _types_level__WEBPACK_IMPORTED_MODULE_8__.Level(mediaPlaylist);});this.fragmentTracker.removeAllFragments();this.fragPrevious=null;this.levels.forEach(function(level){_this2.tracksBuffered[level.id]=[];});this.mediaBuffer=null;};_proto.onSubtitleTrackSwitch=function onSubtitleTrackSwitch(event,data){this.currentTrackId=data.id;if(!this.levels.length||this.currentTrackId===-1){this.clearInterval();return;}// Check if track has the necessary details to load fragments
|
|
|
var currentTrack=this.levels[this.currentTrackId];if(currentTrack!==null&¤tTrack!==void 0&¤tTrack.details){this.mediaBuffer=this.mediaBufferTimeRanges;}else{this.mediaBuffer=null;}if(currentTrack){this.setInterval(TICK_INTERVAL);}}// Got a new set of subtitle fragments.
|
|
|
;_proto.onSubtitleTrackLoaded=function onSubtitleTrackLoaded(event,data){var _track$details;var newDetails=data.details,trackId=data.id;var currentTrackId=this.currentTrackId,levels=this.levels;if(!levels.length){return;}var track=levels[currentTrackId];if(trackId>=levels.length||trackId!==currentTrackId||!track){return;}this.mediaBuffer=this.mediaBufferTimeRanges;var sliding=0;if(newDetails.live||(_track$details=track.details)!==null&&_track$details!==void 0&&_track$details.live){var mainDetails=this.mainDetails;if(newDetails.deltaUpdateFailed||!mainDetails){return;}var mainSlidingStartFragment=mainDetails.fragments[0];if(!track.details){if(newDetails.hasProgramDateTime&&mainDetails.hasProgramDateTime){(0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_3__.alignMediaPlaylistByPDT)(newDetails,mainDetails);sliding=newDetails.fragments[0].start;}else if(mainSlidingStartFragment){// line up live playlist with main so that fragments in range are loaded
|
|
|
sliding=mainSlidingStartFragment.start;(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addSliding)(newDetails,sliding);}}else{sliding=this.alignPlaylists(newDetails,track.details);if(sliding===0&&mainSlidingStartFragment){// realign with main when there is no overlap with last refresh
|
|
|
sliding=mainSlidingStartFragment.start;(0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addSliding)(newDetails,sliding);}}}track.details=newDetails;this.levelLastLoaded=trackId;if(!this.startFragRequested&&(this.mainDetails||!newDetails.live)){this.setStartPosition(track.details,sliding);}// trigger handler right now
|
|
|
this.tick();// If playlist is misaligned because of bad PDT or drift, delete details to resync with main on reload
|
|
|
if(newDetails.live&&!this.fragCurrent&&this.media&&this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE){var foundFrag=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_2__.findFragmentByPTS)(null,newDetails.fragments,this.media.currentTime,0);if(!foundFrag){this.warn('Subtitle playlist not aligned with playback');track.details=undefined;}}};_proto._handleFragmentLoadComplete=function _handleFragmentLoadComplete(fragLoadedData){var _this3=this;var frag=fragLoadedData.frag,payload=fragLoadedData.payload;var decryptData=frag.decryptdata;var hls=this.hls;if(this.fragContextChanged(frag)){return;}// check to see if the payload needs to be decrypted
|
|
|
if(payload&&payload.byteLength>0&&decryptData&&decryptData.key&&decryptData.iv&&decryptData.method==='AES-128'){var startTime=performance.now();// decrypt the subtitles
|
|
|
this.decrypter.decrypt(new Uint8Array(payload),decryptData.key.buffer,decryptData.iv.buffer).then(function(decryptedData){var endTime=performance.now();hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_DECRYPTED,{frag:frag,payload:decryptedData,stats:{tstart:startTime,tdecrypt:endTime}});})["catch"](function(err){_this3.warn(err.name+": "+err.message);_this3.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;});}};_proto.doTick=function doTick(){if(!this.media){this.state=_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;return;}if(this.state===_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE){var currentTrackId=this.currentTrackId,levels=this.levels;if(!levels.length||!levels[currentTrackId]||!levels[currentTrackId].details){return;}// Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists
|
|
|
var trackDetails=levels[currentTrackId].details;var targetDuration=trackDetails.targetduration;var config=this.config;var currentTime=this.getLoadPosition();var bufferedInfo=_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_1__.BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId]||[],currentTime-targetDuration,config.maxBufferHole);var targetBufferTime=bufferedInfo.end,bufferLen=bufferedInfo.len;var mainBufferInfo=this.getFwdBufferInfo(this.media,_types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.MAIN);var maxBufLen=this.getMaxBufferLength(mainBufferInfo===null||mainBufferInfo===void 0?void 0:mainBufferInfo.len)+targetDuration;if(bufferLen>maxBufLen){return;}console.assert(trackDetails,'Subtitle track details are defined on idle subtitle stream controller tick');var fragments=trackDetails.fragments;var fragLen=fragments.length;var end=trackDetails.edge;var foundFrag=null;var fragPrevious=this.fragPrevious;if(targetBufferTime<end){var maxFragLookUpTolerance=config.maxFragLookUpTolerance;foundFrag=(0,_fragment_finders__WEBPACK_IMPORTED_MODULE_2__.findFragmentByPTS)(fragPrevious,fragments,Math.max(fragments[0].start,targetBufferTime),maxFragLookUpTolerance);if(!foundFrag&&fragPrevious&&fragPrevious.start<fragments[0].start){foundFrag=fragments[0];}}else{foundFrag=fragments[fragLen-1];}if(!foundFrag){return;}foundFrag=this.mapToInitFragWhenRequired(foundFrag);if(this.fragmentTracker.getState(foundFrag)===_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.NOT_LOADED){// only load if fragment is not loaded
|
|
|
this.loadFragment(foundFrag,trackDetails,targetBufferTime);}}};_proto.getMaxBufferLength=function getMaxBufferLength(mainBufferLength){var maxConfigBuffer=_BaseStreamController.prototype.getMaxBufferLength.call(this);if(!mainBufferLength){return maxConfigBuffer;}return Math.max(maxConfigBuffer,mainBufferLength);};_proto.loadFragment=function loadFragment(frag,levelDetails,targetBufferTime){this.fragCurrent=frag;if(frag.sn==='initSegment'){this._loadInitSegment(frag,levelDetails);}else{this.startFragRequested=true;_BaseStreamController.prototype.loadFragment.call(this,frag,levelDetails,targetBufferTime);}};_createClass(SubtitleStreamController,[{key:"mediaBufferTimeRanges",get:function get(){return new BufferableInstance(this.tracksBuffered[this.currentTrackId]||[]);}}]);return SubtitleStreamController;}(_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__["default"]);var BufferableInstance=function BufferableInstance(timeranges){this.buffered=void 0;var getRange=function getRange(name,index,length){index=index>>>0;if(index>length-1){throw new DOMException("Failed to execute '"+name+"' on 'TimeRanges': The index provided ("+index+") is greater than the maximum bound ("+length+")");}return timeranges[index][name];};this.buffered={get length(){return timeranges.length;},end:function end(index){return getRange('end',index,timeranges.length);},start:function start(index){return getRange('start',index,timeranges.length);}};};/***/},/***/"./src/controller/subtitle-track-controller.ts":/*!*****************************************************!*\
|
|
|
!*** ./src/controller/subtitle-track-controller.ts ***!
|
|
|
\*****************************************************/ /***/function srcControllerSubtitleTrackControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_373166__){"use strict";__nested_webpack_require_373166__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_373166__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_373166__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_373166__(/*! ../utils/texttrack-utils */"./src/utils/texttrack-utils.ts");/* harmony import */var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_373166__(/*! ./base-playlist-controller */"./src/controller/base-playlist-controller.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_373166__(/*! ../types/loader */"./src/types/loader.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}var SubtitleTrackController=/*#__PURE__*/function(_BasePlaylistControll){_inheritsLoose(SubtitleTrackController,_BasePlaylistControll);function SubtitleTrackController(hls){var _this;_this=_BasePlaylistControll.call(this,hls,'[subtitle-track-controller]')||this;_this.media=null;_this.tracks=[];_this.groupId=null;_this.tracksInGroup=[];_this.trackId=-1;_this.selectDefaultTrack=true;_this.queuedDefaultTrack=-1;_this.trackChangeListener=function(){return _this.onTextTracksChanged();};_this.asyncPollTrackChange=function(){return _this.pollTrackChange(0);};_this.useTextTrackPolling=false;_this.subtitlePollingInterval=-1;_this._subtitleDisplay=true;_this.registerListeners();return _this;}var _proto=SubtitleTrackController.prototype;_proto.destroy=function destroy(){this.unregisterListeners();this.tracks.length=0;this.tracksInGroup.length=0;this.trackChangeListener=this.asyncPollTrackChange=null;_BasePlaylistControll.prototype.destroy.call(this);};_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING,this.onLevelSwitching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED,this.onSubtitleTrackLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED,this.onMediaAttached,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED,this.onManifestParsed,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING,this.onLevelSwitching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED,this.onSubtitleTrackLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,this.onError,this);}// Listen for subtitle track change, then extract the current track ID.
|
|
|
;_proto.onMediaAttached=function onMediaAttached(event,data){this.media=data.media;if(!this.media){return;}if(this.queuedDefaultTrack>-1){this.subtitleTrack=this.queuedDefaultTrack;this.queuedDefaultTrack=-1;}this.useTextTrackPolling=!(this.media.textTracks&&'onchange'in this.media.textTracks);if(this.useTextTrackPolling){this.pollTrackChange(500);}else{this.media.textTracks.addEventListener('change',this.asyncPollTrackChange);}};_proto.pollTrackChange=function pollTrackChange(timeout){self.clearInterval(this.subtitlePollingInterval);this.subtitlePollingInterval=self.setInterval(this.trackChangeListener,timeout);};_proto.onMediaDetaching=function onMediaDetaching(){if(!this.media){return;}self.clearInterval(this.subtitlePollingInterval);if(!this.useTextTrackPolling){this.media.textTracks.removeEventListener('change',this.asyncPollTrackChange);}if(this.trackId>-1){this.queuedDefaultTrack=this.trackId;}var textTracks=filterSubtitleTracks(this.media.textTracks);// Clear loaded cues on media detachment from tracks
|
|
|
textTracks.forEach(function(track){(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__.clearCurrentCues)(track);});// Disable all subtitle tracks before detachment so when reattached only tracks in that content are enabled.
|
|
|
this.subtitleTrack=-1;this.media=null;};_proto.onManifestLoading=function onManifestLoading(){this.tracks=[];this.groupId=null;this.tracksInGroup=[];this.trackId=-1;this.selectDefaultTrack=true;}// Fired whenever a new manifest is loaded.
|
|
|
;_proto.onManifestParsed=function onManifestParsed(event,data){this.tracks=data.subtitleTracks;};_proto.onSubtitleTrackLoaded=function onSubtitleTrackLoaded(event,data){var id=data.id,details=data.details;var trackId=this.trackId;var currentTrack=this.tracksInGroup[trackId];if(!currentTrack){this.warn("Invalid subtitle track id "+id);return;}var curDetails=currentTrack.details;currentTrack.details=data.details;this.log("subtitle track "+id+" loaded ["+details.startSN+"-"+details.endSN+"]");if(id===this.trackId){this.retryCount=0;this.playlistLoaded(id,data,curDetails);}};_proto.onLevelLoading=function onLevelLoading(event,data){this.switchLevel(data.level);};_proto.onLevelSwitching=function onLevelSwitching(event,data){this.switchLevel(data.level);};_proto.switchLevel=function switchLevel(levelIndex){var levelInfo=this.hls.levels[levelIndex];if(!(levelInfo!==null&&levelInfo!==void 0&&levelInfo.textGroupIds)){return;}var textGroupId=levelInfo.textGroupIds[levelInfo.urlId];if(this.groupId!==textGroupId){var lastTrack=this.tracksInGroup?this.tracksInGroup[this.trackId]:undefined;var subtitleTracks=this.tracks.filter(function(track){return!textGroupId||track.groupId===textGroupId;});this.tracksInGroup=subtitleTracks;var initialTrackId=this.findTrackId(lastTrack===null||lastTrack===void 0?void 0:lastTrack.name)||this.findTrackId();this.groupId=textGroupId;var subtitleTracksUpdated={subtitleTracks:subtitleTracks};this.log("Updating subtitle tracks, "+subtitleTracks.length+" track(s) found in \""+textGroupId+"\" group-id");this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED,subtitleTracksUpdated);if(initialTrackId!==-1){this.setSubtitleTrack(initialTrackId,lastTrack);}}};_proto.findTrackId=function findTrackId(name){var textTracks=this.tracksInGroup;for(var i=0;i<textTracks.length;i++){var track=textTracks[i];if(!this.selectDefaultTrack||track["default"]){if(!name||name===track.name){return track.id;}}}return-1;};_proto.onError=function onError(event,data){_BasePlaylistControll.prototype.onError.call(this,event,data);if(data.fatal||!data.context){return;}if(data.context.type===_types_loader__WEBPACK_IMPORTED_MODULE_3__.PlaylistContextType.SUBTITLE_TRACK&&data.context.id===this.trackId&&data.context.groupId===this.groupId){this.retryLoadingOrFail(data);}}/** get alternate subtitle tracks list from playlist **/;_proto.loadPlaylist=function loadPlaylist(hlsUrlParameters){_BasePlaylistControll.prototype.loadPlaylist.call(this);var currentTrack=this.tracksInGroup[this.trackId];if(this.shouldLoadTrack(currentTrack)){var id=currentTrack.id;var groupId=currentTrack.groupId;var url=currentTrack.url;if(hlsUrlParameters){try{url=hlsUrlParameters.addDirectives(url);}catch(error){this.warn("Could not construct new URL with HLS Delivery Directives: "+error);}}this.log("Loading subtitle playlist for id "+id);this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADING,{url:url,id:id,groupId:groupId,deliveryDirectives:hlsUrlParameters||null});}}/**
|
|
|
* Disables the old subtitleTrack and sets current mode on the next subtitleTrack.
|
|
|
* This operates on the DOM textTracks.
|
|
|
* A value of -1 will disable all subtitle tracks.
|
|
|
*/;_proto.toggleTrackModes=function toggleTrackModes(newId){var _this2=this;var media=this.media,trackId=this.trackId;if(!media){return;}var textTracks=filterSubtitleTracks(media.textTracks);var groupTracks=textTracks.filter(function(track){return track.groupId===_this2.groupId;});if(newId===-1){[].slice.call(textTracks).forEach(function(track){track.mode='disabled';});}else{var oldTrack=groupTracks[trackId];if(oldTrack){oldTrack.mode='disabled';}}var nextTrack=groupTracks[newId];if(nextTrack){nextTrack.mode=this.subtitleDisplay?'showing':'hidden';}}/**
|
|
|
* This method is responsible for validating the subtitle index and periodically reloading if live.
|
|
|
* Dispatches the SUBTITLE_TRACK_SWITCH event, which instructs the subtitle-stream-controller to load the selected track.
|
|
|
*/;_proto.setSubtitleTrack=function setSubtitleTrack(newId,lastTrack){var _tracks$newId;var tracks=this.tracksInGroup;// setting this.subtitleTrack will trigger internal logic
|
|
|
// if media has not been attached yet, it will fail
|
|
|
// we keep a reference to the default track id
|
|
|
// and we'll set subtitleTrack when onMediaAttached is triggered
|
|
|
if(!this.media){this.queuedDefaultTrack=newId;return;}if(this.trackId!==newId){this.toggleTrackModes(newId);}// exit if track id as already set or invalid
|
|
|
if(this.trackId===newId&&(newId===-1||(_tracks$newId=tracks[newId])!==null&&_tracks$newId!==void 0&&_tracks$newId.details)||newId<-1||newId>=tracks.length){return;}// stopping live reloading timer if any
|
|
|
this.clearTimer();var track=tracks[newId];this.log("Switching to subtitle track "+newId);this.trackId=newId;if(track){var id=track.id,_track$groupId=track.groupId,groupId=_track$groupId===void 0?'':_track$groupId,name=track.name,type=track.type,url=track.url;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH,{id:id,groupId:groupId,name:name,type:type,url:url});var hlsUrlParameters=this.switchParams(track.url,lastTrack===null||lastTrack===void 0?void 0:lastTrack.details);this.loadPlaylist(hlsUrlParameters);}else{// switch to -1
|
|
|
this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH,{id:newId});}};_proto.onTextTracksChanged=function onTextTracksChanged(){if(!this.useTextTrackPolling){self.clearInterval(this.subtitlePollingInterval);}// Media is undefined when switching streams via loadSource()
|
|
|
if(!this.media||!this.hls.config.renderTextTracksNatively){return;}var trackId=-1;var tracks=filterSubtitleTracks(this.media.textTracks);for(var id=0;id<tracks.length;id++){if(tracks[id].mode==='hidden'){// Do not break in case there is a following track with showing.
|
|
|
trackId=id;}else if(tracks[id].mode==='showing'){trackId=id;break;}}// Setting current subtitleTrack will invoke code.
|
|
|
if(this.subtitleTrack!==trackId){this.subtitleTrack=trackId;}};_createClass(SubtitleTrackController,[{key:"subtitleDisplay",get:function get(){return this._subtitleDisplay;},set:function set(value){this._subtitleDisplay=value;if(this.trackId>-1){this.toggleTrackModes(this.trackId);}}},{key:"subtitleTracks",get:function get(){return this.tracksInGroup;}/** get/set index of the selected subtitle track (based on index in subtitle track lists) **/},{key:"subtitleTrack",get:function get(){return this.trackId;},set:function set(newId){this.selectDefaultTrack=false;var lastTrack=this.tracksInGroup?this.tracksInGroup[this.trackId]:undefined;this.setSubtitleTrack(newId,lastTrack);}}]);return SubtitleTrackController;}(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]);function filterSubtitleTracks(textTrackList){var tracks=[];for(var i=0;i<textTrackList.length;i++){var track=textTrackList[i];// Edge adds a track without a label; we don't want to use it
|
|
|
if((track.kind==='subtitles'||track.kind==='captions')&&track.label){tracks.push(textTrackList[i]);}}return tracks;}/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=SubtitleTrackController;/***/},/***/"./src/controller/timeline-controller.ts":/*!***********************************************!*\
|
|
|
!*** ./src/controller/timeline-controller.ts ***!
|
|
|
\***********************************************/ /***/function srcControllerTimelineControllerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_386988__){"use strict";__nested_webpack_require_386988__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_386988__.d(__webpack_exports__,{/* harmony export */"TimelineController":function TimelineController(){return(/* binding */_TimelineController);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_386988__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_386988__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_386988__(/*! ../utils/cea-608-parser */"./src/utils/cea-608-parser.ts");/* harmony import */var _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_386988__(/*! ../utils/output-filter */"./src/utils/output-filter.ts");/* harmony import */var _utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_386988__(/*! ../utils/webvtt-parser */"./src/utils/webvtt-parser.ts");/* harmony import */var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_386988__(/*! ../utils/texttrack-utils */"./src/utils/texttrack-utils.ts");/* harmony import */var _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_386988__(/*! ../utils/imsc1-ttml-parser */"./src/utils/imsc1-ttml-parser.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_386988__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_386988__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_386988__(/*! ../utils/logger */"./src/utils/logger.ts");var _TimelineController=/*#__PURE__*/function(){function TimelineController(hls){this.hls=void 0;this.media=null;this.config=void 0;this.enabled=true;this.Cues=void 0;this.textTracks=[];this.tracks=[];this.initPTS=[];this.timescale=[];this.unparsedVttFrags=[];this.captionsTracks={};this.nonNativeCaptionsTracks={};this.cea608Parser1=void 0;this.cea608Parser2=void 0;this.lastSn=-1;this.lastPartIndex=-1;this.prevCC=-1;this.vttCCs=newVTTCCs();this.captionsProperties=void 0;this.hls=hls;this.config=hls.config;this.Cues=hls.config.cueHandler;this.captionsProperties={textTrack1:{label:this.config.captionsTextTrack1Label,languageCode:this.config.captionsTextTrack1LanguageCode},textTrack2:{label:this.config.captionsTextTrack2Label,languageCode:this.config.captionsTextTrack2LanguageCode},textTrack3:{label:this.config.captionsTextTrack3Label,languageCode:this.config.captionsTextTrack3LanguageCode},textTrack4:{label:this.config.captionsTextTrack4Label,languageCode:this.config.captionsTextTrack4LanguageCode}};if(this.config.enableCEA708Captions){var channel1=new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this,'textTrack1');var channel2=new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this,'textTrack2');var channel3=new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this,'textTrack3');var channel4=new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this,'textTrack4');this.cea608Parser1=new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](1,channel1,channel2);this.cea608Parser2=new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](3,channel3,channel4);}hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_UPDATED,this.onSubtitleTracksUpdated,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADING,this.onFragLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_USERDATA,this.onFragParsingUserdata,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED,this.onFragDecrypted,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.INIT_PTS_FOUND,this.onInitPtsFound,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_CLEARED,this.onSubtitleTracksCleared,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);}var _proto=TimelineController.prototype;_proto.destroy=function destroy(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING,this.onMediaAttaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING,this.onMediaDetaching,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,this.onManifestLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_UPDATED,this.onSubtitleTracksUpdated,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADING,this.onFragLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,this.onFragLoaded,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_USERDATA,this.onFragParsingUserdata,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED,this.onFragDecrypted,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.INIT_PTS_FOUND,this.onInitPtsFound,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_CLEARED,this.onSubtitleTracksCleared,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING,this.onBufferFlushing,this);// @ts-ignore
|
|
|
this.hls=this.config=this.cea608Parser1=this.cea608Parser2=null;};_proto.addCues=function addCues(trackName,startTime,endTime,screen,cueRanges){// skip cues which overlap more than 50% with previously parsed time ranges
|
|
|
var merged=false;for(var i=cueRanges.length;i--;){var cueRange=cueRanges[i];var overlap=intersection(cueRange[0],cueRange[1],startTime,endTime);if(overlap>=0){cueRange[0]=Math.min(cueRange[0],startTime);cueRange[1]=Math.max(cueRange[1],endTime);merged=true;if(overlap/(endTime-startTime)>0.5){return;}}}if(!merged){cueRanges.push([startTime,endTime]);}if(this.config.renderTextTracksNatively){var track=this.captionsTracks[trackName];this.Cues.newCue(track,startTime,endTime,screen);}else{var cues=this.Cues.newCue(null,startTime,endTime,screen);this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.CUES_PARSED,{type:'captions',cues:cues,track:trackName});}}// Triggered when an initial PTS is found; used for synchronisation of WebVTT.
|
|
|
;_proto.onInitPtsFound=function onInitPtsFound(event,_ref){var _this=this;var frag=_ref.frag,id=_ref.id,initPTS=_ref.initPTS,timescale=_ref.timescale;var unparsedVttFrags=this.unparsedVttFrags;if(id==='main'){this.initPTS[frag.cc]=initPTS;this.timescale[frag.cc]=timescale;}// Due to asynchronous processing, initial PTS may arrive later than the first VTT fragments are loaded.
|
|
|
// Parse any unparsed fragments upon receiving the initial PTS.
|
|
|
if(unparsedVttFrags.length){this.unparsedVttFrags=[];unparsedVttFrags.forEach(function(frag){_this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,frag);});}};_proto.getExistingTrack=function getExistingTrack(trackName){var media=this.media;if(media){for(var i=0;i<media.textTracks.length;i++){var textTrack=media.textTracks[i];if(textTrack[trackName]){return textTrack;}}}return null;};_proto.createCaptionsTrack=function createCaptionsTrack(trackName){if(this.config.renderTextTracksNatively){this.createNativeTrack(trackName);}else{this.createNonNativeTrack(trackName);}};_proto.createNativeTrack=function createNativeTrack(trackName){if(this.captionsTracks[trackName]){return;}var captionsProperties=this.captionsProperties,captionsTracks=this.captionsTracks,media=this.media;var _captionsProperties$t=captionsProperties[trackName],label=_captionsProperties$t.label,languageCode=_captionsProperties$t.languageCode;// Enable reuse of existing text track.
|
|
|
var existingTrack=this.getExistingTrack(trackName);if(!existingTrack){var textTrack=this.createTextTrack('captions',label,languageCode);if(textTrack){// Set a special property on the track so we know it's managed by Hls.js
|
|
|
textTrack[trackName]=true;captionsTracks[trackName]=textTrack;}}else{captionsTracks[trackName]=existingTrack;(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(captionsTracks[trackName]);(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.sendAddTrackEvent)(captionsTracks[trackName],media);}};_proto.createNonNativeTrack=function createNonNativeTrack(trackName){if(this.nonNativeCaptionsTracks[trackName]){return;}// Create a list of a single track for the provider to consume
|
|
|
var trackProperties=this.captionsProperties[trackName];if(!trackProperties){return;}var label=trackProperties.label;var track={_id:trackName,label:label,kind:'captions',"default":trackProperties.media?!!trackProperties.media["default"]:false,closedCaptions:trackProperties.media};this.nonNativeCaptionsTracks[trackName]=track;this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.NON_NATIVE_TEXT_TRACKS_FOUND,{tracks:[track]});};_proto.createTextTrack=function createTextTrack(kind,label,lang){var media=this.media;if(!media){return;}return media.addTextTrack(kind,label,lang);};_proto.onMediaAttaching=function onMediaAttaching(event,data){this.media=data.media;this._cleanTracks();};_proto.onMediaDetaching=function onMediaDetaching(){var captionsTracks=this.captionsTracks;Object.keys(captionsTracks).forEach(function(trackName){(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(captionsTracks[trackName]);delete captionsTracks[trackName];});this.nonNativeCaptionsTracks={};};_proto.onManifestLoading=function onManifestLoading(){this.lastSn=-1;// Detect discontinuity in fragment parsing
|
|
|
this.lastPartIndex=-1;this.prevCC=-1;this.vttCCs=newVTTCCs();// Detect discontinuity in subtitle manifests
|
|
|
this._cleanTracks();this.tracks=[];this.captionsTracks={};this.nonNativeCaptionsTracks={};this.textTracks=[];this.unparsedVttFrags=this.unparsedVttFrags||[];this.initPTS=[];this.timescale=[];if(this.cea608Parser1&&this.cea608Parser2){this.cea608Parser1.reset();this.cea608Parser2.reset();}};_proto._cleanTracks=function _cleanTracks(){// clear outdated subtitles
|
|
|
var media=this.media;if(!media){return;}var textTracks=media.textTracks;if(textTracks){for(var i=0;i<textTracks.length;i++){(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(textTracks[i]);}}};_proto.onSubtitleTracksUpdated=function onSubtitleTracksUpdated(event,data){var _this2=this;this.textTracks=[];var tracks=data.subtitleTracks||[];var hasIMSC1=tracks.some(function(track){return track.textCodec===_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC;});if(this.config.enableWebVTT||hasIMSC1&&this.config.enableIMSC1){var sameTracks=this.tracks&&tracks&&this.tracks.length===tracks.length;this.tracks=tracks||[];if(this.config.renderTextTracksNatively){var inUseTracks=this.media?this.media.textTracks:[];this.tracks.forEach(function(track,index){var textTrack;if(index<inUseTracks.length){var inUseTrack=null;for(var i=0;i<inUseTracks.length;i++){if(canReuseVttTextTrack(inUseTracks[i],track)){inUseTrack=inUseTracks[i];break;}}// Reuse tracks with the same label, but do not reuse 608/708 tracks
|
|
|
if(inUseTrack){textTrack=inUseTrack;}}if(textTrack){(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(textTrack);}else{var textTrackKind=_this2._captionsOrSubtitlesFromCharacteristics(track);textTrack=_this2.createTextTrack(textTrackKind,track.name,track.lang);if(textTrack){textTrack.mode='disabled';}}if(textTrack){textTrack.groupId=track.groupId;_this2.textTracks.push(textTrack);}});}else if(!sameTracks&&this.tracks&&this.tracks.length){// Create a list of tracks for the provider to consume
|
|
|
var tracksList=this.tracks.map(function(track){return{label:track.name,kind:track.type.toLowerCase(),"default":track["default"],subtitleTrack:track};});this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.NON_NATIVE_TEXT_TRACKS_FOUND,{tracks:tracksList});}}};_proto._captionsOrSubtitlesFromCharacteristics=function _captionsOrSubtitlesFromCharacteristics(track){var _track$attrs;if((_track$attrs=track.attrs)!==null&&_track$attrs!==void 0&&_track$attrs.CHARACTERISTICS){var transcribesSpokenDialog=/transcribes-spoken-dialog/gi.test(track.attrs.CHARACTERISTICS);var describesMusicAndSound=/describes-music-and-sound/gi.test(track.attrs.CHARACTERISTICS);if(transcribesSpokenDialog&&describesMusicAndSound){return'captions';}}return'subtitles';};_proto.onManifestLoaded=function onManifestLoaded(event,data){var _this3=this;if(this.config.enableCEA708Captions&&data.captions){data.captions.forEach(function(captionsTrack){var instreamIdMatch=/(?:CC|SERVICE)([1-4])/.exec(captionsTrack.instreamId);if(!instreamIdMatch){return;}var trackName="textTrack"+instreamIdMatch[1];var trackProperties=_this3.captionsProperties[trackName];if(!trackProperties){return;}trackProperties.label=captionsTrack.name;if(captionsTrack.lang){// optional attribute
|
|
|
trackProperties.languageCode=captionsTrack.lang;}trackProperties.media=captionsTrack;});}};_proto.closedCaptionsForLevel=function closedCaptionsForLevel(frag){var level=this.hls.levels[frag.level];return level===null||level===void 0?void 0:level.attrs['CLOSED-CAPTIONS'];};_proto.onFragLoading=function onFragLoading(event,data){var cea608Parser1=this.cea608Parser1,cea608Parser2=this.cea608Parser2,lastSn=this.lastSn,lastPartIndex=this.lastPartIndex;if(!this.enabled||!(cea608Parser1&&cea608Parser2)){return;}// if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
|
|
|
if(data.frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.MAIN){var _data$part$index,_data$part;var sn=data.frag.sn;var partIndex=(_data$part$index=data===null||data===void 0?void 0:(_data$part=data.part)===null||_data$part===void 0?void 0:_data$part.index)!=null?_data$part$index:-1;if(!(sn===lastSn+1||sn===lastSn&&partIndex===lastPartIndex+1)){cea608Parser1.reset();cea608Parser2.reset();}this.lastSn=sn;this.lastPartIndex=partIndex;}};_proto.onFragLoaded=function onFragLoaded(event,data){var frag=data.frag,payload=data.payload;var initPTS=this.initPTS,unparsedVttFrags=this.unparsedVttFrags;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.SUBTITLE){// If fragment is subtitle type, parse as WebVTT.
|
|
|
if(payload.byteLength){// We need an initial synchronisation PTS. Store fragments as long as none has arrived.
|
|
|
if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS[frag.cc])){unparsedVttFrags.push(data);if(initPTS.length){// finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
|
|
|
this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:false,frag:frag,error:new Error('Missing initial subtitle PTS')});}return;}var decryptData=frag.decryptdata;// fragment after decryption has a stats object
|
|
|
var decrypted=('stats'in data);// If the subtitles are not encrypted, parse VTTs now. Otherwise, we need to wait.
|
|
|
if(decryptData==null||!decryptData.encrypted||decrypted){var trackPlaylistMedia=this.tracks[frag.level];var vttCCs=this.vttCCs;if(!vttCCs[frag.cc]){vttCCs[frag.cc]={start:frag.start,prevCC:this.prevCC,"new":true};this.prevCC=frag.cc;}if(trackPlaylistMedia&&trackPlaylistMedia.textCodec===_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC){this._parseIMSC1(frag,payload);}else{this._parseVTTs(frag,payload,vttCCs);}}}else{// In case there is no payload, finish unsuccessfully.
|
|
|
this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:false,frag:frag,error:new Error('Empty subtitle payload')});}}};_proto._parseIMSC1=function _parseIMSC1(frag,payload){var _this4=this;var hls=this.hls;(0,_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.parseIMSC1)(payload,this.initPTS[frag.cc],this.timescale[frag.cc],function(cues){_this4._appendCues(cues,frag.level);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:true,frag:frag});},function(error){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("Failed to parse IMSC1: "+error);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:false,frag:frag,error:error});});};_proto._parseVTTs=function _parseVTTs(frag,payload,vttCCs){var _frag$initSegment,_this5=this;var hls=this.hls;// Parse the WebVTT file contents.
|
|
|
var payloadWebVTT=(_frag$initSegment=frag.initSegment)!==null&&_frag$initSegment!==void 0&&_frag$initSegment.data?(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_7__.appendUint8Array)(frag.initSegment.data,new Uint8Array(payload)):payload;(0,_utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__.parseWebVTT)(payloadWebVTT,this.initPTS[frag.cc],this.timescale[frag.cc],vttCCs,frag.cc,frag.start,function(cues){_this5._appendCues(cues,frag.level);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:true,frag:frag});},function(error){_this5._fallbackToIMSC1(frag,payload);// Something went wrong while parsing. Trigger event with success false.
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("Failed to parse VTT cue: "+error);hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED,{success:false,frag:frag,error:error});});};_proto._fallbackToIMSC1=function _fallbackToIMSC1(frag,payload){var _this6=this;// If textCodec is unknown, try parsing as IMSC1. Set textCodec based on the result
|
|
|
var trackPlaylistMedia=this.tracks[frag.level];if(!trackPlaylistMedia.textCodec){(0,_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.parseIMSC1)(payload,this.initPTS[frag.cc],this.timescale[frag.cc],function(){trackPlaylistMedia.textCodec=_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC;_this6._parseIMSC1(frag,payload);},function(){trackPlaylistMedia.textCodec='wvtt';});}};_proto._appendCues=function _appendCues(cues,fragLevel){var hls=this.hls;if(this.config.renderTextTracksNatively){var textTrack=this.textTracks[fragLevel];// WebVTTParser.parse is an async method and if the currently selected text track mode is set to "disabled"
|
|
|
// before parsing is done then don't try to access currentTrack.cues.getCueById as cues will be null
|
|
|
// and trying to access getCueById method of cues will throw an exception
|
|
|
// Because we check if the mode is disabled, we can force check `cues` below. They can't be null.
|
|
|
if(!textTrack||textTrack.mode==='disabled'){return;}cues.forEach(function(cue){return(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.addCueToTrack)(textTrack,cue);});}else{var currentTrack=this.tracks[fragLevel];if(!currentTrack){return;}var track=currentTrack["default"]?'default':'subtitles'+fragLevel;hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.CUES_PARSED,{type:'subtitles',cues:cues,track:track});}};_proto.onFragDecrypted=function onFragDecrypted(event,data){var frag=data.frag;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.SUBTITLE){if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.initPTS[frag.cc])){this.unparsedVttFrags.push(data);return;}this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED,data);}};_proto.onSubtitleTracksCleared=function onSubtitleTracksCleared(){this.tracks=[];this.captionsTracks={};};_proto.onFragParsingUserdata=function onFragParsingUserdata(event,data){var cea608Parser1=this.cea608Parser1,cea608Parser2=this.cea608Parser2;if(!this.enabled||!(cea608Parser1&&cea608Parser2)){return;}var frag=data.frag,samples=data.samples;if(frag.type===_types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.MAIN&&this.closedCaptionsForLevel(frag)==='NONE'){return;}// If the event contains captions (found in the bytes property), push all bytes into the parser immediately
|
|
|
// It will create the proper timestamps based on the PTS value
|
|
|
for(var i=0;i<samples.length;i++){var ccBytes=samples[i].bytes;if(ccBytes){var ccdatas=this.extractCea608Data(ccBytes);cea608Parser1.addData(samples[i].pts,ccdatas[0]);cea608Parser2.addData(samples[i].pts,ccdatas[1]);}}};_proto.onBufferFlushing=function onBufferFlushing(event,_ref2){var startOffset=_ref2.startOffset,endOffset=_ref2.endOffset,endOffsetSubtitles=_ref2.endOffsetSubtitles,type=_ref2.type;var media=this.media;if(!media||media.currentTime<endOffset){return;}// Clear 608 caption cues from the captions TextTracks when the video back buffer is flushed
|
|
|
// Forward cues are never removed because we can loose streamed 608 content from recent fragments
|
|
|
if(!type||type==='video'){var captionsTracks=this.captionsTracks;Object.keys(captionsTracks).forEach(function(trackName){return(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.removeCuesInRange)(captionsTracks[trackName],startOffset,endOffset);});}if(this.config.renderTextTracksNatively){// Clear VTT/IMSC1 subtitle cues from the subtitle TextTracks when the back buffer is flushed
|
|
|
if(startOffset===0&&endOffsetSubtitles!==undefined){var textTracks=this.textTracks;Object.keys(textTracks).forEach(function(trackName){return(0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.removeCuesInRange)(textTracks[trackName],startOffset,endOffsetSubtitles);});}}};_proto.extractCea608Data=function extractCea608Data(byteArray){var actualCCBytes=[[],[]];var count=byteArray[0]&0x1f;var position=2;for(var j=0;j<count;j++){var tmpByte=byteArray[position++];var ccbyte1=0x7f&byteArray[position++];var ccbyte2=0x7f&byteArray[position++];if(ccbyte1===0&&ccbyte2===0){continue;}var ccValid=(0x04&tmpByte)!==0;// Support all four channels
|
|
|
if(ccValid){var ccType=0x03&tmpByte;if(0x00/* CEA608 field1*/===ccType||0x01/* CEA608 field2*/===ccType){// Exclude CEA708 CC data.
|
|
|
actualCCBytes[ccType].push(ccbyte1);actualCCBytes[ccType].push(ccbyte2);}}}return actualCCBytes;};return TimelineController;}();function canReuseVttTextTrack(inUseTrack,manifestTrack){return inUseTrack&&inUseTrack.label===manifestTrack.name&&!(inUseTrack.textTrack1||inUseTrack.textTrack2);}function intersection(x1,x2,y1,y2){return Math.min(x2,y2)-Math.max(x1,y1);}function newVTTCCs(){return{ccOffset:0,presentationOffset:0,0:{start:0,prevCC:-1,"new":true}};}/***/},/***/"./src/crypt/aes-crypto.ts":/*!*********************************!*\
|
|
|
!*** ./src/crypt/aes-crypto.ts ***!
|
|
|
\*********************************/ /***/function srcCryptAesCryptoTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_409910__){"use strict";__nested_webpack_require_409910__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_409910__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */AESCrypto);}/* harmony export */});var AESCrypto=/*#__PURE__*/function(){function AESCrypto(subtle,iv){this.subtle=void 0;this.aesIV=void 0;this.subtle=subtle;this.aesIV=iv;}var _proto=AESCrypto.prototype;_proto.decrypt=function decrypt(data,key){return this.subtle.decrypt({name:'AES-CBC',iv:this.aesIV},key,data);};return AESCrypto;}();/***/},/***/"./src/crypt/aes-decryptor.ts":/*!************************************!*\
|
|
|
!*** ./src/crypt/aes-decryptor.ts ***!
|
|
|
\************************************/ /***/function srcCryptAesDecryptorTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_410707__){"use strict";__nested_webpack_require_410707__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_410707__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */AESDecryptor);},/* harmony export */"removePadding":function removePadding(){return(/* binding */_removePadding);}/* harmony export */});/* harmony import */var _utils_typed_array__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_410707__(/*! ../utils/typed-array */"./src/utils/typed-array.ts");// PKCS7
|
|
|
function _removePadding(array){var outputBytes=array.byteLength;var paddingBytes=outputBytes&&new DataView(array.buffer).getUint8(outputBytes-1);if(paddingBytes){return(0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_0__.sliceUint8)(array,0,outputBytes-paddingBytes);}return array;}var AESDecryptor=/*#__PURE__*/function(){function AESDecryptor(){this.rcon=[0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x1b,0x36];this.subMix=[new Uint32Array(256),new Uint32Array(256),new Uint32Array(256),new Uint32Array(256)];this.invSubMix=[new Uint32Array(256),new Uint32Array(256),new Uint32Array(256),new Uint32Array(256)];this.sBox=new Uint32Array(256);this.invSBox=new Uint32Array(256);this.key=new Uint32Array(0);this.ksRows=0;this.keySize=0;this.keySchedule=void 0;this.invKeySchedule=void 0;this.initTable();}// Using view.getUint32() also swaps the byte order.
|
|
|
var _proto=AESDecryptor.prototype;_proto.uint8ArrayToUint32Array_=function uint8ArrayToUint32Array_(arrayBuffer){var view=new DataView(arrayBuffer);var newArray=new Uint32Array(4);for(var i=0;i<4;i++){newArray[i]=view.getUint32(i*4);}return newArray;};_proto.initTable=function initTable(){var sBox=this.sBox;var invSBox=this.invSBox;var subMix=this.subMix;var subMix0=subMix[0];var subMix1=subMix[1];var subMix2=subMix[2];var subMix3=subMix[3];var invSubMix=this.invSubMix;var invSubMix0=invSubMix[0];var invSubMix1=invSubMix[1];var invSubMix2=invSubMix[2];var invSubMix3=invSubMix[3];var d=new Uint32Array(256);var x=0;var xi=0;var i=0;for(i=0;i<256;i++){if(i<128){d[i]=i<<1;}else{d[i]=i<<1^0x11b;}}for(i=0;i<256;i++){var sx=xi^xi<<1^xi<<2^xi<<3^xi<<4;sx=sx>>>8^sx&0xff^0x63;sBox[x]=sx;invSBox[sx]=x;// Compute multiplication
|
|
|
var x2=d[x];var x4=d[x2];var x8=d[x4];// Compute sub/invSub bytes, mix columns tables
|
|
|
var t=d[sx]*0x101^sx*0x1010100;subMix0[x]=t<<24|t>>>8;subMix1[x]=t<<16|t>>>16;subMix2[x]=t<<8|t>>>24;subMix3[x]=t;// Compute inv sub bytes, inv mix columns tables
|
|
|
t=x8*0x1010101^x4*0x10001^x2*0x101^x*0x1010100;invSubMix0[sx]=t<<24|t>>>8;invSubMix1[sx]=t<<16|t>>>16;invSubMix2[sx]=t<<8|t>>>24;invSubMix3[sx]=t;// Compute next counter
|
|
|
if(!x){x=xi=1;}else{x=x2^d[d[d[x8^x2]]];xi^=d[d[xi]];}}};_proto.expandKey=function expandKey(keyBuffer){// convert keyBuffer to Uint32Array
|
|
|
var key=this.uint8ArrayToUint32Array_(keyBuffer);var sameKey=true;var offset=0;while(offset<key.length&&sameKey){sameKey=key[offset]===this.key[offset];offset++;}if(sameKey){return;}this.key=key;var keySize=this.keySize=key.length;if(keySize!==4&&keySize!==6&&keySize!==8){throw new Error('Invalid aes key size='+keySize);}var ksRows=this.ksRows=(keySize+6+1)*4;var ksRow;var invKsRow;var keySchedule=this.keySchedule=new Uint32Array(ksRows);var invKeySchedule=this.invKeySchedule=new Uint32Array(ksRows);var sbox=this.sBox;var rcon=this.rcon;var invSubMix=this.invSubMix;var invSubMix0=invSubMix[0];var invSubMix1=invSubMix[1];var invSubMix2=invSubMix[2];var invSubMix3=invSubMix[3];var prev;var t;for(ksRow=0;ksRow<ksRows;ksRow++){if(ksRow<keySize){prev=keySchedule[ksRow]=key[ksRow];continue;}t=prev;if(ksRow%keySize===0){// Rot word
|
|
|
t=t<<8|t>>>24;// Sub word
|
|
|
t=sbox[t>>>24]<<24|sbox[t>>>16&0xff]<<16|sbox[t>>>8&0xff]<<8|sbox[t&0xff];// Mix Rcon
|
|
|
t^=rcon[ksRow/keySize|0]<<24;}else if(keySize>6&&ksRow%keySize===4){// Sub word
|
|
|
t=sbox[t>>>24]<<24|sbox[t>>>16&0xff]<<16|sbox[t>>>8&0xff]<<8|sbox[t&0xff];}keySchedule[ksRow]=prev=(keySchedule[ksRow-keySize]^t)>>>0;}for(invKsRow=0;invKsRow<ksRows;invKsRow++){ksRow=ksRows-invKsRow;if(invKsRow&3){t=keySchedule[ksRow];}else{t=keySchedule[ksRow-4];}if(invKsRow<4||ksRow<=4){invKeySchedule[invKsRow]=t;}else{invKeySchedule[invKsRow]=invSubMix0[sbox[t>>>24]]^invSubMix1[sbox[t>>>16&0xff]]^invSubMix2[sbox[t>>>8&0xff]]^invSubMix3[sbox[t&0xff]];}invKeySchedule[invKsRow]=invKeySchedule[invKsRow]>>>0;}}// Adding this as a method greatly improves performance.
|
|
|
;_proto.networkToHostOrderSwap=function networkToHostOrderSwap(word){return word<<24|(word&0xff00)<<8|(word&0xff0000)>>8|word>>>24;};_proto.decrypt=function decrypt(inputArrayBuffer,offset,aesIV){var nRounds=this.keySize+6;var invKeySchedule=this.invKeySchedule;var invSBOX=this.invSBox;var invSubMix=this.invSubMix;var invSubMix0=invSubMix[0];var invSubMix1=invSubMix[1];var invSubMix2=invSubMix[2];var invSubMix3=invSubMix[3];var initVector=this.uint8ArrayToUint32Array_(aesIV);var initVector0=initVector[0];var initVector1=initVector[1];var initVector2=initVector[2];var initVector3=initVector[3];var inputInt32=new Int32Array(inputArrayBuffer);var outputInt32=new Int32Array(inputInt32.length);var t0,t1,t2,t3;var s0,s1,s2,s3;var inputWords0,inputWords1,inputWords2,inputWords3;var ksRow,i;var swapWord=this.networkToHostOrderSwap;while(offset<inputInt32.length){inputWords0=swapWord(inputInt32[offset]);inputWords1=swapWord(inputInt32[offset+1]);inputWords2=swapWord(inputInt32[offset+2]);inputWords3=swapWord(inputInt32[offset+3]);s0=inputWords0^invKeySchedule[0];s1=inputWords3^invKeySchedule[1];s2=inputWords2^invKeySchedule[2];s3=inputWords1^invKeySchedule[3];ksRow=4;// Iterate through the rounds of decryption
|
|
|
for(i=1;i<nRounds;i++){t0=invSubMix0[s0>>>24]^invSubMix1[s1>>16&0xff]^invSubMix2[s2>>8&0xff]^invSubMix3[s3&0xff]^invKeySchedule[ksRow];t1=invSubMix0[s1>>>24]^invSubMix1[s2>>16&0xff]^invSubMix2[s3>>8&0xff]^invSubMix3[s0&0xff]^invKeySchedule[ksRow+1];t2=invSubMix0[s2>>>24]^invSubMix1[s3>>16&0xff]^invSubMix2[s0>>8&0xff]^invSubMix3[s1&0xff]^invKeySchedule[ksRow+2];t3=invSubMix0[s3>>>24]^invSubMix1[s0>>16&0xff]^invSubMix2[s1>>8&0xff]^invSubMix3[s2&0xff]^invKeySchedule[ksRow+3];// Update state
|
|
|
s0=t0;s1=t1;s2=t2;s3=t3;ksRow=ksRow+4;}// Shift rows, sub bytes, add round key
|
|
|
t0=invSBOX[s0>>>24]<<24^invSBOX[s1>>16&0xff]<<16^invSBOX[s2>>8&0xff]<<8^invSBOX[s3&0xff]^invKeySchedule[ksRow];t1=invSBOX[s1>>>24]<<24^invSBOX[s2>>16&0xff]<<16^invSBOX[s3>>8&0xff]<<8^invSBOX[s0&0xff]^invKeySchedule[ksRow+1];t2=invSBOX[s2>>>24]<<24^invSBOX[s3>>16&0xff]<<16^invSBOX[s0>>8&0xff]<<8^invSBOX[s1&0xff]^invKeySchedule[ksRow+2];t3=invSBOX[s3>>>24]<<24^invSBOX[s0>>16&0xff]<<16^invSBOX[s1>>8&0xff]<<8^invSBOX[s2&0xff]^invKeySchedule[ksRow+3];// Write
|
|
|
outputInt32[offset]=swapWord(t0^initVector0);outputInt32[offset+1]=swapWord(t3^initVector1);outputInt32[offset+2]=swapWord(t2^initVector2);outputInt32[offset+3]=swapWord(t1^initVector3);// reset initVector to last 4 unsigned int
|
|
|
initVector0=inputWords0;initVector1=inputWords1;initVector2=inputWords2;initVector3=inputWords3;offset=offset+4;}return outputInt32.buffer;};return AESDecryptor;}();/***/},/***/"./src/crypt/decrypter.ts":/*!********************************!*\
|
|
|
!*** ./src/crypt/decrypter.ts ***!
|
|
|
\********************************/ /***/function srcCryptDecrypterTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_417926__){"use strict";__nested_webpack_require_417926__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_417926__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */Decrypter);}/* harmony export */});/* harmony import */var _aes_crypto__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_417926__(/*! ./aes-crypto */"./src/crypt/aes-crypto.ts");/* harmony import */var _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_417926__(/*! ./fast-aes-key */"./src/crypt/fast-aes-key.ts");/* harmony import */var _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_417926__(/*! ./aes-decryptor */"./src/crypt/aes-decryptor.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_417926__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_417926__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_417926__(/*! ../utils/typed-array */"./src/utils/typed-array.ts");var CHUNK_SIZE=16;// 16 bytes, 128 bits
|
|
|
var Decrypter=/*#__PURE__*/function(){function Decrypter(config,_temp){var _ref=_temp===void 0?{}:_temp,_ref$removePKCS7Paddi=_ref.removePKCS7Padding,removePKCS7Padding=_ref$removePKCS7Paddi===void 0?true:_ref$removePKCS7Paddi;this.logEnabled=true;this.removePKCS7Padding=void 0;this.subtle=null;this.softwareDecrypter=null;this.key=null;this.fastAesKey=null;this.remainderData=null;this.currentIV=null;this.currentResult=null;this.useSoftware=void 0;this.useSoftware=config.enableSoftwareAES;this.removePKCS7Padding=removePKCS7Padding;// built in decryptor expects PKCS7 padding
|
|
|
if(removePKCS7Padding){try{var browserCrypto=self.crypto;if(browserCrypto){this.subtle=browserCrypto.subtle||browserCrypto.webkitSubtle;}}catch(e){/* no-op */}}if(this.subtle===null){this.useSoftware=true;}}var _proto=Decrypter.prototype;_proto.destroy=function destroy(){this.subtle=null;this.softwareDecrypter=null;this.key=null;this.fastAesKey=null;this.remainderData=null;this.currentIV=null;this.currentResult=null;};_proto.isSync=function isSync(){return this.useSoftware;};_proto.flush=function flush(){var currentResult=this.currentResult,remainderData=this.remainderData;if(!currentResult||remainderData){this.reset();return null;}var data=new Uint8Array(currentResult);this.reset();if(this.removePKCS7Padding){return(0,_aes_decryptor__WEBPACK_IMPORTED_MODULE_2__.removePadding)(data);}return data;};_proto.reset=function reset(){this.currentResult=null;this.currentIV=null;this.remainderData=null;if(this.softwareDecrypter){this.softwareDecrypter=null;}};_proto.decrypt=function decrypt(data,key,iv){var _this=this;if(this.useSoftware){return new Promise(function(resolve,reject){_this.softwareDecrypt(new Uint8Array(data),key,iv);var decryptResult=_this.flush();if(decryptResult){resolve(decryptResult.buffer);}else{reject(new Error('[softwareDecrypt] Failed to decrypt data'));}});}return this.webCryptoDecrypt(new Uint8Array(data),key,iv);}// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
|
|
// data is handled in the flush() call
|
|
|
;_proto.softwareDecrypt=function softwareDecrypt(data,key,iv){var currentIV=this.currentIV,currentResult=this.currentResult,remainderData=this.remainderData;this.logOnce('JS AES decrypt');// The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
|
|
|
// This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
|
|
|
// the end on flush(), but by that time we have already received all bytes for the segment.
|
|
|
// Progressive decryption does not work with WebCrypto
|
|
|
if(remainderData){data=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(remainderData,data);this.remainderData=null;}// Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes)
|
|
|
var currentChunk=this.getValidChunk(data);if(!currentChunk.length){return null;}if(currentIV){iv=currentIV;}var softwareDecrypter=this.softwareDecrypter;if(!softwareDecrypter){softwareDecrypter=this.softwareDecrypter=new _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["default"]();}softwareDecrypter.expandKey(key);var result=currentResult;this.currentResult=softwareDecrypter.decrypt(currentChunk.buffer,0,iv);this.currentIV=(0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(currentChunk,-16).buffer;if(!result){return null;}return result;};_proto.webCryptoDecrypt=function webCryptoDecrypt(data,key,iv){var _this2=this;var subtle=this.subtle;if(this.key!==key||!this.fastAesKey){this.key=key;this.fastAesKey=new _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__["default"](subtle,key);}return this.fastAesKey.expandKey().then(function(aesKey){// decrypt using web crypto
|
|
|
if(!subtle){return Promise.reject(new Error('web crypto not initialized'));}_this2.logOnce('WebCrypto AES decrypt');var crypto=new _aes_crypto__WEBPACK_IMPORTED_MODULE_0__["default"](subtle,new Uint8Array(iv));return crypto.decrypt(data.buffer,aesKey);})["catch"](function(err){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, "+err.name+": "+err.message);return _this2.onWebCryptoError(data,key,iv);});};_proto.onWebCryptoError=function onWebCryptoError(data,key,iv){this.useSoftware=true;this.logEnabled=true;this.softwareDecrypt(data,key,iv);var decryptResult=this.flush();if(decryptResult){return decryptResult.buffer;}throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');};_proto.getValidChunk=function getValidChunk(data){var currentChunk=data;var splitPoint=data.length-data.length%CHUNK_SIZE;if(splitPoint!==data.length){currentChunk=(0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data,0,splitPoint);this.remainderData=(0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data,splitPoint);}return currentChunk;};_proto.logOnce=function logOnce(msg){if(!this.logEnabled){return;}_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[decrypter]: "+msg);this.logEnabled=false;};return Decrypter;}();/***/},/***/"./src/crypt/fast-aes-key.ts":/*!***********************************!*\
|
|
|
!*** ./src/crypt/fast-aes-key.ts ***!
|
|
|
\***********************************/ /***/function srcCryptFastAesKeyTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_424347__){"use strict";__nested_webpack_require_424347__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_424347__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */FastAESKey);}/* harmony export */});var FastAESKey=/*#__PURE__*/function(){function FastAESKey(subtle,key){this.subtle=void 0;this.key=void 0;this.subtle=subtle;this.key=key;}var _proto=FastAESKey.prototype;_proto.expandKey=function expandKey(){return this.subtle.importKey('raw',this.key,{name:'AES-CBC'},false,['encrypt','decrypt']);};return FastAESKey;}();/***/},/***/"./src/demux/aacdemuxer.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/aacdemuxer.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxAacdemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_425151__){"use strict";__nested_webpack_require_425151__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_425151__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_425151__(/*! ./base-audio-demuxer */"./src/demux/base-audio-demuxer.ts");/* harmony import */var _adts__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_425151__(/*! ./adts */"./src/demux/adts.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_425151__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_425151__(/*! ../demux/id3 */"./src/demux/id3.ts");function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}/**
|
|
|
* AAC demuxer
|
|
|
*/var AACDemuxer=/*#__PURE__*/function(_BaseAudioDemuxer){_inheritsLoose(AACDemuxer,_BaseAudioDemuxer);function AACDemuxer(observer,config){var _this;_this=_BaseAudioDemuxer.call(this)||this;_this.observer=void 0;_this.config=void 0;_this.observer=observer;_this.config=config;return _this;}var _proto=AACDemuxer.prototype;_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,trackDuration){_BaseAudioDemuxer.prototype.resetInitSegment.call(this,initSegment,audioCodec,videoCodec,trackDuration);this._audioTrack={container:'audio/adts',type:'audio',id:2,pid:-1,sequenceNumber:0,segmentCodec:'aac',samples:[],manifestCodec:audioCodec,duration:trackDuration,inputTimeScale:90000,dropped:0};}// Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
|
|
|
;AACDemuxer.probe=function probe(data){if(!data){return false;}// Check for the ADTS sync word
|
|
|
// Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
|
|
|
// Layer bits (position 14 and 15) in header should be always 0 for ADTS
|
|
|
// More info https://wiki.multimedia.cx/index.php?title=ADTS
|
|
|
var id3Data=_demux_id3__WEBPACK_IMPORTED_MODULE_3__.getID3Data(data,0)||[];var offset=id3Data.length;for(var length=data.length;offset<length;offset++){if(_adts__WEBPACK_IMPORTED_MODULE_1__.probe(data,offset)){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('ADTS sync word found !');return true;}}return false;};_proto.canParse=function canParse(data,offset){return _adts__WEBPACK_IMPORTED_MODULE_1__.canParse(data,offset);};_proto.appendFrame=function appendFrame(track,data,offset){_adts__WEBPACK_IMPORTED_MODULE_1__.initTrackConfig(track,this.observer,data,offset,track.manifestCodec);var frame=_adts__WEBPACK_IMPORTED_MODULE_1__.appendFrame(track,data,offset,this.basePTS,this.frameIndex);if(frame&&frame.missing===0){return frame;}};return AACDemuxer;}(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]);/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=AACDemuxer;/***/},/***/"./src/demux/adts.ts":/*!***************************!*\
|
|
|
!*** ./src/demux/adts.ts ***!
|
|
|
\***************************/ /***/function srcDemuxAdtsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_428513__){"use strict";__nested_webpack_require_428513__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_428513__.d(__webpack_exports__,{/* harmony export */"appendFrame":function appendFrame(){return(/* binding */_appendFrame);},/* harmony export */"canGetFrameLength":function canGetFrameLength(){return(/* binding */_canGetFrameLength);},/* harmony export */"canParse":function canParse(){return(/* binding */_canParse);},/* harmony export */"getAudioConfig":function getAudioConfig(){return(/* binding */_getAudioConfig);},/* harmony export */"getFrameDuration":function getFrameDuration(){return(/* binding */_getFrameDuration);},/* harmony export */"getFullFrameLength":function getFullFrameLength(){return(/* binding */_getFullFrameLength);},/* harmony export */"getHeaderLength":function getHeaderLength(){return(/* binding */_getHeaderLength);},/* harmony export */"initTrackConfig":function initTrackConfig(){return(/* binding */_initTrackConfig);},/* harmony export */"isHeader":function isHeader(){return(/* binding */_isHeader);},/* harmony export */"isHeaderPattern":function isHeaderPattern(){return(/* binding */_isHeaderPattern);},/* harmony export */"parseFrameHeader":function parseFrameHeader(){return(/* binding */_parseFrameHeader);},/* harmony export */"probe":function probe(){return(/* binding */_probe);}/* harmony export */});/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_428513__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_428513__(/*! ../errors */"./src/errors.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_428513__(/*! ../events */"./src/events.ts");/**
|
|
|
* ADTS parser helper
|
|
|
* @link https://wiki.multimedia.cx/index.php?title=ADTS
|
|
|
*/function _getAudioConfig(observer,data,offset,audioCodec){var adtsObjectType;var adtsExtensionSamplingIndex;var adtsChannelConfig;var config;var userAgent=navigator.userAgent.toLowerCase();var manifestCodec=audioCodec;var adtsSamplingRates=[96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350];// byte 2
|
|
|
adtsObjectType=((data[offset+2]&0xc0)>>>6)+1;var adtsSamplingIndex=(data[offset+2]&0x3c)>>>2;if(adtsSamplingIndex>adtsSamplingRates.length-1){observer.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_PARSING_ERROR,fatal:true,reason:"invalid ADTS sampling index:"+adtsSamplingIndex});return;}adtsChannelConfig=(data[offset+2]&0x01)<<2;// byte 3
|
|
|
adtsChannelConfig|=(data[offset+3]&0xc0)>>>6;_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log("manifest codec:"+audioCodec+", ADTS type:"+adtsObjectType+", samplingIndex:"+adtsSamplingIndex);// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
|
|
if(/firefox/i.test(userAgent)){if(adtsSamplingIndex>=6){adtsObjectType=5;config=new Array(4);// HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
|
|
|
// there is a factor 2 between frame sample rate and output sample rate
|
|
|
// multiply frequency by 2 (see table below, equivalent to substract 3)
|
|
|
adtsExtensionSamplingIndex=adtsSamplingIndex-3;}else{adtsObjectType=2;config=new Array(2);adtsExtensionSamplingIndex=adtsSamplingIndex;}// Android : always use AAC
|
|
|
}else if(userAgent.indexOf('android')!==-1){adtsObjectType=2;config=new Array(2);adtsExtensionSamplingIndex=adtsSamplingIndex;}else{/* for other browsers (Chrome/Vivaldi/Opera ...)
|
|
|
always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)
|
|
|
*/adtsObjectType=5;config=new Array(4);// if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)
|
|
|
if(audioCodec&&(audioCodec.indexOf('mp4a.40.29')!==-1||audioCodec.indexOf('mp4a.40.5')!==-1)||!audioCodec&&adtsSamplingIndex>=6){// HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
|
|
|
// there is a factor 2 between frame sample rate and output sample rate
|
|
|
// multiply frequency by 2 (see table below, equivalent to substract 3)
|
|
|
adtsExtensionSamplingIndex=adtsSamplingIndex-3;}else{// if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
|
|
|
// Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.
|
|
|
if(audioCodec&&audioCodec.indexOf('mp4a.40.2')!==-1&&(adtsSamplingIndex>=6&&adtsChannelConfig===1||/vivaldi/i.test(userAgent))||!audioCodec&&adtsChannelConfig===1){adtsObjectType=2;config=new Array(2);}adtsExtensionSamplingIndex=adtsSamplingIndex;}}/* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config
|
|
|
ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig()
|
|
|
Audio Profile / Audio Object Type
|
|
|
0: Null
|
|
|
1: AAC Main
|
|
|
2: AAC LC (Low Complexity)
|
|
|
3: AAC SSR (Scalable Sample Rate)
|
|
|
4: AAC LTP (Long Term Prediction)
|
|
|
5: SBR (Spectral Band Replication)
|
|
|
6: AAC Scalable
|
|
|
sampling freq
|
|
|
0: 96000 Hz
|
|
|
1: 88200 Hz
|
|
|
2: 64000 Hz
|
|
|
3: 48000 Hz
|
|
|
4: 44100 Hz
|
|
|
5: 32000 Hz
|
|
|
6: 24000 Hz
|
|
|
7: 22050 Hz
|
|
|
8: 16000 Hz
|
|
|
9: 12000 Hz
|
|
|
10: 11025 Hz
|
|
|
11: 8000 Hz
|
|
|
12: 7350 Hz
|
|
|
13: Reserved
|
|
|
14: Reserved
|
|
|
15: frequency is written explictly
|
|
|
Channel Configurations
|
|
|
These are the channel configurations:
|
|
|
0: Defined in AOT Specifc Config
|
|
|
1: 1 channel: front-center
|
|
|
2: 2 channels: front-left, front-right
|
|
|
*/ // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1
|
|
|
config[0]=adtsObjectType<<3;// samplingFrequencyIndex
|
|
|
config[0]|=(adtsSamplingIndex&0x0e)>>1;config[1]|=(adtsSamplingIndex&0x01)<<7;// channelConfiguration
|
|
|
config[1]|=adtsChannelConfig<<3;if(adtsObjectType===5){// adtsExtensionSamplingIndex
|
|
|
config[1]|=(adtsExtensionSamplingIndex&0x0e)>>1;config[2]=(adtsExtensionSamplingIndex&0x01)<<7;// adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???
|
|
|
// https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc
|
|
|
config[2]|=2<<2;config[3]=0;}return{config:config,samplerate:adtsSamplingRates[adtsSamplingIndex],channelCount:adtsChannelConfig,codec:'mp4a.40.'+adtsObjectType,manifestCodec:manifestCodec};}function _isHeaderPattern(data,offset){return data[offset]===0xff&&(data[offset+1]&0xf6)===0xf0;}function _getHeaderLength(data,offset){return data[offset+1]&0x01?7:9;}function _getFullFrameLength(data,offset){return(data[offset+3]&0x03)<<11|data[offset+4]<<3|(data[offset+5]&0xe0)>>>5;}function _canGetFrameLength(data,offset){return offset+5<data.length;}function _isHeader(data,offset){// Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
|
|
|
// Layer bits (position 14 and 15) in header should be always 0 for ADTS
|
|
|
// More info https://wiki.multimedia.cx/index.php?title=ADTS
|
|
|
return offset+1<data.length&&_isHeaderPattern(data,offset);}function _canParse(data,offset){return _canGetFrameLength(data,offset)&&_isHeaderPattern(data,offset)&&_getFullFrameLength(data,offset)<=data.length-offset;}function _probe(data,offset){// same as isHeader but we also check that ADTS frame follows last ADTS frame
|
|
|
// or end of data is reached
|
|
|
if(_isHeader(data,offset)){// ADTS header Length
|
|
|
var headerLength=_getHeaderLength(data,offset);if(offset+headerLength>=data.length){return false;}// ADTS frame Length
|
|
|
var frameLength=_getFullFrameLength(data,offset);if(frameLength<=headerLength){return false;}var newOffset=offset+frameLength;return newOffset===data.length||_isHeader(data,newOffset);}return false;}function _initTrackConfig(track,observer,data,offset,audioCodec){if(!track.samplerate){var config=_getAudioConfig(observer,data,offset,audioCodec);if(!config){return;}track.config=config.config;track.samplerate=config.samplerate;track.channelCount=config.channelCount;track.codec=config.codec;track.manifestCodec=config.manifestCodec;_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log("parsed codec:"+track.codec+", rate:"+config.samplerate+", channels:"+config.channelCount);}}function _getFrameDuration(samplerate){return 1024*90000/samplerate;}function _parseFrameHeader(data,offset){// The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
|
|
|
var headerLength=_getHeaderLength(data,offset);if(offset+headerLength<=data.length){// retrieve frame size
|
|
|
var frameLength=_getFullFrameLength(data,offset)-headerLength;if(frameLength>0){// logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}`);
|
|
|
return{headerLength:headerLength,frameLength:frameLength};}}}function _appendFrame(track,data,offset,pts,frameIndex){var frameDuration=_getFrameDuration(track.samplerate);var stamp=pts+frameIndex*frameDuration;var header=_parseFrameHeader(data,offset);var unit;if(header){var frameLength=header.frameLength,headerLength=header.headerLength;var _length=headerLength+frameLength;var missing=Math.max(0,offset+_length-data.length);// logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`);
|
|
|
if(missing){unit=new Uint8Array(_length-headerLength);unit.set(data.subarray(offset+headerLength,data.length),0);}else{unit=data.subarray(offset+headerLength,offset+_length);}var _sample={unit:unit,pts:stamp};if(!missing){track.samples.push(_sample);}return{sample:_sample,length:_length,missing:missing};}// overflow incomplete header
|
|
|
var length=data.length-offset;unit=new Uint8Array(length);unit.set(data.subarray(offset,data.length),0);var sample={unit:unit,pts:stamp};return{sample:sample,length:length,missing:-1};}/***/},/***/"./src/demux/base-audio-demuxer.ts":/*!*****************************************!*\
|
|
|
!*** ./src/demux/base-audio-demuxer.ts ***!
|
|
|
\*****************************************/ /***/function srcDemuxBaseAudioDemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_438624__){"use strict";__nested_webpack_require_438624__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_438624__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;},/* harmony export */"initPTSFn":function initPTSFn(){return(/* binding */_initPTSFn);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_438624__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_438624__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _types_demuxer__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_438624__(/*! ../types/demuxer */"./src/types/demuxer.ts");/* harmony import */var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_438624__(/*! ./dummy-demuxed-track */"./src/demux/dummy-demuxed-track.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_438624__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_438624__(/*! ../utils/typed-array */"./src/utils/typed-array.ts");var BaseAudioDemuxer=/*#__PURE__*/function(){function BaseAudioDemuxer(){this._audioTrack=void 0;this._id3Track=void 0;this.frameIndex=0;this.cachedData=null;this.basePTS=null;this.initPTS=null;this.lastPTS=null;}var _proto=BaseAudioDemuxer.prototype;_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,trackDuration){this._id3Track={type:'id3',id:3,pid:-1,inputTimeScale:90000,sequenceNumber:0,samples:[],dropped:0};};_proto.resetTimeStamp=function resetTimeStamp(deaultTimestamp){this.initPTS=deaultTimestamp;this.resetContiguity();};_proto.resetContiguity=function resetContiguity(){this.basePTS=null;this.lastPTS=null;this.frameIndex=0;};_proto.canParse=function canParse(data,offset){return false;};_proto.appendFrame=function appendFrame(track,data,offset){}// feed incoming data to the front of the parsing pipeline
|
|
|
;_proto.demux=function demux(data,timeOffset){if(this.cachedData){data=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(this.cachedData,data);this.cachedData=null;}var id3Data=_demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data,0);var offset=id3Data?id3Data.length:0;var lastDataIndex;var track=this._audioTrack;var id3Track=this._id3Track;var timestamp=id3Data?_demux_id3__WEBPACK_IMPORTED_MODULE_1__.getTimeStamp(id3Data):undefined;var length=data.length;if(this.basePTS===null||this.frameIndex===0&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(timestamp)){this.basePTS=_initPTSFn(timestamp,timeOffset,this.initPTS);this.lastPTS=this.basePTS;}if(this.lastPTS===null){this.lastPTS=this.basePTS;}// more expressive than alternative: id3Data?.length
|
|
|
if(id3Data&&id3Data.length>0){id3Track.samples.push({pts:this.lastPTS,dts:this.lastPTS,data:id3Data,type:_types_demuxer__WEBPACK_IMPORTED_MODULE_2__.MetadataSchema.audioId3,duration:Number.POSITIVE_INFINITY});}while(offset<length){if(this.canParse(data,offset)){var frame=this.appendFrame(track,data,offset);if(frame){this.frameIndex++;this.lastPTS=frame.sample.pts;offset+=frame.length;lastDataIndex=offset;}else{offset=length;}}else if(_demux_id3__WEBPACK_IMPORTED_MODULE_1__.canParse(data,offset)){// after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data
|
|
|
id3Data=_demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data,offset);id3Track.samples.push({pts:this.lastPTS,dts:this.lastPTS,data:id3Data,type:_types_demuxer__WEBPACK_IMPORTED_MODULE_2__.MetadataSchema.audioId3,duration:Number.POSITIVE_INFINITY});offset+=id3Data.length;lastDataIndex=offset;}else{offset++;}if(offset===length&&lastDataIndex!==length){var partialData=(0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data,lastDataIndex);if(this.cachedData){this.cachedData=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(this.cachedData,partialData);}else{this.cachedData=partialData;}}}return{audioTrack:track,videoTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),id3Track:id3Track,textTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()};};_proto.demuxSampleAes=function demuxSampleAes(data,keyData,timeOffset){return Promise.reject(new Error("["+this+"] This demuxer does not support Sample-AES decryption"));};_proto.flush=function flush(timeOffset){// Parse cache in case of remaining frames.
|
|
|
var cachedData=this.cachedData;if(cachedData){this.cachedData=null;this.demux(cachedData,0);}return{audioTrack:this._audioTrack,videoTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),id3Track:this._id3Track,textTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()};};_proto.destroy=function destroy(){};return BaseAudioDemuxer;}();/**
|
|
|
* Initialize PTS
|
|
|
* <p>
|
|
|
* use timestamp unless it is undefined, NaN or Infinity
|
|
|
* </p>
|
|
|
*/var _initPTSFn=function initPTSFn(timestamp,timeOffset,initPTS){if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(timestamp)){return timestamp*90;}return timeOffset*90000+(initPTS||0);};/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=BaseAudioDemuxer;/***/},/***/"./src/demux/chunk-cache.ts":/*!**********************************!*\
|
|
|
!*** ./src/demux/chunk-cache.ts ***!
|
|
|
\**********************************/ /***/function srcDemuxChunkCacheTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_444232__){"use strict";__nested_webpack_require_444232__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_444232__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */ChunkCache);}/* harmony export */});var ChunkCache=/*#__PURE__*/function(){function ChunkCache(){this.chunks=[];this.dataLength=0;}var _proto=ChunkCache.prototype;_proto.push=function push(chunk){this.chunks.push(chunk);this.dataLength+=chunk.length;};_proto.flush=function flush(){var chunks=this.chunks,dataLength=this.dataLength;var result;if(!chunks.length){return new Uint8Array(0);}else if(chunks.length===1){result=chunks[0];}else{result=concatUint8Arrays(chunks,dataLength);}this.reset();return result;};_proto.reset=function reset(){this.chunks.length=0;this.dataLength=0;};return ChunkCache;}();function concatUint8Arrays(chunks,dataLength){var result=new Uint8Array(dataLength);var offset=0;for(var i=0;i<chunks.length;i++){var chunk=chunks[i];result.set(chunk,offset);offset+=chunk.length;}return result;}/***/},/***/"./src/demux/dummy-demuxed-track.ts":/*!******************************************!*\
|
|
|
!*** ./src/demux/dummy-demuxed-track.ts ***!
|
|
|
\******************************************/ /***/function srcDemuxDummyDemuxedTrackTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_445537__){"use strict";__nested_webpack_require_445537__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_445537__.d(__webpack_exports__,{/* harmony export */"dummyTrack":function dummyTrack(){return(/* binding */_dummyTrack);}/* harmony export */});function _dummyTrack(type,inputTimeScale){if(type===void 0){type='';}if(inputTimeScale===void 0){inputTimeScale=90000;}return{type:type,id:-1,pid:-1,inputTimeScale:inputTimeScale,sequenceNumber:-1,samples:[],dropped:0};}/***/},/***/"./src/demux/exp-golomb.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/exp-golomb.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxExpGolombTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_446243__){"use strict";__nested_webpack_require_446243__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_446243__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_446243__(/*! ../utils/logger */"./src/utils/logger.ts");/**
|
|
|
* Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
|
|
|
*/var ExpGolomb=/*#__PURE__*/function(){function ExpGolomb(data){this.data=void 0;this.bytesAvailable=void 0;this.word=void 0;this.bitsAvailable=void 0;this.data=data;// the number of bytes left to examine in this.data
|
|
|
this.bytesAvailable=data.byteLength;// the current word being examined
|
|
|
this.word=0;// :uint
|
|
|
// the number of bits left to examine in the current word
|
|
|
this.bitsAvailable=0;// :uint
|
|
|
}// ():void
|
|
|
var _proto=ExpGolomb.prototype;_proto.loadWord=function loadWord(){var data=this.data;var bytesAvailable=this.bytesAvailable;var position=data.byteLength-bytesAvailable;var workingBytes=new Uint8Array(4);var availableBytes=Math.min(4,bytesAvailable);if(availableBytes===0){throw new Error('no bytes available');}workingBytes.set(data.subarray(position,position+availableBytes));this.word=new DataView(workingBytes.buffer).getUint32(0);// track the amount of this.data that has been processed
|
|
|
this.bitsAvailable=availableBytes*8;this.bytesAvailable-=availableBytes;}// (count:int):void
|
|
|
;_proto.skipBits=function skipBits(count){var skipBytes;// :int
|
|
|
count=Math.min(count,this.bytesAvailable*8+this.bitsAvailable);if(this.bitsAvailable>count){this.word<<=count;this.bitsAvailable-=count;}else{count-=this.bitsAvailable;skipBytes=count>>3;count-=skipBytes<<3;this.bytesAvailable-=skipBytes;this.loadWord();this.word<<=count;this.bitsAvailable-=count;}}// (size:int):uint
|
|
|
;_proto.readBits=function readBits(size){var bits=Math.min(this.bitsAvailable,size);// :uint
|
|
|
var valu=this.word>>>32-bits;// :uint
|
|
|
if(size>32){_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.error('Cannot read more than 32 bits at a time');}this.bitsAvailable-=bits;if(this.bitsAvailable>0){this.word<<=bits;}else if(this.bytesAvailable>0){this.loadWord();}else{throw new Error('no bits available');}bits=size-bits;if(bits>0&&this.bitsAvailable){return valu<<bits|this.readBits(bits);}else{return valu;}}// ():uint
|
|
|
;_proto.skipLZ=function skipLZ(){var leadingZeroCount;// :uint
|
|
|
for(leadingZeroCount=0;leadingZeroCount<this.bitsAvailable;++leadingZeroCount){if((this.word&0x80000000>>>leadingZeroCount)!==0){// the first bit of working word is 1
|
|
|
this.word<<=leadingZeroCount;this.bitsAvailable-=leadingZeroCount;return leadingZeroCount;}}// we exhausted word and still have not found a 1
|
|
|
this.loadWord();return leadingZeroCount+this.skipLZ();}// ():void
|
|
|
;_proto.skipUEG=function skipUEG(){this.skipBits(1+this.skipLZ());}// ():void
|
|
|
;_proto.skipEG=function skipEG(){this.skipBits(1+this.skipLZ());}// ():uint
|
|
|
;_proto.readUEG=function readUEG(){var clz=this.skipLZ();// :uint
|
|
|
return this.readBits(clz+1)-1;}// ():int
|
|
|
;_proto.readEG=function readEG(){var valu=this.readUEG();// :int
|
|
|
if(0x01&valu){// the number is odd if the low order bit is set
|
|
|
return 1+valu>>>1;// add 1 to make it even, and divide by 2
|
|
|
}else{return-1*(valu>>>1);// divide by two then make it negative
|
|
|
}}// Some convenience functions
|
|
|
// :Boolean
|
|
|
;_proto.readBoolean=function readBoolean(){return this.readBits(1)===1;}// ():int
|
|
|
;_proto.readUByte=function readUByte(){return this.readBits(8);}// ():int
|
|
|
;_proto.readUShort=function readUShort(){return this.readBits(16);}// ():int
|
|
|
;_proto.readUInt=function readUInt(){return this.readBits(32);}/**
|
|
|
* Advance the ExpGolomb decoder past a scaling list. The scaling
|
|
|
* list is optionally transmitted as part of a sequence parameter
|
|
|
* set and is not relevant to transmuxing.
|
|
|
* @param count the number of entries in this scaling list
|
|
|
* @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
|
|
|
*/;_proto.skipScalingList=function skipScalingList(count){var lastScale=8;var nextScale=8;var deltaScale;for(var j=0;j<count;j++){if(nextScale!==0){deltaScale=this.readEG();nextScale=(lastScale+deltaScale+256)%256;}lastScale=nextScale===0?lastScale:nextScale;}}/**
|
|
|
* Read a sequence parameter set and return some interesting video
|
|
|
* properties. A sequence parameter set is the H264 metadata that
|
|
|
* describes the properties of upcoming video frames.
|
|
|
* @param data {Uint8Array} the bytes of a sequence parameter set
|
|
|
* @return {object} an object with configuration parsed from the
|
|
|
* sequence parameter set, including the dimensions of the
|
|
|
* associated video frames.
|
|
|
*/;_proto.readSPS=function readSPS(){var frameCropLeftOffset=0;var frameCropRightOffset=0;var frameCropTopOffset=0;var frameCropBottomOffset=0;var numRefFramesInPicOrderCntCycle;var scalingListCount;var i;var readUByte=this.readUByte.bind(this);var readBits=this.readBits.bind(this);var readUEG=this.readUEG.bind(this);var readBoolean=this.readBoolean.bind(this);var skipBits=this.skipBits.bind(this);var skipEG=this.skipEG.bind(this);var skipUEG=this.skipUEG.bind(this);var skipScalingList=this.skipScalingList.bind(this);readUByte();var profileIdc=readUByte();// profile_idc
|
|
|
readBits(5);// profileCompat constraint_set[0-4]_flag, u(5)
|
|
|
skipBits(3);// reserved_zero_3bits u(3),
|
|
|
readUByte();// level_idc u(8)
|
|
|
skipUEG();// seq_parameter_set_id
|
|
|
// some profiles have more optional data we don't need
|
|
|
if(profileIdc===100||profileIdc===110||profileIdc===122||profileIdc===244||profileIdc===44||profileIdc===83||profileIdc===86||profileIdc===118||profileIdc===128){var chromaFormatIdc=readUEG();if(chromaFormatIdc===3){skipBits(1);}// separate_colour_plane_flag
|
|
|
skipUEG();// bit_depth_luma_minus8
|
|
|
skipUEG();// bit_depth_chroma_minus8
|
|
|
skipBits(1);// qpprime_y_zero_transform_bypass_flag
|
|
|
if(readBoolean()){// seq_scaling_matrix_present_flag
|
|
|
scalingListCount=chromaFormatIdc!==3?8:12;for(i=0;i<scalingListCount;i++){if(readBoolean()){// seq_scaling_list_present_flag[ i ]
|
|
|
if(i<6){skipScalingList(16);}else{skipScalingList(64);}}}}}skipUEG();// log2_max_frame_num_minus4
|
|
|
var picOrderCntType=readUEG();if(picOrderCntType===0){readUEG();// log2_max_pic_order_cnt_lsb_minus4
|
|
|
}else if(picOrderCntType===1){skipBits(1);// delta_pic_order_always_zero_flag
|
|
|
skipEG();// offset_for_non_ref_pic
|
|
|
skipEG();// offset_for_top_to_bottom_field
|
|
|
numRefFramesInPicOrderCntCycle=readUEG();for(i=0;i<numRefFramesInPicOrderCntCycle;i++){skipEG();}// offset_for_ref_frame[ i ]
|
|
|
}skipUEG();// max_num_ref_frames
|
|
|
skipBits(1);// gaps_in_frame_num_value_allowed_flag
|
|
|
var picWidthInMbsMinus1=readUEG();var picHeightInMapUnitsMinus1=readUEG();var frameMbsOnlyFlag=readBits(1);if(frameMbsOnlyFlag===0){skipBits(1);}// mb_adaptive_frame_field_flag
|
|
|
skipBits(1);// direct_8x8_inference_flag
|
|
|
if(readBoolean()){// frame_cropping_flag
|
|
|
frameCropLeftOffset=readUEG();frameCropRightOffset=readUEG();frameCropTopOffset=readUEG();frameCropBottomOffset=readUEG();}var pixelRatio=[1,1];if(readBoolean()){// vui_parameters_present_flag
|
|
|
if(readBoolean()){// aspect_ratio_info_present_flag
|
|
|
var aspectRatioIdc=readUByte();switch(aspectRatioIdc){case 1:pixelRatio=[1,1];break;case 2:pixelRatio=[12,11];break;case 3:pixelRatio=[10,11];break;case 4:pixelRatio=[16,11];break;case 5:pixelRatio=[40,33];break;case 6:pixelRatio=[24,11];break;case 7:pixelRatio=[20,11];break;case 8:pixelRatio=[32,11];break;case 9:pixelRatio=[80,33];break;case 10:pixelRatio=[18,11];break;case 11:pixelRatio=[15,11];break;case 12:pixelRatio=[64,33];break;case 13:pixelRatio=[160,99];break;case 14:pixelRatio=[4,3];break;case 15:pixelRatio=[3,2];break;case 16:pixelRatio=[2,1];break;case 255:{pixelRatio=[readUByte()<<8|readUByte(),readUByte()<<8|readUByte()];break;}}}}return{width:Math.ceil((picWidthInMbsMinus1+1)*16-frameCropLeftOffset*2-frameCropRightOffset*2),height:(2-frameMbsOnlyFlag)*(picHeightInMapUnitsMinus1+1)*16-(frameMbsOnlyFlag?2:4)*(frameCropTopOffset+frameCropBottomOffset),pixelRatio:pixelRatio};};_proto.readSliceType=function readSliceType(){// skip NALu type
|
|
|
this.readUByte();// discard first_mb_in_slice
|
|
|
this.readUEG();// return slice_type
|
|
|
return this.readUEG();};return ExpGolomb;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=ExpGolomb;/***/},/***/"./src/demux/id3.ts":/*!**************************!*\
|
|
|
!*** ./src/demux/id3.ts ***!
|
|
|
\**************************/ /***/function srcDemuxId3Ts(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_454703__){"use strict";__nested_webpack_require_454703__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_454703__.d(__webpack_exports__,{/* harmony export */"canParse":function canParse(){return(/* binding */_canParse2);},/* harmony export */"decodeFrame":function decodeFrame(){return(/* binding */_decodeFrame);},/* harmony export */"getID3Data":function getID3Data(){return(/* binding */_getID3Data);},/* harmony export */"getID3Frames":function getID3Frames(){return(/* binding */_getID3Frames);},/* harmony export */"getTimeStamp":function getTimeStamp(){return(/* binding */_getTimeStamp);},/* harmony export */"isFooter":function isFooter(){return(/* binding */_isFooter);},/* harmony export */"isHeader":function isHeader(){return(/* binding */_isHeader2);},/* harmony export */"isTimeStampFrame":function isTimeStampFrame(){return(/* binding */_isTimeStampFrame);},/* harmony export */"testables":function testables(){return(/* binding */_testables);},/* harmony export */"utf8ArrayToStr":function utf8ArrayToStr(){return(/* binding */_utf8ArrayToStr);}/* harmony export */});// breaking up those two types in order to clarify what is happening in the decoding path.
|
|
|
/**
|
|
|
* Returns true if an ID3 header can be found at offset in data
|
|
|
* @param {Uint8Array} data - The data to search in
|
|
|
* @param {number} offset - The offset at which to start searching
|
|
|
* @return {boolean} - True if an ID3 header is found
|
|
|
*/var _isHeader2=function isHeader(data,offset){/*
|
|
|
* http://id3.org/id3v2.3.0
|
|
|
* [0] = 'I'
|
|
|
* [1] = 'D'
|
|
|
* [2] = '3'
|
|
|
* [3,4] = {Version}
|
|
|
* [5] = {Flags}
|
|
|
* [6-9] = {ID3 Size}
|
|
|
*
|
|
|
* An ID3v2 tag can be detected with the following pattern:
|
|
|
* $49 44 33 yy yy xx zz zz zz zz
|
|
|
* Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80
|
|
|
*/if(offset+10<=data.length){// look for 'ID3' identifier
|
|
|
if(data[offset]===0x49&&data[offset+1]===0x44&&data[offset+2]===0x33){// check version is within range
|
|
|
if(data[offset+3]<0xff&&data[offset+4]<0xff){// check size is within range
|
|
|
if(data[offset+6]<0x80&&data[offset+7]<0x80&&data[offset+8]<0x80&&data[offset+9]<0x80){return true;}}}}return false;};/**
|
|
|
* Returns true if an ID3 footer can be found at offset in data
|
|
|
* @param {Uint8Array} data - The data to search in
|
|
|
* @param {number} offset - The offset at which to start searching
|
|
|
* @return {boolean} - True if an ID3 footer is found
|
|
|
*/var _isFooter=function isFooter(data,offset){/*
|
|
|
* The footer is a copy of the header, but with a different identifier
|
|
|
*/if(offset+10<=data.length){// look for '3DI' identifier
|
|
|
if(data[offset]===0x33&&data[offset+1]===0x44&&data[offset+2]===0x49){// check version is within range
|
|
|
if(data[offset+3]<0xff&&data[offset+4]<0xff){// check size is within range
|
|
|
if(data[offset+6]<0x80&&data[offset+7]<0x80&&data[offset+8]<0x80&&data[offset+9]<0x80){return true;}}}}return false;};/**
|
|
|
* Returns any adjacent ID3 tags found in data starting at offset, as one block of data
|
|
|
* @param {Uint8Array} data - The data to search in
|
|
|
* @param {number} offset - The offset at which to start searching
|
|
|
* @return {Uint8Array | undefined} - The block of data containing any ID3 tags found
|
|
|
* or *undefined* if no header is found at the starting offset
|
|
|
*/var _getID3Data=function getID3Data(data,offset){var front=offset;var length=0;while(_isHeader2(data,offset)){// ID3 header is 10 bytes
|
|
|
length+=10;var size=readSize(data,offset+6);length+=size;if(_isFooter(data,offset+10)){// ID3 footer is 10 bytes
|
|
|
length+=10;}offset+=length;}if(length>0){return data.subarray(front,front+length);}return undefined;};var readSize=function readSize(data,offset){var size=0;size=(data[offset]&0x7f)<<21;size|=(data[offset+1]&0x7f)<<14;size|=(data[offset+2]&0x7f)<<7;size|=data[offset+3]&0x7f;return size;};var _canParse2=function canParse(data,offset){return _isHeader2(data,offset)&&readSize(data,offset+6)+10<=data.length-offset;};/**
|
|
|
* Searches for the Elementary Stream timestamp found in the ID3 data chunk
|
|
|
* @param {Uint8Array} data - Block of data containing one or more ID3 tags
|
|
|
* @return {number | undefined} - The timestamp
|
|
|
*/var _getTimeStamp=function getTimeStamp(data){var frames=_getID3Frames(data);for(var i=0;i<frames.length;i++){var frame=frames[i];if(_isTimeStampFrame(frame)){return readTimeStamp(frame);}}return undefined;};/**
|
|
|
* Returns true if the ID3 frame is an Elementary Stream timestamp frame
|
|
|
* @param {ID3 frame} frame
|
|
|
*/var _isTimeStampFrame=function isTimeStampFrame(frame){return frame&&frame.key==='PRIV'&&frame.info==='com.apple.streaming.transportStreamTimestamp';};var getFrameData=function getFrameData(data){/*
|
|
|
Frame ID $xx xx xx xx (four characters)
|
|
|
Size $xx xx xx xx
|
|
|
Flags $xx xx
|
|
|
*/var type=String.fromCharCode(data[0],data[1],data[2],data[3]);var size=readSize(data,4);// skip frame id, size, and flags
|
|
|
var offset=10;return{type:type,size:size,data:data.subarray(offset,offset+size)};};/**
|
|
|
* Returns an array of ID3 frames found in all the ID3 tags in the id3Data
|
|
|
* @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags
|
|
|
* @return {ID3.Frame[]} - Array of ID3 frame objects
|
|
|
*/var _getID3Frames=function getID3Frames(id3Data){var offset=0;var frames=[];while(_isHeader2(id3Data,offset)){var size=readSize(id3Data,offset+6);// skip past ID3 header
|
|
|
offset+=10;var end=offset+size;// loop through frames in the ID3 tag
|
|
|
while(offset+8<end){var frameData=getFrameData(id3Data.subarray(offset));var frame=_decodeFrame(frameData);if(frame){frames.push(frame);}// skip frame header and frame data
|
|
|
offset+=frameData.size+10;}if(_isFooter(id3Data,offset)){offset+=10;}}return frames;};var _decodeFrame=function decodeFrame(frame){if(frame.type==='PRIV'){return decodePrivFrame(frame);}else if(frame.type[0]==='W'){return decodeURLFrame(frame);}return decodeTextFrame(frame);};var decodePrivFrame=function decodePrivFrame(frame){/*
|
|
|
Format: <text string>\0<binary data>
|
|
|
*/if(frame.size<2){return undefined;}var owner=_utf8ArrayToStr(frame.data,true);var privateData=new Uint8Array(frame.data.subarray(owner.length+1));return{key:frame.type,info:owner,data:privateData.buffer};};var decodeTextFrame=function decodeTextFrame(frame){if(frame.size<2){return undefined;}if(frame.type==='TXXX'){/*
|
|
|
Format:
|
|
|
[0] = {Text Encoding}
|
|
|
[1-?] = {Description}\0{Value}
|
|
|
*/var index=1;var description=_utf8ArrayToStr(frame.data.subarray(index),true);index+=description.length+1;var value=_utf8ArrayToStr(frame.data.subarray(index));return{key:frame.type,info:description,data:value};}/*
|
|
|
Format:
|
|
|
[0] = {Text Encoding}
|
|
|
[1-?] = {Value}
|
|
|
*/var text=_utf8ArrayToStr(frame.data.subarray(1));return{key:frame.type,data:text};};var decodeURLFrame=function decodeURLFrame(frame){if(frame.type==='WXXX'){/*
|
|
|
Format:
|
|
|
[0] = {Text Encoding}
|
|
|
[1-?] = {Description}\0{URL}
|
|
|
*/if(frame.size<2){return undefined;}var index=1;var description=_utf8ArrayToStr(frame.data.subarray(index),true);index+=description.length+1;var value=_utf8ArrayToStr(frame.data.subarray(index));return{key:frame.type,info:description,data:value};}/*
|
|
|
Format:
|
|
|
[0-?] = {URL}
|
|
|
*/var url=_utf8ArrayToStr(frame.data);return{key:frame.type,data:url};};var readTimeStamp=function readTimeStamp(timeStampFrame){if(timeStampFrame.data.byteLength===8){var data=new Uint8Array(timeStampFrame.data);// timestamp is 33 bit expressed as a big-endian eight-octet number,
|
|
|
// with the upper 31 bits set to zero.
|
|
|
var pts33Bit=data[3]&0x1;var timestamp=(data[4]<<23)+(data[5]<<15)+(data[6]<<7)+data[7];timestamp/=45;if(pts33Bit){timestamp+=47721858.84;}// 2^32 / 90
|
|
|
return Math.round(timestamp);}return undefined;};// http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197
|
|
|
// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
|
|
|
/* utf.js - UTF-8 <=> UTF-16 convertion
|
|
|
*
|
|
|
* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
|
|
|
* Version: 1.0
|
|
|
* LastModified: Dec 25 1999
|
|
|
* This library is free. You can redistribute it and/or modify it.
|
|
|
*/var _utf8ArrayToStr=function utf8ArrayToStr(array,exitOnNull){if(exitOnNull===void 0){exitOnNull=false;}var decoder=getTextDecoder();if(decoder){var decoded=decoder.decode(array);if(exitOnNull){// grab up to the first null
|
|
|
var idx=decoded.indexOf('\0');return idx!==-1?decoded.substring(0,idx):decoded;}// remove any null characters
|
|
|
return decoded.replace(/\0/g,'');}var len=array.length;var c;var char2;var char3;var out='';var i=0;while(i<len){c=array[i++];if(c===0x00&&exitOnNull){return out;}else if(c===0x00||c===0x03){// If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it
|
|
|
continue;}switch(c>>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:// 0xxxxxxx
|
|
|
out+=String.fromCharCode(c);break;case 12:case 13:// 110x xxxx 10xx xxxx
|
|
|
char2=array[i++];out+=String.fromCharCode((c&0x1f)<<6|char2&0x3f);break;case 14:// 1110 xxxx 10xx xxxx 10xx xxxx
|
|
|
char2=array[i++];char3=array[i++];out+=String.fromCharCode((c&0x0f)<<12|(char2&0x3f)<<6|(char3&0x3f)<<0);break;default:}}return out;};var _testables={decodeTextFrame:decodeTextFrame};var decoder;function getTextDecoder(){if(!decoder&&typeof self.TextDecoder!=='undefined'){decoder=new self.TextDecoder('utf-8');}return decoder;}/***/},/***/"./src/demux/mp3demuxer.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/mp3demuxer.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxMp3demuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_464173__){"use strict";__nested_webpack_require_464173__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_464173__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_464173__(/*! ./base-audio-demuxer */"./src/demux/base-audio-demuxer.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_464173__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_464173__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _mpegaudio__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_464173__(/*! ./mpegaudio */"./src/demux/mpegaudio.ts");function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}/**
|
|
|
* MP3 demuxer
|
|
|
*/var MP3Demuxer=/*#__PURE__*/function(_BaseAudioDemuxer){_inheritsLoose(MP3Demuxer,_BaseAudioDemuxer);function MP3Demuxer(){return _BaseAudioDemuxer.apply(this,arguments)||this;}var _proto=MP3Demuxer.prototype;_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,trackDuration){_BaseAudioDemuxer.prototype.resetInitSegment.call(this,initSegment,audioCodec,videoCodec,trackDuration);this._audioTrack={container:'audio/mpeg',type:'audio',id:2,pid:-1,sequenceNumber:0,segmentCodec:'mp3',samples:[],manifestCodec:audioCodec,duration:trackDuration,inputTimeScale:90000,dropped:0};};MP3Demuxer.probe=function probe(data){if(!data){return false;}// check if data contains ID3 timestamp and MPEG sync word
|
|
|
// Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
|
|
|
// Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
|
|
|
// More info http://www.mp3-tech.org/programmer/frame_header.html
|
|
|
var id3Data=_demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data,0)||[];var offset=id3Data.length;for(var length=data.length;offset<length;offset++){if(_mpegaudio__WEBPACK_IMPORTED_MODULE_3__.probe(data,offset)){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('MPEG Audio sync word found !');return true;}}return false;};_proto.canParse=function canParse(data,offset){return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__.canParse(data,offset);};_proto.appendFrame=function appendFrame(track,data,offset){if(this.basePTS===null){return;}return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__.appendFrame(track,data,offset,this.basePTS,this.frameIndex);};return MP3Demuxer;}(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]);/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=MP3Demuxer;/***/},/***/"./src/demux/mp4demuxer.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/mp4demuxer.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxMp4demuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_467392__){"use strict";__nested_webpack_require_467392__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_467392__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_467392__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _types_demuxer__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_467392__(/*! ../types/demuxer */"./src/types/demuxer.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_467392__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_467392__(/*! ./dummy-demuxed-track */"./src/demux/dummy-demuxed-track.ts");/**
|
|
|
* MP4 demuxer
|
|
|
*/var emsgSchemePattern=/\/emsg[-/]ID3/i;var MP4Demuxer=/*#__PURE__*/function(){function MP4Demuxer(observer,config){this.remainderData=null;this.timeOffset=0;this.config=void 0;this.videoTrack=void 0;this.audioTrack=void 0;this.id3Track=void 0;this.txtTrack=void 0;this.config=config;}var _proto=MP4Demuxer.prototype;_proto.resetTimeStamp=function resetTimeStamp(){};_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,trackDuration){var videoTrack=this.videoTrack=(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('video',1);var audioTrack=this.audioTrack=(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('audio',1);var captionTrack=this.txtTrack=(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('text',1);this.id3Track=(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('id3',1);this.timeOffset=0;if(!initSegment||!initSegment.byteLength){return;}var initData=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseInitSegment)(initSegment);if(initData.video){var _initData$video=initData.video,id=_initData$video.id,timescale=_initData$video.timescale,codec=_initData$video.codec;videoTrack.id=id;videoTrack.timescale=captionTrack.timescale=timescale;videoTrack.codec=codec;}if(initData.audio){var _initData$audio=initData.audio,_id=_initData$audio.id,_timescale=_initData$audio.timescale,_codec=_initData$audio.codec;audioTrack.id=_id;audioTrack.timescale=_timescale;audioTrack.codec=_codec;}captionTrack.id=_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.RemuxerTrackIdConfig.text;videoTrack.sampleDuration=0;videoTrack.duration=audioTrack.duration=trackDuration;};_proto.resetContiguity=function resetContiguity(){};MP4Demuxer.probe=function probe(data){// ensure we find a moof box in the first 16 kB
|
|
|
data=data.length>16384?data.subarray(0,16384):data;return(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.findBox)(data,['moof']).length>0;};_proto.demux=function demux(data,timeOffset){this.timeOffset=timeOffset;// Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter
|
|
|
var videoSamples=data;var videoTrack=this.videoTrack;var textTrack=this.txtTrack;if(this.config.progressive){// Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else.
|
|
|
// This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee
|
|
|
// that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception.
|
|
|
if(this.remainderData){videoSamples=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.appendUint8Array)(this.remainderData,data);}var segmentedData=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.segmentValidRange)(videoSamples);this.remainderData=segmentedData.remainder;videoTrack.samples=segmentedData.valid||new Uint8Array();}else{videoTrack.samples=videoSamples;}var id3Track=this.extractID3Track(videoTrack,timeOffset);textTrack.samples=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseSamples)(timeOffset,videoTrack);return{videoTrack:videoTrack,audioTrack:this.audioTrack,id3Track:id3Track,textTrack:this.txtTrack};};_proto.flush=function flush(){var timeOffset=this.timeOffset;var videoTrack=this.videoTrack;var textTrack=this.txtTrack;videoTrack.samples=this.remainderData||new Uint8Array();this.remainderData=null;var id3Track=this.extractID3Track(videoTrack,this.timeOffset);textTrack.samples=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseSamples)(timeOffset,videoTrack);return{videoTrack:videoTrack,audioTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),id3Track:id3Track,textTrack:(0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()};};_proto.extractID3Track=function extractID3Track(videoTrack,timeOffset){var id3Track=this.id3Track;if(videoTrack.samples.length){var emsgs=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.findBox)(videoTrack.samples,['emsg']);if(emsgs){emsgs.forEach(function(data){var emsgInfo=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseEmsg)(data);if(emsgSchemePattern.test(emsgInfo.schemeIdUri)){var pts=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(emsgInfo.presentationTime)?emsgInfo.presentationTime/emsgInfo.timeScale:timeOffset+emsgInfo.presentationTimeDelta/emsgInfo.timeScale;var duration=emsgInfo.eventDuration===0xffffffff?Number.POSITIVE_INFINITY:emsgInfo.eventDuration/emsgInfo.timeScale;// Safari takes anything <= 0.001 seconds and maps it to Infinity
|
|
|
if(duration<=0.001){duration=Number.POSITIVE_INFINITY;}var payload=emsgInfo.payload;id3Track.samples.push({data:payload,len:payload.byteLength,dts:pts,pts:pts,type:_types_demuxer__WEBPACK_IMPORTED_MODULE_1__.MetadataSchema.emsg,duration:duration});}});}}return id3Track;};_proto.demuxSampleAes=function demuxSampleAes(data,keyData,timeOffset){return Promise.reject(new Error('The MP4 demuxer does not support SAMPLE-AES decryption'));};_proto.destroy=function destroy(){};return MP4Demuxer;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=MP4Demuxer;/***/},/***/"./src/demux/mpegaudio.ts":/*!********************************!*\
|
|
|
!*** ./src/demux/mpegaudio.ts ***!
|
|
|
\********************************/ /***/function srcDemuxMpegaudioTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_473712__){"use strict";__nested_webpack_require_473712__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_473712__.d(__webpack_exports__,{/* harmony export */"appendFrame":function appendFrame(){return(/* binding */_appendFrame2);},/* harmony export */"canParse":function canParse(){return(/* binding */_canParse3);},/* harmony export */"isHeader":function isHeader(){return(/* binding */_isHeader3);},/* harmony export */"isHeaderPattern":function isHeaderPattern(){return(/* binding */_isHeaderPattern2);},/* harmony export */"parseHeader":function parseHeader(){return(/* binding */_parseHeader);},/* harmony export */"probe":function probe(){return(/* binding */_probe2);}/* harmony export */});/**
|
|
|
* MPEG parser helper
|
|
|
*/var chromeVersion=null;var BitratesMap=[32,64,96,128,160,192,224,256,288,320,352,384,416,448,32,48,56,64,80,96,112,128,160,192,224,256,320,384,32,40,48,56,64,80,96,112,128,160,192,224,256,320,32,48,56,64,80,96,112,128,144,160,176,192,224,256,8,16,24,32,40,48,56,64,80,96,112,128,144,160];var SamplingRateMap=[44100,48000,32000,22050,24000,16000,11025,12000,8000];var SamplesCoefficients=[// MPEG 2.5
|
|
|
[0,// Reserved
|
|
|
72,// Layer3
|
|
|
144,// Layer2
|
|
|
12// Layer1
|
|
|
],// Reserved
|
|
|
[0,// Reserved
|
|
|
0,// Layer3
|
|
|
0,// Layer2
|
|
|
0// Layer1
|
|
|
],// MPEG 2
|
|
|
[0,// Reserved
|
|
|
72,// Layer3
|
|
|
144,// Layer2
|
|
|
12// Layer1
|
|
|
],// MPEG 1
|
|
|
[0,// Reserved
|
|
|
144,// Layer3
|
|
|
144,// Layer2
|
|
|
12// Layer1
|
|
|
]];var BytesInSlot=[0,// Reserved
|
|
|
1,// Layer3
|
|
|
1,// Layer2
|
|
|
4// Layer1
|
|
|
];function _appendFrame2(track,data,offset,pts,frameIndex){// Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
|
|
|
if(offset+24>data.length){return;}var header=_parseHeader(data,offset);if(header&&offset+header.frameLength<=data.length){var frameDuration=header.samplesPerFrame*90000/header.sampleRate;var stamp=pts+frameIndex*frameDuration;var sample={unit:data.subarray(offset,offset+header.frameLength),pts:stamp,dts:stamp};track.config=[];track.channelCount=header.channelCount;track.samplerate=header.sampleRate;track.samples.push(sample);return{sample:sample,length:header.frameLength,missing:0};}}function _parseHeader(data,offset){var mpegVersion=data[offset+1]>>3&3;var mpegLayer=data[offset+1]>>1&3;var bitRateIndex=data[offset+2]>>4&15;var sampleRateIndex=data[offset+2]>>2&3;if(mpegVersion!==1&&bitRateIndex!==0&&bitRateIndex!==15&&sampleRateIndex!==3){var paddingBit=data[offset+2]>>1&1;var channelMode=data[offset+3]>>6;var columnInBitrates=mpegVersion===3?3-mpegLayer:mpegLayer===3?3:4;var bitRate=BitratesMap[columnInBitrates*14+bitRateIndex-1]*1000;var columnInSampleRates=mpegVersion===3?0:mpegVersion===2?1:2;var sampleRate=SamplingRateMap[columnInSampleRates*3+sampleRateIndex];var channelCount=channelMode===3?1:2;// If bits of channel mode are `11` then it is a single channel (Mono)
|
|
|
var sampleCoefficient=SamplesCoefficients[mpegVersion][mpegLayer];var bytesInSlot=BytesInSlot[mpegLayer];var samplesPerFrame=sampleCoefficient*8*bytesInSlot;var frameLength=Math.floor(sampleCoefficient*bitRate/sampleRate+paddingBit)*bytesInSlot;if(chromeVersion===null){var userAgent=navigator.userAgent||'';var result=userAgent.match(/Chrome\/(\d+)/i);chromeVersion=result?parseInt(result[1]):0;}var needChromeFix=!!chromeVersion&&chromeVersion<=87;if(needChromeFix&&mpegLayer===2&&bitRate>=224000&&channelMode===0){// Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00)
|
|
|
data[offset+3]=data[offset+3]|0x80;}return{sampleRate:sampleRate,channelCount:channelCount,frameLength:frameLength,samplesPerFrame:samplesPerFrame};}}function _isHeaderPattern2(data,offset){return data[offset]===0xff&&(data[offset+1]&0xe0)===0xe0&&(data[offset+1]&0x06)!==0x00;}function _isHeader3(data,offset){// Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
|
|
|
// Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
|
|
|
// More info http://www.mp3-tech.org/programmer/frame_header.html
|
|
|
return offset+1<data.length&&_isHeaderPattern2(data,offset);}function _canParse3(data,offset){var headerSize=4;return _isHeaderPattern2(data,offset)&&headerSize<=data.length-offset;}function _probe2(data,offset){// same as isHeader but we also check that MPEG frame follows last MPEG frame
|
|
|
// or end of data is reached
|
|
|
if(offset+1<data.length&&_isHeaderPattern2(data,offset)){// MPEG header Length
|
|
|
var headerLength=4;// MPEG frame Length
|
|
|
var header=_parseHeader(data,offset);var frameLength=headerLength;if(header!==null&&header!==void 0&&header.frameLength){frameLength=header.frameLength;}var newOffset=offset+frameLength;return newOffset===data.length||_isHeader3(data,newOffset);}return false;}/***/},/***/"./src/demux/sample-aes.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/sample-aes.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxSampleAesTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_478625__){"use strict";__nested_webpack_require_478625__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_478625__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_478625__(/*! ../crypt/decrypter */"./src/crypt/decrypter.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_478625__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/**
|
|
|
* SAMPLE-AES decrypter
|
|
|
*/var SampleAesDecrypter=/*#__PURE__*/function(){function SampleAesDecrypter(observer,config,keyData){this.keyData=void 0;this.decrypter=void 0;this.keyData=keyData;this.decrypter=new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__["default"](config,{removePKCS7Padding:false});}var _proto=SampleAesDecrypter.prototype;_proto.decryptBuffer=function decryptBuffer(encryptedData){return this.decrypter.decrypt(encryptedData,this.keyData.key.buffer,this.keyData.iv.buffer);}// AAC - encrypt all full 16 bytes blocks starting from offset 16
|
|
|
;_proto.decryptAacSample=function decryptAacSample(samples,sampleIndex,callback){var _this=this;var curUnit=samples[sampleIndex].unit;if(curUnit.length<=16){// No encrypted portion in this sample (first 16 bytes is not
|
|
|
// encrypted, see https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Encryption/Encryption.html),
|
|
|
return;}var encryptedData=curUnit.subarray(16,curUnit.length-curUnit.length%16);var encryptedBuffer=encryptedData.buffer.slice(encryptedData.byteOffset,encryptedData.byteOffset+encryptedData.length);this.decryptBuffer(encryptedBuffer).then(function(decryptedBuffer){var decryptedData=new Uint8Array(decryptedBuffer);curUnit.set(decryptedData,16);if(!_this.decrypter.isSync()){_this.decryptAacSamples(samples,sampleIndex+1,callback);}});};_proto.decryptAacSamples=function decryptAacSamples(samples,sampleIndex,callback){for(;;sampleIndex++){if(sampleIndex>=samples.length){callback();return;}if(samples[sampleIndex].unit.length<32){continue;}this.decryptAacSample(samples,sampleIndex,callback);if(!this.decrypter.isSync()){return;}}}// AVC - encrypt one 16 bytes block out of ten, starting from offset 32
|
|
|
;_proto.getAvcEncryptedData=function getAvcEncryptedData(decodedData){var encryptedDataLen=Math.floor((decodedData.length-48)/160)*16+16;var encryptedData=new Int8Array(encryptedDataLen);var outputPos=0;for(var inputPos=32;inputPos<decodedData.length-16;inputPos+=160,outputPos+=16){encryptedData.set(decodedData.subarray(inputPos,inputPos+16),outputPos);}return encryptedData;};_proto.getAvcDecryptedUnit=function getAvcDecryptedUnit(decodedData,decryptedData){var uint8DecryptedData=new Uint8Array(decryptedData);var inputPos=0;for(var outputPos=32;outputPos<decodedData.length-16;outputPos+=160,inputPos+=16){decodedData.set(uint8DecryptedData.subarray(inputPos,inputPos+16),outputPos);}return decodedData;};_proto.decryptAvcSample=function decryptAvcSample(samples,sampleIndex,unitIndex,callback,curUnit){var _this2=this;var decodedData=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__.discardEPB)(curUnit.data);var encryptedData=this.getAvcEncryptedData(decodedData);this.decryptBuffer(encryptedData.buffer).then(function(decryptedBuffer){curUnit.data=_this2.getAvcDecryptedUnit(decodedData,decryptedBuffer);if(!_this2.decrypter.isSync()){_this2.decryptAvcSamples(samples,sampleIndex,unitIndex+1,callback);}});};_proto.decryptAvcSamples=function decryptAvcSamples(samples,sampleIndex,unitIndex,callback){if(samples instanceof Uint8Array){throw new Error('Cannot decrypt samples of type Uint8Array');}for(;;sampleIndex++,unitIndex=0){if(sampleIndex>=samples.length){callback();return;}var curUnits=samples[sampleIndex].units;for(;;unitIndex++){if(unitIndex>=curUnits.length){break;}var curUnit=curUnits[unitIndex];if(curUnit.data.length<=48||curUnit.type!==1&&curUnit.type!==5){continue;}this.decryptAvcSample(samples,sampleIndex,unitIndex,callback,curUnit);if(!this.decrypter.isSync()){return;}}}};return SampleAesDecrypter;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=SampleAesDecrypter;/***/},/***/"./src/demux/transmuxer-interface.ts":/*!*******************************************!*\
|
|
|
!*** ./src/demux/transmuxer-interface.ts ***!
|
|
|
\*******************************************/ /***/function srcDemuxTransmuxerInterfaceTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_483091__){"use strict";__nested_webpack_require_483091__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_483091__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */TransmuxerInterface);}/* harmony export */});/* harmony import */var _webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_483091__(/*! ./webworkify-webpack */"./src/demux/webworkify-webpack.js");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_483091__(/*! ../events */"./src/events.ts");/* harmony import */var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_483091__(/*! ../demux/transmuxer */"./src/demux/transmuxer.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_483091__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_483091__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_483091__(/*! ../utils/mediasource-helper */"./src/utils/mediasource-helper.ts");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_483091__(/*! eventemitter3 */"./node_modules/eventemitter3/index.js");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_6___default=/*#__PURE__*/__nested_webpack_require_483091__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_6__);var MediaSource=(0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__.getMediaSource)()||{isTypeSupported:function isTypeSupported(){return false;}};var TransmuxerInterface=/*#__PURE__*/function(){function TransmuxerInterface(hls,id,onTransmuxComplete,onFlush){var _this=this;this.hls=void 0;this.id=void 0;this.observer=void 0;this.frag=null;this.part=null;this.useWorker=void 0;this.worker=void 0;this.onwmsg=void 0;this.transmuxer=null;this.onTransmuxComplete=void 0;this.onFlush=void 0;var config=hls.config;this.hls=hls;this.id=id;this.useWorker=!!config.enableWorker;this.onTransmuxComplete=onTransmuxComplete;this.onFlush=onFlush;var forwardMessage=function forwardMessage(ev,data){data=data||{};data.frag=_this.frag;data.id=_this.id;_this.hls.trigger(ev,data);};// forward events to main thread
|
|
|
this.observer=new eventemitter3__WEBPACK_IMPORTED_MODULE_6__.EventEmitter();this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED,forwardMessage);this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,forwardMessage);var typeSupported={mp4:MediaSource.isTypeSupported('video/mp4'),mpeg:MediaSource.isTypeSupported('audio/mpeg'),mp3:MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')};// navigator.vendor is not always available in Web Worker
|
|
|
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
|
|
var vendor=navigator.vendor;if(this.useWorker&&typeof Worker!=='undefined'){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log('demuxing in webworker');var worker;try{worker=this.worker=(0,_webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__["default"])(/*require.resolve*/ /*! ../demux/transmuxer-worker.ts */"./src/demux/transmuxer-worker.ts");this.onwmsg=this.onWorkerMessage.bind(this);worker.addEventListener('message',this.onwmsg);worker.onerror=function(event){_this.useWorker=false;_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Exception in webworker, fallback to inline');_this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.OTHER_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.INTERNAL_EXCEPTION,fatal:false,event:'demuxerWorker',error:new Error(event.message+" ("+event.filename+":"+event.lineno+")")});};worker.postMessage({cmd:'init',typeSupported:typeSupported,vendor:vendor,id:id,config:JSON.stringify(config)});}catch(err){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Error in worker:',err);_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error('Error while initializing DemuxerWorker, fallback to inline');if(worker){// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
|
|
self.URL.revokeObjectURL(worker.objectURL);}this.transmuxer=new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer,typeSupported,config,vendor,id);this.worker=null;}}else{this.transmuxer=new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer,typeSupported,config,vendor,id);}}var _proto=TransmuxerInterface.prototype;_proto.destroy=function destroy(){var w=this.worker;if(w){w.removeEventListener('message',this.onwmsg);w.terminate();this.worker=null;this.onwmsg=undefined;}else{var transmuxer=this.transmuxer;if(transmuxer){transmuxer.destroy();this.transmuxer=null;}}var observer=this.observer;if(observer){observer.removeAllListeners();}this.frag=null;// @ts-ignore
|
|
|
this.observer=null;// @ts-ignore
|
|
|
this.hls=null;};_proto.push=function push(data,initSegmentData,audioCodec,videoCodec,frag,part,duration,accurateTimeOffset,chunkMeta,defaultInitPTS){var _frag$initSegment,_lastFrag$initSegment,_this2=this;chunkMeta.transmuxing.start=self.performance.now();var transmuxer=this.transmuxer,worker=this.worker;var timeOffset=part?part.start:frag.start;// TODO: push "clear-lead" decrypt data for unencrypted fragments in streams with encrypted ones
|
|
|
var decryptdata=frag.decryptdata;var lastFrag=this.frag;var discontinuity=!(lastFrag&&frag.cc===lastFrag.cc);var trackSwitch=!(lastFrag&&chunkMeta.level===lastFrag.level);var snDiff=lastFrag?chunkMeta.sn-lastFrag.sn:-1;var partDiff=this.part?chunkMeta.part-this.part.index:-1;var progressive=snDiff===0&&chunkMeta.id>1&&chunkMeta.id===(lastFrag===null||lastFrag===void 0?void 0:lastFrag.stats.chunkCount);var contiguous=!trackSwitch&&(snDiff===1||snDiff===0&&(partDiff===1||progressive&&partDiff<=0));var now=self.performance.now();if(trackSwitch||snDiff||frag.stats.parsing.start===0){frag.stats.parsing.start=now;}if(part&&(partDiff||!contiguous)){part.stats.parsing.start=now;}var initSegmentChange=!(lastFrag&&((_frag$initSegment=frag.initSegment)===null||_frag$initSegment===void 0?void 0:_frag$initSegment.url)===((_lastFrag$initSegment=lastFrag.initSegment)===null||_lastFrag$initSegment===void 0?void 0:_lastFrag$initSegment.url));var state=new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.TransmuxState(discontinuity,contiguous,accurateTimeOffset,trackSwitch,timeOffset,initSegmentChange);if(!contiguous||discontinuity||initSegmentChange){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[transmuxer-interface, "+frag.type+"]: Starting new transmux session for sn: "+chunkMeta.sn+" p: "+chunkMeta.part+" level: "+chunkMeta.level+" id: "+chunkMeta.id+"\n discontinuity: "+discontinuity+"\n trackSwitch: "+trackSwitch+"\n contiguous: "+contiguous+"\n accurateTimeOffset: "+accurateTimeOffset+"\n timeOffset: "+timeOffset+"\n initSegmentChange: "+initSegmentChange);var config=new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.TransmuxConfig(audioCodec,videoCodec,initSegmentData,duration,defaultInitPTS);this.configureTransmuxer(config);}this.frag=frag;this.part=part;// Frags with sn of 'initSegment' are not transmuxed
|
|
|
if(worker){// post fragment payload as transferable objects for ArrayBuffer (no copy)
|
|
|
worker.postMessage({cmd:'demux',data:data,decryptdata:decryptdata,chunkMeta:chunkMeta,state:state},data instanceof ArrayBuffer?[data]:[]);}else if(transmuxer){var _transmuxResult=transmuxer.push(data,decryptdata,chunkMeta,state);if((0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult)){transmuxer.async=true;_transmuxResult.then(function(data){_this2.handleTransmuxComplete(data);})["catch"](function(error){_this2.transmuxerError(error,chunkMeta,'transmuxer-interface push error');});}else{transmuxer.async=false;this.handleTransmuxComplete(_transmuxResult);}}};_proto.flush=function flush(chunkMeta){var _this3=this;chunkMeta.transmuxing.start=self.performance.now();var transmuxer=this.transmuxer,worker=this.worker;if(worker){1;worker.postMessage({cmd:'flush',chunkMeta:chunkMeta});}else if(transmuxer){var _transmuxResult2=transmuxer.flush(chunkMeta);var asyncFlush=(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult2);if(asyncFlush||transmuxer.async){if(!(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult2)){_transmuxResult2=Promise.resolve(_transmuxResult2);}_transmuxResult2.then(function(data){_this3.handleFlushResult(data,chunkMeta);})["catch"](function(error){_this3.transmuxerError(error,chunkMeta,'transmuxer-interface flush error');});}else{this.handleFlushResult(_transmuxResult2,chunkMeta);}}};_proto.transmuxerError=function transmuxerError(error,chunkMeta,reason){if(!this.hls){return;}this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,chunkMeta:chunkMeta,fatal:false,error:error,err:error,reason:reason});};_proto.handleFlushResult=function handleFlushResult(results,chunkMeta){var _this4=this;results.forEach(function(result){_this4.handleTransmuxComplete(result);});this.onFlush(chunkMeta);};_proto.onWorkerMessage=function onWorkerMessage(ev){var data=ev.data;var hls=this.hls;switch(data.event){case'init':{// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
|
|
self.URL.revokeObjectURL(this.worker.objectURL);break;}case'transmuxComplete':{this.handleTransmuxComplete(data.data);break;}case'flush':{this.onFlush(data.data);break;}// pass logs from the worker thread to the main logger
|
|
|
case'workerLog':if(_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger[data.data.logType]){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger[data.data.logType](data.data.message);}break;default:{data.data=data.data||{};data.data.frag=this.frag;data.data.id=this.id;hls.trigger(data.event,data.data);break;}}};_proto.configureTransmuxer=function configureTransmuxer(config){var worker=this.worker,transmuxer=this.transmuxer;if(worker){worker.postMessage({cmd:'configure',config:config});}else if(transmuxer){transmuxer.configure(config);}};_proto.handleTransmuxComplete=function handleTransmuxComplete(result){result.chunkMeta.transmuxing.end=self.performance.now();this.onTransmuxComplete(result);};return TransmuxerInterface;}();/***/},/***/"./src/demux/transmuxer-worker.ts":/*!****************************************!*\
|
|
|
!*** ./src/demux/transmuxer-worker.ts ***!
|
|
|
\****************************************/ /***/function srcDemuxTransmuxerWorkerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_493728__){"use strict";__nested_webpack_require_493728__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_493728__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */TransmuxerWorker);}/* harmony export */});/* harmony import */var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_493728__(/*! ../demux/transmuxer */"./src/demux/transmuxer.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_493728__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_493728__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_493728__(/*! eventemitter3 */"./node_modules/eventemitter3/index.js");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_3___default=/*#__PURE__*/__nested_webpack_require_493728__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_3__);/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_493728__(/*! ../errors */"./src/errors.ts");function TransmuxerWorker(self){var observer=new eventemitter3__WEBPACK_IMPORTED_MODULE_3__.EventEmitter();var forwardMessage=function forwardMessage(ev,data){self.postMessage({event:ev,data:data});};// forward events to main thread
|
|
|
observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED,forwardMessage);observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,forwardMessage);// forward logger events to main thread
|
|
|
var forwardWorkerLogs=function forwardWorkerLogs(){var _loop=function _loop(logFn){var func=function func(message){forwardMessage('workerLog',{logType:logFn,message:message});};_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger[logFn]=func;};for(var logFn in _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger){_loop(logFn);}};self.addEventListener('message',function(ev){var data=ev.data;switch(data.cmd){case'init':{var config=JSON.parse(data.config);self.transmuxer=new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["default"](observer,data.typeSupported,config,data.vendor,data.id);(0,_utils_logger__WEBPACK_IMPORTED_MODULE_2__.enableLogs)(config.debug,data.id);forwardWorkerLogs();forwardMessage('init',null);break;}case'configure':{self.transmuxer.configure(data.config);break;}case'demux':{var transmuxResult=self.transmuxer.push(data.data,data.decryptdata,data.chunkMeta,data.state);if((0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(transmuxResult)){self.transmuxer.async=true;transmuxResult.then(function(data){emitTransmuxComplete(self,data);})["catch"](function(error){forwardMessage(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,chunkMeta:data.chunkMeta,fatal:false,error:error,err:error,reason:"transmuxer-worker push error"});});}else{self.transmuxer.async=false;emitTransmuxComplete(self,transmuxResult);}break;}case'flush':{var id=data.chunkMeta;var _transmuxResult=self.transmuxer.flush(id);var asyncFlush=(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(_transmuxResult);if(asyncFlush||self.transmuxer.async){if(!(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(_transmuxResult)){_transmuxResult=Promise.resolve(_transmuxResult);}_transmuxResult.then(function(results){handleFlushResult(self,results,id);})["catch"](function(error){forwardMessage(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,chunkMeta:data.chunkMeta,fatal:false,error:error,err:error,reason:"transmuxer-worker flush error"});});}else{handleFlushResult(self,_transmuxResult,id);}break;}default:break;}});}function emitTransmuxComplete(self,transmuxResult){if(isEmptyResult(transmuxResult.remuxResult)){return false;}var transferable=[];var _transmuxResult$remux=transmuxResult.remuxResult,audio=_transmuxResult$remux.audio,video=_transmuxResult$remux.video;if(audio){addToTransferable(transferable,audio);}if(video){addToTransferable(transferable,video);}self.postMessage({event:'transmuxComplete',data:transmuxResult},transferable);return true;}// Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast)
|
|
|
// in order to minimize message passing overhead
|
|
|
function addToTransferable(transferable,track){if(track.data1){transferable.push(track.data1.buffer);}if(track.data2){transferable.push(track.data2.buffer);}}function handleFlushResult(self,results,chunkMeta){var parsed=results.reduce(function(parsed,result){return emitTransmuxComplete(self,result)||parsed;},false);if(!parsed){// Emit at least one "transmuxComplete" message even if media is not found to update stream-controller state to PARSING
|
|
|
self.postMessage({event:'transmuxComplete',data:results[0]});}self.postMessage({event:'flush',data:chunkMeta});}function isEmptyResult(remuxResult){return!remuxResult.audio&&!remuxResult.video&&!remuxResult.text&&!remuxResult.id3&&!remuxResult.initSegment;}/***/},/***/"./src/demux/transmuxer.ts":/*!*********************************!*\
|
|
|
!*** ./src/demux/transmuxer.ts ***!
|
|
|
\*********************************/ /***/function srcDemuxTransmuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_499113__){"use strict";__nested_webpack_require_499113__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_499113__.d(__webpack_exports__,{/* harmony export */"TransmuxConfig":function TransmuxConfig(){return(/* binding */_TransmuxConfig);},/* harmony export */"TransmuxState":function TransmuxState(){return(/* binding */_TransmuxState);},/* harmony export */"default":function _default(){return(/* binding */Transmuxer);},/* harmony export */"isPromise":function isPromise(){return(/* binding */_isPromise);}/* harmony export */});/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_499113__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_499113__(/*! ../errors */"./src/errors.ts");/* harmony import */var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_499113__(/*! ../crypt/decrypter */"./src/crypt/decrypter.ts");/* harmony import */var _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_499113__(/*! ../demux/aacdemuxer */"./src/demux/aacdemuxer.ts");/* harmony import */var _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_499113__(/*! ../demux/mp4demuxer */"./src/demux/mp4demuxer.ts");/* harmony import */var _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_499113__(/*! ../demux/tsdemuxer */"./src/demux/tsdemuxer.ts");/* harmony import */var _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_499113__(/*! ../demux/mp3demuxer */"./src/demux/mp3demuxer.ts");/* harmony import */var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_499113__(/*! ../remux/mp4-remuxer */"./src/remux/mp4-remuxer.ts");/* harmony import */var _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_499113__(/*! ../remux/passthrough-remuxer */"./src/remux/passthrough-remuxer.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_499113__(/*! ../utils/logger */"./src/utils/logger.ts");var now;// performance.now() not available on WebWorker, at least on Safari Desktop
|
|
|
try{now=self.performance.now.bind(self.performance);}catch(err){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.debug('Unable to use Performance API on this environment');now=self.Date.now;}var muxConfig=[{demux:_demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"],remux:_remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"]},{demux:_demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__["default"],remux:_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]},{demux:_demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__["default"],remux:_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]},{demux:_demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__["default"],remux:_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]}];var Transmuxer=/*#__PURE__*/function(){function Transmuxer(observer,typeSupported,config,vendor,id){this.async=false;this.observer=void 0;this.typeSupported=void 0;this.config=void 0;this.vendor=void 0;this.id=void 0;this.demuxer=void 0;this.remuxer=void 0;this.decrypter=void 0;this.probe=void 0;this.decryptionPromise=null;this.transmuxConfig=void 0;this.currentTransmuxState=void 0;this.observer=observer;this.typeSupported=typeSupported;this.config=config;this.vendor=vendor;this.id=id;}var _proto=Transmuxer.prototype;_proto.configure=function configure(transmuxConfig){this.transmuxConfig=transmuxConfig;if(this.decrypter){this.decrypter.reset();}};_proto.push=function push(data,decryptdata,chunkMeta,state){var _this=this;var stats=chunkMeta.transmuxing;stats.executeStart=now();var uintData=new Uint8Array(data);var currentTransmuxState=this.currentTransmuxState,transmuxConfig=this.transmuxConfig;if(state){this.currentTransmuxState=state;}var _ref=state||currentTransmuxState,contiguous=_ref.contiguous,discontinuity=_ref.discontinuity,trackSwitch=_ref.trackSwitch,accurateTimeOffset=_ref.accurateTimeOffset,timeOffset=_ref.timeOffset,initSegmentChange=_ref.initSegmentChange;var audioCodec=transmuxConfig.audioCodec,videoCodec=transmuxConfig.videoCodec,defaultInitPts=transmuxConfig.defaultInitPts,duration=transmuxConfig.duration,initSegmentData=transmuxConfig.initSegmentData;var keyData=getEncryptionType(uintData,decryptdata);if(keyData&&keyData.method==='AES-128'){var decrypter=this.getDecrypter();// Software decryption is synchronous; webCrypto is not
|
|
|
if(decrypter.isSync()){// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
|
|
// data is handled in the flush() call
|
|
|
var decryptedData=decrypter.softwareDecrypt(uintData,keyData.key.buffer,keyData.iv.buffer);// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
|
|
|
var loadingParts=chunkMeta.part>-1;if(loadingParts){decryptedData=decrypter.flush();}if(!decryptedData){stats.executeEnd=now();return emptyResult(chunkMeta);}uintData=new Uint8Array(decryptedData);}else{this.decryptionPromise=decrypter.webCryptoDecrypt(uintData,keyData.key.buffer,keyData.iv.buffer).then(function(decryptedData){// Calling push here is important; if flush() is called while this is still resolving, this ensures that
|
|
|
// the decrypted data has been transmuxed
|
|
|
var result=_this.push(decryptedData,null,chunkMeta);_this.decryptionPromise=null;return result;});return this.decryptionPromise;}}var resetMuxers=this.needsProbing(discontinuity,trackSwitch);if(resetMuxers){this.configureTransmuxer(uintData);}if(discontinuity||trackSwitch||initSegmentChange||resetMuxers){this.resetInitSegment(initSegmentData,audioCodec,videoCodec,duration,decryptdata);}if(discontinuity||initSegmentChange||resetMuxers){this.resetInitialTimestamp(defaultInitPts);}if(!contiguous){this.resetContiguity();}var result=this.transmux(uintData,keyData,timeOffset,accurateTimeOffset,chunkMeta);var currentState=this.currentTransmuxState;currentState.contiguous=true;currentState.discontinuity=false;currentState.trackSwitch=false;stats.executeEnd=now();return result;}// Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type)
|
|
|
;_proto.flush=function flush(chunkMeta){var _this2=this;var stats=chunkMeta.transmuxing;stats.executeStart=now();var decrypter=this.decrypter,currentTransmuxState=this.currentTransmuxState,decryptionPromise=this.decryptionPromise;if(decryptionPromise){// Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
|
|
|
// only flushing is required for async decryption
|
|
|
return decryptionPromise.then(function(){return _this2.flush(chunkMeta);});}var transmuxResults=[];var timeOffset=currentTransmuxState.timeOffset;if(decrypter){// The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults
|
|
|
// This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads,
|
|
|
// or for progressive downloads with small segments)
|
|
|
var decryptedData=decrypter.flush();if(decryptedData){// Push always returns a TransmuxerResult if decryptdata is null
|
|
|
transmuxResults.push(this.push(decryptedData,null,chunkMeta));}}var demuxer=this.demuxer,remuxer=this.remuxer;if(!demuxer||!remuxer){// If probing failed, then Hls.js has been given content its not able to handle
|
|
|
this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_PARSING_ERROR,fatal:true,reason:'no demux matching with content found'});stats.executeEnd=now();return[emptyResult(chunkMeta)];}var demuxResultOrPromise=demuxer.flush(timeOffset);if(_isPromise(demuxResultOrPromise)){// Decrypt final SAMPLE-AES samples
|
|
|
return demuxResultOrPromise.then(function(demuxResult){_this2.flushRemux(transmuxResults,demuxResult,chunkMeta);return transmuxResults;});}this.flushRemux(transmuxResults,demuxResultOrPromise,chunkMeta);return transmuxResults;};_proto.flushRemux=function flushRemux(transmuxResults,demuxResult,chunkMeta){var audioTrack=demuxResult.audioTrack,videoTrack=demuxResult.videoTrack,id3Track=demuxResult.id3Track,textTrack=demuxResult.textTrack;var _this$currentTransmux=this.currentTransmuxState,accurateTimeOffset=_this$currentTransmux.accurateTimeOffset,timeOffset=_this$currentTransmux.timeOffset;_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("[transmuxer.ts]: Flushed fragment "+chunkMeta.sn+(chunkMeta.part>-1?' p: '+chunkMeta.part:'')+" of level "+chunkMeta.level);var remuxResult=this.remuxer.remux(audioTrack,videoTrack,id3Track,textTrack,timeOffset,accurateTimeOffset,true,this.id);transmuxResults.push({remuxResult:remuxResult,chunkMeta:chunkMeta});chunkMeta.transmuxing.executeEnd=now();};_proto.resetInitialTimestamp=function resetInitialTimestamp(defaultInitPts){var demuxer=this.demuxer,remuxer=this.remuxer;if(!demuxer||!remuxer){return;}demuxer.resetTimeStamp(defaultInitPts);remuxer.resetTimeStamp(defaultInitPts);};_proto.resetContiguity=function resetContiguity(){var demuxer=this.demuxer,remuxer=this.remuxer;if(!demuxer||!remuxer){return;}demuxer.resetContiguity();remuxer.resetNextTimestamp();};_proto.resetInitSegment=function resetInitSegment(initSegmentData,audioCodec,videoCodec,trackDuration,decryptdata){var demuxer=this.demuxer,remuxer=this.remuxer;if(!demuxer||!remuxer){return;}demuxer.resetInitSegment(initSegmentData,audioCodec,videoCodec,trackDuration);remuxer.resetInitSegment(initSegmentData,audioCodec,videoCodec,decryptdata);};_proto.destroy=function destroy(){if(this.demuxer){this.demuxer.destroy();this.demuxer=undefined;}if(this.remuxer){this.remuxer.destroy();this.remuxer=undefined;}};_proto.transmux=function transmux(data,keyData,timeOffset,accurateTimeOffset,chunkMeta){var result;if(keyData&&keyData.method==='SAMPLE-AES'){result=this.transmuxSampleAes(data,keyData,timeOffset,accurateTimeOffset,chunkMeta);}else{result=this.transmuxUnencrypted(data,timeOffset,accurateTimeOffset,chunkMeta);}return result;};_proto.transmuxUnencrypted=function transmuxUnencrypted(data,timeOffset,accurateTimeOffset,chunkMeta){var _demux=this.demuxer.demux(data,timeOffset,false,!this.config.progressive),audioTrack=_demux.audioTrack,videoTrack=_demux.videoTrack,id3Track=_demux.id3Track,textTrack=_demux.textTrack;var remuxResult=this.remuxer.remux(audioTrack,videoTrack,id3Track,textTrack,timeOffset,accurateTimeOffset,false,this.id);return{remuxResult:remuxResult,chunkMeta:chunkMeta};};_proto.transmuxSampleAes=function transmuxSampleAes(data,decryptData,timeOffset,accurateTimeOffset,chunkMeta){var _this3=this;return this.demuxer.demuxSampleAes(data,decryptData,timeOffset).then(function(demuxResult){var remuxResult=_this3.remuxer.remux(demuxResult.audioTrack,demuxResult.videoTrack,demuxResult.id3Track,demuxResult.textTrack,timeOffset,accurateTimeOffset,false,_this3.id);return{remuxResult:remuxResult,chunkMeta:chunkMeta};});};_proto.configureTransmuxer=function configureTransmuxer(data){var config=this.config,observer=this.observer,typeSupported=this.typeSupported,vendor=this.vendor;// probe for content type
|
|
|
var mux;for(var i=0,len=muxConfig.length;i<len;i++){if(muxConfig[i].demux.probe(data)){mux=muxConfig[i];break;}}if(!mux){// If probing previous configs fail, use mp4 passthrough
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.warn('Failed to find demuxer by probing frag, treating as mp4 passthrough');mux={demux:_demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"],remux:_remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"]};}// so let's check that current remuxer and demuxer are still valid
|
|
|
var demuxer=this.demuxer;var remuxer=this.remuxer;var Remuxer=mux.remux;var Demuxer=mux.demux;if(!remuxer||!(remuxer instanceof Remuxer)){this.remuxer=new Remuxer(observer,config,typeSupported,vendor);}if(!demuxer||!(demuxer instanceof Demuxer)){this.demuxer=new Demuxer(observer,config,typeSupported);this.probe=Demuxer.probe;}};_proto.needsProbing=function needsProbing(discontinuity,trackSwitch){// in case of continuity change, or track switch
|
|
|
// we might switch from content type (AAC container to TS container, or TS to fmp4 for example)
|
|
|
return!this.demuxer||!this.remuxer||discontinuity||trackSwitch;};_proto.getDecrypter=function getDecrypter(){var decrypter=this.decrypter;if(!decrypter){decrypter=this.decrypter=new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__["default"](this.config);}return decrypter;};return Transmuxer;}();function getEncryptionType(data,decryptData){var encryptionType=null;if(data.byteLength>0&&decryptData!=null&&decryptData.key!=null&&decryptData.iv!==null&&decryptData.method!=null){encryptionType=decryptData;}return encryptionType;}var emptyResult=function emptyResult(chunkMeta){return{remuxResult:{},chunkMeta:chunkMeta};};function _isPromise(p){return'then'in p&&p.then instanceof Function;}var _TransmuxConfig=function TransmuxConfig(audioCodec,videoCodec,initSegmentData,duration,defaultInitPts){this.audioCodec=void 0;this.videoCodec=void 0;this.initSegmentData=void 0;this.duration=void 0;this.defaultInitPts=void 0;this.audioCodec=audioCodec;this.videoCodec=videoCodec;this.initSegmentData=initSegmentData;this.duration=duration;this.defaultInitPts=defaultInitPts;};var _TransmuxState=function TransmuxState(discontinuity,contiguous,accurateTimeOffset,trackSwitch,timeOffset,initSegmentChange){this.discontinuity=void 0;this.contiguous=void 0;this.accurateTimeOffset=void 0;this.trackSwitch=void 0;this.timeOffset=void 0;this.initSegmentChange=void 0;this.discontinuity=discontinuity;this.contiguous=contiguous;this.accurateTimeOffset=accurateTimeOffset;this.trackSwitch=trackSwitch;this.timeOffset=timeOffset;this.initSegmentChange=initSegmentChange;};/***/},/***/"./src/demux/tsdemuxer.ts":/*!********************************!*\
|
|
|
!*** ./src/demux/tsdemuxer.ts ***!
|
|
|
\********************************/ /***/function srcDemuxTsdemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_513058__){"use strict";__nested_webpack_require_513058__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_513058__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _adts__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_513058__(/*! ./adts */"./src/demux/adts.ts");/* harmony import */var _mpegaudio__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_513058__(/*! ./mpegaudio */"./src/demux/mpegaudio.ts");/* harmony import */var _exp_golomb__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_513058__(/*! ./exp-golomb */"./src/demux/exp-golomb.ts");/* harmony import */var _sample_aes__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_513058__(/*! ./sample-aes */"./src/demux/sample-aes.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_513058__(/*! ../events */"./src/events.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_513058__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_513058__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_513058__(/*! ../errors */"./src/errors.ts");/* harmony import */var _types_demuxer__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_513058__(/*! ../types/demuxer */"./src/types/demuxer.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}/**
|
|
|
* highly optimized TS demuxer:
|
|
|
* parse PAT, PMT
|
|
|
* extract PES packet from audio and video PIDs
|
|
|
* extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
|
|
|
* trigger the remuxer upon parsing completion
|
|
|
* it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
|
|
|
* it also controls the remuxing process :
|
|
|
* upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.
|
|
|
*/var PACKET_LENGTH=188;var TSDemuxer=/*#__PURE__*/function(){function TSDemuxer(observer,config,typeSupported){this.observer=void 0;this.config=void 0;this.typeSupported=void 0;this.sampleAes=null;this.pmtParsed=false;this.audioCodec=void 0;this.videoCodec=void 0;this._duration=0;this._pmtId=-1;this._avcTrack=void 0;this._audioTrack=void 0;this._id3Track=void 0;this._txtTrack=void 0;this.aacOverFlow=null;this.avcSample=null;this.remainderData=null;this.observer=observer;this.config=config;this.typeSupported=typeSupported;}TSDemuxer.probe=function probe(data){var syncOffset=TSDemuxer.syncOffset(data);if(syncOffset>0){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("MPEG2-TS detected but first sync word found @ offset "+syncOffset);}return syncOffset!==-1;};TSDemuxer.syncOffset=function syncOffset(data){var length=data.length;var scanwindow=Math.min(PACKET_LENGTH*5,data.length-PACKET_LENGTH)+1;var i=0;while(i<scanwindow){// a TS init segment should contain at least 2 TS packets: PAT and PMT, each starting with 0x47
|
|
|
var foundPat=false;for(var j=i;j<length;j+=PACKET_LENGTH){if(data[j]===0x47){if(!foundPat&&parsePID(data,j)===0){foundPat=true;}if(foundPat&&j+PACKET_LENGTH>scanwindow){return i;}}else{break;}}i++;}return-1;}/**
|
|
|
* Creates a track model internal to demuxer used to drive remuxing input
|
|
|
*
|
|
|
* @param type 'audio' | 'video' | 'id3' | 'text'
|
|
|
* @param duration
|
|
|
* @return TSDemuxer's internal track model
|
|
|
*/;TSDemuxer.createTrack=function createTrack(type,duration){return{container:type==='video'||type==='audio'?'video/mp2t':undefined,type:type,id:_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.RemuxerTrackIdConfig[type],pid:-1,inputTimeScale:90000,sequenceNumber:0,samples:[],dropped:0,duration:type==='audio'?duration:undefined};}/**
|
|
|
* Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start)
|
|
|
* Resets all internal track instances of the demuxer.
|
|
|
*/;var _proto=TSDemuxer.prototype;_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,trackDuration){this.pmtParsed=false;this._pmtId=-1;this._avcTrack=TSDemuxer.createTrack('video');this._audioTrack=TSDemuxer.createTrack('audio',trackDuration);this._id3Track=TSDemuxer.createTrack('id3');this._txtTrack=TSDemuxer.createTrack('text');this._audioTrack.segmentCodec='aac';// flush any partial content
|
|
|
this.aacOverFlow=null;this.avcSample=null;this.remainderData=null;this.audioCodec=audioCodec;this.videoCodec=videoCodec;this._duration=trackDuration;};_proto.resetTimeStamp=function resetTimeStamp(){};_proto.resetContiguity=function resetContiguity(){var _audioTrack=this._audioTrack,_avcTrack=this._avcTrack,_id3Track=this._id3Track;if(_audioTrack){_audioTrack.pesData=null;}if(_avcTrack){_avcTrack.pesData=null;}if(_id3Track){_id3Track.pesData=null;}this.aacOverFlow=null;this.avcSample=null;this.remainderData=null;};_proto.demux=function demux(data,timeOffset,isSampleAes,flush){if(isSampleAes===void 0){isSampleAes=false;}if(flush===void 0){flush=false;}if(!isSampleAes){this.sampleAes=null;}var pes;var videoTrack=this._avcTrack;var audioTrack=this._audioTrack;var id3Track=this._id3Track;var textTrack=this._txtTrack;var avcId=videoTrack.pid;var avcData=videoTrack.pesData;var audioId=audioTrack.pid;var id3Id=id3Track.pid;var audioData=audioTrack.pesData;var id3Data=id3Track.pesData;var unknownPID=null;var pmtParsed=this.pmtParsed;var pmtId=this._pmtId;var len=data.length;if(this.remainderData){data=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.appendUint8Array)(this.remainderData,data);len=data.length;this.remainderData=null;}if(len<PACKET_LENGTH&&!flush){this.remainderData=data;return{audioTrack:audioTrack,videoTrack:videoTrack,id3Track:id3Track,textTrack:textTrack};}var syncOffset=Math.max(0,TSDemuxer.syncOffset(data));len-=(len-syncOffset)%PACKET_LENGTH;if(len<data.byteLength&&!flush){this.remainderData=new Uint8Array(data.buffer,len,data.buffer.byteLength-len);}// loop through TS packets
|
|
|
var tsPacketErrors=0;for(var start=syncOffset;start<len;start+=PACKET_LENGTH){if(data[start]===0x47){var stt=!!(data[start+1]&0x40);var pid=parsePID(data,start);var atf=(data[start+3]&0x30)>>4;// if an adaption field is present, its length is specified by the fifth byte of the TS packet header.
|
|
|
var offset=void 0;if(atf>1){offset=start+5+data[start+4];// continue if there is only adaptation field
|
|
|
if(offset===start+PACKET_LENGTH){continue;}}else{offset=start+4;}switch(pid){case avcId:if(stt){if(avcData&&(pes=parsePES(avcData))){this.parseAVCPES(videoTrack,textTrack,pes,false);}avcData={data:[],size:0};}if(avcData){avcData.data.push(data.subarray(offset,start+PACKET_LENGTH));avcData.size+=start+PACKET_LENGTH-offset;}break;case audioId:if(stt){if(audioData&&(pes=parsePES(audioData))){switch(audioTrack.segmentCodec){case'aac':this.parseAACPES(audioTrack,pes);break;case'mp3':this.parseMPEGPES(audioTrack,pes);break;}}audioData={data:[],size:0};}if(audioData){audioData.data.push(data.subarray(offset,start+PACKET_LENGTH));audioData.size+=start+PACKET_LENGTH-offset;}break;case id3Id:if(stt){if(id3Data&&(pes=parsePES(id3Data))){this.parseID3PES(id3Track,pes);}id3Data={data:[],size:0};}if(id3Data){id3Data.data.push(data.subarray(offset,start+PACKET_LENGTH));id3Data.size+=start+PACKET_LENGTH-offset;}break;case 0:if(stt){offset+=data[offset]+1;}pmtId=this._pmtId=parsePAT(data,offset);// logger.log('PMT PID:' + this._pmtId);
|
|
|
break;case pmtId:{if(stt){offset+=data[offset]+1;}var parsedPIDs=parsePMT(data,offset,this.typeSupported,isSampleAes);// only update track id if track PID found while parsing PMT
|
|
|
// this is to avoid resetting the PID to -1 in case
|
|
|
// track PID transiently disappears from the stream
|
|
|
// this could happen in case of transient missing audio samples for example
|
|
|
// NOTE this is only the PID of the track as found in TS,
|
|
|
// but we are not using this for MP4 track IDs.
|
|
|
avcId=parsedPIDs.avc;if(avcId>0){videoTrack.pid=avcId;}audioId=parsedPIDs.audio;if(audioId>0){audioTrack.pid=audioId;audioTrack.segmentCodec=parsedPIDs.segmentCodec;}id3Id=parsedPIDs.id3;if(id3Id>0){id3Track.pid=id3Id;}if(unknownPID!==null&&!pmtParsed){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("MPEG-TS PMT found at "+start+" after unknown PID '"+unknownPID+"'. Backtracking to sync byte @"+syncOffset+" to parse all TS packets.");unknownPID=null;// we set it to -188, the += 188 in the for loop will reset start to 0
|
|
|
start=syncOffset-188;}pmtParsed=this.pmtParsed=true;break;}case 0x11:case 0x1fff:break;default:unknownPID=pid;break;}}else{tsPacketErrors++;}}if(tsPacketErrors>0){this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR,_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_7__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_7__.ErrorDetails.FRAG_PARSING_ERROR,fatal:false,reason:"Found "+tsPacketErrors+" TS packet/s that do not start with 0x47"});}videoTrack.pesData=avcData;audioTrack.pesData=audioData;id3Track.pesData=id3Data;var demuxResult={audioTrack:audioTrack,videoTrack:videoTrack,id3Track:id3Track,textTrack:textTrack};if(flush){this.extractRemainingSamples(demuxResult);}return demuxResult;};_proto.flush=function flush(){var remainderData=this.remainderData;this.remainderData=null;var result;if(remainderData){result=this.demux(remainderData,-1,false,true);}else{result={videoTrack:this._avcTrack,audioTrack:this._audioTrack,id3Track:this._id3Track,textTrack:this._txtTrack};}this.extractRemainingSamples(result);if(this.sampleAes){return this.decrypt(result,this.sampleAes);}return result;};_proto.extractRemainingSamples=function extractRemainingSamples(demuxResult){var audioTrack=demuxResult.audioTrack,videoTrack=demuxResult.videoTrack,id3Track=demuxResult.id3Track,textTrack=demuxResult.textTrack;var avcData=videoTrack.pesData;var audioData=audioTrack.pesData;var id3Data=id3Track.pesData;// try to parse last PES packets
|
|
|
var pes;if(avcData&&(pes=parsePES(avcData))){this.parseAVCPES(videoTrack,textTrack,pes,true);videoTrack.pesData=null;}else{// either avcData null or PES truncated, keep it for next frag parsing
|
|
|
videoTrack.pesData=avcData;}if(audioData&&(pes=parsePES(audioData))){switch(audioTrack.segmentCodec){case'aac':this.parseAACPES(audioTrack,pes);break;case'mp3':this.parseMPEGPES(audioTrack,pes);break;}audioTrack.pesData=null;}else{if(audioData!==null&&audioData!==void 0&&audioData.size){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('last AAC PES packet truncated,might overlap between fragments');}// either audioData null or PES truncated, keep it for next frag parsing
|
|
|
audioTrack.pesData=audioData;}if(id3Data&&(pes=parsePES(id3Data))){this.parseID3PES(id3Track,pes);id3Track.pesData=null;}else{// either id3Data null or PES truncated, keep it for next frag parsing
|
|
|
id3Track.pesData=id3Data;}};_proto.demuxSampleAes=function demuxSampleAes(data,keyData,timeOffset){var demuxResult=this.demux(data,timeOffset,true,!this.config.progressive);var sampleAes=this.sampleAes=new _sample_aes__WEBPACK_IMPORTED_MODULE_3__["default"](this.observer,this.config,keyData);return this.decrypt(demuxResult,sampleAes);};_proto.decrypt=function decrypt(demuxResult,sampleAes){return new Promise(function(resolve){var audioTrack=demuxResult.audioTrack,videoTrack=demuxResult.videoTrack;if(audioTrack.samples&&audioTrack.segmentCodec==='aac'){sampleAes.decryptAacSamples(audioTrack.samples,0,function(){if(videoTrack.samples){sampleAes.decryptAvcSamples(videoTrack.samples,0,0,function(){resolve(demuxResult);});}else{resolve(demuxResult);}});}else if(videoTrack.samples){sampleAes.decryptAvcSamples(videoTrack.samples,0,0,function(){resolve(demuxResult);});}});};_proto.destroy=function destroy(){this._duration=0;};_proto.parseAVCPES=function parseAVCPES(track,textTrack,pes,last){var _this=this;var units=this.parseAVCNALu(track,pes.data);var debug=false;var avcSample=this.avcSample;var push;var spsfound=false;// free pes.data to save up some memory
|
|
|
pes.data=null;// if new NAL units found and last sample still there, let's push ...
|
|
|
// this helps parsing streams with missing AUD (only do this if AUD never found)
|
|
|
if(avcSample&&units.length&&!track.audFound){pushAccessUnit(avcSample,track);avcSample=this.avcSample=createAVCSample(false,pes.pts,pes.dts,'');}units.forEach(function(unit){switch(unit.type){// NDR
|
|
|
case 1:{push=true;if(!avcSample){avcSample=_this.avcSample=createAVCSample(true,pes.pts,pes.dts,'');}if(debug){avcSample.debug+='NDR ';}avcSample.frame=true;var data=unit.data;// only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
|
|
|
if(spsfound&&data.length>4){// retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
|
|
|
var sliceType=new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](data).readSliceType();// 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
|
|
|
// SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
|
|
|
// An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
|
|
|
// I slice: A slice that is not an SI slice that is decoded using intra prediction only.
|
|
|
// if (sliceType === 2 || sliceType === 7) {
|
|
|
if(sliceType===2||sliceType===4||sliceType===7||sliceType===9){avcSample.key=true;}}break;// IDR
|
|
|
}case 5:push=true;// handle PES not starting with AUD
|
|
|
if(!avcSample){avcSample=_this.avcSample=createAVCSample(true,pes.pts,pes.dts,'');}if(debug){avcSample.debug+='IDR ';}avcSample.key=true;avcSample.frame=true;break;// SEI
|
|
|
case 6:{push=true;if(debug&&avcSample){avcSample.debug+='SEI ';}(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.parseSEIMessageFromNALu)(unit.data,1,pes.pts,textTrack.samples);break;// SPS
|
|
|
}case 7:push=true;spsfound=true;if(debug&&avcSample){avcSample.debug+='SPS ';}if(!track.sps){var expGolombDecoder=new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](unit.data);var config=expGolombDecoder.readSPS();track.width=config.width;track.height=config.height;track.pixelRatio=config.pixelRatio;// TODO: `track.sps` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`.
|
|
|
track.sps=[unit.data];track.duration=_this._duration;var codecarray=unit.data.subarray(1,4);var codecstring='avc1.';for(var i=0;i<3;i++){var h=codecarray[i].toString(16);if(h.length<2){h='0'+h;}codecstring+=h;}track.codec=codecstring;}break;// PPS
|
|
|
case 8:push=true;if(debug&&avcSample){avcSample.debug+='PPS ';}if(!track.pps){// TODO: `track.pss` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`.
|
|
|
track.pps=[unit.data];}break;// AUD
|
|
|
case 9:push=false;track.audFound=true;if(avcSample){pushAccessUnit(avcSample,track);}avcSample=_this.avcSample=createAVCSample(false,pes.pts,pes.dts,debug?'AUD ':'');break;// Filler Data
|
|
|
case 12:push=true;break;default:push=false;if(avcSample){avcSample.debug+='unknown NAL '+unit.type+' ';}break;}if(avcSample&&push){var _units=avcSample.units;_units.push(unit);}});// if last PES packet, push samples
|
|
|
if(last&&avcSample){pushAccessUnit(avcSample,track);this.avcSample=null;}};_proto.getLastNalUnit=function getLastNalUnit(samples){var _avcSample;var avcSample=this.avcSample;var lastUnit;// try to fallback to previous sample if current one is empty
|
|
|
if(!avcSample||avcSample.units.length===0){avcSample=samples[samples.length-1];}if((_avcSample=avcSample)!==null&&_avcSample!==void 0&&_avcSample.units){var units=avcSample.units;lastUnit=units[units.length-1];}return lastUnit;};_proto.parseAVCNALu=function parseAVCNALu(track,array){var len=array.byteLength;var state=track.naluState||0;var lastState=state;var units=[];var i=0;var value;var overflow;var unitType;var lastUnitStart=-1;var lastUnitType=0;// logger.log('PES:' + Hex.hexDump(array));
|
|
|
if(state===-1){// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
|
|
lastUnitStart=0;// NALu type is value read from offset 0
|
|
|
lastUnitType=array[0]&0x1f;state=0;i=1;}while(i<len){value=array[i++];// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
|
|
if(!state){state=value?0:1;continue;}if(state===1){state=value?0:2;continue;}// here we have state either equal to 2 or 3
|
|
|
if(!value){state=3;}else if(value===1){if(lastUnitStart>=0){var unit={data:array.subarray(lastUnitStart,i-state-1),type:lastUnitType};// logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
|
|
units.push(unit);}else{// lastUnitStart is undefined => this is the first start code found in this PES packet
|
|
|
// first check if start code delimiter is overlapping between 2 PES packets,
|
|
|
// ie it started in last packet (lastState not zero)
|
|
|
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
|
|
var lastUnit=this.getLastNalUnit(track.samples);if(lastUnit){if(lastState&&i<=4-lastState){// start delimiter overlapping between PES packets
|
|
|
// strip start delimiter bytes from the end of last NAL unit
|
|
|
// check if lastUnit had a state different from zero
|
|
|
if(lastUnit.state){// strip last bytes
|
|
|
lastUnit.data=lastUnit.data.subarray(0,lastUnit.data.byteLength-lastState);}}// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
|
|
overflow=i-state-1;if(overflow>0){// logger.log('first NALU found with overflow:' + overflow);
|
|
|
var tmp=new Uint8Array(lastUnit.data.byteLength+overflow);tmp.set(lastUnit.data,0);tmp.set(array.subarray(0,overflow),lastUnit.data.byteLength);lastUnit.data=tmp;lastUnit.state=0;}}}// check if we can read unit type
|
|
|
if(i<len){unitType=array[i]&0x1f;// logger.log('find NALU @ offset:' + i + ',type:' + unitType);
|
|
|
lastUnitStart=i;lastUnitType=unitType;state=0;}else{// not enough byte to read unit type. let's read it on next PES parsing
|
|
|
state=-1;}}else{state=0;}}if(lastUnitStart>=0&&state>=0){var _unit={data:array.subarray(lastUnitStart,len),type:lastUnitType,state:state};units.push(_unit);// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
|
|
}// no NALu found
|
|
|
if(units.length===0){// append pes.data to previous NAL unit
|
|
|
var _lastUnit=this.getLastNalUnit(track.samples);if(_lastUnit){var _tmp=new Uint8Array(_lastUnit.data.byteLength+array.byteLength);_tmp.set(_lastUnit.data,0);_tmp.set(array,_lastUnit.data.byteLength);_lastUnit.data=_tmp;}}track.naluState=state;return units;};_proto.parseAACPES=function parseAACPES(track,pes){var startOffset=0;var aacOverFlow=this.aacOverFlow;var data=pes.data;if(aacOverFlow){this.aacOverFlow=null;var frameMissingBytes=aacOverFlow.missing;var sampleLength=aacOverFlow.sample.unit.byteLength;// logger.log(`AAC: append overflowing ${sampleLength} bytes to beginning of new PES`);
|
|
|
if(frameMissingBytes===-1){var tmp=new Uint8Array(sampleLength+data.byteLength);tmp.set(aacOverFlow.sample.unit,0);tmp.set(data,sampleLength);data=tmp;}else{var frameOverflowBytes=sampleLength-frameMissingBytes;aacOverFlow.sample.unit.set(data.subarray(0,frameMissingBytes),frameOverflowBytes);track.samples.push(aacOverFlow.sample);startOffset=aacOverFlow.missing;}}// look for ADTS header (0xFFFx)
|
|
|
var offset;var len;for(offset=startOffset,len=data.length;offset<len-1;offset++){if(_adts__WEBPACK_IMPORTED_MODULE_0__.isHeader(data,offset)){break;}}// if ADTS header does not start straight from the beginning of the PES payload, raise an error
|
|
|
if(offset!==startOffset){var reason;var fatal;if(offset<len-1){reason="AAC PES did not start with ADTS header,offset:"+offset;fatal=false;}else{reason='no ADTS header found in AAC PES';fatal=true;}_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("parsing error:"+reason);this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR,_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_7__.ErrorTypes.MEDIA_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_7__.ErrorDetails.FRAG_PARSING_ERROR,fatal:fatal,reason:reason});if(fatal){return;}}_adts__WEBPACK_IMPORTED_MODULE_0__.initTrackConfig(track,this.observer,data,offset,this.audioCodec);var pts;if(pes.pts!==undefined){pts=pes.pts;}else if(aacOverFlow){// if last AAC frame is overflowing, we should ensure timestamps are contiguous:
|
|
|
// first sample PTS should be equal to last sample PTS + frameDuration
|
|
|
var frameDuration=_adts__WEBPACK_IMPORTED_MODULE_0__.getFrameDuration(track.samplerate);pts=aacOverFlow.sample.pts+frameDuration;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: AAC PES unknown PTS');return;}// scan for aac samples
|
|
|
var frameIndex=0;var frame;while(offset<len){frame=_adts__WEBPACK_IMPORTED_MODULE_0__.appendFrame(track,data,offset,pts,frameIndex);offset+=frame.length;if(!frame.missing){frameIndex++;for(;offset<len-1;offset++){if(_adts__WEBPACK_IMPORTED_MODULE_0__.isHeader(data,offset)){break;}}}else{this.aacOverFlow=frame;break;}}};_proto.parseMPEGPES=function parseMPEGPES(track,pes){var data=pes.data;var length=data.length;var frameIndex=0;var offset=0;var pts=pes.pts;if(pts===undefined){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');return;}while(offset<length){if(_mpegaudio__WEBPACK_IMPORTED_MODULE_1__.isHeader(data,offset)){var frame=_mpegaudio__WEBPACK_IMPORTED_MODULE_1__.appendFrame(track,data,offset,pts,frameIndex);if(frame){offset+=frame.length;frameIndex++;}else{// logger.log('Unable to parse Mpeg audio frame');
|
|
|
break;}}else{// nothing found, keep looking
|
|
|
offset++;}}};_proto.parseID3PES=function parseID3PES(id3Track,pes){if(pes.pts===undefined){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');return;}var id3Sample=_extends({},pes,{type:this._avcTrack?_types_demuxer__WEBPACK_IMPORTED_MODULE_8__.MetadataSchema.emsg:_types_demuxer__WEBPACK_IMPORTED_MODULE_8__.MetadataSchema.audioId3,duration:Number.POSITIVE_INFINITY});id3Track.samples.push(id3Sample);};return TSDemuxer;}();function createAVCSample(key,pts,dts,debug){return{key:key,frame:false,pts:pts,dts:dts,units:[],debug:debug,length:0};}function parsePID(data,offset){// pid is a 13-bit field starting at the last bit of TS[1]
|
|
|
return((data[offset+1]&0x1f)<<8)+data[offset+2];}function parsePAT(data,offset){// skip the PSI header and parse the first PMT entry
|
|
|
return(data[offset+10]&0x1f)<<8|data[offset+11];}function parsePMT(data,offset,typeSupported,isSampleAes){var result={audio:-1,avc:-1,id3:-1,segmentCodec:'aac'};var sectionLength=(data[offset+1]&0x0f)<<8|data[offset+2];var tableEnd=offset+3+sectionLength-4;// to determine where the table is, we have to figure out how
|
|
|
// long the program info descriptors are
|
|
|
var programInfoLength=(data[offset+10]&0x0f)<<8|data[offset+11];// advance the offset to the first entry in the mapping table
|
|
|
offset+=12+programInfoLength;while(offset<tableEnd){var pid=parsePID(data,offset);switch(data[offset]){case 0xcf:// SAMPLE-AES AAC
|
|
|
if(!isSampleAes){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('ADTS AAC with AES-128-CBC frame encryption found in unencrypted stream');break;}/* falls through */case 0x0f:// ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
|
|
|
// logger.log('AAC PID:' + pid);
|
|
|
if(result.audio===-1){result.audio=pid;}break;// Packetized metadata (ID3)
|
|
|
case 0x15:// logger.log('ID3 PID:' + pid);
|
|
|
if(result.id3===-1){result.id3=pid;}break;case 0xdb:// SAMPLE-AES AVC
|
|
|
if(!isSampleAes){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('H.264 with AES-128-CBC slice encryption found in unencrypted stream');break;}/* falls through */case 0x1b:// ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
|
|
|
// logger.log('AVC PID:' + pid);
|
|
|
if(result.avc===-1){result.avc=pid;}break;// ISO/IEC 11172-3 (MPEG-1 audio)
|
|
|
// or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
|
|
|
case 0x03:case 0x04:// logger.log('MPEG PID:' + pid);
|
|
|
if(typeSupported.mpeg!==true&&typeSupported.mp3!==true){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('MPEG audio found, not supported in this browser');}else if(result.audio===-1){result.audio=pid;result.segmentCodec='mp3';}break;case 0x24:_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('Unsupported HEVC stream type found');break;default:// logger.log('unknown stream type:' + data[offset]);
|
|
|
break;}// move to the next table entry
|
|
|
// skip past the elementary stream descriptors, if present
|
|
|
offset+=((data[offset+3]&0x0f)<<8|data[offset+4])+5;}return result;}function parsePES(stream){var i=0;var frag;var pesLen;var pesHdrLen;var pesPts;var pesDts;var data=stream.data;// safety check
|
|
|
if(!stream||stream.size===0){return null;}// we might need up to 19 bytes to read PES header
|
|
|
// if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes
|
|
|
// usually only one merge is needed (and this is rare ...)
|
|
|
while(data[0].length<19&&data.length>1){var newData=new Uint8Array(data[0].length+data[1].length);newData.set(data[0]);newData.set(data[1],data[0].length);data[0]=newData;data.splice(1,1);}// retrieve PTS/DTS from first fragment
|
|
|
frag=data[0];var pesPrefix=(frag[0]<<16)+(frag[1]<<8)+frag[2];if(pesPrefix===1){pesLen=(frag[4]<<8)+frag[5];// if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated
|
|
|
// minus 6 : PES header size
|
|
|
if(pesLen&&pesLen>stream.size-6){return null;}var pesFlags=frag[7];if(pesFlags&0xc0){/* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
|
|
|
as PTS / DTS is 33 bit we cannot use bitwise operator in JS,
|
|
|
as Bitwise operators treat their operands as a sequence of 32 bits */pesPts=(frag[9]&0x0e)*536870912+// 1 << 29
|
|
|
(frag[10]&0xff)*4194304+// 1 << 22
|
|
|
(frag[11]&0xfe)*16384+// 1 << 14
|
|
|
(frag[12]&0xff)*128+// 1 << 7
|
|
|
(frag[13]&0xfe)/2;if(pesFlags&0x40){pesDts=(frag[14]&0x0e)*536870912+// 1 << 29
|
|
|
(frag[15]&0xff)*4194304+// 1 << 22
|
|
|
(frag[16]&0xfe)*16384+// 1 << 14
|
|
|
(frag[17]&0xff)*128+// 1 << 7
|
|
|
(frag[18]&0xfe)/2;if(pesPts-pesDts>60*90000){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn(Math.round((pesPts-pesDts)/90000)+"s delta between PTS and DTS, align them");pesPts=pesDts;}}else{pesDts=pesPts;}}pesHdrLen=frag[8];// 9 bytes : 6 bytes for PES header + 3 bytes for PES extension
|
|
|
var payloadStartOffset=pesHdrLen+9;if(stream.size<=payloadStartOffset){return null;}stream.size-=payloadStartOffset;// reassemble PES packet
|
|
|
var pesData=new Uint8Array(stream.size);for(var j=0,dataLen=data.length;j<dataLen;j++){frag=data[j];var len=frag.byteLength;if(payloadStartOffset){if(payloadStartOffset>len){// trim full frag if PES header bigger than frag
|
|
|
payloadStartOffset-=len;continue;}else{// trim partial frag if PES header smaller than frag
|
|
|
frag=frag.subarray(payloadStartOffset);len-=payloadStartOffset;payloadStartOffset=0;}}pesData.set(frag,i);i+=len;}if(pesLen){// payload size : remove PES header + PES extension
|
|
|
pesLen-=pesHdrLen+3;}return{data:pesData,pts:pesPts,dts:pesDts,len:pesLen};}return null;}function pushAccessUnit(avcSample,avcTrack){if(avcSample.units.length&&avcSample.frame){// if sample does not have PTS/DTS, patch with last sample PTS/DTS
|
|
|
if(avcSample.pts===undefined){var samples=avcTrack.samples;var nbSamples=samples.length;if(nbSamples){var lastSample=samples[nbSamples-1];avcSample.pts=lastSample.pts;avcSample.dts=lastSample.dts;}else{// dropping samples, no timestamp found
|
|
|
avcTrack.dropped++;return;}}avcTrack.samples.push(avcSample);}if(avcSample.debug.length){_utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log(avcSample.pts+'/'+avcSample.dts+':'+avcSample.debug);}}/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=TSDemuxer;/***/},/***/"./src/demux/webworkify-webpack.js":/*!*****************************************!*\
|
|
|
!*** ./src/demux/webworkify-webpack.js ***!
|
|
|
\*****************************************/ /***/function srcDemuxWebworkifyWebpackJs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_541164__){"use strict";__nested_webpack_require_541164__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_541164__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* export default binding */__WEBPACK_DEFAULT_EXPORT__);}/* harmony export */});/*
|
|
|
* Fork of webworkify-webpack with support for Webpack 5
|
|
|
* https://github.com/wupeng-engineer/webworkify-webpack/blob/db0de7/index.js
|
|
|
*/var webpackBootstrapFunc=function webpackBootstrapFunc(){// webpackBootstrap
|
|
|
/******/var __webpack_modules__=ENTRY_MODULE;/************************************************************************/ /******/ // The module cache
|
|
|
/******/var __webpack_module_cache__={};/******/ /******/ // The require function
|
|
|
/******/var __nested_webpack_require_497__=function __webpack_require__(moduleId){/******/ // Check if module is in cache
|
|
|
/******/var cachedModule=__webpack_module_cache__[moduleId];/******/if(cachedModule!==undefined){/******/return cachedModule.exports;/******/}/******/ // Create a new module (and put it into the cache)
|
|
|
/******/var module=__webpack_module_cache__[moduleId]={/******/ // no module.id needed
|
|
|
/******/ // no module.loaded needed
|
|
|
/******/exports:{}/******/};/******/ /******/ // Execute the module function
|
|
|
/******/__webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__);/******/ /******/ // Return the exports of the module
|
|
|
/******/return module.exports;/******/};/******/ /******/ // expose the modules object (__webpack_modules__)
|
|
|
/******/__nested_webpack_require_497__.m=__webpack_modules__;/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/(function(){/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
|
/******/__nested_webpack_require_497__.n=function(module){/******/var getter=module&&module.__esModule?/******/function(){return module['default'];}:/******/function(){return module;};/******/__nested_webpack_require_497__.d(getter,{a:getter});/******/return getter;/******/};/******/})();/******/ /******/ /* webpack/runtime/define property getters */ /******/(function(){/******/ // define getter functions for harmony exports
|
|
|
/******/__nested_webpack_require_497__.d=function(exports,definition){/******/for(var key in definition){/******/if(__nested_webpack_require_497__.o(definition,key)&&!__nested_webpack_require_497__.o(exports,key)){/******/Object.defineProperty(exports,key,{enumerable:true,get:definition[key]});/******/}/******/}/******/};/******/})();/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/(function(){/******/__nested_webpack_require_497__.o=function(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);};/******/})();/******/ /******/ /* webpack/runtime/make namespace object */ /******/(function(){/******/ // define __esModule on exports
|
|
|
/******/__nested_webpack_require_497__.r=function(exports){/******/if(typeof Symbol!=='undefined'&&Symbol.toStringTag){/******/Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});/******/}/******/Object.defineProperty(exports,'__esModule',{value:true});/******/};/******/})();/******/ /************************************************************************/ /******/ /******/ // module factories are used so entry inlining is disabled
|
|
|
/******/ // startup
|
|
|
/******/ // Load entry module and return exports
|
|
|
/******/var result=__nested_webpack_require_497__(ENTRY_MODULE);/******/return result["default"]||result;};var webpackBootstrapFuncArr=webpackBootstrapFunc.toString().split('ENTRY_MODULE');var moduleNameReqExp='[\\.|\\-|\\+|\\w|\/|@]+';var dependencyRegExp='\\(\\s*(\/\\*.*?\\*\/)?\\s*.*?('+moduleNameReqExp+').*?\\)';function quoteRegExp(str){return(str+'').replace(/[.?*+^$[\]\\(){}|-]/g,'\\$&');}function isNumeric(n){return!isNaN(1*n);}function getModuleDependencies(sources,module,queueName){var retval={};retval[queueName]=[];var fnString=module.toString().replace(/^"[^"]+"/,'function');;var wrapperSignature=fnString.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/)||fnString.match(/^\(\w+,\s*\w+,\s*(\w+)\)\s?\=\s?\>/);if(!wrapperSignature)return retval;var webpackRequireName=wrapperSignature[1];var re=new RegExp('(\\\\n|\\W)'+quoteRegExp(webpackRequireName)+dependencyRegExp,'g');var match;while(match=re.exec(fnString)){if(match[3]==='dll-reference')continue;retval[queueName].push(match[3]);}re=new RegExp('\\('+quoteRegExp(webpackRequireName)+'\\("(dll-reference\\s('+moduleNameReqExp+'))"\\)\\)'+dependencyRegExp,'g');while(match=re.exec(fnString)){if(!sources[match[2]]){retval[queueName].push(match[1]);sources[match[2]]=__nested_webpack_require_541164__(match[1]).m;}retval[match[2]]=retval[match[2]]||[];retval[match[2]].push(match[4]);}var keys=Object.keys(retval);for(var i=0;i<keys.length;i++){for(var j=0;j<retval[keys[i]].length;j++){if(isNumeric(retval[keys[i]][j])){retval[keys[i]][j]=1*retval[keys[i]][j];}}}return retval;}function hasValuesInQueues(queues){var keys=Object.keys(queues);return keys.reduce(function(hasValues,key){return hasValues||queues[key].length>0;},false);}function getRequiredModules(sources,moduleId){var modulesQueue={main:[moduleId]};var requiredModules={main:[]};var seenModules={main:{}};while(hasValuesInQueues(modulesQueue)){var queues=Object.keys(modulesQueue);for(var i=0;i<queues.length;i++){var queueName=queues[i];var queue=modulesQueue[queueName];var moduleToCheck=queue.pop();seenModules[queueName]=seenModules[queueName]||{};if(seenModules[queueName][moduleToCheck]||!sources[queueName][moduleToCheck])continue;seenModules[queueName][moduleToCheck]=true;requiredModules[queueName]=requiredModules[queueName]||[];requiredModules[queueName].push(moduleToCheck);var newModules=getModuleDependencies(sources,sources[queueName][moduleToCheck],queueName);var newModulesKeys=Object.keys(newModules);for(var j=0;j<newModulesKeys.length;j++){modulesQueue[newModulesKeys[j]]=modulesQueue[newModulesKeys[j]]||[];modulesQueue[newModulesKeys[j]]=modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]);}}}return requiredModules;}function getWebpackString(requiredModules,sources,entryModule,key){var moduleString=requiredModules[key].map(function(id){return"\""+id+"\": "+sources[key][id].toString().replace(/^"[^"]+"/,'function');}).join(",");return webpackBootstrapFuncArr[0]+"{"+moduleString+"}"+webpackBootstrapFuncArr[1]+"\""+entryModule+"\""+webpackBootstrapFuncArr[2];}/* harmony default export */function __WEBPACK_DEFAULT_EXPORT__(moduleId,options){options=options||{};var sources={main:__nested_webpack_require_541164__.m};var requiredModules=options.all?{main:Object.keys(sources.main)}:getRequiredModules(sources,moduleId);var src='';Object.keys(requiredModules).filter(function(m){return m!=='main';}).forEach(function(module){var entryModule=0;while(requiredModules[module][entryModule]){entryModule++;}requiredModules[module].push(entryModule);sources[module][entryModule]='(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })';src=src+("var "+module+" = ("+getWebpackString(requiredModules,sources,entryModule,modules)+")();\n");});src=src+("new (("+getWebpackString(requiredModules,sources,moduleId,'main')+")())(self);");var blob=new window.Blob([src],{type:'text/javascript'});var URL=window.URL||window.webkitURL||window.mozURL||window.msURL;var workerUrl=URL.createObjectURL(blob);var worker=new window.Worker(workerUrl);worker.objectURL=workerUrl;return worker;}/***/},/***/"./src/errors.ts":/*!***********************!*\
|
|
|
!*** ./src/errors.ts ***!
|
|
|
\***********************/ /***/function srcErrorsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_548849__){"use strict";__nested_webpack_require_548849__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_548849__.d(__webpack_exports__,{/* harmony export */"ErrorDetails":function ErrorDetails(){return(/* binding */_ErrorDetails);},/* harmony export */"ErrorTypes":function ErrorTypes(){return(/* binding */_ErrorTypes);}/* harmony export */});var _ErrorTypes;/**
|
|
|
* @enum {ErrorDetails}
|
|
|
* @typedef {string} ErrorDetail
|
|
|
*/(function(ErrorTypes){ErrorTypes["NETWORK_ERROR"]="networkError";ErrorTypes["MEDIA_ERROR"]="mediaError";ErrorTypes["KEY_SYSTEM_ERROR"]="keySystemError";ErrorTypes["MUX_ERROR"]="muxError";ErrorTypes["OTHER_ERROR"]="otherError";})(_ErrorTypes||(_ErrorTypes={}));var _ErrorDetails;(function(ErrorDetails){ErrorDetails["KEY_SYSTEM_NO_KEYS"]="keySystemNoKeys";ErrorDetails["KEY_SYSTEM_NO_ACCESS"]="keySystemNoAccess";ErrorDetails["KEY_SYSTEM_NO_SESSION"]="keySystemNoSession";ErrorDetails["KEY_SYSTEM_NO_CONFIGURED_LICENSE"]="keySystemNoConfiguredLicense";ErrorDetails["KEY_SYSTEM_LICENSE_REQUEST_FAILED"]="keySystemLicenseRequestFailed";ErrorDetails["KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED"]="keySystemServerCertificateRequestFailed";ErrorDetails["KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED"]="keySystemServerCertificateUpdateFailed";ErrorDetails["KEY_SYSTEM_SESSION_UPDATE_FAILED"]="keySystemSessionUpdateFailed";ErrorDetails["KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED"]="keySystemStatusOutputRestricted";ErrorDetails["KEY_SYSTEM_STATUS_INTERNAL_ERROR"]="keySystemStatusInternalError";ErrorDetails["MANIFEST_LOAD_ERROR"]="manifestLoadError";ErrorDetails["MANIFEST_LOAD_TIMEOUT"]="manifestLoadTimeOut";ErrorDetails["MANIFEST_PARSING_ERROR"]="manifestParsingError";ErrorDetails["MANIFEST_INCOMPATIBLE_CODECS_ERROR"]="manifestIncompatibleCodecsError";ErrorDetails["LEVEL_EMPTY_ERROR"]="levelEmptyError";ErrorDetails["LEVEL_LOAD_ERROR"]="levelLoadError";ErrorDetails["LEVEL_LOAD_TIMEOUT"]="levelLoadTimeOut";ErrorDetails["LEVEL_SWITCH_ERROR"]="levelSwitchError";ErrorDetails["AUDIO_TRACK_LOAD_ERROR"]="audioTrackLoadError";ErrorDetails["AUDIO_TRACK_LOAD_TIMEOUT"]="audioTrackLoadTimeOut";ErrorDetails["SUBTITLE_LOAD_ERROR"]="subtitleTrackLoadError";ErrorDetails["SUBTITLE_TRACK_LOAD_TIMEOUT"]="subtitleTrackLoadTimeOut";ErrorDetails["FRAG_LOAD_ERROR"]="fragLoadError";ErrorDetails["FRAG_LOAD_TIMEOUT"]="fragLoadTimeOut";ErrorDetails["FRAG_DECRYPT_ERROR"]="fragDecryptError";ErrorDetails["FRAG_PARSING_ERROR"]="fragParsingError";ErrorDetails["REMUX_ALLOC_ERROR"]="remuxAllocError";ErrorDetails["KEY_LOAD_ERROR"]="keyLoadError";ErrorDetails["KEY_LOAD_TIMEOUT"]="keyLoadTimeOut";ErrorDetails["BUFFER_ADD_CODEC_ERROR"]="bufferAddCodecError";ErrorDetails["BUFFER_INCOMPATIBLE_CODECS_ERROR"]="bufferIncompatibleCodecsError";ErrorDetails["BUFFER_APPEND_ERROR"]="bufferAppendError";ErrorDetails["BUFFER_APPENDING_ERROR"]="bufferAppendingError";ErrorDetails["BUFFER_STALLED_ERROR"]="bufferStalledError";ErrorDetails["BUFFER_FULL_ERROR"]="bufferFullError";ErrorDetails["BUFFER_SEEK_OVER_HOLE"]="bufferSeekOverHole";ErrorDetails["BUFFER_NUDGE_ON_STALL"]="bufferNudgeOnStall";ErrorDetails["INTERNAL_EXCEPTION"]="internalException";ErrorDetails["INTERNAL_ABORTED"]="aborted";ErrorDetails["UNKNOWN"]="unknown";})(_ErrorDetails||(_ErrorDetails={}));/***/},/***/"./src/events.ts":/*!***********************!*\
|
|
|
!*** ./src/events.ts ***!
|
|
|
\***********************/ /***/function srcEventsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_552291__){"use strict";__nested_webpack_require_552291__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_552291__.d(__webpack_exports__,{/* harmony export */"Events":function Events(){return(/* binding */_Events);}/* harmony export */});/**
|
|
|
* @readonly
|
|
|
* @enum {string}
|
|
|
*/var _Events;(function(Events){Events["MEDIA_ATTACHING"]="hlsMediaAttaching";Events["MEDIA_ATTACHED"]="hlsMediaAttached";Events["MEDIA_DETACHING"]="hlsMediaDetaching";Events["MEDIA_DETACHED"]="hlsMediaDetached";Events["BUFFER_RESET"]="hlsBufferReset";Events["BUFFER_CODECS"]="hlsBufferCodecs";Events["BUFFER_CREATED"]="hlsBufferCreated";Events["BUFFER_APPENDING"]="hlsBufferAppending";Events["BUFFER_APPENDED"]="hlsBufferAppended";Events["BUFFER_EOS"]="hlsBufferEos";Events["BUFFER_FLUSHING"]="hlsBufferFlushing";Events["BUFFER_FLUSHED"]="hlsBufferFlushed";Events["MANIFEST_LOADING"]="hlsManifestLoading";Events["MANIFEST_LOADED"]="hlsManifestLoaded";Events["MANIFEST_PARSED"]="hlsManifestParsed";Events["LEVEL_SWITCHING"]="hlsLevelSwitching";Events["LEVEL_SWITCHED"]="hlsLevelSwitched";Events["LEVEL_LOADING"]="hlsLevelLoading";Events["LEVEL_LOADED"]="hlsLevelLoaded";Events["LEVEL_UPDATED"]="hlsLevelUpdated";Events["LEVEL_PTS_UPDATED"]="hlsLevelPtsUpdated";Events["LEVELS_UPDATED"]="hlsLevelsUpdated";Events["AUDIO_TRACKS_UPDATED"]="hlsAudioTracksUpdated";Events["AUDIO_TRACK_SWITCHING"]="hlsAudioTrackSwitching";Events["AUDIO_TRACK_SWITCHED"]="hlsAudioTrackSwitched";Events["AUDIO_TRACK_LOADING"]="hlsAudioTrackLoading";Events["AUDIO_TRACK_LOADED"]="hlsAudioTrackLoaded";Events["SUBTITLE_TRACKS_UPDATED"]="hlsSubtitleTracksUpdated";Events["SUBTITLE_TRACKS_CLEARED"]="hlsSubtitleTracksCleared";Events["SUBTITLE_TRACK_SWITCH"]="hlsSubtitleTrackSwitch";Events["SUBTITLE_TRACK_LOADING"]="hlsSubtitleTrackLoading";Events["SUBTITLE_TRACK_LOADED"]="hlsSubtitleTrackLoaded";Events["SUBTITLE_FRAG_PROCESSED"]="hlsSubtitleFragProcessed";Events["CUES_PARSED"]="hlsCuesParsed";Events["NON_NATIVE_TEXT_TRACKS_FOUND"]="hlsNonNativeTextTracksFound";Events["INIT_PTS_FOUND"]="hlsInitPtsFound";Events["FRAG_LOADING"]="hlsFragLoading";Events["FRAG_LOAD_EMERGENCY_ABORTED"]="hlsFragLoadEmergencyAborted";Events["FRAG_LOADED"]="hlsFragLoaded";Events["FRAG_DECRYPTED"]="hlsFragDecrypted";Events["FRAG_PARSING_INIT_SEGMENT"]="hlsFragParsingInitSegment";Events["FRAG_PARSING_USERDATA"]="hlsFragParsingUserdata";Events["FRAG_PARSING_METADATA"]="hlsFragParsingMetadata";Events["FRAG_PARSED"]="hlsFragParsed";Events["FRAG_BUFFERED"]="hlsFragBuffered";Events["FRAG_CHANGED"]="hlsFragChanged";Events["FPS_DROP"]="hlsFpsDrop";Events["FPS_DROP_LEVEL_CAPPING"]="hlsFpsDropLevelCapping";Events["ERROR"]="hlsError";Events["DESTROYING"]="hlsDestroying";Events["KEY_LOADING"]="hlsKeyLoading";Events["KEY_LOADED"]="hlsKeyLoaded";Events["LIVE_BACK_BUFFER_REACHED"]="hlsLiveBackBufferReached";Events["BACK_BUFFER_REACHED"]="hlsBackBufferReached";})(_Events||(_Events={}));/***/},/***/"./src/hls.ts":/*!********************!*\
|
|
|
!*** ./src/hls.ts ***!
|
|
|
\********************/ /***/function srcHlsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_555377__){"use strict";__nested_webpack_require_555377__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_555377__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */Hls);}/* harmony export */});/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_555377__(/*! url-toolkit */"./node_modules/url-toolkit/src/url-toolkit.js");/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default=/*#__PURE__*/__nested_webpack_require_555377__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */var _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_555377__(/*! ./loader/playlist-loader */"./src/loader/playlist-loader.ts");/* harmony import */var _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_555377__(/*! ./controller/id3-track-controller */"./src/controller/id3-track-controller.ts");/* harmony import */var _controller_latency_controller__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_555377__(/*! ./controller/latency-controller */"./src/controller/latency-controller.ts");/* harmony import */var _controller_level_controller__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_555377__(/*! ./controller/level-controller */"./src/controller/level-controller.ts");/* harmony import */var _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_555377__(/*! ./controller/fragment-tracker */"./src/controller/fragment-tracker.ts");/* harmony import */var _loader_key_loader__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_555377__(/*! ./loader/key-loader */"./src/loader/key-loader.ts");/* harmony import */var _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_555377__(/*! ./controller/stream-controller */"./src/controller/stream-controller.ts");/* harmony import */var _is_supported__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_555377__(/*! ./is-supported */"./src/is-supported.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_9__=__nested_webpack_require_555377__(/*! ./utils/logger */"./src/utils/logger.ts");/* harmony import */var _config__WEBPACK_IMPORTED_MODULE_10__=__nested_webpack_require_555377__(/*! ./config */"./src/config.ts");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_11__=__nested_webpack_require_555377__(/*! eventemitter3 */"./node_modules/eventemitter3/index.js");/* harmony import */var eventemitter3__WEBPACK_IMPORTED_MODULE_11___default=/*#__PURE__*/__nested_webpack_require_555377__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_11__);/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_12__=__nested_webpack_require_555377__(/*! ./events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_13__=__nested_webpack_require_555377__(/*! ./errors */"./src/errors.ts");/* harmony import */var _types_level__WEBPACK_IMPORTED_MODULE_14__=__nested_webpack_require_555377__(/*! ./types/level */"./src/types/level.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}/**
|
|
|
* @module Hls
|
|
|
* @class
|
|
|
* @constructor
|
|
|
*/var Hls=/*#__PURE__*/function(){Hls.isSupported=function isSupported(){return(0,_is_supported__WEBPACK_IMPORTED_MODULE_8__.isSupported)();};/**
|
|
|
* Creates an instance of an HLS client that can attach to exactly one `HTMLMediaElement`.
|
|
|
*
|
|
|
* @constructs Hls
|
|
|
* @param {HlsConfig} config
|
|
|
*/function Hls(userConfig){if(userConfig===void 0){userConfig={};}this.config=void 0;this.userConfig=void 0;this.coreComponents=void 0;this.networkControllers=void 0;this._emitter=new eventemitter3__WEBPACK_IMPORTED_MODULE_11__.EventEmitter();this._autoLevelCapping=void 0;this._maxHdcpLevel=null;this.abrController=void 0;this.bufferController=void 0;this.capLevelController=void 0;this.latencyController=void 0;this.levelController=void 0;this.streamController=void 0;this.audioTrackController=void 0;this.subtitleTrackController=void 0;this.emeController=void 0;this.cmcdController=void 0;this._media=null;this.url=null;var config=this.config=(0,_config__WEBPACK_IMPORTED_MODULE_10__.mergeConfig)(Hls.DefaultConfig,userConfig);this.userConfig=userConfig;(0,_utils_logger__WEBPACK_IMPORTED_MODULE_9__.enableLogs)(config.debug,'Hls instance');this._autoLevelCapping=-1;if(config.progressive){(0,_config__WEBPACK_IMPORTED_MODULE_10__.enableStreamingMode)(config);}// core controllers and network loaders
|
|
|
var ConfigAbrController=config.abrController,ConfigBufferController=config.bufferController,ConfigCapLevelController=config.capLevelController,ConfigFpsController=config.fpsController;var abrController=this.abrController=new ConfigAbrController(this);var bufferController=this.bufferController=new ConfigBufferController(this);var capLevelController=this.capLevelController=new ConfigCapLevelController(this);var fpsController=new ConfigFpsController(this);var playListLoader=new _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__["default"](this);var id3TrackController=new _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"](this);// network controllers
|
|
|
var levelController=this.levelController=new _controller_level_controller__WEBPACK_IMPORTED_MODULE_4__["default"](this);// FragmentTracker must be defined before StreamController because the order of event handling is important
|
|
|
var fragmentTracker=new _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentTracker(this);var keyLoader=new _loader_key_loader__WEBPACK_IMPORTED_MODULE_6__["default"](this.config);var streamController=this.streamController=new _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"](this,fragmentTracker,keyLoader);// Cap level controller uses streamController to flush the buffer
|
|
|
capLevelController.setStreamController(streamController);// fpsController uses streamController to switch when frames are being dropped
|
|
|
fpsController.setStreamController(streamController);var networkControllers=[playListLoader,levelController,streamController];this.networkControllers=networkControllers;var coreComponents=[abrController,bufferController,capLevelController,fpsController,id3TrackController,fragmentTracker];this.audioTrackController=this.createController(config.audioTrackController,networkControllers);var AudioStreamControllerClass=config.audioStreamController;if(AudioStreamControllerClass){networkControllers.push(new AudioStreamControllerClass(this,fragmentTracker,keyLoader));}// subtitleTrackController must be defined before subtitleStreamController because the order of event handling is important
|
|
|
this.subtitleTrackController=this.createController(config.subtitleTrackController,networkControllers);var SubtitleStreamControllerClass=config.subtitleStreamController;if(SubtitleStreamControllerClass){networkControllers.push(new SubtitleStreamControllerClass(this,fragmentTracker,keyLoader));}this.createController(config.timelineController,coreComponents);keyLoader.emeController=this.emeController=this.createController(config.emeController,coreComponents);this.cmcdController=this.createController(config.cmcdController,coreComponents);this.latencyController=this.createController(_controller_latency_controller__WEBPACK_IMPORTED_MODULE_3__["default"],coreComponents);this.coreComponents=coreComponents;}var _proto=Hls.prototype;_proto.createController=function createController(ControllerClass,components){if(ControllerClass){var controllerInstance=new ControllerClass(this);if(components){components.push(controllerInstance);}return controllerInstance;}return null;}// Delegate the EventEmitter through the public API of Hls.js
|
|
|
;_proto.on=function on(event,listener,context){if(context===void 0){context=this;}this._emitter.on(event,listener,context);};_proto.once=function once(event,listener,context){if(context===void 0){context=this;}this._emitter.once(event,listener,context);};_proto.removeAllListeners=function removeAllListeners(event){this._emitter.removeAllListeners(event);};_proto.off=function off(event,listener,context,once){if(context===void 0){context=this;}this._emitter.off(event,listener,context,once);};_proto.listeners=function listeners(event){return this._emitter.listeners(event);};_proto.emit=function emit(event,name,eventObject){return this._emitter.emit(event,name,eventObject);};_proto.trigger=function trigger(event,eventObject){if(this.config.debug){return this.emit(event,event,eventObject);}else{try{return this.emit(event,event,eventObject);}catch(e){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.error('An internal error happened while handling event '+event+'. Error message: "'+e.message+'". Here is a stacktrace:',e);this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes.OTHER_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.INTERNAL_EXCEPTION,fatal:false,event:event,error:e});}}return false;};_proto.listenerCount=function listenerCount(event){return this._emitter.listenerCount(event);}/**
|
|
|
* Dispose of the instance
|
|
|
*/;_proto.destroy=function destroy(){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('destroy');this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.DESTROYING,undefined);this.detachMedia();this.removeAllListeners();this._autoLevelCapping=-1;this.url=null;this.networkControllers.forEach(function(component){return component.destroy();});this.networkControllers.length=0;this.coreComponents.forEach(function(component){return component.destroy();});this.coreComponents.length=0;}/**
|
|
|
* Attaches Hls.js to a media element
|
|
|
* @param {HTMLMediaElement} media
|
|
|
*/;_proto.attachMedia=function attachMedia(media){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('attachMedia');this._media=media;this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MEDIA_ATTACHING,{media:media});}/**
|
|
|
* Detach Hls.js from the media
|
|
|
*/;_proto.detachMedia=function detachMedia(){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('detachMedia');this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MEDIA_DETACHING,undefined);this._media=null;}/**
|
|
|
* Set the source URL. Can be relative or absolute.
|
|
|
* @param {string} url
|
|
|
*/;_proto.loadSource=function loadSource(url){this.stopLoad();var media=this.media;var loadedSource=this.url;var loadingSource=this.url=url_toolkit__WEBPACK_IMPORTED_MODULE_0__.buildAbsoluteURL(self.location.href,url,{alwaysNormalize:true});_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("loadSource:"+loadingSource);if(media&&loadedSource&&loadedSource!==loadingSource&&this.bufferController.hasSourceTypes()){this.detachMedia();this.attachMedia(media);}// when attaching to a source URL, trigger a playlist load
|
|
|
this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MANIFEST_LOADING,{url:url});}/**
|
|
|
* Start loading data from the stream source.
|
|
|
* Depending on default config, client starts loading automatically when a source is set.
|
|
|
*
|
|
|
* @param {number} startPosition Set the start position to stream from
|
|
|
* @default -1 None (from earliest point)
|
|
|
*/;_proto.startLoad=function startLoad(startPosition){if(startPosition===void 0){startPosition=-1;}_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("startLoad("+startPosition+")");this.networkControllers.forEach(function(controller){controller.startLoad(startPosition);});}/**
|
|
|
* Stop loading of any stream data.
|
|
|
*/;_proto.stopLoad=function stopLoad(){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('stopLoad');this.networkControllers.forEach(function(controller){controller.stopLoad();});}/**
|
|
|
* Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
|
|
|
*/;_proto.swapAudioCodec=function swapAudioCodec(){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('swapAudioCodec');this.streamController.swapAudioCodec();}/**
|
|
|
* When the media-element fails, this allows to detach and then re-attach it
|
|
|
* as one call (convenience method).
|
|
|
*
|
|
|
* Automatic recovery of media-errors by this process is configurable.
|
|
|
*/;_proto.recoverMediaError=function recoverMediaError(){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('recoverMediaError');var media=this._media;this.detachMedia();if(media){this.attachMedia(media);}};_proto.removeLevel=function removeLevel(levelIndex,urlId){if(urlId===void 0){urlId=0;}this.levelController.removeLevel(levelIndex,urlId);}/**
|
|
|
* @type {Level[]}
|
|
|
*/;_createClass(Hls,[{key:"levels",get:function get(){var levels=this.levelController.levels;return levels?levels:[];}/**
|
|
|
* Index of quality level currently played
|
|
|
* @type {number}
|
|
|
*/},{key:"currentLevel",get:function get(){return this.streamController.currentLevel;}/**
|
|
|
* Set quality level index immediately .
|
|
|
* This will flush the current buffer to replace the quality asap.
|
|
|
* That means playback will interrupt at least shortly to re-buffer and re-sync eventually.
|
|
|
* @type {number} -1 for automatic level selection
|
|
|
*/,set:function set(newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set currentLevel:"+newLevel);this.loadLevel=newLevel;this.abrController.clearTimer();this.streamController.immediateLevelSwitch();}/**
|
|
|
* Index of next quality level loaded as scheduled by stream controller.
|
|
|
* @type {number}
|
|
|
*/},{key:"nextLevel",get:function get(){return this.streamController.nextLevel;}/**
|
|
|
* Set quality level index for next loaded data.
|
|
|
* This will switch the video quality asap, without interrupting playback.
|
|
|
* May abort current loading of data, and flush parts of buffer (outside currently played fragment region).
|
|
|
* @type {number} -1 for automatic level selection
|
|
|
*/,set:function set(newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set nextLevel:"+newLevel);this.levelController.manualLevel=newLevel;this.streamController.nextLevelSwitch();}/**
|
|
|
* Return the quality level of the currently or last (of none is loaded currently) segment
|
|
|
* @type {number}
|
|
|
*/},{key:"loadLevel",get:function get(){return this.levelController.level;}/**
|
|
|
* Set quality level index for next loaded data in a conservative way.
|
|
|
* This will switch the quality without flushing, but interrupt current loading.
|
|
|
* Thus the moment when the quality switch will appear in effect will only be after the already existing buffer.
|
|
|
* @type {number} newLevel -1 for automatic level selection
|
|
|
*/,set:function set(newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set loadLevel:"+newLevel);this.levelController.manualLevel=newLevel;}/**
|
|
|
* get next quality level loaded
|
|
|
* @type {number}
|
|
|
*/},{key:"nextLoadLevel",get:function get(){return this.levelController.nextLoadLevel;}/**
|
|
|
* Set quality level of next loaded segment in a fully "non-destructive" way.
|
|
|
* Same as `loadLevel` but will wait for next switch (until current loading is done).
|
|
|
* @type {number} level
|
|
|
*/,set:function set(level){this.levelController.nextLoadLevel=level;}/**
|
|
|
* Return "first level": like a default level, if not set,
|
|
|
* falls back to index of first level referenced in manifest
|
|
|
* @type {number}
|
|
|
*/},{key:"firstLevel",get:function get(){return Math.max(this.levelController.firstLevel,this.minAutoLevel);}/**
|
|
|
* Sets "first-level", see getter.
|
|
|
* @type {number}
|
|
|
*/,set:function set(newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set firstLevel:"+newLevel);this.levelController.firstLevel=newLevel;}/**
|
|
|
* Return start level (level of first fragment that will be played back)
|
|
|
* if not overrided by user, first level appearing in manifest will be used as start level
|
|
|
* if -1 : automatic start level selection, playback will start from level matching download bandwidth
|
|
|
* (determined from download of first segment)
|
|
|
* @type {number}
|
|
|
*/},{key:"startLevel",get:function get(){return this.levelController.startLevel;}/**
|
|
|
* set start level (level of first fragment that will be played back)
|
|
|
* if not overrided by user, first level appearing in manifest will be used as start level
|
|
|
* if -1 : automatic start level selection, playback will start from level matching download bandwidth
|
|
|
* (determined from download of first segment)
|
|
|
* @type {number} newLevel
|
|
|
*/,set:function set(newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set startLevel:"+newLevel);// if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
|
|
|
if(newLevel!==-1){newLevel=Math.max(newLevel,this.minAutoLevel);}this.levelController.startLevel=newLevel;}/**
|
|
|
* Get the current setting for capLevelToPlayerSize
|
|
|
*
|
|
|
* @type {boolean}
|
|
|
*/},{key:"capLevelToPlayerSize",get:function get(){return this.config.capLevelToPlayerSize;}/**
|
|
|
* set dynamically set capLevelToPlayerSize against (`CapLevelController`)
|
|
|
*
|
|
|
* @type {boolean}
|
|
|
*/,set:function set(shouldStartCapping){var newCapLevelToPlayerSize=!!shouldStartCapping;if(newCapLevelToPlayerSize!==this.config.capLevelToPlayerSize){if(newCapLevelToPlayerSize){this.capLevelController.startCapping();// If capping occurs, nextLevelSwitch will happen based on size.
|
|
|
}else{this.capLevelController.stopCapping();this.autoLevelCapping=-1;this.streamController.nextLevelSwitch();// Now we're uncapped, get the next level asap.
|
|
|
}this.config.capLevelToPlayerSize=newCapLevelToPlayerSize;}}/**
|
|
|
* Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
|
|
|
* @type {number}
|
|
|
*/},{key:"autoLevelCapping",get:function get(){return this._autoLevelCapping;}/**
|
|
|
* get bandwidth estimate
|
|
|
* @type {number}
|
|
|
*/,set:/**
|
|
|
* Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
|
|
|
* @type {number}
|
|
|
*/function set(newLevel){if(this._autoLevelCapping!==newLevel){_utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set autoLevelCapping:"+newLevel);this._autoLevelCapping=newLevel;}}},{key:"bandwidthEstimate",get:function get(){var bwEstimator=this.abrController.bwEstimator;if(!bwEstimator){return NaN;}return bwEstimator.getEstimate();}},{key:"maxHdcpLevel",get:function get(){return this._maxHdcpLevel;},set:function set(value){if(_types_level__WEBPACK_IMPORTED_MODULE_14__.HdcpLevels.indexOf(value)>-1){this._maxHdcpLevel=value;}}/**
|
|
|
* True when automatic level selection enabled
|
|
|
* @type {boolean}
|
|
|
*/},{key:"autoLevelEnabled",get:function get(){return this.levelController.manualLevel===-1;}/**
|
|
|
* Level set manually (if any)
|
|
|
* @type {number}
|
|
|
*/},{key:"manualLevel",get:function get(){return this.levelController.manualLevel;}/**
|
|
|
* min level selectable in auto mode according to config.minAutoBitrate
|
|
|
* @type {number}
|
|
|
*/},{key:"minAutoLevel",get:function get(){var levels=this.levels,minAutoBitrate=this.config.minAutoBitrate;if(!levels)return 0;var len=levels.length;for(var i=0;i<len;i++){if(levels[i].maxBitrate>=minAutoBitrate){return i;}}return 0;}/**
|
|
|
* max level selectable in auto mode according to autoLevelCapping
|
|
|
* @type {number}
|
|
|
*/},{key:"maxAutoLevel",get:function get(){var levels=this.levels,autoLevelCapping=this.autoLevelCapping,maxHdcpLevel=this.maxHdcpLevel;var maxAutoLevel;if(autoLevelCapping===-1&&levels&&levels.length){maxAutoLevel=levels.length-1;}else{maxAutoLevel=autoLevelCapping;}if(maxHdcpLevel){for(var i=maxAutoLevel;i--;){var hdcpLevel=levels[i].attrs['HDCP-LEVEL'];if(hdcpLevel&&hdcpLevel<=maxHdcpLevel){return i;}}}return maxAutoLevel;}/**
|
|
|
* next automatically selected quality level
|
|
|
* @type {number}
|
|
|
*/},{key:"nextAutoLevel",get:function get(){// ensure next auto level is between min and max auto level
|
|
|
return Math.min(Math.max(this.abrController.nextAutoLevel,this.minAutoLevel),this.maxAutoLevel);}/**
|
|
|
* this setter is used to force next auto level.
|
|
|
* this is useful to force a switch down in auto mode:
|
|
|
* in case of load error on level N, hls.js can set nextAutoLevel to N-1 for example)
|
|
|
* forced value is valid for one fragment. upon successful frag loading at forced level,
|
|
|
* this value will be resetted to -1 by ABR controller.
|
|
|
* @type {number}
|
|
|
*/,set:function set(nextLevel){this.abrController.nextAutoLevel=Math.max(this.minAutoLevel,nextLevel);}/**
|
|
|
* get the datetime value relative to media.currentTime for the active level Program Date Time if present
|
|
|
* @type {Date}
|
|
|
*/},{key:"playingDate",get:function get(){return this.streamController.currentProgramDateTime;}},{key:"mainForwardBufferInfo",get:function get(){return this.streamController.getMainFwdBufferInfo();}/**
|
|
|
* @type {AudioTrack[]}
|
|
|
*/},{key:"audioTracks",get:function get(){var audioTrackController=this.audioTrackController;return audioTrackController?audioTrackController.audioTracks:[];}/**
|
|
|
* index of the selected audio track (index in audio track lists)
|
|
|
* @type {number}
|
|
|
*/},{key:"audioTrack",get:function get(){var audioTrackController=this.audioTrackController;return audioTrackController?audioTrackController.audioTrack:-1;}/**
|
|
|
* selects an audio track, based on its index in audio track lists
|
|
|
* @type {number}
|
|
|
*/,set:function set(audioTrackId){var audioTrackController=this.audioTrackController;if(audioTrackController){audioTrackController.audioTrack=audioTrackId;}}/**
|
|
|
* get alternate subtitle tracks list from playlist
|
|
|
* @type {MediaPlaylist[]}
|
|
|
*/},{key:"subtitleTracks",get:function get(){var subtitleTrackController=this.subtitleTrackController;return subtitleTrackController?subtitleTrackController.subtitleTracks:[];}/**
|
|
|
* index of the selected subtitle track (index in subtitle track lists)
|
|
|
* @type {number}
|
|
|
*/},{key:"subtitleTrack",get:function get(){var subtitleTrackController=this.subtitleTrackController;return subtitleTrackController?subtitleTrackController.subtitleTrack:-1;},set:/**
|
|
|
* select an subtitle track, based on its index in subtitle track lists
|
|
|
* @type {number}
|
|
|
*/function set(subtitleTrackId){var subtitleTrackController=this.subtitleTrackController;if(subtitleTrackController){subtitleTrackController.subtitleTrack=subtitleTrackId;}}/**
|
|
|
* @type {boolean}
|
|
|
*/},{key:"media",get:function get(){return this._media;}},{key:"subtitleDisplay",get:function get(){var subtitleTrackController=this.subtitleTrackController;return subtitleTrackController?subtitleTrackController.subtitleDisplay:false;}/**
|
|
|
* Enable/disable subtitle display rendering
|
|
|
* @type {boolean}
|
|
|
*/,set:function set(value){var subtitleTrackController=this.subtitleTrackController;if(subtitleTrackController){subtitleTrackController.subtitleDisplay=value;}}/**
|
|
|
* get mode for Low-Latency HLS loading
|
|
|
* @type {boolean}
|
|
|
*/},{key:"lowLatencyMode",get:function get(){return this.config.lowLatencyMode;}/**
|
|
|
* Enable/disable Low-Latency HLS part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK.
|
|
|
* @type {boolean}
|
|
|
*/,set:function set(mode){this.config.lowLatencyMode=mode;}/**
|
|
|
* position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```hls.config.liveSyncDuration```)
|
|
|
* @type {number}
|
|
|
*/},{key:"liveSyncPosition",get:function get(){return this.latencyController.liveSyncPosition;}/**
|
|
|
* estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced)
|
|
|
* returns 0 before first playlist is loaded
|
|
|
* @type {number}
|
|
|
*/},{key:"latency",get:function get(){return this.latencyController.latency;}/**
|
|
|
* maximum distance from the edge before the player seeks forward to ```hls.liveSyncPosition```
|
|
|
* configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration```
|
|
|
* returns 0 before first playlist is loaded
|
|
|
* @type {number}
|
|
|
*/},{key:"maxLatency",get:function get(){return this.latencyController.maxLatency;}/**
|
|
|
* target distance from the edge as calculated by the latency controller
|
|
|
* @type {number}
|
|
|
*/},{key:"targetLatency",get:function get(){return this.latencyController.targetLatency;}/**
|
|
|
* the rate at which the edge of the current live playlist is advancing or 1 if there is none
|
|
|
* @type {number}
|
|
|
*/},{key:"drift",get:function get(){return this.latencyController.drift;}/**
|
|
|
* set to true when startLoad is called before MANIFEST_PARSED event
|
|
|
* @type {boolean}
|
|
|
*/},{key:"forceStartLoad",get:function get(){return this.streamController.forceStartLoad;}}],[{key:"version",get:function get(){return"1.3.5";}},{key:"Events",get:function get(){return _events__WEBPACK_IMPORTED_MODULE_12__.Events;}},{key:"ErrorTypes",get:function get(){return _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes;}},{key:"ErrorDetails",get:function get(){return _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails;}},{key:"DefaultConfig",get:function get(){if(!Hls.defaultConfig){return _config__WEBPACK_IMPORTED_MODULE_10__.hlsDefaultConfig;}return Hls.defaultConfig;}/**
|
|
|
* @type {HlsConfig}
|
|
|
*/,set:function set(defaultConfig){Hls.defaultConfig=defaultConfig;}}]);return Hls;}();Hls.defaultConfig=void 0;/***/},/***/"./src/is-supported.ts":/*!*****************************!*\
|
|
|
!*** ./src/is-supported.ts ***!
|
|
|
\*****************************/ /***/function srcIsSupportedTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_581631__){"use strict";__nested_webpack_require_581631__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_581631__.d(__webpack_exports__,{/* harmony export */"changeTypeSupported":function changeTypeSupported(){return(/* binding */_changeTypeSupported);},/* harmony export */"isSupported":function isSupported(){return(/* binding */_isSupported);}/* harmony export */});/* harmony import */var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_581631__(/*! ./utils/mediasource-helper */"./src/utils/mediasource-helper.ts");function getSourceBuffer(){return self.SourceBuffer||self.WebKitSourceBuffer;}function _isSupported(){var mediaSource=(0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__.getMediaSource)();if(!mediaSource){return false;}var sourceBuffer=getSourceBuffer();var isTypeSupported=mediaSource&&typeof mediaSource.isTypeSupported==='function'&&mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');// if SourceBuffer is exposed ensure its API is valid
|
|
|
// safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
|
|
|
var sourceBufferValidAPI=!sourceBuffer||sourceBuffer.prototype&&typeof sourceBuffer.prototype.appendBuffer==='function'&&typeof sourceBuffer.prototype.remove==='function';return!!isTypeSupported&&!!sourceBufferValidAPI;}function _changeTypeSupported(){var _sourceBuffer$prototy;var sourceBuffer=getSourceBuffer();return typeof(sourceBuffer===null||sourceBuffer===void 0?void 0:(_sourceBuffer$prototy=sourceBuffer.prototype)===null||_sourceBuffer$prototy===void 0?void 0:_sourceBuffer$prototy.changeType)==='function';}/***/},/***/"./src/loader/date-range.ts":/*!**********************************!*\
|
|
|
!*** ./src/loader/date-range.ts ***!
|
|
|
\**********************************/ /***/function srcLoaderDateRangeTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_583520__){"use strict";__nested_webpack_require_583520__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_583520__.d(__webpack_exports__,{/* harmony export */"DateRange":function DateRange(){return(/* binding */_DateRange);},/* harmony export */"DateRangeAttribute":function DateRangeAttribute(){return(/* binding */_DateRangeAttribute);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_583520__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _utils_attr_list__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_583520__(/*! ../utils/attr-list */"./src/utils/attr-list.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_583520__(/*! ../utils/logger */"./src/utils/logger.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var _DateRangeAttribute;(function(DateRangeAttribute){DateRangeAttribute["ID"]="ID";DateRangeAttribute["CLASS"]="CLASS";DateRangeAttribute["START_DATE"]="START-DATE";DateRangeAttribute["DURATION"]="DURATION";DateRangeAttribute["END_DATE"]="END-DATE";DateRangeAttribute["END_ON_NEXT"]="END-ON-NEXT";DateRangeAttribute["PLANNED_DURATION"]="PLANNED-DURATION";DateRangeAttribute["SCTE35_OUT"]="SCTE35-OUT";DateRangeAttribute["SCTE35_IN"]="SCTE35-IN";})(_DateRangeAttribute||(_DateRangeAttribute={}));var _DateRange=/*#__PURE__*/function(){function DateRange(dateRangeAttr,dateRangeWithSameId){this.attr=void 0;this._startDate=void 0;this._endDate=void 0;this._badValueForSameId=void 0;if(dateRangeWithSameId){var previousAttr=dateRangeWithSameId.attr;for(var key in previousAttr){if(Object.prototype.hasOwnProperty.call(dateRangeAttr,key)&&dateRangeAttr[key]!==previousAttr[key]){_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("DATERANGE tag attribute: \""+key+"\" does not match for tags with ID: \""+dateRangeAttr.ID+"\"");this._badValueForSameId=key;break;}}// Merge DateRange tags with the same ID
|
|
|
dateRangeAttr=_extends(new _utils_attr_list__WEBPACK_IMPORTED_MODULE_1__.AttrList({}),previousAttr,dateRangeAttr);}this.attr=dateRangeAttr;this._startDate=new Date(dateRangeAttr[_DateRangeAttribute.START_DATE]);if(_DateRangeAttribute.END_DATE in this.attr){var endDate=new Date(this.attr[_DateRangeAttribute.END_DATE]);if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(endDate.getTime())){this._endDate=endDate;}}}_createClass(DateRange,[{key:"id",get:function get(){return this.attr.ID;}},{key:"class",get:function get(){return this.attr.CLASS;}},{key:"startDate",get:function get(){return this._startDate;}},{key:"endDate",get:function get(){if(this._endDate){return this._endDate;}var duration=this.duration;if(duration!==null){return new Date(this._startDate.getTime()+duration*1000);}return null;}},{key:"duration",get:function get(){if(_DateRangeAttribute.DURATION in this.attr){var duration=this.attr.decimalFloatingPoint(_DateRangeAttribute.DURATION);if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(duration)){return duration;}}else if(this._endDate){return(this._endDate.getTime()-this._startDate.getTime())/1000;}return null;}},{key:"plannedDuration",get:function get(){if(_DateRangeAttribute.PLANNED_DURATION in this.attr){return this.attr.decimalFloatingPoint(_DateRangeAttribute.PLANNED_DURATION);}return null;}},{key:"endOnNext",get:function get(){return this.attr.bool(_DateRangeAttribute.END_ON_NEXT);}},{key:"isValid",get:function get(){return!!this.id&&!this._badValueForSameId&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.startDate.getTime())&&(this.duration===null||this.duration>=0)&&(!this.endOnNext||!!this["class"]);}}]);return DateRange;}();/***/},/***/"./src/loader/fragment-loader.ts":/*!***************************************!*\
|
|
|
!*** ./src/loader/fragment-loader.ts ***!
|
|
|
\***************************************/ /***/function srcLoaderFragmentLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_588869__){"use strict";__nested_webpack_require_588869__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_588869__.d(__webpack_exports__,{/* harmony export */"LoadError":function LoadError(){return(/* binding */_LoadError);},/* harmony export */"default":function _default(){return(/* binding */FragmentLoader);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_588869__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_588869__(/*! ../errors */"./src/errors.ts");function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map():undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function");}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper);}function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor);}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class);};return _wrapNativeSuper(Class);}function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct.bind();}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor();if(Class)_setPrototypeOf(instance,Class.prototype);return instance;};}return _construct.apply(null,arguments);}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1;}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}var MIN_CHUNK_SIZE=Math.pow(2,17);// 128kb
|
|
|
var FragmentLoader=/*#__PURE__*/function(){function FragmentLoader(config){this.config=void 0;this.loader=null;this.partLoadTimeout=-1;this.config=config;}var _proto=FragmentLoader.prototype;_proto.destroy=function destroy(){if(this.loader){this.loader.destroy();this.loader=null;}};_proto.abort=function abort(){if(this.loader){// Abort the loader for current fragment. Only one may load at any given time
|
|
|
this.loader.abort();}};_proto.load=function load(frag,_onProgress){var _this=this;var url=frag.url;if(!url){return Promise.reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,fatal:false,frag:frag,networkDetails:null},"Fragment does not have a "+(url?'part list':'url')));}this.abort();var config=this.config;var FragmentILoader=config.fLoader;var DefaultILoader=config.loader;return new Promise(function(resolve,reject){if(_this.loader){_this.loader.destroy();}var loader=_this.loader=frag.loader=FragmentILoader?new FragmentILoader(config):new DefaultILoader(config);var loaderContext=createLoaderContext(frag);var loaderConfig={timeout:config.fragLoadingTimeOut,maxRetry:0,retryDelay:0,maxRetryDelay:config.fragLoadingMaxRetryTimeout,highWaterMark:frag.sn==='initSegment'?Infinity:MIN_CHUNK_SIZE};// Assign frag stats to the loader's stats reference
|
|
|
frag.stats=loader.stats;loader.load(loaderContext,loaderConfig,{onSuccess:function onSuccess(response,stats,context,networkDetails){_this.resetLoader(frag,loader);var payload=response.data;if(context.resetIV&&frag.decryptdata){frag.decryptdata.iv=new Uint8Array(payload.slice(0,16));payload=payload.slice(16);}resolve({frag:frag,part:null,payload:payload,networkDetails:networkDetails});},onError:function onError(response,context,networkDetails){_this.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,fatal:false,frag:frag,response:response,networkDetails:networkDetails}));},onAbort:function onAbort(stats,context,networkDetails){_this.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.INTERNAL_ABORTED,fatal:false,frag:frag,networkDetails:networkDetails}));},onTimeout:function onTimeout(response,context,networkDetails){_this.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_TIMEOUT,fatal:false,frag:frag,networkDetails:networkDetails}));},onProgress:function onProgress(stats,context,data,networkDetails){if(_onProgress){_onProgress({frag:frag,part:null,payload:data,networkDetails:networkDetails});}}});});};_proto.loadPart=function loadPart(frag,part,onProgress){var _this2=this;this.abort();var config=this.config;var FragmentILoader=config.fLoader;var DefaultILoader=config.loader;return new Promise(function(resolve,reject){if(_this2.loader){_this2.loader.destroy();}var loader=_this2.loader=frag.loader=FragmentILoader?new FragmentILoader(config):new DefaultILoader(config);var loaderContext=createLoaderContext(frag,part);var loaderConfig={timeout:config.fragLoadingTimeOut,maxRetry:0,retryDelay:0,maxRetryDelay:config.fragLoadingMaxRetryTimeout,highWaterMark:MIN_CHUNK_SIZE};// Assign part stats to the loader's stats reference
|
|
|
part.stats=loader.stats;loader.load(loaderContext,loaderConfig,{onSuccess:function onSuccess(response,stats,context,networkDetails){_this2.resetLoader(frag,loader);_this2.updateStatsFromPart(frag,part);var partLoadedData={frag:frag,part:part,payload:response.data,networkDetails:networkDetails};onProgress(partLoadedData);resolve(partLoadedData);},onError:function onError(response,context,networkDetails){_this2.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,fatal:false,frag:frag,part:part,response:response,networkDetails:networkDetails}));},onAbort:function onAbort(stats,context,networkDetails){frag.stats.aborted=part.stats.aborted;_this2.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.INTERNAL_ABORTED,fatal:false,frag:frag,part:part,networkDetails:networkDetails}));},onTimeout:function onTimeout(response,context,networkDetails){_this2.resetLoader(frag,loader);reject(new _LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_TIMEOUT,fatal:false,frag:frag,part:part,networkDetails:networkDetails}));}});});};_proto.updateStatsFromPart=function updateStatsFromPart(frag,part){var fragStats=frag.stats;var partStats=part.stats;var partTotal=partStats.total;fragStats.loaded+=partStats.loaded;if(partTotal){var estTotalParts=Math.round(frag.duration/part.duration);var estLoadedParts=Math.min(Math.round(fragStats.loaded/partTotal),estTotalParts);var estRemainingParts=estTotalParts-estLoadedParts;var estRemainingBytes=estRemainingParts*Math.round(fragStats.loaded/estLoadedParts);fragStats.total=fragStats.loaded+estRemainingBytes;}else{fragStats.total=Math.max(fragStats.loaded,fragStats.total);}var fragLoading=fragStats.loading;var partLoading=partStats.loading;if(fragLoading.start){// add to fragment loader latency
|
|
|
fragLoading.first+=partLoading.first-partLoading.start;}else{fragLoading.start=partLoading.start;fragLoading.first=partLoading.first;}fragLoading.end=partLoading.end;};_proto.resetLoader=function resetLoader(frag,loader){frag.loader=null;if(this.loader===loader){self.clearTimeout(this.partLoadTimeout);this.loader=null;}loader.destroy();};return FragmentLoader;}();function createLoaderContext(frag,part){if(part===void 0){part=null;}var segment=part||frag;var loaderContext={frag:frag,part:part,responseType:'arraybuffer',url:segment.url,headers:{},rangeStart:0,rangeEnd:0};var start=segment.byteRangeStartOffset;var end=segment.byteRangeEndOffset;if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(start)&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(end)){var _frag$decryptdata;var byteRangeStart=start;var byteRangeEnd=end;if(frag.sn==='initSegment'&&((_frag$decryptdata=frag.decryptdata)===null||_frag$decryptdata===void 0?void 0:_frag$decryptdata.method)==='AES-128'){// MAP segment encrypted with method 'AES-128', when served with HTTP Range,
|
|
|
// has the unencrypted size specified in the range.
|
|
|
// Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
|
|
|
var fragmentLen=end-start;if(fragmentLen%16){byteRangeEnd=end+(16-fragmentLen%16);}if(start!==0){loaderContext.resetIV=true;byteRangeStart=start-16;}}loaderContext.rangeStart=byteRangeStart;loaderContext.rangeEnd=byteRangeEnd;}return loaderContext;}var _LoadError=/*#__PURE__*/function(_Error){_inheritsLoose(LoadError,_Error);function LoadError(data){var _this3;for(var _len=arguments.length,params=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){params[_key-1]=arguments[_key];}_this3=_Error.call.apply(_Error,[this].concat(params))||this;_this3.data=void 0;_this3.data=data;return _this3;}return LoadError;}(/*#__PURE__*/_wrapNativeSuper(Error));/***/},/***/"./src/loader/fragment.ts":/*!********************************!*\
|
|
|
!*** ./src/loader/fragment.ts ***!
|
|
|
\********************************/ /***/function srcLoaderFragmentTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_599354__){"use strict";__nested_webpack_require_599354__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_599354__.d(__webpack_exports__,{/* harmony export */"BaseSegment":function BaseSegment(){return(/* binding */_BaseSegment3);},/* harmony export */"ElementaryStreamTypes":function ElementaryStreamTypes(){return(/* binding */_ElementaryStreamTypes);},/* harmony export */"Fragment":function Fragment(){return(/* binding */_Fragment);},/* harmony export */"Part":function Part(){return(/* binding */_Part);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_599354__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_599354__(/*! url-toolkit */"./node_modules/url-toolkit/src/url-toolkit.js");/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default=/*#__PURE__*/__nested_webpack_require_599354__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */var _load_stats__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_599354__(/*! ./load-stats */"./src/loader/load-stats.ts");function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var _ElementaryStreamTypes;(function(ElementaryStreamTypes){ElementaryStreamTypes["AUDIO"]="audio";ElementaryStreamTypes["VIDEO"]="video";ElementaryStreamTypes["AUDIOVIDEO"]="audiovideo";})(_ElementaryStreamTypes||(_ElementaryStreamTypes={}));var _BaseSegment3=/*#__PURE__*/function(){// baseurl is the URL to the playlist
|
|
|
// relurl is the portion of the URL that comes from inside the playlist.
|
|
|
// Holds the types of data this fragment supports
|
|
|
function BaseSegment(baseurl){var _this$elementaryStrea;this._byteRange=null;this._url=null;this.baseurl=void 0;this.relurl=void 0;this.elementaryStreams=(_this$elementaryStrea={},_this$elementaryStrea[_ElementaryStreamTypes.AUDIO]=null,_this$elementaryStrea[_ElementaryStreamTypes.VIDEO]=null,_this$elementaryStrea[_ElementaryStreamTypes.AUDIOVIDEO]=null,_this$elementaryStrea);this.baseurl=baseurl;}// setByteRange converts a EXT-X-BYTERANGE attribute into a two element array
|
|
|
var _proto=BaseSegment.prototype;_proto.setByteRange=function setByteRange(value,previous){var params=value.split('@',2);var byteRange=[];if(params.length===1){byteRange[0]=previous?previous.byteRangeEndOffset:0;}else{byteRange[0]=parseInt(params[1]);}byteRange[1]=parseInt(params[0])+byteRange[0];this._byteRange=byteRange;};_createClass(BaseSegment,[{key:"byteRange",get:function get(){if(!this._byteRange){return[];}return this._byteRange;}},{key:"byteRangeStartOffset",get:function get(){return this.byteRange[0];}},{key:"byteRangeEndOffset",get:function get(){return this.byteRange[1];}},{key:"url",get:function get(){if(!this._url&&this.baseurl&&this.relurl){this._url=(0,url_toolkit__WEBPACK_IMPORTED_MODULE_1__.buildAbsoluteURL)(this.baseurl,this.relurl,{alwaysNormalize:true});}return this._url||'';},set:function set(value){this._url=value;}}]);return BaseSegment;}();var _Fragment=/*#__PURE__*/function(_BaseSegment){_inheritsLoose(Fragment,_BaseSegment);// EXTINF has to be present for a m3u8 to be considered valid
|
|
|
// sn notates the sequence number for a segment, and if set to a string can be 'initSegment'
|
|
|
// levelkeys are the EXT-X-KEY tags that apply to this segment for decryption
|
|
|
// core difference from the private field _decryptdata is the lack of the initialized IV
|
|
|
// _decryptdata will set the IV for this segment based on the segment number in the fragment
|
|
|
// A string representing the fragment type
|
|
|
// A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading
|
|
|
// A reference to the key loader. Set while the key is loading, and removed afterwards. Used to abort key loading
|
|
|
// The level/track index to which the fragment belongs
|
|
|
// The continuity counter of the fragment
|
|
|
// The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.
|
|
|
// The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.
|
|
|
// The latest Presentation Time Stamp (PTS) appended to the buffer.
|
|
|
// The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete.
|
|
|
// The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete.
|
|
|
// The start time of the fragment, as listed in the manifest. Updated after transmux complete.
|
|
|
// Set by `updateFragPTSDTS` in level-helper
|
|
|
// The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.
|
|
|
// The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.
|
|
|
// Load/parse timing information
|
|
|
// A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered
|
|
|
// #EXTINF segment title
|
|
|
// The Media Initialization Section for this segment
|
|
|
// Fragment is the last fragment in the media playlist
|
|
|
function Fragment(type,baseurl){var _this;_this=_BaseSegment.call(this,baseurl)||this;_this._decryptdata=null;_this.rawProgramDateTime=null;_this.programDateTime=null;_this.tagList=[];_this.duration=0;_this.sn=0;_this.levelkeys=void 0;_this.type=void 0;_this.loader=null;_this.keyLoader=null;_this.level=-1;_this.cc=0;_this.startPTS=void 0;_this.endPTS=void 0;_this.appendedPTS=void 0;_this.startDTS=void 0;_this.endDTS=void 0;_this.start=0;_this.deltaPTS=void 0;_this.maxStartPTS=void 0;_this.minEndPTS=void 0;_this.stats=new _load_stats__WEBPACK_IMPORTED_MODULE_2__.LoadStats();_this.urlId=0;_this.data=void 0;_this.bitrateTest=false;_this.title=null;_this.initSegment=null;_this.endList=void 0;_this.type=type;return _this;}var _proto2=Fragment.prototype;_proto2.setKeyFormat=function setKeyFormat(keyFormat){if(this.levelkeys){var _key=this.levelkeys[keyFormat];if(_key&&!this._decryptdata){this._decryptdata=_key.getDecryptData(this.sn);}}};_proto2.abortRequests=function abortRequests(){var _this$loader,_this$keyLoader;(_this$loader=this.loader)===null||_this$loader===void 0?void 0:_this$loader.abort();(_this$keyLoader=this.keyLoader)===null||_this$keyLoader===void 0?void 0:_this$keyLoader.abort();};_proto2.setElementaryStreamInfo=function setElementaryStreamInfo(type,startPTS,endPTS,startDTS,endDTS,partial){if(partial===void 0){partial=false;}var elementaryStreams=this.elementaryStreams;var info=elementaryStreams[type];if(!info){elementaryStreams[type]={startPTS:startPTS,endPTS:endPTS,startDTS:startDTS,endDTS:endDTS,partial:partial};return;}info.startPTS=Math.min(info.startPTS,startPTS);info.endPTS=Math.max(info.endPTS,endPTS);info.startDTS=Math.min(info.startDTS,startDTS);info.endDTS=Math.max(info.endDTS,endDTS);};_proto2.clearElementaryStreamInfo=function clearElementaryStreamInfo(){var elementaryStreams=this.elementaryStreams;elementaryStreams[_ElementaryStreamTypes.AUDIO]=null;elementaryStreams[_ElementaryStreamTypes.VIDEO]=null;elementaryStreams[_ElementaryStreamTypes.AUDIOVIDEO]=null;};_createClass(Fragment,[{key:"decryptdata",get:function get(){var levelkeys=this.levelkeys;if(!levelkeys&&!this._decryptdata){return null;}if(!this._decryptdata&&this.levelkeys&&!this.levelkeys.NONE){var _key2=this.levelkeys.identity;if(_key2){this._decryptdata=_key2.getDecryptData(this.sn);}else{var keyFormats=Object.keys(this.levelkeys);if(keyFormats.length===1){return this._decryptdata=this.levelkeys[keyFormats[0]].getDecryptData(this.sn);}else{// Multiple keys. key-loader to call Fragment.setKeyFormat based on selected key-system.
|
|
|
}}}return this._decryptdata;}},{key:"end",get:function get(){return this.start+this.duration;}},{key:"endProgramDateTime",get:function get(){if(this.programDateTime===null){return null;}if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.programDateTime)){return null;}var duration=!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.duration)?0:this.duration;return this.programDateTime+duration*1000;}},{key:"encrypted",get:function get(){var _this$_decryptdata;// At the m3u8-parser level we need to add support for manifest signalled keyformats
|
|
|
// when we want the fragment to start reporting that it is encrypted.
|
|
|
// Currently, keyFormat will only be set for identity keys
|
|
|
if((_this$_decryptdata=this._decryptdata)!==null&&_this$_decryptdata!==void 0&&_this$_decryptdata.encrypted){return true;}else if(this.levelkeys){var keyFormats=Object.keys(this.levelkeys);var len=keyFormats.length;if(len>1||len===1&&this.levelkeys[keyFormats[0]].encrypted){return true;}}return false;}}]);return Fragment;}(_BaseSegment3);var _Part=/*#__PURE__*/function(_BaseSegment2){_inheritsLoose(Part,_BaseSegment2);function Part(partAttrs,frag,baseurl,index,previous){var _this2;_this2=_BaseSegment2.call(this,baseurl)||this;_this2.fragOffset=0;_this2.duration=0;_this2.gap=false;_this2.independent=false;_this2.relurl=void 0;_this2.fragment=void 0;_this2.index=void 0;_this2.stats=new _load_stats__WEBPACK_IMPORTED_MODULE_2__.LoadStats();_this2.duration=partAttrs.decimalFloatingPoint('DURATION');_this2.gap=partAttrs.bool('GAP');_this2.independent=partAttrs.bool('INDEPENDENT');_this2.relurl=partAttrs.enumeratedString('URI');_this2.fragment=frag;_this2.index=index;var byteRange=partAttrs.enumeratedString('BYTERANGE');if(byteRange){_this2.setByteRange(byteRange,previous);}if(previous){_this2.fragOffset=previous.fragOffset+previous.duration;}return _this2;}_createClass(Part,[{key:"start",get:function get(){return this.fragment.start+this.fragOffset;}},{key:"end",get:function get(){return this.start+this.duration;}},{key:"loaded",get:function get(){var elementaryStreams=this.elementaryStreams;return!!(elementaryStreams.audio||elementaryStreams.video||elementaryStreams.audiovideo);}}]);return Part;}(_BaseSegment3);/***/},/***/"./src/loader/key-loader.ts":/*!**********************************!*\
|
|
|
!*** ./src/loader/key-loader.ts ***!
|
|
|
\**********************************/ /***/function srcLoaderKeyLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_610739__){"use strict";__nested_webpack_require_610739__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_610739__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */KeyLoader);}/* harmony export */});/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_610739__(/*! ../errors */"./src/errors.ts");/* harmony import */var _fragment_loader__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_610739__(/*! ./fragment-loader */"./src/loader/fragment-loader.ts");var KeyLoader=/*#__PURE__*/function(){function KeyLoader(config){this.config=void 0;this.keyUriToKeyInfo={};this.emeController=null;this.config=config;}var _proto=KeyLoader.prototype;_proto.abort=function abort(){for(var uri in this.keyUriToKeyInfo){var loader=this.keyUriToKeyInfo[uri].loader;if(loader){loader.abort();}}};_proto.detach=function detach(){for(var uri in this.keyUriToKeyInfo){var keyInfo=this.keyUriToKeyInfo[uri];// Remove cached EME keys on detach
|
|
|
if(keyInfo.mediaKeySessionContext||keyInfo.decryptdata.isCommonEncryption){delete this.keyUriToKeyInfo[uri];}}};_proto.destroy=function destroy(){this.detach();for(var uri in this.keyUriToKeyInfo){var loader=this.keyUriToKeyInfo[uri].loader;if(loader){loader.destroy();}}this.keyUriToKeyInfo={};};_proto.createKeyLoadError=function createKeyLoadError(frag,details,networkDetails,message){if(details===void 0){details=_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR;}return new _fragment_loader__WEBPACK_IMPORTED_MODULE_1__.LoadError({type:_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.NETWORK_ERROR,details:details,fatal:false,frag:frag,networkDetails:networkDetails});};_proto.loadClear=function loadClear(loadingFrag,encryptedFragments){var _this=this;if(this.emeController&&this.config.emeEnabled){// access key-system with nearest key on start (loaidng frag is unencrypted)
|
|
|
var sn=loadingFrag.sn,cc=loadingFrag.cc;var _loop=function _loop(i){var frag=encryptedFragments[i];if(cc<=frag.cc&&(sn==='initSegment'||sn<frag.sn)){_this.emeController.selectKeySystemFormat(frag).then(function(keySystemFormat){frag.setKeyFormat(keySystemFormat);});return"break";}};for(var i=0;i<encryptedFragments.length;i++){var _ret=_loop(i);if(_ret==="break")break;}}};_proto.load=function load(frag){var _this2=this;if(!frag.decryptdata&&frag.encrypted&&this.emeController){// Multiple keys, but none selected, resolve in eme-controller
|
|
|
return this.emeController.selectKeySystemFormat(frag).then(function(keySystemFormat){return _this2.loadInternal(frag,keySystemFormat);});}return this.loadInternal(frag);};_proto.loadInternal=function loadInternal(frag,keySystemFormat){var _keyInfo,_keyInfo2;if(keySystemFormat){frag.setKeyFormat(keySystemFormat);}var decryptdata=frag.decryptdata;if(!decryptdata){var errorMessage=keySystemFormat?"Expected frag.decryptdata to be defined after setting format "+keySystemFormat:'Missing decryption data on fragment in onKeyLoading';return Promise.reject(this.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR,null,errorMessage));}var uri=decryptdata.uri;if(!uri){return Promise.reject(this.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR,null,"Invalid key URI: \""+uri+"\""));}var keyInfo=this.keyUriToKeyInfo[uri];if((_keyInfo=keyInfo)!==null&&_keyInfo!==void 0&&_keyInfo.decryptdata.key){decryptdata.key=keyInfo.decryptdata.key;return Promise.resolve({frag:frag,keyInfo:keyInfo});}// Return key load promise as long as it does not have a mediakey session with an unusable key status
|
|
|
if((_keyInfo2=keyInfo)!==null&&_keyInfo2!==void 0&&_keyInfo2.keyLoadPromise){var _keyInfo$mediaKeySess;switch((_keyInfo$mediaKeySess=keyInfo.mediaKeySessionContext)===null||_keyInfo$mediaKeySess===void 0?void 0:_keyInfo$mediaKeySess.keyStatus){case undefined:case'status-pending':case'usable':case'usable-in-future':return keyInfo.keyLoadPromise.then(function(keyLoadedData){// Return the correct fragment with updated decryptdata key and loaded keyInfo
|
|
|
decryptdata.key=keyLoadedData.keyInfo.decryptdata.key;return{frag:frag,keyInfo:keyInfo};});}// If we have a key session and status and it is not pending or usable, continue
|
|
|
// This will go back to the eme-controller for expired keys to get a new keyLoadPromise
|
|
|
}// Load the key or return the loading promise
|
|
|
keyInfo=this.keyUriToKeyInfo[uri]={decryptdata:decryptdata,keyLoadPromise:null,loader:null,mediaKeySessionContext:null};switch(decryptdata.method){case'ISO-23001-7':case'SAMPLE-AES':case'SAMPLE-AES-CENC':case'SAMPLE-AES-CTR':if(decryptdata.keyFormat==='identity'){// loadKeyHTTP handles http(s) and data URLs
|
|
|
return this.loadKeyHTTP(keyInfo,frag);}return this.loadKeyEME(keyInfo,frag);case'AES-128':return this.loadKeyHTTP(keyInfo,frag);default:return Promise.reject(this.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR,null,"Key supplied with unsupported METHOD: \""+decryptdata.method+"\""));}};_proto.loadKeyEME=function loadKeyEME(keyInfo,frag){var keyLoadedData={frag:frag,keyInfo:keyInfo};if(this.emeController&&this.config.emeEnabled){var keySessionContextPromise=this.emeController.loadKey(keyLoadedData);if(keySessionContextPromise){return(keyInfo.keyLoadPromise=keySessionContextPromise.then(function(keySessionContext){keyInfo.mediaKeySessionContext=keySessionContext;return keyLoadedData;}))["catch"](function(error){// Remove promise for license renewal or retry
|
|
|
keyInfo.keyLoadPromise=null;throw error;});}}return Promise.resolve(keyLoadedData);};_proto.loadKeyHTTP=function loadKeyHTTP(keyInfo,frag){var _this3=this;var config=this.config;var Loader=config.loader;var keyLoader=new Loader(config);frag.keyLoader=keyInfo.loader=keyLoader;return keyInfo.keyLoadPromise=new Promise(function(resolve,reject){var loaderContext={keyInfo:keyInfo,frag:frag,responseType:'arraybuffer',url:keyInfo.decryptdata.uri};// maxRetry is 0 so that instead of retrying the same key on the same variant multiple times,
|
|
|
// key-loader will trigger an error and rely on stream-controller to handle retry logic.
|
|
|
// this will also align retry logic with fragment-loader
|
|
|
var loaderConfig={timeout:config.fragLoadingTimeOut,maxRetry:0,retryDelay:config.fragLoadingRetryDelay,maxRetryDelay:config.fragLoadingMaxRetryTimeout,highWaterMark:0};var loaderCallbacks={onSuccess:function onSuccess(response,stats,context,networkDetails){var frag=context.frag,keyInfo=context.keyInfo,uri=context.url;if(!frag.decryptdata||keyInfo!==_this3.keyUriToKeyInfo[uri]){return reject(_this3.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR,networkDetails,'after key load, decryptdata unset or changed'));}keyInfo.decryptdata.key=frag.decryptdata.key=new Uint8Array(response.data);// detach fragment key loader on load success
|
|
|
frag.keyLoader=null;keyInfo.loader=null;resolve({frag:frag,keyInfo:keyInfo});},onError:function onError(error,context,networkDetails){_this3.resetLoader(context);reject(_this3.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR,networkDetails));},onTimeout:function onTimeout(stats,context,networkDetails){_this3.resetLoader(context);reject(_this3.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_TIMEOUT,networkDetails));},onAbort:function onAbort(stats,context,networkDetails){_this3.resetLoader(context);reject(_this3.createKeyLoadError(frag,_errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.INTERNAL_ABORTED,networkDetails));}};keyLoader.load(loaderContext,loaderConfig,loaderCallbacks);});};_proto.resetLoader=function resetLoader(context){var frag=context.frag,keyInfo=context.keyInfo,uri=context.url;var loader=keyInfo.loader;if(frag.keyLoader===loader){frag.keyLoader=null;keyInfo.loader=null;}delete this.keyUriToKeyInfo[uri];if(loader){loader.destroy();}};return KeyLoader;}();/***/},/***/"./src/loader/level-details.ts":/*!*************************************!*\
|
|
|
!*** ./src/loader/level-details.ts ***!
|
|
|
\*************************************/ /***/function srcLoaderLevelDetailsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_618871__){"use strict";__nested_webpack_require_618871__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_618871__.d(__webpack_exports__,{/* harmony export */"LevelDetails":function LevelDetails(){return(/* binding */_LevelDetails);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_618871__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var DEFAULT_TARGET_DURATION=10;var _LevelDetails=/*#__PURE__*/function(){// Manifest reload synchronization
|
|
|
function LevelDetails(baseUrl){this.PTSKnown=false;this.alignedSliding=false;this.averagetargetduration=void 0;this.endCC=0;this.endSN=0;this.fragments=void 0;this.fragmentHint=void 0;this.partList=null;this.dateRanges=void 0;this.live=true;this.ageHeader=0;this.advancedDateTime=void 0;this.updated=true;this.advanced=true;this.availabilityDelay=void 0;this.misses=0;this.startCC=0;this.startSN=0;this.startTimeOffset=null;this.targetduration=0;this.totalduration=0;this.type=null;this.url=void 0;this.m3u8='';this.version=null;this.canBlockReload=false;this.canSkipUntil=0;this.canSkipDateRanges=false;this.skippedSegments=0;this.recentlyRemovedDateranges=void 0;this.partHoldBack=0;this.holdBack=0;this.partTarget=0;this.preloadHint=void 0;this.renditionReports=void 0;this.tuneInGoal=0;this.deltaUpdateFailed=void 0;this.driftStartTime=0;this.driftEndTime=0;this.driftStart=0;this.driftEnd=0;this.encryptedFragments=void 0;this.fragments=[];this.encryptedFragments=[];this.dateRanges={};this.url=baseUrl;}var _proto=LevelDetails.prototype;_proto.reloaded=function reloaded(previous){if(!previous){this.advanced=true;this.updated=true;return;}var partSnDiff=this.lastPartSn-previous.lastPartSn;var partIndexDiff=this.lastPartIndex-previous.lastPartIndex;this.updated=this.endSN!==previous.endSN||!!partIndexDiff||!!partSnDiff;this.advanced=this.endSN>previous.endSN||partSnDiff>0||partSnDiff===0&&partIndexDiff>0;if(this.updated||this.advanced){this.misses=Math.floor(previous.misses*0.6);}else{this.misses=previous.misses+1;}this.availabilityDelay=previous.availabilityDelay;};_createClass(LevelDetails,[{key:"hasProgramDateTime",get:function get(){if(this.fragments.length){return(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.fragments[this.fragments.length-1].programDateTime);}return false;}},{key:"levelTargetDuration",get:function get(){return this.averagetargetduration||this.targetduration||DEFAULT_TARGET_DURATION;}},{key:"drift",get:function get(){var runTime=this.driftEndTime-this.driftStartTime;if(runTime>0){var runDuration=this.driftEnd-this.driftStart;return runDuration*1000/runTime;}return 1;}},{key:"edge",get:function get(){return this.partEnd||this.fragmentEnd;}},{key:"partEnd",get:function get(){var _this$partList;if((_this$partList=this.partList)!==null&&_this$partList!==void 0&&_this$partList.length){return this.partList[this.partList.length-1].end;}return this.fragmentEnd;}},{key:"fragmentEnd",get:function get(){var _this$fragments;if((_this$fragments=this.fragments)!==null&&_this$fragments!==void 0&&_this$fragments.length){return this.fragments[this.fragments.length-1].end;}return 0;}},{key:"age",get:function get(){if(this.advancedDateTime){return Math.max(Date.now()-this.advancedDateTime,0)/1000;}return 0;}},{key:"lastPartIndex",get:function get(){var _this$partList2;if((_this$partList2=this.partList)!==null&&_this$partList2!==void 0&&_this$partList2.length){return this.partList[this.partList.length-1].index;}return-1;}},{key:"lastPartSn",get:function get(){var _this$partList3;if((_this$partList3=this.partList)!==null&&_this$partList3!==void 0&&_this$partList3.length){return this.partList[this.partList.length-1].fragment.sn;}return this.endSN;}}]);return LevelDetails;}();/***/},/***/"./src/loader/level-key.ts":/*!*********************************!*\
|
|
|
!*** ./src/loader/level-key.ts ***!
|
|
|
\*********************************/ /***/function srcLoaderLevelKeyTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_623955__){"use strict";__nested_webpack_require_623955__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_623955__.d(__webpack_exports__,{/* harmony export */"LevelKey":function LevelKey(){return(/* binding */_LevelKey);}/* harmony export */});/* harmony import */var _utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_623955__(/*! ../utils/keysystem-util */"./src/utils/keysystem-util.ts");/* harmony import */var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_623955__(/*! ../utils/mediakeys-helper */"./src/utils/mediakeys-helper.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_623955__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_623955__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_623955__(/*! ../utils/numeric-encoding-utils */"./src/utils/numeric-encoding-utils.ts");var keyUriToKeyIdMap={};var _LevelKey=/*#__PURE__*/function(){LevelKey.clearKeyUriToKeyIdMap=function clearKeyUriToKeyIdMap(){keyUriToKeyIdMap={};};function LevelKey(method,uri,format,formatversions,iv){if(formatversions===void 0){formatversions=[1];}if(iv===void 0){iv=null;}this.uri=void 0;this.method=void 0;this.keyFormat=void 0;this.keyFormatVersions=void 0;this.encrypted=void 0;this.isCommonEncryption=void 0;this.iv=null;this.key=null;this.keyId=null;this.pssh=null;this.method=method;this.uri=uri;this.keyFormat=format;this.keyFormatVersions=formatversions;this.iv=iv;this.encrypted=method?method!=='NONE':false;this.isCommonEncryption=this.encrypted&&method!=='AES-128';}var _proto=LevelKey.prototype;_proto.isSupported=function isSupported(){// If it's Segment encryption or No encryption, just select that key system
|
|
|
if(this.method){if(this.method==='AES-128'||this.method==='NONE'){return true;}switch(this.keyFormat){case'identity':// Maintain support for clear SAMPLE-AES with MPEG-3 TS
|
|
|
return this.method==='SAMPLE-AES';case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.FAIRPLAY:case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.WIDEVINE:case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.PLAYREADY:case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.CLEARKEY:return['ISO-23001-7','SAMPLE-AES','SAMPLE-AES-CENC','SAMPLE-AES-CTR'].indexOf(this.method)!==-1;}}return false;};_proto.getDecryptData=function getDecryptData(sn){if(!this.encrypted||!this.uri){return null;}if(this.method==='AES-128'&&this.uri&&!this.iv){if(typeof sn!=='number'){// We are fetching decryption data for a initialization segment
|
|
|
// If the segment was encrypted with AES-128
|
|
|
// It must have an IV defined. We cannot substitute the Segment Number in.
|
|
|
if(this.method==='AES-128'&&!this.iv){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("missing IV for initialization segment with method=\""+this.method+"\" - compliance issue");}// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
|
|
|
sn=0;}var iv=createInitializationVector(sn);var decryptdata=new LevelKey(this.method,this.uri,'identity',this.keyFormatVersions,iv);return decryptdata;}// Initialize keyId if possible
|
|
|
var keyBytes=(0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__.convertDataUriToArrayBytes)(this.uri);if(keyBytes){switch(this.keyFormat){case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.WIDEVINE:this.pssh=keyBytes;// In case of widevine keyID is embedded in PSSH box. Read Key ID.
|
|
|
if(keyBytes.length>=22){this.keyId=keyBytes.subarray(keyBytes.length-22,keyBytes.length-6);}break;case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.PLAYREADY:{var PlayReadyKeySystemUUID=new Uint8Array([0x9a,0x04,0xf0,0x79,0x98,0x40,0x42,0x86,0xab,0x92,0xe6,0x5b,0xe0,0x88,0x5f,0x95]);this.pssh=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.mp4pssh)(PlayReadyKeySystemUUID,null,keyBytes);var keyBytesUtf16=new Uint16Array(keyBytes.buffer,keyBytes.byteOffset,keyBytes.byteLength/2);var keyByteStr=String.fromCharCode.apply(null,Array.from(keyBytesUtf16));// Parse Playready WRMHeader XML
|
|
|
var xmlKeyBytes=keyByteStr.substring(keyByteStr.indexOf('<'),keyByteStr.length);var parser=new DOMParser();var xmlDoc=parser.parseFromString(xmlKeyBytes,'text/xml');var keyData=xmlDoc.getElementsByTagName('KID')[0];if(keyData){var keyId=keyData.childNodes[0]?keyData.childNodes[0].nodeValue:keyData.getAttribute('VALUE');if(keyId){var keyIdArray=(0,_utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_4__.base64Decode)(keyId).subarray(0,16);// KID value in PRO is a base64-encoded little endian GUID interpretation of UUID
|
|
|
// KID value in ‘tenc’ is a big endian UUID GUID interpretation of UUID
|
|
|
(0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__.changeEndianness)(keyIdArray);this.keyId=keyIdArray;}}break;}default:{var keydata=keyBytes.subarray(0,16);if(keydata.length!==16){var padded=new Uint8Array(16);padded.set(keydata,16-keydata.length);keydata=padded;}this.keyId=keydata;break;}}}// Default behavior: assign a new keyId for each uri
|
|
|
if(!this.keyId||this.keyId.byteLength!==16){var _keyId=keyUriToKeyIdMap[this.uri];if(!_keyId){var val=Object.keys(keyUriToKeyIdMap).length%Number.MAX_SAFE_INTEGER;_keyId=new Uint8Array(16);var dv=new DataView(_keyId.buffer,12,4);// Just set the last 4 bytes
|
|
|
dv.setUint32(0,val);keyUriToKeyIdMap[this.uri]=_keyId;}this.keyId=_keyId;}return this;};return LevelKey;}();function createInitializationVector(segmentNumber){var uint8View=new Uint8Array(16);for(var i=12;i<16;i++){uint8View[i]=segmentNumber>>8*(15-i)&0xff;}return uint8View;}/***/},/***/"./src/loader/load-stats.ts":/*!**********************************!*\
|
|
|
!*** ./src/loader/load-stats.ts ***!
|
|
|
\**********************************/ /***/function srcLoaderLoadStatsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_629940__){"use strict";__nested_webpack_require_629940__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_629940__.d(__webpack_exports__,{/* harmony export */"LoadStats":function LoadStats(){return(/* binding */_LoadStats);}/* harmony export */});var _LoadStats=function LoadStats(){this.aborted=false;this.loaded=0;this.retry=0;this.total=0;this.chunkCount=0;this.bwEstimate=0;this.loading={start:0,first:0,end:0};this.parsing={start:0,end:0};this.buffering={start:0,first:0,end:0};};/***/},/***/"./src/loader/m3u8-parser.ts":/*!***********************************!*\
|
|
|
!*** ./src/loader/m3u8-parser.ts ***!
|
|
|
\***********************************/ /***/function srcLoaderM3u8ParserTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_630671__){"use strict";__nested_webpack_require_630671__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_630671__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */M3U8Parser);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_630671__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_630671__(/*! url-toolkit */"./node_modules/url-toolkit/src/url-toolkit.js");/* harmony import */var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default=/*#__PURE__*/__nested_webpack_require_630671__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */var _date_range__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_630671__(/*! ./date-range */"./src/loader/date-range.ts");/* harmony import */var _fragment__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_630671__(/*! ./fragment */"./src/loader/fragment.ts");/* harmony import */var _level_details__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_630671__(/*! ./level-details */"./src/loader/level-details.ts");/* harmony import */var _level_key__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_630671__(/*! ./level-key */"./src/loader/level-key.ts");/* harmony import */var _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_630671__(/*! ../utils/attr-list */"./src/utils/attr-list.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_630671__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _utils_codecs__WEBPACK_IMPORTED_MODULE_8__=__nested_webpack_require_630671__(/*! ../utils/codecs */"./src/utils/codecs.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}// https://regex101.com is your friend
|
|
|
var MASTER_PLAYLIST_REGEX=/#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-SESSION-DATA:([^\r\n]*)[\r\n]+|#EXT-X-SESSION-KEY:([^\n\r]*)[\r\n]+/g;var MASTER_PLAYLIST_MEDIA_REGEX=/#EXT-X-MEDIA:(.*)/g;var LEVEL_PLAYLIST_REGEX_FAST=new RegExp([/#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source,// duration (#EXTINF:<duration>,<title>), group 1 => duration, group 2 => title
|
|
|
/(?!#) *(\S[\S ]*)/.source,// segment URI, group 3 => the URI (note newline is not eaten)
|
|
|
/#EXT-X-BYTERANGE:*(.+)/.source,// next segment's byterange, group 4 => range spec (x@y)
|
|
|
/#EXT-X-PROGRAM-DATE-TIME:(.+)/.source,// next segment's program date/time group 5 => the datetime spec
|
|
|
/#.*/.source// All other non-segment oriented tags will match with all groups empty
|
|
|
].join('|'),'g');var LEVEL_PLAYLIST_REGEX_SLOW=new RegExp([/#(EXTM3U)/.source,/#EXT-X-(DATERANGE|KEY|MAP|PART|PART-INF|PLAYLIST-TYPE|PRELOAD-HINT|RENDITION-REPORT|SERVER-CONTROL|SKIP|START):(.+)/.source,/#EXT-X-(BITRATE|DISCONTINUITY-SEQUENCE|MEDIA-SEQUENCE|TARGETDURATION|VERSION): *(\d+)/.source,/#EXT-X-(DISCONTINUITY|ENDLIST|GAP)/.source,/(#)([^:]*):(.*)/.source,/(#)(.*)(?:.*)\r?\n?/.source].join('|'));var M3U8Parser=/*#__PURE__*/function(){function M3U8Parser(){}M3U8Parser.findGroup=function findGroup(groups,mediaGroupId){for(var i=0;i<groups.length;i++){var group=groups[i];if(group.id===mediaGroupId){return group;}}};M3U8Parser.convertAVC1ToAVCOTI=function convertAVC1ToAVCOTI(codec){// Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported
|
|
|
var avcdata=codec.split('.');if(avcdata.length>2){var result=avcdata.shift()+'.';result+=parseInt(avcdata.shift()).toString(16);result+=('000'+parseInt(avcdata.shift()).toString(16)).slice(-4);return result;}return codec;};M3U8Parser.resolve=function resolve(url,baseUrl){return(0,url_toolkit__WEBPACK_IMPORTED_MODULE_1__.buildAbsoluteURL)(baseUrl,url,{alwaysNormalize:true});};M3U8Parser.parseMasterPlaylist=function parseMasterPlaylist(string,baseurl){var levels=[];var levelsWithKnownCodecs=[];var sessionData={};var sessionKeys=[];var hasSessionData=false;MASTER_PLAYLIST_REGEX.lastIndex=0;var result;while((result=MASTER_PLAYLIST_REGEX.exec(string))!=null){if(result[1]){var _level$unknownCodecs;// '#EXT-X-STREAM-INF' is found, parse level tag in group 1
|
|
|
var attrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[1]);var level={attrs:attrs,bitrate:attrs.decimalInteger('AVERAGE-BANDWIDTH')||attrs.decimalInteger('BANDWIDTH'),name:attrs.NAME,url:M3U8Parser.resolve(result[2],baseurl)};var resolution=attrs.decimalResolution('RESOLUTION');if(resolution){level.width=resolution.width;level.height=resolution.height;}setCodecs((attrs.CODECS||'').split(/[ ,]+/).filter(function(c){return c;}),level);if(level.videoCodec&&level.videoCodec.indexOf('avc1')!==-1){level.videoCodec=M3U8Parser.convertAVC1ToAVCOTI(level.videoCodec);}if(!((_level$unknownCodecs=level.unknownCodecs)!==null&&_level$unknownCodecs!==void 0&&_level$unknownCodecs.length)){levelsWithKnownCodecs.push(level);}levels.push(level);}else if(result[3]){// '#EXT-X-SESSION-DATA' is found, parse session data in group 3
|
|
|
var sessionAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[3]);if(sessionAttrs['DATA-ID']){hasSessionData=true;sessionData[sessionAttrs['DATA-ID']]=sessionAttrs;}}else if(result[4]){// '#EXT-X-SESSION-KEY' is found
|
|
|
var keyTag=result[4];var sessionKey=parseKey(keyTag,baseurl);if(sessionKey.encrypted&&sessionKey.isSupported()){sessionKeys.push(sessionKey);}else{_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: \""+keyTag+"\"");}}}// Filter out levels with unknown codecs if it does not remove all levels
|
|
|
var stripUnknownCodecLevels=levelsWithKnownCodecs.length>0&&levelsWithKnownCodecs.length<levels.length;return{levels:stripUnknownCodecLevels?levelsWithKnownCodecs:levels,sessionData:hasSessionData?sessionData:null,sessionKeys:sessionKeys.length?sessionKeys:null};};M3U8Parser.parseMasterPlaylistMedia=function parseMasterPlaylistMedia(string,baseurl,type,groups){if(groups===void 0){groups=[];}var result;var medias=[];var id=0;MASTER_PLAYLIST_MEDIA_REGEX.lastIndex=0;while((result=MASTER_PLAYLIST_MEDIA_REGEX.exec(string))!==null){var attrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[1]);if(attrs.TYPE===type){var media={attrs:attrs,bitrate:0,id:id++,groupId:attrs['GROUP-ID'],instreamId:attrs['INSTREAM-ID'],name:attrs.NAME||attrs.LANGUAGE||'',type:type,"default":attrs.bool('DEFAULT'),autoselect:attrs.bool('AUTOSELECT'),forced:attrs.bool('FORCED'),lang:attrs.LANGUAGE,url:attrs.URI?M3U8Parser.resolve(attrs.URI,baseurl):''};if(groups.length){// If there are audio or text groups signalled in the manifest, let's look for a matching codec string for this track
|
|
|
// If we don't find the track signalled, lets use the first audio groups codec we have
|
|
|
// Acting as a best guess
|
|
|
var groupCodec=M3U8Parser.findGroup(groups,media.groupId)||groups[0];assignCodec(media,groupCodec,'audioCodec');assignCodec(media,groupCodec,'textCodec');}medias.push(media);}}return medias;};M3U8Parser.parseLevelPlaylist=function parseLevelPlaylist(string,baseurl,id,type,levelUrlId){var level=new _level_details__WEBPACK_IMPORTED_MODULE_4__.LevelDetails(baseurl);var fragments=level.fragments;// The most recent init segment seen (applies to all subsequent segments)
|
|
|
var currentInitSegment=null;var currentSN=0;var currentPart=0;var totalduration=0;var discontinuityCounter=0;var prevFrag=null;var frag=new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type,baseurl);var result;var i;var levelkeys;var firstPdtIndex=-1;var createNextFrag=false;LEVEL_PLAYLIST_REGEX_FAST.lastIndex=0;level.m3u8=string;while((result=LEVEL_PLAYLIST_REGEX_FAST.exec(string))!==null){if(createNextFrag){createNextFrag=false;frag=new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type,baseurl);// setup the next fragment for part loading
|
|
|
frag.start=totalduration;frag.sn=currentSN;frag.cc=discontinuityCounter;frag.level=id;if(currentInitSegment){frag.initSegment=currentInitSegment;frag.rawProgramDateTime=currentInitSegment.rawProgramDateTime;currentInitSegment.rawProgramDateTime=null;}}var duration=result[1];if(duration){// INF
|
|
|
frag.duration=parseFloat(duration);// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
|
|
|
var title=(' '+result[2]).slice(1);frag.title=title||null;frag.tagList.push(title?['INF',duration,title]:['INF',duration]);}else if(result[3]){// url
|
|
|
if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.duration)){frag.start=totalduration;if(levelkeys){setFragLevelKeys(frag,levelkeys,level);}frag.sn=currentSN;frag.level=id;frag.cc=discontinuityCounter;frag.urlId=levelUrlId;fragments.push(frag);// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
|
|
|
frag.relurl=(' '+result[3]).slice(1);assignProgramDateTime(frag,prevFrag);prevFrag=frag;totalduration+=frag.duration;currentSN++;currentPart=0;createNextFrag=true;}}else if(result[4]){// X-BYTERANGE
|
|
|
var data=(' '+result[4]).slice(1);if(prevFrag){frag.setByteRange(data,prevFrag);}else{frag.setByteRange(data);}}else if(result[5]){// PROGRAM-DATE-TIME
|
|
|
// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
|
|
|
frag.rawProgramDateTime=(' '+result[5]).slice(1);frag.tagList.push(['PROGRAM-DATE-TIME',frag.rawProgramDateTime]);if(firstPdtIndex===-1){firstPdtIndex=fragments.length;}}else{result=result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);if(!result){_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn('No matches on slow regex match for level playlist!');continue;}for(i=1;i<result.length;i++){if(typeof result[i]!=='undefined'){break;}}// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
|
|
|
var tag=(' '+result[i]).slice(1);var value1=(' '+result[i+1]).slice(1);var value2=result[i+2]?(' '+result[i+2]).slice(1):'';switch(tag){case'PLAYLIST-TYPE':level.type=value1.toUpperCase();break;case'MEDIA-SEQUENCE':currentSN=level.startSN=parseInt(value1);break;case'SKIP':{var skipAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);var skippedSegments=skipAttrs.decimalInteger('SKIPPED-SEGMENTS');if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(skippedSegments)){level.skippedSegments=skippedSegments;// This will result in fragments[] containing undefined values, which we will fill in with `mergeDetails`
|
|
|
for(var _i=skippedSegments;_i--;){fragments.unshift(null);}currentSN+=skippedSegments;}var recentlyRemovedDateranges=skipAttrs.enumeratedString('RECENTLY-REMOVED-DATERANGES');if(recentlyRemovedDateranges){level.recentlyRemovedDateranges=recentlyRemovedDateranges.split('\t');}break;}case'TARGETDURATION':level.targetduration=parseFloat(value1);break;case'VERSION':level.version=parseInt(value1);break;case'EXTM3U':break;case'ENDLIST':level.live=false;break;case'#':if(value1||value2){frag.tagList.push(value2?[value1,value2]:[value1]);}break;case'DISCONTINUITY':discontinuityCounter++;frag.tagList.push(['DIS']);break;case'GAP':frag.tagList.push([tag]);break;case'BITRATE':frag.tagList.push([tag,value1]);break;case'DATERANGE':{var dateRangeAttr=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);var dateRange=new _date_range__WEBPACK_IMPORTED_MODULE_2__.DateRange(dateRangeAttr,level.dateRanges[dateRangeAttr.ID]);if(dateRange.isValid||level.skippedSegments){level.dateRanges[dateRange.id]=dateRange;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("Ignoring invalid DATERANGE tag: \""+value1+"\"");}// Add to fragment tag list for backwards compatibility (< v1.2.0)
|
|
|
frag.tagList.push(['EXT-X-DATERANGE',value1]);break;}case'DISCONTINUITY-SEQUENCE':discontinuityCounter=parseInt(value1);break;case'KEY':{var levelKey=parseKey(value1,baseurl);if(levelKey.isSupported()){if(levelKey.method==='NONE'){levelkeys=undefined;break;}if(!levelkeys){levelkeys={};}if(levelkeys[levelKey.keyFormat]){levelkeys=_extends({},levelkeys);}levelkeys[levelKey.keyFormat]=levelKey;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("[Keys] Ignoring invalid EXT-X-KEY tag: \""+value1+"\"");}break;}case'START':{var startAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);var startTimeOffset=startAttrs.decimalFloatingPoint('TIME-OFFSET');// TIME-OFFSET can be 0
|
|
|
if((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(startTimeOffset)){level.startTimeOffset=startTimeOffset;}break;}case'MAP':{var mapAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);if(frag.duration){// Initial segment tag is after segment duration tag.
|
|
|
// #EXTINF: 6.0
|
|
|
// #EXT-X-MAP:URI="init.mp4
|
|
|
var init=new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type,baseurl);setInitSegment(init,mapAttrs,id,levelkeys);currentInitSegment=init;frag.initSegment=currentInitSegment;if(currentInitSegment.rawProgramDateTime&&!frag.rawProgramDateTime){frag.rawProgramDateTime=currentInitSegment.rawProgramDateTime;}}else{// Initial segment tag is before segment duration tag
|
|
|
setInitSegment(frag,mapAttrs,id,levelkeys);currentInitSegment=frag;createNextFrag=true;}break;}case'SERVER-CONTROL':{var serverControlAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);level.canBlockReload=serverControlAttrs.bool('CAN-BLOCK-RELOAD');level.canSkipUntil=serverControlAttrs.optionalFloat('CAN-SKIP-UNTIL',0);level.canSkipDateRanges=level.canSkipUntil>0&&serverControlAttrs.bool('CAN-SKIP-DATERANGES');level.partHoldBack=serverControlAttrs.optionalFloat('PART-HOLD-BACK',0);level.holdBack=serverControlAttrs.optionalFloat('HOLD-BACK',0);break;}case'PART-INF':{var partInfAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);level.partTarget=partInfAttrs.decimalFloatingPoint('PART-TARGET');break;}case'PART':{var partList=level.partList;if(!partList){partList=level.partList=[];}var previousFragmentPart=currentPart>0?partList[partList.length-1]:undefined;var index=currentPart++;var part=new _fragment__WEBPACK_IMPORTED_MODULE_3__.Part(new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1),frag,baseurl,index,previousFragmentPart);partList.push(part);frag.duration+=part.duration;break;}case'PRELOAD-HINT':{var preloadHintAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);level.preloadHint=preloadHintAttrs;break;}case'RENDITION-REPORT':{var renditionReportAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);level.renditionReports=level.renditionReports||[];level.renditionReports.push(renditionReportAttrs);break;}default:_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("line parsed but not handled: "+result);break;}}}if(prevFrag&&!prevFrag.relurl){fragments.pop();totalduration-=prevFrag.duration;if(level.partList){level.fragmentHint=prevFrag;}}else if(level.partList){assignProgramDateTime(frag,prevFrag);frag.cc=discontinuityCounter;level.fragmentHint=frag;if(levelkeys){setFragLevelKeys(frag,levelkeys,level);}}var fragmentLength=fragments.length;var firstFragment=fragments[0];var lastFragment=fragments[fragmentLength-1];totalduration+=level.skippedSegments*level.targetduration;if(totalduration>0&&fragmentLength&&lastFragment){level.averagetargetduration=totalduration/fragmentLength;var lastSn=lastFragment.sn;level.endSN=lastSn!=='initSegment'?lastSn:0;if(!level.live){lastFragment.endList=true;}if(firstFragment){level.startCC=firstFragment.cc;}}else{level.endSN=0;level.startCC=0;}if(level.fragmentHint){totalduration+=level.fragmentHint.duration;}level.totalduration=totalduration;level.endCC=discontinuityCounter;/**
|
|
|
* Backfill any missing PDT values
|
|
|
* "If the first EXT-X-PROGRAM-DATE-TIME tag in a Playlist appears after
|
|
|
* one or more Media Segment URIs, the client SHOULD extrapolate
|
|
|
* backward from that tag (using EXTINF durations and/or media
|
|
|
* timestamps) to associate dates with those segments."
|
|
|
* We have already extrapolated forward, but all fragments up to the first instance of PDT do not have their PDTs
|
|
|
* computed.
|
|
|
*/if(firstPdtIndex>0){backfillProgramDateTimes(fragments,firstPdtIndex);}return level;};return M3U8Parser;}();function parseKey(keyTag,baseurl){var _keyAttrs$enumeratedS,_keyAttrs$enumeratedS2;// https://tools.ietf.org/html/rfc8216#section-4.3.2.4
|
|
|
var keyAttrs=new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(keyTag);var decryptmethod=(_keyAttrs$enumeratedS=keyAttrs.enumeratedString('METHOD'))!=null?_keyAttrs$enumeratedS:'';var decrypturi=keyAttrs.URI;var decryptiv=keyAttrs.hexadecimalInteger('IV');var decryptkeyformatversions=keyAttrs.enumeratedString('KEYFORMATVERSIONS');// From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity".
|
|
|
var decryptkeyformat=(_keyAttrs$enumeratedS2=keyAttrs.enumeratedString('KEYFORMAT'))!=null?_keyAttrs$enumeratedS2:'identity';if(decrypturi&&keyAttrs.IV&&!decryptiv){_utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.error("Invalid IV: "+keyAttrs.IV);}// If decrypturi is a URI with a scheme, then baseurl will be ignored
|
|
|
// No uri is allowed when METHOD is NONE
|
|
|
var resolvedUri=decrypturi?M3U8Parser.resolve(decrypturi,baseurl):'';var keyFormatVersions=(decryptkeyformatversions?decryptkeyformatversions:'1').split('/').map(Number).filter(Number.isFinite);return new _level_key__WEBPACK_IMPORTED_MODULE_5__.LevelKey(decryptmethod,resolvedUri,decryptkeyformat,keyFormatVersions,decryptiv);}function setCodecs(codecs,level){['video','audio','text'].forEach(function(type){var filtered=codecs.filter(function(codec){return(0,_utils_codecs__WEBPACK_IMPORTED_MODULE_8__.isCodecType)(codec,type);});if(filtered.length){var preferred=filtered.filter(function(codec){return codec.lastIndexOf('avc1',0)===0||codec.lastIndexOf('mp4a',0)===0;});level[type+"Codec"]=preferred.length>0?preferred[0]:filtered[0];// remove from list
|
|
|
codecs=codecs.filter(function(codec){return filtered.indexOf(codec)===-1;});}});level.unknownCodecs=codecs;}function assignCodec(media,groupItem,codecProperty){var codecValue=groupItem[codecProperty];if(codecValue){media[codecProperty]=codecValue;}}function backfillProgramDateTimes(fragments,firstPdtIndex){var fragPrev=fragments[firstPdtIndex];for(var i=firstPdtIndex;i--;){var frag=fragments[i];// Exit on delta-playlist skipped segments
|
|
|
if(!frag){return;}frag.programDateTime=fragPrev.programDateTime-frag.duration*1000;fragPrev=frag;}}function assignProgramDateTime(frag,prevFrag){if(frag.rawProgramDateTime){frag.programDateTime=Date.parse(frag.rawProgramDateTime);}else if(prevFrag!==null&&prevFrag!==void 0&&prevFrag.programDateTime){frag.programDateTime=prevFrag.endProgramDateTime;}if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.programDateTime)){frag.programDateTime=null;frag.rawProgramDateTime=null;}}function setInitSegment(frag,mapAttrs,id,levelkeys){frag.relurl=mapAttrs.URI;if(mapAttrs.BYTERANGE){frag.setByteRange(mapAttrs.BYTERANGE);}frag.level=id;frag.sn='initSegment';if(levelkeys){frag.levelkeys=levelkeys;}frag.initSegment=null;}function setFragLevelKeys(frag,levelkeys,level){frag.levelkeys=levelkeys;var encryptedFragments=level.encryptedFragments;if((!encryptedFragments.length||encryptedFragments[encryptedFragments.length-1].levelkeys!==levelkeys)&&Object.keys(levelkeys).some(function(format){return levelkeys[format].isCommonEncryption;})){encryptedFragments.push(frag);}}/***/},/***/"./src/loader/playlist-loader.ts":/*!***************************************!*\
|
|
|
!*** ./src/loader/playlist-loader.ts ***!
|
|
|
\***************************************/ /***/function srcLoaderPlaylistLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_650470__){"use strict";__nested_webpack_require_650470__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_650470__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_650470__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_650470__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_650470__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_650470__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_650470__(/*! ./m3u8-parser */"./src/loader/m3u8-parser.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_650470__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_650470__(/*! ../utils/attr-list */"./src/utils/attr-list.ts");/**
|
|
|
* PlaylistLoader - delegate for media manifest/playlist loading tasks. Takes care of parsing media to internal data-models.
|
|
|
*
|
|
|
* Once loaded, dispatches events with parsed data-models of manifest/levels/audio/subtitle tracks.
|
|
|
*
|
|
|
* Uses loader(s) set in config to do actual internal loading of resource tasks.
|
|
|
*
|
|
|
* @module
|
|
|
*
|
|
|
*/function mapContextToLevelType(context){var type=context.type;switch(type){case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.AUDIO;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.SUBTITLE;default:return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.MAIN;}}function getResponseUrl(response,context){var url=response.url;// responseURL not supported on some browsers (it is used to detect URL redirection)
|
|
|
// data-uri mode also not supported (but no need to detect redirection)
|
|
|
if(url===undefined||url.indexOf('data:')===0){// fallback to initial URL
|
|
|
url=context.url;}return url;}var PlaylistLoader=/*#__PURE__*/function(){function PlaylistLoader(hls){this.hls=void 0;this.loaders=Object.create(null);this.hls=hls;this.registerListeners();}var _proto=PlaylistLoader.prototype;_proto.startLoad=function startLoad(startPosition){};_proto.stopLoad=function stopLoad(){this.destroyInternalLoaders();};_proto.registerListeners=function registerListeners(){var hls=this.hls;hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADING,this.onAudioTrackLoading,this);hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADING,this.onSubtitleTrackLoading,this);};_proto.unregisterListeners=function unregisterListeners(){var hls=this.hls;hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING,this.onManifestLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING,this.onLevelLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADING,this.onAudioTrackLoading,this);hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADING,this.onSubtitleTrackLoading,this);}/**
|
|
|
* Returns defaults or configured loader-type overloads (pLoader and loader config params)
|
|
|
*/;_proto.createInternalLoader=function createInternalLoader(context){var config=this.hls.config;var PLoader=config.pLoader;var Loader=config.loader;var InternalLoader=PLoader||Loader;var loader=new InternalLoader(config);context.loader=loader;this.loaders[context.type]=loader;return loader;};_proto.getInternalLoader=function getInternalLoader(context){return this.loaders[context.type];};_proto.resetInternalLoader=function resetInternalLoader(contextType){if(this.loaders[contextType]){delete this.loaders[contextType];}}/**
|
|
|
* Call `destroy` on all internal loader instances mapped (one per context type)
|
|
|
*/;_proto.destroyInternalLoaders=function destroyInternalLoaders(){for(var contextType in this.loaders){var loader=this.loaders[contextType];if(loader){loader.destroy();}this.resetInternalLoader(contextType);}};_proto.destroy=function destroy(){this.unregisterListeners();this.destroyInternalLoaders();};_proto.onManifestLoading=function onManifestLoading(event,data){var url=data.url;this.load({id:null,groupId:null,level:0,responseType:'text',type:_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST,url:url,deliveryDirectives:null});};_proto.onLevelLoading=function onLevelLoading(event,data){var id=data.id,level=data.level,url=data.url,deliveryDirectives=data.deliveryDirectives;this.load({id:id,groupId:null,level:level,responseType:'text',type:_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL,url:url,deliveryDirectives:deliveryDirectives});};_proto.onAudioTrackLoading=function onAudioTrackLoading(event,data){var id=data.id,groupId=data.groupId,url=data.url,deliveryDirectives=data.deliveryDirectives;this.load({id:id,groupId:groupId,level:null,responseType:'text',type:_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK,url:url,deliveryDirectives:deliveryDirectives});};_proto.onSubtitleTrackLoading=function onSubtitleTrackLoading(event,data){var id=data.id,groupId=data.groupId,url=data.url,deliveryDirectives=data.deliveryDirectives;this.load({id:id,groupId:groupId,level:null,responseType:'text',type:_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK,url:url,deliveryDirectives:deliveryDirectives});};_proto.load=function load(context){var _context$deliveryDire;var config=this.hls.config;// logger.debug(`[playlist-loader]: Loading playlist of type ${context.type}, level: ${context.level}, id: ${context.id}`);
|
|
|
// Check if a loader for this context already exists
|
|
|
var loader=this.getInternalLoader(context);if(loader){var loaderContext=loader.context;if(loaderContext&&loaderContext.url===context.url){// same URL can't overlap
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.trace('[playlist-loader]: playlist request ongoing');return;}_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[playlist-loader]: aborting previous loader for type: "+context.type);loader.abort();}var maxRetry;var timeout;var retryDelay;var maxRetryDelay;// apply different configs for retries depending on
|
|
|
// context (manifest, level, audio/subs playlist)
|
|
|
switch(context.type){case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:maxRetry=config.manifestLoadingMaxRetry;timeout=config.manifestLoadingTimeOut;retryDelay=config.manifestLoadingRetryDelay;maxRetryDelay=config.manifestLoadingMaxRetryTimeout;break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:// Manage retries in Level/Track Controller
|
|
|
maxRetry=0;timeout=config.levelLoadingTimeOut;break;default:maxRetry=config.levelLoadingMaxRetry;timeout=config.levelLoadingTimeOut;retryDelay=config.levelLoadingRetryDelay;maxRetryDelay=config.levelLoadingMaxRetryTimeout;break;}loader=this.createInternalLoader(context);// Override level/track timeout for LL-HLS requests
|
|
|
// (the default of 10000ms is counter productive to blocking playlist reload requests)
|
|
|
if((_context$deliveryDire=context.deliveryDirectives)!==null&&_context$deliveryDire!==void 0&&_context$deliveryDire.part){var levelDetails;if(context.type===_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL&&context.level!==null){levelDetails=this.hls.levels[context.level].details;}else if(context.type===_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK&&context.id!==null){levelDetails=this.hls.audioTracks[context.id].details;}else if(context.type===_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK&&context.id!==null){levelDetails=this.hls.subtitleTracks[context.id].details;}if(levelDetails){var partTarget=levelDetails.partTarget;var targetDuration=levelDetails.targetduration;if(partTarget&&targetDuration){timeout=Math.min(Math.max(partTarget*3,targetDuration*0.8)*1000,timeout);}}}var loaderConfig={timeout:timeout,maxRetry:maxRetry,retryDelay:retryDelay,maxRetryDelay:maxRetryDelay,highWaterMark:0};var loaderCallbacks={onSuccess:this.loadsuccess.bind(this),onError:this.loaderror.bind(this),onTimeout:this.loadtimeout.bind(this)};// logger.debug(`[playlist-loader]: Calling internal loader delegate for URL: ${context.url}`);
|
|
|
loader.load(context,loaderConfig,loaderCallbacks);};_proto.loadsuccess=function loadsuccess(response,stats,context,networkDetails){if(networkDetails===void 0){networkDetails=null;}this.resetInternalLoader(context.type);var string=response.data;// Validate if it is an M3U8 at all
|
|
|
if(string.indexOf('#EXTM3U')!==0){this.handleManifestParsingError(response,context,'no EXTM3U delimiter',networkDetails);return;}stats.parsing.start=performance.now();// Check if chunk-list or master. handle empty chunk list case (first EXTINF not signaled, but TARGETDURATION present)
|
|
|
if(string.indexOf('#EXTINF:')>0||string.indexOf('#EXT-X-TARGETDURATION:')>0){this.handleTrackOrLevelPlaylist(response,stats,context,networkDetails);}else{this.handleMasterPlaylist(response,stats,context,networkDetails);}};_proto.loaderror=function loaderror(response,context,networkDetails){if(networkDetails===void 0){networkDetails=null;}this.handleNetworkError(context,networkDetails,false,response);};_proto.loadtimeout=function loadtimeout(stats,context,networkDetails){if(networkDetails===void 0){networkDetails=null;}this.handleNetworkError(context,networkDetails,true);};_proto.handleMasterPlaylist=function handleMasterPlaylist(response,stats,context,networkDetails){var hls=this.hls;var string=response.data;var url=getResponseUrl(response,context);var _M3U8Parser$parseMast=_m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylist(string,url),levels=_M3U8Parser$parseMast.levels,sessionData=_M3U8Parser$parseMast.sessionData,sessionKeys=_M3U8Parser$parseMast.sessionKeys;if(!levels.length){this.handleManifestParsingError(response,context,'no level found in manifest',networkDetails);return;}// multi level playlist, parse level info
|
|
|
var audioGroups=levels.map(function(level){return{id:level.attrs.AUDIO,audioCodec:level.audioCodec};});var subtitleGroups=levels.map(function(level){return{id:level.attrs.SUBTITLES,textCodec:level.textCodec};});var audioTracks=_m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string,url,'AUDIO',audioGroups);var subtitles=_m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string,url,'SUBTITLES',subtitleGroups);var captions=_m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string,url,'CLOSED-CAPTIONS');if(audioTracks.length){// check if we have found an audio track embedded in main playlist (audio track without URI attribute)
|
|
|
var embeddedAudioFound=audioTracks.some(function(audioTrack){return!audioTrack.url;});// if no embedded audio track defined, but audio codec signaled in quality level,
|
|
|
// we need to signal this main audio track this could happen with playlists with
|
|
|
// alt audio rendition in which quality levels (main)
|
|
|
// contains both audio+video. but with mixed audio track not signaled
|
|
|
if(!embeddedAudioFound&&levels[0].audioCodec&&!levels[0].attrs.AUDIO){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log('[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one');audioTracks.unshift({type:'main',name:'main',"default":false,autoselect:false,forced:false,id:-1,attrs:new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList({}),bitrate:0,url:''});}}hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,{levels:levels,audioTracks:audioTracks,subtitles:subtitles,captions:captions,url:url,stats:stats,networkDetails:networkDetails,sessionData:sessionData,sessionKeys:sessionKeys});};_proto.handleTrackOrLevelPlaylist=function handleTrackOrLevelPlaylist(response,stats,context,networkDetails){var hls=this.hls;var id=context.id,level=context.level,type=context.type;var url=getResponseUrl(response,context);var levelUrlId=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(id)?id:0;var levelId=(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(level)?level:levelUrlId;var levelType=mapContextToLevelType(context);var levelDetails=_m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseLevelPlaylist(response.data,url,levelId,levelType,levelUrlId);if(!levelDetails.fragments.length){hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_EMPTY_ERROR,fatal:false,url:url,reason:'no fragments found in level',level:typeof context.level==='number'?context.level:undefined});return;}// We have done our first request (Manifest-type) and receive
|
|
|
// not a master playlist but a chunk-list (track/level)
|
|
|
// We fire the manifest-loaded event anyway with the parsed level-details
|
|
|
// by creating a single-level structure for it.
|
|
|
if(type===_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST){var singleLevel={attrs:new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList({}),bitrate:0,details:levelDetails,name:'',url:url};hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED,{levels:[singleLevel],audioTracks:[],url:url,stats:stats,networkDetails:networkDetails,sessionData:null,sessionKeys:null});}// save parsing time
|
|
|
stats.parsing.end=performance.now();// extend the context with the new levelDetails property
|
|
|
context.levelDetails=levelDetails;this.handlePlaylistLoaded(response,stats,context,networkDetails);};_proto.handleManifestParsingError=function handleManifestParsingError(response,context,reason,networkDetails){this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_PARSING_ERROR,fatal:context.type===_types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST,url:response.url,reason:reason,response:response,context:context,networkDetails:networkDetails});};_proto.handleNetworkError=function handleNetworkError(context,networkDetails,timeout,response){if(timeout===void 0){timeout=false;}_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("[playlist-loader]: A network "+(timeout?'timeout':'error')+" occurred while loading "+context.type+" level: "+context.level+" id: "+context.id+" group-id: \""+context.groupId+"\"");var details=_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.UNKNOWN;var fatal=false;var loader=this.getInternalLoader(context);switch(context.type){case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:details=timeout?_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_LOAD_TIMEOUT:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_LOAD_ERROR;fatal=true;break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:details=timeout?_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_TIMEOUT:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_ERROR;fatal=false;break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:details=timeout?_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR;fatal=false;break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:details=timeout?_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.SUBTITLE_TRACK_LOAD_TIMEOUT:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.SUBTITLE_LOAD_ERROR;fatal=false;break;}if(loader){this.resetInternalLoader(context.type);}var errorData={type:_errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,details:details,fatal:fatal,url:context.url,loader:loader,context:context,networkDetails:networkDetails};if(response){errorData.response=response;}this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR,errorData);};_proto.handlePlaylistLoaded=function handlePlaylistLoaded(response,stats,context,networkDetails){var type=context.type,level=context.level,id=context.id,groupId=context.groupId,loader=context.loader,levelDetails=context.levelDetails,deliveryDirectives=context.deliveryDirectives;if(!(levelDetails!==null&&levelDetails!==void 0&&levelDetails.targetduration)){this.handleManifestParsingError(response,context,'invalid target duration',networkDetails);return;}if(!loader){return;}if(levelDetails.live){if(loader.getCacheAge){levelDetails.ageHeader=loader.getCacheAge()||0;}if(!loader.getCacheAge||isNaN(levelDetails.ageHeader)){levelDetails.ageHeader=0;}}switch(type){case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED,{details:levelDetails,level:level||0,id:id||0,stats:stats,networkDetails:networkDetails,deliveryDirectives:deliveryDirectives});break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADED,{details:levelDetails,id:id||0,groupId:groupId||'',stats:stats,networkDetails:networkDetails,deliveryDirectives:deliveryDirectives});break;case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADED,{details:levelDetails,id:id||0,groupId:groupId||'',stats:stats,networkDetails:networkDetails,deliveryDirectives:deliveryDirectives});break;}};return PlaylistLoader;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=PlaylistLoader;/***/},/***/"./src/polyfills/number.ts":/*!*********************************!*\
|
|
|
!*** ./src/polyfills/number.ts ***!
|
|
|
\*********************************/ /***/function srcPolyfillsNumberTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_669199__){"use strict";__nested_webpack_require_669199__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_669199__.d(__webpack_exports__,{/* harmony export */"MAX_SAFE_INTEGER":function MAX_SAFE_INTEGER(){return(/* binding */_MAX_SAFE_INTEGER);},/* harmony export */"isFiniteNumber":function isFiniteNumber(){return(/* binding */_isFiniteNumber);}/* harmony export */});var _isFiniteNumber=Number.isFinite||function(value){return typeof value==='number'&&isFinite(value);};var _MAX_SAFE_INTEGER=Number.MAX_SAFE_INTEGER||9007199254740991;/***/},/***/"./src/remux/aac-helper.ts":/*!*********************************!*\
|
|
|
!*** ./src/remux/aac-helper.ts ***!
|
|
|
\*********************************/ /***/function srcRemuxAacHelperTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_669972__){"use strict";__nested_webpack_require_669972__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_669972__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/**
|
|
|
* AAC helper
|
|
|
*/var AAC=/*#__PURE__*/function(){function AAC(){}AAC.getSilentFrame=function getSilentFrame(codec,channelCount){switch(codec){case'mp4a.40.2':if(channelCount===1){return new Uint8Array([0x00,0xc8,0x00,0x80,0x23,0x80]);}else if(channelCount===2){return new Uint8Array([0x21,0x00,0x49,0x90,0x02,0x19,0x00,0x23,0x80]);}else if(channelCount===3){return new Uint8Array([0x00,0xc8,0x00,0x80,0x20,0x84,0x01,0x26,0x40,0x08,0x64,0x00,0x8e]);}else if(channelCount===4){return new Uint8Array([0x00,0xc8,0x00,0x80,0x20,0x84,0x01,0x26,0x40,0x08,0x64,0x00,0x80,0x2c,0x80,0x08,0x02,0x38]);}else if(channelCount===5){return new Uint8Array([0x00,0xc8,0x00,0x80,0x20,0x84,0x01,0x26,0x40,0x08,0x64,0x00,0x82,0x30,0x04,0x99,0x00,0x21,0x90,0x02,0x38]);}else if(channelCount===6){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]);}break;// handle HE-AAC below (mp4a.40.5 / mp4a.40.29)
|
|
|
default:if(channelCount===1){// 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
|
|
|
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]);}else if(channelCount===2){// 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
|
|
|
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]);}else if(channelCount===3){// 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
|
|
|
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]);}break;}return undefined;};return AAC;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=AAC;/***/},/***/"./src/remux/mp4-generator.ts":/*!************************************!*\
|
|
|
!*** ./src/remux/mp4-generator.ts ***!
|
|
|
\************************************/ /***/function srcRemuxMp4GeneratorTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_673040__){"use strict";__nested_webpack_require_673040__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_673040__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/**
|
|
|
* Generate MP4 Box
|
|
|
*/var UINT32_MAX=Math.pow(2,32)-1;var MP4=/*#__PURE__*/function(){function MP4(){}MP4.init=function init(){MP4.types={avc1:[],// codingname
|
|
|
avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],'.mp3':[],mvex:[],mvhd:[],pasp:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};var i;for(i in MP4.types){if(MP4.types.hasOwnProperty(i)){MP4.types[i]=[i.charCodeAt(0),i.charCodeAt(1),i.charCodeAt(2),i.charCodeAt(3)];}}var videoHdlr=new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00,// pre_defined
|
|
|
0x76,0x69,0x64,0x65,// handler_type: 'vide'
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x56,0x69,0x64,0x65,0x6f,0x48,0x61,0x6e,0x64,0x6c,0x65,0x72,0x00// name: 'VideoHandler'
|
|
|
]);var audioHdlr=new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00,// pre_defined
|
|
|
0x73,0x6f,0x75,0x6e,// handler_type: 'soun'
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x53,0x6f,0x75,0x6e,0x64,0x48,0x61,0x6e,0x64,0x6c,0x65,0x72,0x00// name: 'SoundHandler'
|
|
|
]);MP4.HDLR_TYPES={video:videoHdlr,audio:audioHdlr};var dref=new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x01,// entry_count
|
|
|
0x00,0x00,0x00,0x0c,// entry_size
|
|
|
0x75,0x72,0x6c,0x20,// 'url' type
|
|
|
0x00,// version 0
|
|
|
0x00,0x00,0x01// entry_flags
|
|
|
]);var stco=new Uint8Array([0x00,// version
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00// entry_count
|
|
|
]);MP4.STTS=MP4.STSC=MP4.STCO=stco;MP4.STSZ=new Uint8Array([0x00,// version
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00,// sample_size
|
|
|
0x00,0x00,0x00,0x00// sample_count
|
|
|
]);MP4.VMHD=new Uint8Array([0x00,// version
|
|
|
0x00,0x00,0x01,// flags
|
|
|
0x00,0x00,// graphicsmode
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00// opcolor
|
|
|
]);MP4.SMHD=new Uint8Array([0x00,// version
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,// balance
|
|
|
0x00,0x00// reserved
|
|
|
]);MP4.STSD=new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x01]);// entry_count
|
|
|
var majorBrand=new Uint8Array([105,115,111,109]);// isom
|
|
|
var avc1Brand=new Uint8Array([97,118,99,49]);// avc1
|
|
|
var minorVersion=new Uint8Array([0,0,0,1]);MP4.FTYP=MP4.box(MP4.types.ftyp,majorBrand,minorVersion,majorBrand,avc1Brand);MP4.DINF=MP4.box(MP4.types.dinf,MP4.box(MP4.types.dref,dref));};MP4.box=function box(type){var size=8;for(var _len=arguments.length,payload=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){payload[_key-1]=arguments[_key];}var i=payload.length;var len=i;// calculate the total size we need to allocate
|
|
|
while(i--){size+=payload[i].byteLength;}var result=new Uint8Array(size);result[0]=size>>24&0xff;result[1]=size>>16&0xff;result[2]=size>>8&0xff;result[3]=size&0xff;result.set(type,4);// copy the payload into the result
|
|
|
for(i=0,size=8;i<len;i++){// copy payload[i] array @ offset size
|
|
|
result.set(payload[i],size);size+=payload[i].byteLength;}return result;};MP4.hdlr=function hdlr(type){return MP4.box(MP4.types.hdlr,MP4.HDLR_TYPES[type]);};MP4.mdat=function mdat(data){return MP4.box(MP4.types.mdat,data);};MP4.mdhd=function mdhd(timescale,duration){duration*=timescale;var upperWordDuration=Math.floor(duration/(UINT32_MAX+1));var lowerWordDuration=Math.floor(duration%(UINT32_MAX+1));return MP4.box(MP4.types.mdhd,new Uint8Array([0x01,// version 1
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,// creation_time
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,// modification_time
|
|
|
timescale>>24&0xff,timescale>>16&0xff,timescale>>8&0xff,timescale&0xff,// timescale
|
|
|
upperWordDuration>>24,upperWordDuration>>16&0xff,upperWordDuration>>8&0xff,upperWordDuration&0xff,lowerWordDuration>>24,lowerWordDuration>>16&0xff,lowerWordDuration>>8&0xff,lowerWordDuration&0xff,0x55,0xc4,// 'und' language (undetermined)
|
|
|
0x00,0x00]));};MP4.mdia=function mdia(track){return MP4.box(MP4.types.mdia,MP4.mdhd(track.timescale,track.duration),MP4.hdlr(track.type),MP4.minf(track));};MP4.mfhd=function mfhd(sequenceNumber){return MP4.box(MP4.types.mfhd,new Uint8Array([0x00,0x00,0x00,0x00,// flags
|
|
|
sequenceNumber>>24,sequenceNumber>>16&0xff,sequenceNumber>>8&0xff,sequenceNumber&0xff// sequence_number
|
|
|
]));};MP4.minf=function minf(track){if(track.type==='audio'){return MP4.box(MP4.types.minf,MP4.box(MP4.types.smhd,MP4.SMHD),MP4.DINF,MP4.stbl(track));}else{return MP4.box(MP4.types.minf,MP4.box(MP4.types.vmhd,MP4.VMHD),MP4.DINF,MP4.stbl(track));}};MP4.moof=function moof(sn,baseMediaDecodeTime,track){return MP4.box(MP4.types.moof,MP4.mfhd(sn),MP4.traf(track,baseMediaDecodeTime));}/**
|
|
|
* @param tracks... (optional) {array} the tracks associated with this movie
|
|
|
*/;MP4.moov=function moov(tracks){var i=tracks.length;var boxes=[];while(i--){boxes[i]=MP4.trak(tracks[i]);}return MP4.box.apply(null,[MP4.types.moov,MP4.mvhd(tracks[0].timescale,tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));};MP4.mvex=function mvex(tracks){var i=tracks.length;var boxes=[];while(i--){boxes[i]=MP4.trex(tracks[i]);}return MP4.box.apply(null,[MP4.types.mvex].concat(boxes));};MP4.mvhd=function mvhd(timescale,duration){duration*=timescale;var upperWordDuration=Math.floor(duration/(UINT32_MAX+1));var lowerWordDuration=Math.floor(duration%(UINT32_MAX+1));var bytes=new Uint8Array([0x01,// version 1
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,// creation_time
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,// modification_time
|
|
|
timescale>>24&0xff,timescale>>16&0xff,timescale>>8&0xff,timescale&0xff,// timescale
|
|
|
upperWordDuration>>24,upperWordDuration>>16&0xff,upperWordDuration>>8&0xff,upperWordDuration&0xff,lowerWordDuration>>24,lowerWordDuration>>16&0xff,lowerWordDuration>>8&0xff,lowerWordDuration&0xff,0x00,0x01,0x00,0x00,// 1.0 rate
|
|
|
0x01,0x00,// 1.0 volume
|
|
|
0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x01,0x00,0x00,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,// transformation: unity matrix
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// pre_defined
|
|
|
0xff,0xff,0xff,0xff// next_track_ID
|
|
|
]);return MP4.box(MP4.types.mvhd,bytes);};MP4.sdtp=function sdtp(track){var samples=track.samples||[];var bytes=new Uint8Array(4+samples.length);var i;var flags;// leave the full box header (4 bytes) all zero
|
|
|
// write the sample table
|
|
|
for(i=0;i<samples.length;i++){flags=samples[i].flags;bytes[i+4]=flags.dependsOn<<4|flags.isDependedOn<<2|flags.hasRedundancy;}return MP4.box(MP4.types.sdtp,bytes);};MP4.stbl=function stbl(track){return MP4.box(MP4.types.stbl,MP4.stsd(track),MP4.box(MP4.types.stts,MP4.STTS),MP4.box(MP4.types.stsc,MP4.STSC),MP4.box(MP4.types.stsz,MP4.STSZ),MP4.box(MP4.types.stco,MP4.STCO));};MP4.avc1=function avc1(track){var sps=[];var pps=[];var i;var data;var len;// assemble the SPSs
|
|
|
for(i=0;i<track.sps.length;i++){data=track.sps[i];len=data.byteLength;sps.push(len>>>8&0xff);sps.push(len&0xff);// SPS
|
|
|
sps=sps.concat(Array.prototype.slice.call(data));}// assemble the PPSs
|
|
|
for(i=0;i<track.pps.length;i++){data=track.pps[i];len=data.byteLength;pps.push(len>>>8&0xff);pps.push(len&0xff);pps=pps.concat(Array.prototype.slice.call(data));}var avcc=MP4.box(MP4.types.avcC,new Uint8Array([0x01,// version
|
|
|
sps[3],// profile
|
|
|
sps[4],// profile compat
|
|
|
sps[5],// level
|
|
|
0xfc|3,// lengthSizeMinusOne, hard-coded to 4 bytes
|
|
|
0xe0|track.sps.length// 3bit reserved (111) + numOfSequenceParameterSets
|
|
|
].concat(sps).concat([track.pps.length// numOfPictureParameterSets
|
|
|
]).concat(pps)));// "PPS"
|
|
|
var width=track.width;var height=track.height;var hSpacing=track.pixelRatio[0];var vSpacing=track.pixelRatio[1];return MP4.box(MP4.types.avc1,new Uint8Array([0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,// reserved
|
|
|
0x00,0x01,// data_reference_index
|
|
|
0x00,0x00,// pre_defined
|
|
|
0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// pre_defined
|
|
|
width>>8&0xff,width&0xff,// width
|
|
|
height>>8&0xff,height&0xff,// height
|
|
|
0x00,0x48,0x00,0x00,// horizresolution
|
|
|
0x00,0x48,0x00,0x00,// vertresolution
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x01,// frame_count
|
|
|
0x12,0x64,0x61,0x69,0x6c,// dailymotion/hls.js
|
|
|
0x79,0x6d,0x6f,0x74,0x69,0x6f,0x6e,0x2f,0x68,0x6c,0x73,0x2e,0x6a,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// compressorname
|
|
|
0x00,0x18,// depth = 24
|
|
|
0x11,0x11]),// pre_defined = -1
|
|
|
avcc,MP4.box(MP4.types.btrt,new Uint8Array([0x00,0x1c,0x9c,0x80,// bufferSizeDB
|
|
|
0x00,0x2d,0xc6,0xc0,// maxBitrate
|
|
|
0x00,0x2d,0xc6,0xc0])),// avgBitrate
|
|
|
MP4.box(MP4.types.pasp,new Uint8Array([hSpacing>>24,// hSpacing
|
|
|
hSpacing>>16&0xff,hSpacing>>8&0xff,hSpacing&0xff,vSpacing>>24,// vSpacing
|
|
|
vSpacing>>16&0xff,vSpacing>>8&0xff,vSpacing&0xff])));};MP4.esds=function esds(track){var configlen=track.config.length;return new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
0x03,// descriptor_type
|
|
|
0x17+configlen,// length
|
|
|
0x00,0x01,// es_id
|
|
|
0x00,// stream_priority
|
|
|
0x04,// descriptor_type
|
|
|
0x0f+configlen,// length
|
|
|
0x40,// codec : mpeg4_audio
|
|
|
0x15,// stream_type
|
|
|
0x00,0x00,0x00,// buffer_size
|
|
|
0x00,0x00,0x00,0x00,// maxBitrate
|
|
|
0x00,0x00,0x00,0x00,// avgBitrate
|
|
|
0x05// descriptor_type
|
|
|
].concat([configlen]).concat(track.config).concat([0x06,0x01,0x02]));// GASpecificConfig)); // length + audio config descriptor
|
|
|
};MP4.mp4a=function mp4a(track){var samplerate=track.samplerate;return MP4.box(MP4.types.mp4a,new Uint8Array([0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,// reserved
|
|
|
0x00,0x01,// data_reference_index
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,track.channelCount,// channelcount
|
|
|
0x00,0x10,// sampleSize:16bits
|
|
|
0x00,0x00,0x00,0x00,// reserved2
|
|
|
samplerate>>8&0xff,samplerate&0xff,//
|
|
|
0x00,0x00]),MP4.box(MP4.types.esds,MP4.esds(track)));};MP4.mp3=function mp3(track){var samplerate=track.samplerate;return MP4.box(MP4.types['.mp3'],new Uint8Array([0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,0x00,// reserved
|
|
|
0x00,0x01,// data_reference_index
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,track.channelCount,// channelcount
|
|
|
0x00,0x10,// sampleSize:16bits
|
|
|
0x00,0x00,0x00,0x00,// reserved2
|
|
|
samplerate>>8&0xff,samplerate&0xff,//
|
|
|
0x00,0x00]));};MP4.stsd=function stsd(track){if(track.type==='audio'){if(track.segmentCodec==='mp3'&&track.codec==='mp3'){return MP4.box(MP4.types.stsd,MP4.STSD,MP4.mp3(track));}return MP4.box(MP4.types.stsd,MP4.STSD,MP4.mp4a(track));}else{return MP4.box(MP4.types.stsd,MP4.STSD,MP4.avc1(track));}};MP4.tkhd=function tkhd(track){var id=track.id;var duration=track.duration*track.timescale;var width=track.width;var height=track.height;var upperWordDuration=Math.floor(duration/(UINT32_MAX+1));var lowerWordDuration=Math.floor(duration%(UINT32_MAX+1));return MP4.box(MP4.types.tkhd,new Uint8Array([0x01,// version 1
|
|
|
0x00,0x00,0x07,// flags
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,// creation_time
|
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,// modification_time
|
|
|
id>>24&0xff,id>>16&0xff,id>>8&0xff,id&0xff,// track_ID
|
|
|
0x00,0x00,0x00,0x00,// reserved
|
|
|
upperWordDuration>>24,upperWordDuration>>16&0xff,upperWordDuration>>8&0xff,upperWordDuration&0xff,lowerWordDuration>>24,lowerWordDuration>>16&0xff,lowerWordDuration>>8&0xff,lowerWordDuration&0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// reserved
|
|
|
0x00,0x00,// layer
|
|
|
0x00,0x00,// alternate_group
|
|
|
0x00,0x00,// non-audio track volume
|
|
|
0x00,0x00,// reserved
|
|
|
0x00,0x01,0x00,0x00,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,// transformation: unity matrix
|
|
|
width>>8&0xff,width&0xff,0x00,0x00,// width
|
|
|
height>>8&0xff,height&0xff,0x00,0x00// height
|
|
|
]));};MP4.traf=function traf(track,baseMediaDecodeTime){var sampleDependencyTable=MP4.sdtp(track);var id=track.id;var upperWordBaseMediaDecodeTime=Math.floor(baseMediaDecodeTime/(UINT32_MAX+1));var lowerWordBaseMediaDecodeTime=Math.floor(baseMediaDecodeTime%(UINT32_MAX+1));return MP4.box(MP4.types.traf,MP4.box(MP4.types.tfhd,new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
id>>24,id>>16&0xff,id>>8&0xff,id&0xff// track_ID
|
|
|
])),MP4.box(MP4.types.tfdt,new Uint8Array([0x01,// version 1
|
|
|
0x00,0x00,0x00,// flags
|
|
|
upperWordBaseMediaDecodeTime>>24,upperWordBaseMediaDecodeTime>>16&0xff,upperWordBaseMediaDecodeTime>>8&0xff,upperWordBaseMediaDecodeTime&0xff,lowerWordBaseMediaDecodeTime>>24,lowerWordBaseMediaDecodeTime>>16&0xff,lowerWordBaseMediaDecodeTime>>8&0xff,lowerWordBaseMediaDecodeTime&0xff])),MP4.trun(track,sampleDependencyTable.length+16+// tfhd
|
|
|
20+// tfdt
|
|
|
8+// traf header
|
|
|
16+// mfhd
|
|
|
8+// moof header
|
|
|
8),// mdat header
|
|
|
sampleDependencyTable);}/**
|
|
|
* Generate a track box.
|
|
|
* @param track {object} a track definition
|
|
|
* @return {Uint8Array} the track box
|
|
|
*/;MP4.trak=function trak(track){track.duration=track.duration||0xffffffff;return MP4.box(MP4.types.trak,MP4.tkhd(track),MP4.mdia(track));};MP4.trex=function trex(track){var id=track.id;return MP4.box(MP4.types.trex,new Uint8Array([0x00,// version 0
|
|
|
0x00,0x00,0x00,// flags
|
|
|
id>>24,id>>16&0xff,id>>8&0xff,id&0xff,// track_ID
|
|
|
0x00,0x00,0x00,0x01,// default_sample_description_index
|
|
|
0x00,0x00,0x00,0x00,// default_sample_duration
|
|
|
0x00,0x00,0x00,0x00,// default_sample_size
|
|
|
0x00,0x01,0x00,0x01// default_sample_flags
|
|
|
]));};MP4.trun=function trun(track,offset){var samples=track.samples||[];var len=samples.length;var arraylen=12+16*len;var array=new Uint8Array(arraylen);var i;var sample;var duration;var size;var flags;var cts;offset+=8+arraylen;array.set([track.type==='video'?0x01:0x00,// version 1 for video with signed-int sample_composition_time_offset
|
|
|
0x00,0x0f,0x01,// flags
|
|
|
len>>>24&0xff,len>>>16&0xff,len>>>8&0xff,len&0xff,// sample_count
|
|
|
offset>>>24&0xff,offset>>>16&0xff,offset>>>8&0xff,offset&0xff// data_offset
|
|
|
],0);for(i=0;i<len;i++){sample=samples[i];duration=sample.duration;size=sample.size;flags=sample.flags;cts=sample.cts;array.set([duration>>>24&0xff,duration>>>16&0xff,duration>>>8&0xff,duration&0xff,// sample_duration
|
|
|
size>>>24&0xff,size>>>16&0xff,size>>>8&0xff,size&0xff,// sample_size
|
|
|
flags.isLeading<<2|flags.dependsOn,flags.isDependedOn<<6|flags.hasRedundancy<<4|flags.paddingValue<<1|flags.isNonSync,flags.degradPrio&0xf0<<8,flags.degradPrio&0x0f,// sample_flags
|
|
|
cts>>>24&0xff,cts>>>16&0xff,cts>>>8&0xff,cts&0xff// sample_composition_time_offset
|
|
|
],12+16*i);}return MP4.box(MP4.types.trun,array);};MP4.initSegment=function initSegment(tracks){if(!MP4.types){MP4.init();}var movie=MP4.moov(tracks);var result=new Uint8Array(MP4.FTYP.byteLength+movie.byteLength);result.set(MP4.FTYP);result.set(movie,MP4.FTYP.byteLength);return result;};return MP4;}();MP4.types=void 0;MP4.HDLR_TYPES=void 0;MP4.STTS=void 0;MP4.STSC=void 0;MP4.STCO=void 0;MP4.STSZ=void 0;MP4.VMHD=void 0;MP4.SMHD=void 0;MP4.STSD=void 0;MP4.FTYP=void 0;MP4.DINF=void 0;/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=MP4;/***/},/***/"./src/remux/mp4-remuxer.ts":/*!**********************************!*\
|
|
|
!*** ./src/remux/mp4-remuxer.ts ***!
|
|
|
\**********************************/ /***/function srcRemuxMp4RemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_688526__){"use strict";__nested_webpack_require_688526__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_688526__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */MP4Remuxer);},/* harmony export */"flushTextTrackMetadataCueSamples":function flushTextTrackMetadataCueSamples(){return(/* binding */_flushTextTrackMetadataCueSamples);},/* harmony export */"flushTextTrackUserdataCueSamples":function flushTextTrackUserdataCueSamples(){return(/* binding */_flushTextTrackUserdataCueSamples);},/* harmony export */"normalizePts":function normalizePts(){return(/* binding */_normalizePts);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_688526__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _aac_helper__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_688526__(/*! ./aac-helper */"./src/remux/aac-helper.ts");/* harmony import */var _mp4_generator__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_688526__(/*! ./mp4-generator */"./src/remux/mp4-generator.ts");/* harmony import */var _events__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_688526__(/*! ../events */"./src/events.ts");/* harmony import */var _errors__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_688526__(/*! ../errors */"./src/errors.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_688526__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _types_loader__WEBPACK_IMPORTED_MODULE_6__=__nested_webpack_require_688526__(/*! ../types/loader */"./src/types/loader.ts");/* harmony import */var _utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__=__nested_webpack_require_688526__(/*! ../utils/timescale-conversion */"./src/utils/timescale-conversion.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}var MAX_SILENT_FRAME_DURATION=10*1000;// 10 seconds
|
|
|
var AAC_SAMPLES_PER_FRAME=1024;var MPEG_AUDIO_SAMPLE_PER_FRAME=1152;var chromeVersion=null;var safariWebkitVersion=null;var MP4Remuxer=/*#__PURE__*/function(){function MP4Remuxer(observer,config,typeSupported,vendor){if(vendor===void 0){vendor='';}this.observer=void 0;this.config=void 0;this.typeSupported=void 0;this.ISGenerated=false;this._initPTS=void 0;this._initDTS=void 0;this.nextAvcDts=null;this.nextAudioPts=null;this.videoSampleDuration=null;this.isAudioContiguous=false;this.isVideoContiguous=false;this.observer=observer;this.config=config;this.typeSupported=typeSupported;this.ISGenerated=false;if(chromeVersion===null){var userAgent=navigator.userAgent||'';var result=userAgent.match(/Chrome\/(\d+)/i);chromeVersion=result?parseInt(result[1]):0;}if(safariWebkitVersion===null){var _result=navigator.userAgent.match(/Safari\/(\d+)/i);safariWebkitVersion=_result?parseInt(_result[1]):0;}}var _proto=MP4Remuxer.prototype;_proto.destroy=function destroy(){};_proto.resetTimeStamp=function resetTimeStamp(defaultTimeStamp){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: initPTS & initDTS reset');this._initPTS=this._initDTS=defaultTimeStamp;};_proto.resetNextTimestamp=function resetNextTimestamp(){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: reset next timestamp');this.isVideoContiguous=false;this.isAudioContiguous=false;};_proto.resetInitSegment=function resetInitSegment(){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: ISGenerated flag reset');this.ISGenerated=false;};_proto.getVideoStartPts=function getVideoStartPts(videoSamples){var rolloverDetected=false;var startPTS=videoSamples.reduce(function(minPTS,sample){var delta=sample.pts-minPTS;if(delta<-4294967296){// 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation
|
|
|
rolloverDetected=true;return _normalizePts(minPTS,sample.pts);}else if(delta>0){return minPTS;}else{return sample.pts;}},videoSamples[0].pts);if(rolloverDetected){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.debug('PTS rollover detected');}return startPTS;};_proto.remux=function remux(audioTrack,videoTrack,id3Track,textTrack,timeOffset,accurateTimeOffset,flush,playlistType){var video;var audio;var initSegment;var text;var id3;var independent;var audioTimeOffset=timeOffset;var videoTimeOffset=timeOffset;// If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding.
|
|
|
// This is done to synchronize the audio and video streams. We know if the current segment will have samples if the "pid"
|
|
|
// parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list.
|
|
|
// However, if the initSegment has already been generated, or we've reached the end of a segment (flush),
|
|
|
// then we can remux one track without waiting for the other.
|
|
|
var hasAudio=audioTrack.pid>-1;var hasVideo=videoTrack.pid>-1;var length=videoTrack.samples.length;var enoughAudioSamples=audioTrack.samples.length>0;var enoughVideoSamples=flush&&length>0||length>1;var canRemuxAvc=(!hasAudio||enoughAudioSamples)&&(!hasVideo||enoughVideoSamples)||this.ISGenerated||flush;if(canRemuxAvc){if(!this.ISGenerated){initSegment=this.generateIS(audioTrack,videoTrack,timeOffset);}var isVideoContiguous=this.isVideoContiguous;var firstKeyFrameIndex=-1;var firstKeyFramePTS;if(enoughVideoSamples){firstKeyFrameIndex=findKeyframeIndex(videoTrack.samples);if(!isVideoContiguous&&this.config.forceKeyFrameOnDiscontinuity){independent=true;if(firstKeyFrameIndex>0){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: Dropped "+firstKeyFrameIndex+" out of "+length+" video samples due to a missing keyframe");var startPTS=this.getVideoStartPts(videoTrack.samples);videoTrack.samples=videoTrack.samples.slice(firstKeyFrameIndex);videoTrack.dropped+=firstKeyFrameIndex;videoTimeOffset+=(videoTrack.samples[0].pts-startPTS)/videoTrack.inputTimeScale;firstKeyFramePTS=videoTimeOffset;}else if(firstKeyFrameIndex===-1){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: No keyframe found out of "+length+" video samples");independent=false;}}}if(this.ISGenerated){if(enoughAudioSamples&&enoughVideoSamples){// timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS)
|
|
|
// if first audio DTS is not aligned with first video DTS then we need to take that into account
|
|
|
// when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small
|
|
|
// drift between audio and video streams
|
|
|
var _startPTS=this.getVideoStartPts(videoTrack.samples);var tsDelta=_normalizePts(audioTrack.samples[0].pts,_startPTS)-_startPTS;var audiovideoTimestampDelta=tsDelta/videoTrack.inputTimeScale;audioTimeOffset+=Math.max(0,audiovideoTimestampDelta);videoTimeOffset+=Math.max(0,-audiovideoTimestampDelta);}// Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio.
|
|
|
if(enoughAudioSamples){// if initSegment was generated without audio samples, regenerate it again
|
|
|
if(!audioTrack.samplerate){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');initSegment=this.generateIS(audioTrack,videoTrack,timeOffset);}audio=this.remuxAudio(audioTrack,audioTimeOffset,this.isAudioContiguous,accurateTimeOffset,hasVideo||enoughVideoSamples||playlistType===_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO?videoTimeOffset:undefined);if(enoughVideoSamples){var audioTrackLength=audio?audio.endPTS-audio.startPTS:0;// if initSegment was generated without video samples, regenerate it again
|
|
|
if(!videoTrack.inputTimeScale){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');initSegment=this.generateIS(audioTrack,videoTrack,timeOffset);}video=this.remuxVideo(videoTrack,videoTimeOffset,isVideoContiguous,audioTrackLength);}}else if(enoughVideoSamples){video=this.remuxVideo(videoTrack,videoTimeOffset,isVideoContiguous,0);}if(video){video.firstKeyFrame=firstKeyFrameIndex;video.independent=firstKeyFrameIndex!==-1;video.firstKeyFramePTS=firstKeyFramePTS;}}}// Allow ID3 and text to remux, even if more audio/video samples are required
|
|
|
if(this.ISGenerated){if(id3Track.samples.length){id3=_flushTextTrackMetadataCueSamples(id3Track,timeOffset,this._initPTS,this._initDTS);}if(textTrack.samples.length){text=_flushTextTrackUserdataCueSamples(textTrack,timeOffset,this._initPTS);}}return{audio:audio,video:video,initSegment:initSegment,independent:independent,text:text,id3:id3};};_proto.generateIS=function generateIS(audioTrack,videoTrack,timeOffset){var audioSamples=audioTrack.samples;var videoSamples=videoTrack.samples;var typeSupported=this.typeSupported;var tracks={};var computePTSDTS=!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this._initPTS);var container='audio/mp4';var initPTS;var initDTS;var timescale;if(computePTSDTS){initPTS=initDTS=Infinity;}if(audioTrack.config&&audioSamples.length){// let's use audio sampling rate as MP4 time scale.
|
|
|
// rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)
|
|
|
// using audio sampling rate here helps having an integer MP4 frame duration
|
|
|
// this avoids potential rounding issue and AV sync issue
|
|
|
audioTrack.timescale=audioTrack.samplerate;switch(audioTrack.segmentCodec){case'mp3':if(typeSupported.mpeg){// Chrome and Safari
|
|
|
container='audio/mpeg';audioTrack.codec='';}else if(typeSupported.mp3){// Firefox
|
|
|
audioTrack.codec='mp3';}break;}tracks.audio={id:'audio',container:container,codec:audioTrack.codec,initSegment:audioTrack.segmentCodec==='mp3'&&typeSupported.mpeg?new Uint8Array(0):_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([audioTrack]),metadata:{channelCount:audioTrack.channelCount}};if(computePTSDTS){timescale=audioTrack.inputTimeScale;// remember first PTS of this demuxing context. for audio, PTS = DTS
|
|
|
initPTS=initDTS=audioSamples[0].pts-Math.round(timescale*timeOffset);}}if(videoTrack.sps&&videoTrack.pps&&videoSamples.length){// let's use input time scale as MP4 video timescale
|
|
|
// we use input time scale straight away to avoid rounding issues on frame duration / cts computation
|
|
|
videoTrack.timescale=videoTrack.inputTimeScale;tracks.video={id:'main',container:'video/mp4',codec:videoTrack.codec,initSegment:_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([videoTrack]),metadata:{width:videoTrack.width,height:videoTrack.height}};if(computePTSDTS){timescale=videoTrack.inputTimeScale;var startPTS=this.getVideoStartPts(videoSamples);var startOffset=Math.round(timescale*timeOffset);initDTS=Math.min(initDTS,_normalizePts(videoSamples[0].dts,startPTS)-startOffset);initPTS=Math.min(initPTS,startPTS-startOffset);}}if(Object.keys(tracks).length){this.ISGenerated=true;if(computePTSDTS){this._initPTS=initPTS;this._initDTS=initDTS;}return{tracks:tracks,initPTS:initPTS,timescale:timescale};}};_proto.remuxVideo=function remuxVideo(track,timeOffset,contiguous,audioTrackLength){var timeScale=track.inputTimeScale;var inputSamples=track.samples;var outputSamples=[];var nbSamples=inputSamples.length;var initPTS=this._initPTS;var nextAvcDts=this.nextAvcDts;var offset=8;var mp4SampleDuration=this.videoSampleDuration;var firstDTS;var lastDTS;var minPTS=Number.POSITIVE_INFINITY;var maxPTS=Number.NEGATIVE_INFINITY;var sortSamples=false;// if parsed fragment is contiguous with last one, let's use last DTS value as reference
|
|
|
if(!contiguous||nextAvcDts===null){var pts=timeOffset*timeScale;var cts=inputSamples[0].pts-_normalizePts(inputSamples[0].dts,inputSamples[0].pts);// if not contiguous, let's use target timeOffset
|
|
|
nextAvcDts=pts-cts;}// PTS is coded on 33bits, and can loop from -2^32 to 2^32
|
|
|
// PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
|
|
|
for(var i=0;i<nbSamples;i++){var sample=inputSamples[i];sample.pts=_normalizePts(sample.pts-initPTS,nextAvcDts);sample.dts=_normalizePts(sample.dts-initPTS,nextAvcDts);if(sample.dts<inputSamples[i>0?i-1:i].dts){sortSamples=true;}}// sort video samples by DTS then PTS then demux id order
|
|
|
if(sortSamples){inputSamples.sort(function(a,b){var deltadts=a.dts-b.dts;var deltapts=a.pts-b.pts;return deltadts||deltapts;});}// Get first/last DTS
|
|
|
firstDTS=inputSamples[0].dts;lastDTS=inputSamples[inputSamples.length-1].dts;// Sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
|
|
|
// set this constant duration as being the avg delta between consecutive DTS.
|
|
|
var inputDuration=lastDTS-firstDTS;var averageSampleDuration=inputDuration?Math.round(inputDuration/(nbSamples-1)):mp4SampleDuration||track.inputTimeScale/30;// if fragment are contiguous, detect hole/overlapping between fragments
|
|
|
if(contiguous){// check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole)
|
|
|
var delta=firstDTS-nextAvcDts;var foundHole=delta>averageSampleDuration;var foundOverlap=delta<-1;if(foundHole||foundOverlap){if(foundHole){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("AVC: "+(0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(delta,true)+" ms ("+delta+"dts) hole between fragments detected, filling it");}else{_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("AVC: "+(0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(-delta,true)+" ms ("+delta+"dts) overlapping between fragments detected");}if(!foundOverlap||nextAvcDts>inputSamples[0].pts){firstDTS=nextAvcDts;var firstPTS=inputSamples[0].pts-delta;inputSamples[0].dts=firstDTS;inputSamples[0].pts=firstPTS;_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log("Video: First PTS/DTS adjusted: "+(0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(firstPTS,true)+"/"+(0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(firstDTS,true)+", delta: "+(0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(delta,true)+" ms");}}}firstDTS=Math.max(0,firstDTS);var nbNalu=0;var naluLen=0;for(var _i=0;_i<nbSamples;_i++){// compute total/avc sample length and nb of NAL units
|
|
|
var _sample=inputSamples[_i];var units=_sample.units;var nbUnits=units.length;var sampleLen=0;for(var j=0;j<nbUnits;j++){sampleLen+=units[j].data.length;}naluLen+=sampleLen;nbNalu+=nbUnits;_sample.length=sampleLen;// ensure sample monotonic DTS
|
|
|
_sample.dts=Math.max(_sample.dts,firstDTS);minPTS=Math.min(_sample.pts,minPTS);maxPTS=Math.max(_sample.pts,maxPTS);}lastDTS=inputSamples[nbSamples-1].dts;/* concatenate the video data and construct the mdat in place
|
|
|
(need 8 more bytes to fill length and mpdat type) */var mdatSize=naluLen+4*nbNalu+8;var mdat;try{mdat=new Uint8Array(mdatSize);}catch(err){this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MUX_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.REMUX_ALLOC_ERROR,fatal:false,bytes:mdatSize,reason:"fail allocating video mdat "+mdatSize});return;}var view=new DataView(mdat.buffer);view.setUint32(0,mdatSize);mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat,4);var stretchedLastFrame=false;var minDtsDelta=Number.POSITIVE_INFINITY;var minPtsDelta=Number.POSITIVE_INFINITY;var maxDtsDelta=Number.NEGATIVE_INFINITY;var maxPtsDelta=Number.NEGATIVE_INFINITY;for(var _i2=0;_i2<nbSamples;_i2++){var avcSample=inputSamples[_i2];var avcSampleUnits=avcSample.units;var mp4SampleLength=0;// convert NALU bitstream to MP4 format (prepend NALU with size field)
|
|
|
for(var _j=0,_nbUnits=avcSampleUnits.length;_j<_nbUnits;_j++){var unit=avcSampleUnits[_j];var unitData=unit.data;var unitDataLen=unit.data.byteLength;view.setUint32(offset,unitDataLen);offset+=4;mdat.set(unitData,offset);offset+=unitDataLen;mp4SampleLength+=4+unitDataLen;}// expected sample duration is the Decoding Timestamp diff of consecutive samples
|
|
|
var ptsDelta=void 0;if(_i2<nbSamples-1){mp4SampleDuration=inputSamples[_i2+1].dts-avcSample.dts;ptsDelta=inputSamples[_i2+1].pts-avcSample.pts;}else{var config=this.config;var lastFrameDuration=_i2>0?avcSample.dts-inputSamples[_i2-1].dts:averageSampleDuration;ptsDelta=_i2>0?avcSample.pts-inputSamples[_i2-1].pts:averageSampleDuration;if(config.stretchShortVideoTrack&&this.nextAudioPts!==null){// In some cases, a segment's audio track duration may exceed the video track duration.
|
|
|
// Since we've already remuxed audio, and we know how long the audio track is, we look to
|
|
|
// see if the delta to the next segment is longer than maxBufferHole.
|
|
|
// If so, playback would potentially get stuck, so we artificially inflate
|
|
|
// the duration of the last frame to minimize any potential gap between segments.
|
|
|
var gapTolerance=Math.floor(config.maxBufferHole*timeScale);var deltaToFrameEnd=(audioTrackLength?minPTS+audioTrackLength*timeScale:this.nextAudioPts)-avcSample.pts;if(deltaToFrameEnd>gapTolerance){// We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
|
|
|
// frame overlap. maxBufferHole should be >> lastFrameDuration anyway.
|
|
|
mp4SampleDuration=deltaToFrameEnd-lastFrameDuration;if(mp4SampleDuration<0){mp4SampleDuration=lastFrameDuration;}else{stretchedLastFrame=true;}_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log("[mp4-remuxer]: It is approximately "+deltaToFrameEnd/90+" ms to the next segment; using duration "+mp4SampleDuration/90+" ms for the last video frame.");}else{mp4SampleDuration=lastFrameDuration;}}else{mp4SampleDuration=lastFrameDuration;}}var compositionTimeOffset=Math.round(avcSample.pts-avcSample.dts);minDtsDelta=Math.min(minDtsDelta,mp4SampleDuration);maxDtsDelta=Math.max(maxDtsDelta,mp4SampleDuration);minPtsDelta=Math.min(minPtsDelta,ptsDelta);maxPtsDelta=Math.max(maxPtsDelta,ptsDelta);outputSamples.push(new Mp4Sample(avcSample.key,mp4SampleDuration,mp4SampleLength,compositionTimeOffset));}if(outputSamples.length){if(chromeVersion){if(chromeVersion<70){// Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue
|
|
|
// https://code.google.com/p/chromium/issues/detail?id=229412
|
|
|
var flags=outputSamples[0].flags;flags.dependsOn=2;flags.isNonSync=0;}}else if(safariWebkitVersion){// Fix for "CNN special report, with CC" in test-streams (Safari browser only)
|
|
|
// Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
|
|
|
if(maxPtsDelta-minPtsDelta<maxDtsDelta-minDtsDelta&&averageSampleDuration/maxDtsDelta<0.025&&outputSamples[0].cts===0){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');var dts=firstDTS;for(var _i3=0,len=outputSamples.length;_i3<len;_i3++){var nextDts=dts+outputSamples[_i3].duration;var _pts=dts+outputSamples[_i3].cts;if(_i3<len-1){var nextPts=nextDts+outputSamples[_i3+1].cts;outputSamples[_i3].duration=nextPts-_pts;}else{outputSamples[_i3].duration=_i3?outputSamples[_i3-1].duration:averageSampleDuration;}outputSamples[_i3].cts=0;dts=nextDts;}}}}console.assert(mp4SampleDuration!==null,'mp4SampleDuration must be computed');// next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
|
|
mp4SampleDuration=stretchedLastFrame||!mp4SampleDuration?averageSampleDuration:mp4SampleDuration;this.nextAvcDts=nextAvcDts=lastDTS+mp4SampleDuration;this.videoSampleDuration=mp4SampleDuration;this.isVideoContiguous=true;var moof=_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++,firstDTS,_extends({},track,{samples:outputSamples}));var type='video';var data={data1:moof,data2:mdat,startPTS:minPTS/timeScale,endPTS:(maxPTS+mp4SampleDuration)/timeScale,startDTS:firstDTS/timeScale,endDTS:nextAvcDts/timeScale,type:type,hasAudio:false,hasVideo:true,nb:outputSamples.length,dropped:track.dropped};track.samples=[];track.dropped=0;console.assert(mdat.length,'MDAT length must not be zero');return data;};_proto.remuxAudio=function remuxAudio(track,timeOffset,contiguous,accurateTimeOffset,videoTimeOffset){var inputTimeScale=track.inputTimeScale;var mp4timeScale=track.samplerate?track.samplerate:inputTimeScale;var scaleFactor=inputTimeScale/mp4timeScale;var mp4SampleDuration=track.segmentCodec==='aac'?AAC_SAMPLES_PER_FRAME:MPEG_AUDIO_SAMPLE_PER_FRAME;var inputSampleDuration=mp4SampleDuration*scaleFactor;var initPTS=this._initPTS;var rawMPEG=track.segmentCodec==='mp3'&&this.typeSupported.mpeg;var outputSamples=[];var alignedWithVideo=videoTimeOffset!==undefined;var inputSamples=track.samples;var offset=rawMPEG?0:8;var nextAudioPts=this.nextAudioPts||-1;// window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]);
|
|
|
// for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),
|
|
|
// for sake of clarity:
|
|
|
// consecutive fragments are frags with
|
|
|
// - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR
|
|
|
// - less than 20 audio frames distance
|
|
|
// contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
|
|
|
// this helps ensuring audio continuity
|
|
|
// and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame
|
|
|
var timeOffsetMpegTS=timeOffset*inputTimeScale;this.isAudioContiguous=contiguous=contiguous||inputSamples.length&&nextAudioPts>0&&(accurateTimeOffset&&Math.abs(timeOffsetMpegTS-nextAudioPts)<9000||Math.abs(_normalizePts(inputSamples[0].pts-initPTS,timeOffsetMpegTS)-nextAudioPts)<20*inputSampleDuration);// compute normalized PTS
|
|
|
inputSamples.forEach(function(sample){sample.pts=_normalizePts(sample.pts-initPTS,timeOffsetMpegTS);});if(!contiguous||nextAudioPts<0){// filter out sample with negative PTS that are not playable anyway
|
|
|
// if we don't remove these negative samples, they will shift all audio samples forward.
|
|
|
// leading to audio overlap between current / next fragment
|
|
|
inputSamples=inputSamples.filter(function(sample){return sample.pts>=0;});// in case all samples have negative PTS, and have been filtered out, return now
|
|
|
if(!inputSamples.length){return;}if(videoTimeOffset===0){// Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence
|
|
|
nextAudioPts=0;}else if(accurateTimeOffset&&!alignedWithVideo){// When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS
|
|
|
nextAudioPts=Math.max(0,timeOffsetMpegTS);}else{// if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS
|
|
|
nextAudioPts=inputSamples[0].pts;}}// If the audio track is missing samples, the frames seem to get "left-shifted" within the
|
|
|
// resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
|
|
|
// In an effort to prevent this from happening, we inject frames here where there are gaps.
|
|
|
// When possible, we inject a silent frame; when that's not possible, we duplicate the last
|
|
|
// frame.
|
|
|
if(track.segmentCodec==='aac'){var maxAudioFramesDrift=this.config.maxAudioFramesDrift;for(var i=0,nextPts=nextAudioPts;i<inputSamples.length;i++){// First, let's see how far off this frame is from where we expect it to be
|
|
|
var sample=inputSamples[i];var pts=sample.pts;var delta=pts-nextPts;var duration=Math.abs(1000*delta/inputTimeScale);// When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
|
|
|
if(delta<=-maxAudioFramesDrift*inputSampleDuration&&alignedWithVideo){if(i===0){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("Audio frame @ "+(pts/inputTimeScale).toFixed(3)+"s overlaps nextAudioPts by "+Math.round(1000*delta/inputTimeScale)+" ms.");this.nextAudioPts=nextAudioPts=nextPts=pts;}}// eslint-disable-line brace-style
|
|
|
// Insert missing frames if:
|
|
|
// 1: We're more than maxAudioFramesDrift frame away
|
|
|
// 2: Not more than MAX_SILENT_FRAME_DURATION away
|
|
|
// 3: currentTime (aka nextPtsNorm) is not 0
|
|
|
// 4: remuxing with video (videoTimeOffset !== undefined)
|
|
|
else if(delta>=maxAudioFramesDrift*inputSampleDuration&&duration<MAX_SILENT_FRAME_DURATION&&alignedWithVideo){var missing=Math.round(delta/inputSampleDuration);// Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from
|
|
|
// later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration.
|
|
|
nextPts=pts-missing*inputSampleDuration;if(nextPts<0){missing--;nextPts+=inputSampleDuration;}if(i===0){this.nextAudioPts=nextAudioPts=nextPts;}_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: Injecting "+missing+" audio frame @ "+(nextPts/inputTimeScale).toFixed(3)+"s due to "+Math.round(1000*delta/inputTimeScale)+" ms gap.");for(var j=0;j<missing;j++){var newStamp=Math.max(nextPts,0);var fillFrame=_aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec||track.codec,track.channelCount);if(!fillFrame){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');fillFrame=sample.unit.subarray();}inputSamples.splice(i,0,{unit:fillFrame,pts:newStamp});nextPts+=inputSampleDuration;i++;}}sample.pts=nextPts;nextPts+=inputSampleDuration;}}var firstPTS=null;var lastPTS=null;var mdat;var mdatSize=0;var sampleLength=inputSamples.length;while(sampleLength--){mdatSize+=inputSamples[sampleLength].unit.byteLength;}for(var _j2=0,_nbSamples=inputSamples.length;_j2<_nbSamples;_j2++){var audioSample=inputSamples[_j2];var unit=audioSample.unit;var _pts2=audioSample.pts;if(lastPTS!==null){// If we have more than one sample, set the duration of the sample to the "real" duration; the PTS diff with
|
|
|
// the previous sample
|
|
|
var prevSample=outputSamples[_j2-1];prevSample.duration=Math.round((_pts2-lastPTS)/scaleFactor);}else{if(contiguous&&track.segmentCodec==='aac'){// set PTS/DTS to expected PTS/DTS
|
|
|
_pts2=nextAudioPts;}// remember first PTS of our audioSamples
|
|
|
firstPTS=_pts2;if(mdatSize>0){/* concatenate the audio data and construct the mdat in place
|
|
|
(need 8 more bytes to fill length and mdat type) */mdatSize+=offset;try{mdat=new Uint8Array(mdatSize);}catch(err){this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR,{type:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MUX_ERROR,details:_errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.REMUX_ALLOC_ERROR,fatal:false,bytes:mdatSize,reason:"fail allocating audio mdat "+mdatSize});return;}if(!rawMPEG){var view=new DataView(mdat.buffer);view.setUint32(0,mdatSize);mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat,4);}}else{// no audio samples
|
|
|
return;}}mdat.set(unit,offset);var unitLen=unit.byteLength;offset+=unitLen;// Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG
|
|
|
// In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration
|
|
|
// becomes the PTS diff with the previous sample
|
|
|
outputSamples.push(new Mp4Sample(true,mp4SampleDuration,unitLen,0));lastPTS=_pts2;}// We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones
|
|
|
var nbSamples=outputSamples.length;if(!nbSamples){return;}// The next audio sample PTS should be equal to last sample PTS + duration
|
|
|
var lastSample=outputSamples[outputSamples.length-1];this.nextAudioPts=nextAudioPts=lastPTS+scaleFactor*lastSample.duration;// Set the track samples from inputSamples to outputSamples before remuxing
|
|
|
var moof=rawMPEG?new Uint8Array(0):_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++,firstPTS/scaleFactor,_extends({},track,{samples:outputSamples}));// Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared
|
|
|
track.samples=[];var start=firstPTS/inputTimeScale;var end=nextAudioPts/inputTimeScale;var type='audio';var audioData={data1:moof,data2:mdat,startPTS:start,endPTS:end,startDTS:start,endDTS:end,type:type,hasAudio:true,hasVideo:false,nb:nbSamples};this.isAudioContiguous=true;console.assert(mdat.length,'MDAT length must not be zero');return audioData;};_proto.remuxEmptyAudio=function remuxEmptyAudio(track,timeOffset,contiguous,videoData){var inputTimeScale=track.inputTimeScale;var mp4timeScale=track.samplerate?track.samplerate:inputTimeScale;var scaleFactor=inputTimeScale/mp4timeScale;var nextAudioPts=this.nextAudioPts;// sync with video's timestamp
|
|
|
var startDTS=(nextAudioPts!==null?nextAudioPts:videoData.startDTS*inputTimeScale)+this._initDTS;var endDTS=videoData.endDTS*inputTimeScale+this._initDTS;// one sample's duration value
|
|
|
var frameDuration=scaleFactor*AAC_SAMPLES_PER_FRAME;// samples count of this segment's duration
|
|
|
var nbSamples=Math.ceil((endDTS-startDTS)/frameDuration);// silent frame
|
|
|
var silentFrame=_aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec||track.codec,track.channelCount);_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: remux empty Audio');// Can't remux if we can't generate a silent frame...
|
|
|
if(!silentFrame){_utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace('[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec');return;}var samples=[];for(var i=0;i<nbSamples;i++){var stamp=startDTS+i*frameDuration;samples.push({unit:silentFrame,pts:stamp,dts:stamp});}track.samples=samples;return this.remuxAudio(track,timeOffset,contiguous,false);};return MP4Remuxer;}();function _normalizePts(value,reference){var offset;if(reference===null){return value;}if(reference<value){// - 2^33
|
|
|
offset=-8589934592;}else{// + 2^33
|
|
|
offset=8589934592;}/* PTS is 33bit (from 0 to 2^33 -1)
|
|
|
if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
|
|
|
PTS looping occured. fill the gap */while(Math.abs(value-reference)>4294967296){value+=offset;}return value;}function findKeyframeIndex(samples){for(var i=0;i<samples.length;i++){if(samples[i].key){return i;}}return-1;}function _flushTextTrackMetadataCueSamples(track,timeOffset,initPTS,initDTS){var length=track.samples.length;if(!length){return;}var inputTimeScale=track.inputTimeScale;for(var index=0;index<length;index++){var sample=track.samples[index];// setting id3 pts, dts to relative time
|
|
|
// using this._initPTS and this._initDTS to calculate relative time
|
|
|
sample.pts=_normalizePts(sample.pts-initPTS,timeOffset*inputTimeScale)/inputTimeScale;sample.dts=_normalizePts(sample.dts-initDTS,timeOffset*inputTimeScale)/inputTimeScale;}var samples=track.samples;track.samples=[];return{samples:samples};}function _flushTextTrackUserdataCueSamples(track,timeOffset,initPTS){var length=track.samples.length;if(!length){return;}var inputTimeScale=track.inputTimeScale;for(var index=0;index<length;index++){var sample=track.samples[index];// setting text pts, dts to relative time
|
|
|
// using this._initPTS and this._initDTS to calculate relative time
|
|
|
sample.pts=_normalizePts(sample.pts-initPTS,timeOffset*inputTimeScale)/inputTimeScale;}track.samples.sort(function(a,b){return a.pts-b.pts;});var samples=track.samples;track.samples=[];return{samples:samples};}var Mp4Sample=function Mp4Sample(isKeyframe,duration,size,cts){this.size=void 0;this.duration=void 0;this.cts=void 0;this.flags=void 0;this.duration=duration;this.size=size;this.cts=cts;this.flags=new Mp4SampleFlags(isKeyframe);};var Mp4SampleFlags=function Mp4SampleFlags(isKeyframe){this.isLeading=0;this.isDependedOn=0;this.hasRedundancy=0;this.degradPrio=0;this.dependsOn=1;this.isNonSync=1;this.dependsOn=isKeyframe?2:1;this.isNonSync=isKeyframe?0:1;};/***/},/***/"./src/remux/passthrough-remuxer.ts":/*!******************************************!*\
|
|
|
!*** ./src/remux/passthrough-remuxer.ts ***!
|
|
|
\******************************************/ /***/function srcRemuxPassthroughRemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_721036__){"use strict";__nested_webpack_require_721036__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_721036__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_721036__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_721036__(/*! ./mp4-remuxer */"./src/remux/mp4-remuxer.ts");/* harmony import */var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_721036__(/*! ../utils/mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _loader_fragment__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_721036__(/*! ../loader/fragment */"./src/loader/fragment.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_721036__(/*! ../utils/logger */"./src/utils/logger.ts");var PassThroughRemuxer=/*#__PURE__*/function(){function PassThroughRemuxer(){this.emitInitSegment=false;this.audioCodec=void 0;this.videoCodec=void 0;this.initData=void 0;this.initPTS=void 0;this.initTracks=void 0;this.lastEndTime=null;}var _proto=PassThroughRemuxer.prototype;_proto.destroy=function destroy(){};_proto.resetTimeStamp=function resetTimeStamp(defaultInitPTS){this.initPTS=defaultInitPTS;this.lastEndTime=null;};_proto.resetNextTimestamp=function resetNextTimestamp(){this.lastEndTime=null;};_proto.resetInitSegment=function resetInitSegment(initSegment,audioCodec,videoCodec,decryptdata){this.audioCodec=audioCodec;this.videoCodec=videoCodec;this.generateInitSegment((0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.patchEncyptionData)(initSegment,decryptdata));this.emitInitSegment=true;};_proto.generateInitSegment=function generateInitSegment(initSegment){var audioCodec=this.audioCodec,videoCodec=this.videoCodec;if(!initSegment||!initSegment.byteLength){this.initTracks=undefined;this.initData=undefined;return;}var initData=this.initData=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseInitSegment)(initSegment);// Get codec from initSegment or fallback to default
|
|
|
if(!audioCodec){audioCodec=getParsedTrackCodec(initData.audio,_loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.AUDIO);}if(!videoCodec){videoCodec=getParsedTrackCodec(initData.video,_loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.VIDEO);}var tracks={};if(initData.audio&&initData.video){tracks.audiovideo={container:'video/mp4',codec:audioCodec+','+videoCodec,initSegment:initSegment,id:'main'};}else if(initData.audio){tracks.audio={container:'audio/mp4',codec:audioCodec,initSegment:initSegment,id:'audio'};}else if(initData.video){tracks.video={container:'video/mp4',codec:videoCodec,initSegment:initSegment,id:'main'};}else{_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');}this.initTracks=tracks;};_proto.remux=function remux(audioTrack,videoTrack,id3Track,textTrack,timeOffset){var _this$initPTS;var initPTS=this.initPTS,lastEndTime=this.lastEndTime;var result={audio:undefined,video:undefined,text:textTrack,id3:id3Track,initSegment:undefined};// If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the
|
|
|
// lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update
|
|
|
// the media duration (which is what timeOffset is provided as) before we need to process the next chunk.
|
|
|
if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(lastEndTime)){lastEndTime=this.lastEndTime=timeOffset||0;}// The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only
|
|
|
// audio or video (or both); adding it to video was an arbitrary choice.
|
|
|
var data=videoTrack.samples;if(!data||!data.length){return result;}var initSegment={initPTS:undefined,timescale:1};var initData=this.initData;if(!initData||!initData.length){this.generateInitSegment(data);initData=this.initData;}if(!initData||!initData.length){// We can't remux if the initSegment could not be generated
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');return result;}if(this.emitInitSegment){initSegment.tracks=this.initTracks;this.emitInitSegment=false;}var startDTS=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.getStartDTS)(initData,data);if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS)){this.initPTS=initSegment.initPTS=initPTS=startDTS-timeOffset;}var duration=(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.getDuration)(data,initData);var startTime=audioTrack?startDTS-initPTS:lastEndTime;var endTime=startTime+duration;(0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.offsetStartDTS)(initData,data,initPTS);if(duration>0){this.lastEndTime=endTime;}else{_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('Duration parsed from mp4 should be greater than zero');this.resetNextTimestamp();}var hasAudio=!!initData.audio;var hasVideo=!!initData.video;var type='';if(hasAudio){type+='audio';}if(hasVideo){type+='video';}var track={data1:data,startPTS:startTime,startDTS:startTime,endPTS:endTime,endDTS:endTime,type:type,hasAudio:hasAudio,hasVideo:hasVideo,nb:1,dropped:0};result.audio=track.type==='audio'?track:undefined;result.video=track.type!=='audio'?track:undefined;result.initSegment=initSegment;var initPtsNum=(_this$initPTS=this.initPTS)!=null?_this$initPTS:0;result.id3=(0,_mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__.flushTextTrackMetadataCueSamples)(id3Track,timeOffset,initPtsNum,initPtsNum);if(textTrack.samples.length){result.text=(0,_mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__.flushTextTrackUserdataCueSamples)(textTrack,timeOffset,initPtsNum);}return result;};return PassThroughRemuxer;}();function getParsedTrackCodec(track,type){var parsedCodec=track===null||track===void 0?void 0:track.codec;if(parsedCodec&&parsedCodec.length>4){return parsedCodec;}// Since mp4-tools cannot parse full codec string (see 'TODO: Parse codec details'... in mp4-tools)
|
|
|
// Provide defaults based on codec type
|
|
|
// This allows for some playback of some fmp4 playlists without CODECS defined in manifest
|
|
|
if(parsedCodec==='hvc1'||parsedCodec==='hev1'){return'hvc1.1.c.L120.90';}if(parsedCodec==='av01'){return'av01.0.04M.08';}if(parsedCodec==='avc1'||type===_loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.VIDEO){return'avc1.42e01e';}return'mp4a.40.5';}/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=PassThroughRemuxer;/***/},/***/"./src/task-loop.ts":/*!**************************!*\
|
|
|
!*** ./src/task-loop.ts ***!
|
|
|
\**************************/ /***/function srcTaskLoopTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_727972__){"use strict";__nested_webpack_require_727972__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_727972__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */TaskLoop);}/* harmony export */});/**
|
|
|
* Sub-class specialization of EventHandler base class.
|
|
|
*
|
|
|
* TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop,
|
|
|
* scheduled asynchroneously, avoiding recursive calls in the same tick.
|
|
|
*
|
|
|
* The task itself is implemented in `doTick`. It can be requested and called for single execution
|
|
|
* using the `tick` method.
|
|
|
*
|
|
|
* It will be assured that the task execution method (`tick`) only gets called once per main loop "tick",
|
|
|
* no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly.
|
|
|
*
|
|
|
* If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`,
|
|
|
* and cancelled with `clearNextTick`.
|
|
|
*
|
|
|
* The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`).
|
|
|
*
|
|
|
* Sub-classes need to implement the `doTick` method which will effectively have the task execution routine.
|
|
|
*
|
|
|
* Further explanations:
|
|
|
*
|
|
|
* The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously
|
|
|
* only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks.
|
|
|
*
|
|
|
* When the task execution (`tick` method) is called in re-entrant way this is detected and
|
|
|
* we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
|
|
|
* task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
|
|
|
*/var TaskLoop=/*#__PURE__*/function(){function TaskLoop(){this._boundTick=void 0;this._tickTimer=null;this._tickInterval=null;this._tickCallCount=0;this._boundTick=this.tick.bind(this);}var _proto=TaskLoop.prototype;_proto.destroy=function destroy(){this.onHandlerDestroying();this.onHandlerDestroyed();};_proto.onHandlerDestroying=function onHandlerDestroying(){// clear all timers before unregistering from event bus
|
|
|
this.clearNextTick();this.clearInterval();};_proto.onHandlerDestroyed=function onHandlerDestroyed(){}/**
|
|
|
* @returns {boolean}
|
|
|
*/;_proto.hasInterval=function hasInterval(){return!!this._tickInterval;}/**
|
|
|
* @returns {boolean}
|
|
|
*/;_proto.hasNextTick=function hasNextTick(){return!!this._tickTimer;}/**
|
|
|
* @param {number} millis Interval time (ms)
|
|
|
* @returns {boolean} True when interval has been scheduled, false when already scheduled (no effect)
|
|
|
*/;_proto.setInterval=function setInterval(millis){if(!this._tickInterval){this._tickInterval=self.setInterval(this._boundTick,millis);return true;}return false;}/**
|
|
|
* @returns {boolean} True when interval was cleared, false when none was set (no effect)
|
|
|
*/;_proto.clearInterval=function clearInterval(){if(this._tickInterval){self.clearInterval(this._tickInterval);this._tickInterval=null;return true;}return false;}/**
|
|
|
* @returns {boolean} True when timeout was cleared, false when none was set (no effect)
|
|
|
*/;_proto.clearNextTick=function clearNextTick(){if(this._tickTimer){self.clearTimeout(this._tickTimer);this._tickTimer=null;return true;}return false;}/**
|
|
|
* Will call the subclass doTick implementation in this main loop tick
|
|
|
* or in the next one (via setTimeout(,0)) in case it has already been called
|
|
|
* in this tick (in case this is a re-entrant call).
|
|
|
*/;_proto.tick=function tick(){this._tickCallCount++;if(this._tickCallCount===1){this.doTick();// re-entrant call to tick from previous doTick call stack
|
|
|
// -> schedule a call on the next main loop iteration to process this task processing request
|
|
|
if(this._tickCallCount>1){// make sure only one timer exists at any time at max
|
|
|
this.tickImmediate();}this._tickCallCount=0;}};_proto.tickImmediate=function tickImmediate(){this.clearNextTick();this._tickTimer=self.setTimeout(this._boundTick,0);}/**
|
|
|
* For subclass to implement task logic
|
|
|
* @abstract
|
|
|
*/;_proto.doTick=function doTick(){};return TaskLoop;}();/***/},/***/"./src/types/cmcd.ts":/*!***************************!*\
|
|
|
!*** ./src/types/cmcd.ts ***!
|
|
|
\***************************/ /***/function srcTypesCmcdTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_732351__){"use strict";__nested_webpack_require_732351__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_732351__.d(__webpack_exports__,{/* harmony export */"CMCDObjectType":function CMCDObjectType(){return(/* binding */_CMCDObjectType);},/* harmony export */"CMCDStreamType":function CMCDStreamType(){return(/* binding */_CMCDStreamType);},/* harmony export */"CMCDStreamingFormat":function CMCDStreamingFormat(){return(/* binding */_CMCDStreamingFormat);},/* harmony export */"CMCDVersion":function CMCDVersion(){return(/* binding */_CMCDVersion);}/* harmony export */});/**
|
|
|
* CMCD spec version
|
|
|
*/var _CMCDVersion=1;/**
|
|
|
* CMCD Object Type
|
|
|
*/var _CMCDObjectType;/**
|
|
|
* CMCD Streaming Format
|
|
|
*/(function(CMCDObjectType){CMCDObjectType["MANIFEST"]="m";CMCDObjectType["AUDIO"]="a";CMCDObjectType["VIDEO"]="v";CMCDObjectType["MUXED"]="av";CMCDObjectType["INIT"]="i";CMCDObjectType["CAPTION"]="c";CMCDObjectType["TIMED_TEXT"]="tt";CMCDObjectType["KEY"]="k";CMCDObjectType["OTHER"]="o";})(_CMCDObjectType||(_CMCDObjectType={}));var _CMCDStreamingFormat;/**
|
|
|
* CMCD Streaming Type
|
|
|
*/(function(CMCDStreamingFormat){CMCDStreamingFormat["DASH"]="d";CMCDStreamingFormat["HLS"]="h";CMCDStreamingFormat["SMOOTH"]="s";CMCDStreamingFormat["OTHER"]="o";})(_CMCDStreamingFormat||(_CMCDStreamingFormat={}));var _CMCDStreamType;/**
|
|
|
* CMCD Headers
|
|
|
*/(function(CMCDStreamType){CMCDStreamType["VOD"]="v";CMCDStreamType["LIVE"]="l";})(_CMCDStreamType||(_CMCDStreamType={}));/***/},/***/"./src/types/demuxer.ts":/*!******************************!*\
|
|
|
!*** ./src/types/demuxer.ts ***!
|
|
|
\******************************/ /***/function srcTypesDemuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_734034__){"use strict";__nested_webpack_require_734034__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_734034__.d(__webpack_exports__,{/* harmony export */"MetadataSchema":function MetadataSchema(){return(/* binding */_MetadataSchema);}/* harmony export */});var _MetadataSchema;(function(MetadataSchema){MetadataSchema["audioId3"]="org.id3";MetadataSchema["dateRange"]="com.apple.quicktime.HLS";MetadataSchema["emsg"]="https://aomedia.org/emsg/ID3";})(_MetadataSchema||(_MetadataSchema={}));/***/},/***/"./src/types/level.ts":/*!****************************!*\
|
|
|
!*** ./src/types/level.ts ***!
|
|
|
\****************************/ /***/function srcTypesLevelTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_734741__){"use strict";__nested_webpack_require_734741__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_734741__.d(__webpack_exports__,{/* harmony export */"HdcpLevels":function HdcpLevels(){return(/* binding */_HdcpLevels);},/* harmony export */"HlsSkip":function HlsSkip(){return(/* binding */_HlsSkip);},/* harmony export */"HlsUrlParameters":function HlsUrlParameters(){return(/* binding */_HlsUrlParameters);},/* harmony export */"Level":function Level(){return(/* binding */_Level);},/* harmony export */"getSkipValue":function getSkipValue(){return(/* binding */_getSkipValue);}/* harmony export */});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,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}var _HdcpLevels=['NONE','TYPE-0','TYPE-1','TYPE-2',null];var _HlsSkip;(function(HlsSkip){HlsSkip["No"]="";HlsSkip["Yes"]="YES";HlsSkip["v2"]="v2";})(_HlsSkip||(_HlsSkip={}));function _getSkipValue(details,msn){var canSkipUntil=details.canSkipUntil,canSkipDateRanges=details.canSkipDateRanges,endSN=details.endSN;var snChangeGoal=msn!==undefined?msn-endSN:0;if(canSkipUntil&&snChangeGoal<canSkipUntil){if(canSkipDateRanges){return _HlsSkip.v2;}return _HlsSkip.Yes;}return _HlsSkip.No;}var _HlsUrlParameters=/*#__PURE__*/function(){function HlsUrlParameters(msn,part,skip){this.msn=void 0;this.part=void 0;this.skip=void 0;this.msn=msn;this.part=part;this.skip=skip;}var _proto=HlsUrlParameters.prototype;_proto.addDirectives=function addDirectives(uri){var url=new self.URL(uri);if(this.msn!==undefined){url.searchParams.set('_HLS_msn',this.msn.toString());}if(this.part!==undefined){url.searchParams.set('_HLS_part',this.part.toString());}if(this.skip){url.searchParams.set('_HLS_skip',this.skip);}return url.href;};return HlsUrlParameters;}();var _Level=/*#__PURE__*/function(){function Level(data){this.attrs=void 0;this.audioCodec=void 0;this.bitrate=void 0;this.codecSet=void 0;this.height=void 0;this.id=void 0;this.name=void 0;this.videoCodec=void 0;this.width=void 0;this.unknownCodecs=void 0;this.audioGroupIds=void 0;this.details=void 0;this.fragmentError=0;this.loadError=0;this.loaded=void 0;this.realBitrate=0;this.textGroupIds=void 0;this.url=void 0;this._urlId=0;this.url=[data.url];this.attrs=data.attrs;this.bitrate=data.bitrate;if(data.details){this.details=data.details;}this.id=data.id||0;this.name=data.name;this.width=data.width||0;this.height=data.height||0;this.audioCodec=data.audioCodec;this.videoCodec=data.videoCodec;this.unknownCodecs=data.unknownCodecs;this.codecSet=[data.videoCodec,data.audioCodec].filter(function(c){return c;}).join(',').replace(/\.[^.,]+/g,'');}_createClass(Level,[{key:"maxBitrate",get:function get(){return Math.max(this.realBitrate,this.bitrate);}},{key:"uri",get:function get(){return this.url[this._urlId]||'';}},{key:"urlId",get:function get(){return this._urlId;},set:function set(value){var newValue=value%this.url.length;if(this._urlId!==newValue){this.details=undefined;this._urlId=newValue;}}}]);return Level;}();/***/},/***/"./src/types/loader.ts":/*!*****************************!*\
|
|
|
!*** ./src/types/loader.ts ***!
|
|
|
\*****************************/ /***/function srcTypesLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_738861__){"use strict";__nested_webpack_require_738861__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_738861__.d(__webpack_exports__,{/* harmony export */"PlaylistContextType":function PlaylistContextType(){return(/* binding */_PlaylistContextType);},/* harmony export */"PlaylistLevelType":function PlaylistLevelType(){return(/* binding */_PlaylistLevelType);}/* harmony export */});var _PlaylistContextType;(function(PlaylistContextType){PlaylistContextType["MANIFEST"]="manifest";PlaylistContextType["LEVEL"]="level";PlaylistContextType["AUDIO_TRACK"]="audioTrack";PlaylistContextType["SUBTITLE_TRACK"]="subtitleTrack";})(_PlaylistContextType||(_PlaylistContextType={}));var _PlaylistLevelType;(function(PlaylistLevelType){PlaylistLevelType["MAIN"]="main";PlaylistLevelType["AUDIO"]="audio";PlaylistLevelType["SUBTITLE"]="subtitle";})(_PlaylistLevelType||(_PlaylistLevelType={}));/***/},/***/"./src/types/transmuxer.ts":/*!*********************************!*\
|
|
|
!*** ./src/types/transmuxer.ts ***!
|
|
|
\*********************************/ /***/function srcTypesTransmuxerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_739985__){"use strict";__nested_webpack_require_739985__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_739985__.d(__webpack_exports__,{/* harmony export */"ChunkMetadata":function ChunkMetadata(){return(/* binding */_ChunkMetadata);}/* harmony export */});var _ChunkMetadata=function ChunkMetadata(level,sn,id,size,part,partial){if(size===void 0){size=0;}if(part===void 0){part=-1;}if(partial===void 0){partial=false;}this.level=void 0;this.sn=void 0;this.part=void 0;this.id=void 0;this.size=void 0;this.partial=void 0;this.transmuxing=getNewPerformanceTiming();this.buffering={audio:getNewPerformanceTiming(),video:getNewPerformanceTiming(),audiovideo:getNewPerformanceTiming()};this.level=level;this.sn=sn;this.id=id;this.size=size;this.part=part;this.partial=partial;};function getNewPerformanceTiming(){return{start:0,executeStart:0,executeEnd:0,end:0};}/***/},/***/"./src/utils/attr-list.ts":/*!********************************!*\
|
|
|
!*** ./src/utils/attr-list.ts ***!
|
|
|
\********************************/ /***/function srcUtilsAttrListTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_741078__){"use strict";__nested_webpack_require_741078__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_741078__.d(__webpack_exports__,{/* harmony export */"AttrList":function AttrList(){return(/* binding */_AttrList);}/* harmony export */});var DECIMAL_RESOLUTION_REGEX=/^(\d+)x(\d+)$/;// eslint-disable-line no-useless-escape
|
|
|
var ATTR_LIST_REGEX=/\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g;// eslint-disable-line no-useless-escape
|
|
|
// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
|
|
|
var _AttrList=/*#__PURE__*/function(){function AttrList(attrs){if(typeof attrs==='string'){attrs=AttrList.parseAttrList(attrs);}for(var attr in attrs){if(attrs.hasOwnProperty(attr)){this[attr]=attrs[attr];}}}var _proto=AttrList.prototype;_proto.decimalInteger=function decimalInteger(attrName){var intValue=parseInt(this[attrName],10);if(intValue>Number.MAX_SAFE_INTEGER){return Infinity;}return intValue;};_proto.hexadecimalInteger=function hexadecimalInteger(attrName){if(this[attrName]){var stringValue=(this[attrName]||'0x').slice(2);stringValue=(stringValue.length&1?'0':'')+stringValue;var value=new Uint8Array(stringValue.length/2);for(var i=0;i<stringValue.length/2;i++){value[i]=parseInt(stringValue.slice(i*2,i*2+2),16);}return value;}else{return null;}};_proto.hexadecimalIntegerAsNumber=function hexadecimalIntegerAsNumber(attrName){var intValue=parseInt(this[attrName],16);if(intValue>Number.MAX_SAFE_INTEGER){return Infinity;}return intValue;};_proto.decimalFloatingPoint=function decimalFloatingPoint(attrName){return parseFloat(this[attrName]);};_proto.optionalFloat=function optionalFloat(attrName,defaultValue){var value=this[attrName];return value?parseFloat(value):defaultValue;};_proto.enumeratedString=function enumeratedString(attrName){return this[attrName];};_proto.bool=function bool(attrName){return this[attrName]==='YES';};_proto.decimalResolution=function decimalResolution(attrName){var res=DECIMAL_RESOLUTION_REGEX.exec(this[attrName]);if(res===null){return undefined;}return{width:parseInt(res[1],10),height:parseInt(res[2],10)};};AttrList.parseAttrList=function parseAttrList(input){var match;var attrs={};var quote='"';ATTR_LIST_REGEX.lastIndex=0;while((match=ATTR_LIST_REGEX.exec(input))!==null){var value=match[2];if(value.indexOf(quote)===0&&value.lastIndexOf(quote)===value.length-1){value=value.slice(1,-1);}attrs[match[1]]=value;}return attrs;};return AttrList;}();/***/},/***/"./src/utils/binary-search.ts":/*!************************************!*\
|
|
|
!*** ./src/utils/binary-search.ts ***!
|
|
|
\************************************/ /***/function srcUtilsBinarySearchTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_743749__){"use strict";__nested_webpack_require_743749__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_743749__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});var BinarySearch={/**
|
|
|
* Searches for an item in an array which matches a certain condition.
|
|
|
* This requires the condition to only match one item in the array,
|
|
|
* and for the array to be ordered.
|
|
|
*
|
|
|
* @param {Array<T>} list The array to search.
|
|
|
* @param {BinarySearchComparison<T>} comparisonFn
|
|
|
* Called and provided a candidate item as the first argument.
|
|
|
* Should return:
|
|
|
* > -1 if the item should be located at a lower index than the provided item.
|
|
|
* > 1 if the item should be located at a higher index than the provided item.
|
|
|
* > 0 if the item is the item you're looking for.
|
|
|
*
|
|
|
* @return {T | null} The object if it is found or null otherwise.
|
|
|
*/search:function search(list,comparisonFn){var minIndex=0;var maxIndex=list.length-1;var currentIndex=null;var currentElement=null;while(minIndex<=maxIndex){currentIndex=(minIndex+maxIndex)/2|0;currentElement=list[currentIndex];var comparisonResult=comparisonFn(currentElement);if(comparisonResult>0){minIndex=currentIndex+1;}else if(comparisonResult<0){maxIndex=currentIndex-1;}else{return currentElement;}}return null;}};/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=BinarySearch;/***/},/***/"./src/utils/buffer-helper.ts":/*!************************************!*\
|
|
|
!*** ./src/utils/buffer-helper.ts ***!
|
|
|
\************************************/ /***/function srcUtilsBufferHelperTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_745466__){"use strict";__nested_webpack_require_745466__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_745466__.d(__webpack_exports__,{/* harmony export */"BufferHelper":function BufferHelper(){return(/* binding */_BufferHelper);}/* harmony export */});/* harmony import */var _logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_745466__(/*! ./logger */"./src/utils/logger.ts");/**
|
|
|
* @module BufferHelper
|
|
|
*
|
|
|
* Providing methods dealing with buffer length retrieval for example.
|
|
|
*
|
|
|
* In general, a helper around HTML5 MediaElement TimeRanges gathered from `buffered` property.
|
|
|
*
|
|
|
* Also @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered
|
|
|
*/var noopBuffered={length:0,start:function start(){return 0;},end:function end(){return 0;}};var _BufferHelper=/*#__PURE__*/function(){function BufferHelper(){}/**
|
|
|
* Return true if `media`'s buffered include `position`
|
|
|
* @param {Bufferable} media
|
|
|
* @param {number} position
|
|
|
* @returns {boolean}
|
|
|
*/BufferHelper.isBuffered=function isBuffered(media,position){try{if(media){var buffered=BufferHelper.getBuffered(media);for(var i=0;i<buffered.length;i++){if(position>=buffered.start(i)&&position<=buffered.end(i)){return true;}}}}catch(error){// this is to catch
|
|
|
// InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
|
|
|
// This SourceBuffer has been removed from the parent media source
|
|
|
}return false;};BufferHelper.bufferInfo=function bufferInfo(media,pos,maxHoleDuration){try{if(media){var vbuffered=BufferHelper.getBuffered(media);var buffered=[];var i;for(i=0;i<vbuffered.length;i++){buffered.push({start:vbuffered.start(i),end:vbuffered.end(i)});}return this.bufferedInfo(buffered,pos,maxHoleDuration);}}catch(error){// this is to catch
|
|
|
// InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
|
|
|
// This SourceBuffer has been removed from the parent media source
|
|
|
}return{len:0,start:pos,end:pos,nextStart:undefined};};BufferHelper.bufferedInfo=function bufferedInfo(buffered,pos,maxHoleDuration){pos=Math.max(0,pos);// sort on buffer.start/smaller end (IE does not always return sorted buffered range)
|
|
|
buffered.sort(function(a,b){var diff=a.start-b.start;if(diff){return diff;}else{return b.end-a.end;}});var buffered2=[];if(maxHoleDuration){// there might be some small holes between buffer time range
|
|
|
// consider that holes smaller than maxHoleDuration are irrelevant and build another
|
|
|
// buffer time range representations that discards those holes
|
|
|
for(var i=0;i<buffered.length;i++){var buf2len=buffered2.length;if(buf2len){var buf2end=buffered2[buf2len-1].end;// if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)
|
|
|
if(buffered[i].start-buf2end<maxHoleDuration){// merge overlapping time ranges
|
|
|
// update lastRange.end only if smaller than item.end
|
|
|
// e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end)
|
|
|
// whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])
|
|
|
if(buffered[i].end>buf2end){buffered2[buf2len-1].end=buffered[i].end;}}else{// big hole
|
|
|
buffered2.push(buffered[i]);}}else{// first value
|
|
|
buffered2.push(buffered[i]);}}}else{buffered2=buffered;}var bufferLen=0;// bufferStartNext can possibly be undefined based on the conditional logic below
|
|
|
var bufferStartNext;// bufferStart and bufferEnd are buffer boundaries around current video position
|
|
|
var bufferStart=pos;var bufferEnd=pos;for(var _i=0;_i<buffered2.length;_i++){var start=buffered2[_i].start;var end=buffered2[_i].end;// logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));
|
|
|
if(pos+maxHoleDuration>=start&&pos<end){// play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length
|
|
|
bufferStart=start;bufferEnd=end;bufferLen=bufferEnd-pos;}else if(pos+maxHoleDuration<start){bufferStartNext=start;break;}}return{len:bufferLen,start:bufferStart||0,end:bufferEnd||0,nextStart:bufferStartNext};}/**
|
|
|
* Safe method to get buffered property.
|
|
|
* SourceBuffer.buffered may throw if SourceBuffer is removed from it's MediaSource
|
|
|
*/;BufferHelper.getBuffered=function getBuffered(media){try{return media.buffered;}catch(e){_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log('failed to get media.buffered',e);return noopBuffered;}};return BufferHelper;}();/***/},/***/"./src/utils/cea-608-parser.ts":/*!*************************************!*\
|
|
|
!*** ./src/utils/cea-608-parser.ts ***!
|
|
|
\*************************************/ /***/function srcUtilsCea608ParserTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_750011__){"use strict";__nested_webpack_require_750011__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_750011__.d(__webpack_exports__,{/* harmony export */"CaptionScreen":function CaptionScreen(){return(/* binding */_CaptionScreen);},/* harmony export */"Row":function Row(){return(/* binding */_Row);},/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_750011__(/*! ../utils/logger */"./src/utils/logger.ts");/**
|
|
|
*
|
|
|
* This code was ported from the dash.js project at:
|
|
|
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
|
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
|
*
|
|
|
* The original copyright appears below:
|
|
|
*
|
|
|
* 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) 2015-2016, 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:
|
|
|
* 1. 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.
|
|
|
* 2. 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.
|
|
|
*/ /**
|
|
|
* Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes
|
|
|
*/var specialCea608CharsCodes={0x2a:0xe1,// lowercase a, acute accent
|
|
|
0x5c:0xe9,// lowercase e, acute accent
|
|
|
0x5e:0xed,// lowercase i, acute accent
|
|
|
0x5f:0xf3,// lowercase o, acute accent
|
|
|
0x60:0xfa,// lowercase u, acute accent
|
|
|
0x7b:0xe7,// lowercase c with cedilla
|
|
|
0x7c:0xf7,// division symbol
|
|
|
0x7d:0xd1,// uppercase N tilde
|
|
|
0x7e:0xf1,// lowercase n tilde
|
|
|
0x7f:0x2588,// Full block
|
|
|
// THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
|
|
|
// THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
|
|
|
// THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES
|
|
|
0x80:0xae,// Registered symbol (R)
|
|
|
0x81:0xb0,// degree sign
|
|
|
0x82:0xbd,// 1/2 symbol
|
|
|
0x83:0xbf,// Inverted (open) question mark
|
|
|
0x84:0x2122,// Trademark symbol (TM)
|
|
|
0x85:0xa2,// Cents symbol
|
|
|
0x86:0xa3,// Pounds sterling
|
|
|
0x87:0x266a,// Music 8'th note
|
|
|
0x88:0xe0,// lowercase a, grave accent
|
|
|
0x89:0x20,// transparent space (regular)
|
|
|
0x8a:0xe8,// lowercase e, grave accent
|
|
|
0x8b:0xe2,// lowercase a, circumflex accent
|
|
|
0x8c:0xea,// lowercase e, circumflex accent
|
|
|
0x8d:0xee,// lowercase i, circumflex accent
|
|
|
0x8e:0xf4,// lowercase o, circumflex accent
|
|
|
0x8f:0xfb,// lowercase u, circumflex accent
|
|
|
// THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
|
|
|
// THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
|
|
|
0x90:0xc1,// capital letter A with acute
|
|
|
0x91:0xc9,// capital letter E with acute
|
|
|
0x92:0xd3,// capital letter O with acute
|
|
|
0x93:0xda,// capital letter U with acute
|
|
|
0x94:0xdc,// capital letter U with diaresis
|
|
|
0x95:0xfc,// lowercase letter U with diaeresis
|
|
|
0x96:0x2018,// opening single quote
|
|
|
0x97:0xa1,// inverted exclamation mark
|
|
|
0x98:0x2a,// asterisk
|
|
|
0x99:0x2019,// closing single quote
|
|
|
0x9a:0x2501,// box drawings heavy horizontal
|
|
|
0x9b:0xa9,// copyright sign
|
|
|
0x9c:0x2120,// Service mark
|
|
|
0x9d:0x2022,// (round) bullet
|
|
|
0x9e:0x201c,// Left double quotation mark
|
|
|
0x9f:0x201d,// Right double quotation mark
|
|
|
0xa0:0xc0,// uppercase A, grave accent
|
|
|
0xa1:0xc2,// uppercase A, circumflex
|
|
|
0xa2:0xc7,// uppercase C with cedilla
|
|
|
0xa3:0xc8,// uppercase E, grave accent
|
|
|
0xa4:0xca,// uppercase E, circumflex
|
|
|
0xa5:0xcb,// capital letter E with diaresis
|
|
|
0xa6:0xeb,// lowercase letter e with diaresis
|
|
|
0xa7:0xce,// uppercase I, circumflex
|
|
|
0xa8:0xcf,// uppercase I, with diaresis
|
|
|
0xa9:0xef,// lowercase i, with diaresis
|
|
|
0xaa:0xd4,// uppercase O, circumflex
|
|
|
0xab:0xd9,// uppercase U, grave accent
|
|
|
0xac:0xf9,// lowercase u, grave accent
|
|
|
0xad:0xdb,// uppercase U, circumflex
|
|
|
0xae:0xab,// left-pointing double angle quotation mark
|
|
|
0xaf:0xbb,// right-pointing double angle quotation mark
|
|
|
// THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
|
|
|
// THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
|
|
|
0xb0:0xc3,// Uppercase A, tilde
|
|
|
0xb1:0xe3,// Lowercase a, tilde
|
|
|
0xb2:0xcd,// Uppercase I, acute accent
|
|
|
0xb3:0xcc,// Uppercase I, grave accent
|
|
|
0xb4:0xec,// Lowercase i, grave accent
|
|
|
0xb5:0xd2,// Uppercase O, grave accent
|
|
|
0xb6:0xf2,// Lowercase o, grave accent
|
|
|
0xb7:0xd5,// Uppercase O, tilde
|
|
|
0xb8:0xf5,// Lowercase o, tilde
|
|
|
0xb9:0x7b,// Open curly brace
|
|
|
0xba:0x7d,// Closing curly brace
|
|
|
0xbb:0x5c,// Backslash
|
|
|
0xbc:0x5e,// Caret
|
|
|
0xbd:0x5f,// Underscore
|
|
|
0xbe:0x7c,// Pipe (vertical line)
|
|
|
0xbf:0x223c,// Tilde operator
|
|
|
0xc0:0xc4,// Uppercase A, umlaut
|
|
|
0xc1:0xe4,// Lowercase A, umlaut
|
|
|
0xc2:0xd6,// Uppercase O, umlaut
|
|
|
0xc3:0xf6,// Lowercase o, umlaut
|
|
|
0xc4:0xdf,// Esszett (sharp S)
|
|
|
0xc5:0xa5,// Yen symbol
|
|
|
0xc6:0xa4,// Generic currency sign
|
|
|
0xc7:0x2503,// Box drawings heavy vertical
|
|
|
0xc8:0xc5,// Uppercase A, ring
|
|
|
0xc9:0xe5,// Lowercase A, ring
|
|
|
0xca:0xd8,// Uppercase O, stroke
|
|
|
0xcb:0xf8,// Lowercase o, strok
|
|
|
0xcc:0x250f,// Box drawings heavy down and right
|
|
|
0xcd:0x2513,// Box drawings heavy down and left
|
|
|
0xce:0x2517,// Box drawings heavy up and right
|
|
|
0xcf:0x251b// Box drawings heavy up and left
|
|
|
};/**
|
|
|
* Utils
|
|
|
*/var getCharForByte=function getCharForByte(_byte){var charCode=_byte;if(specialCea608CharsCodes.hasOwnProperty(_byte)){charCode=specialCea608CharsCodes[_byte];}return String.fromCharCode(charCode);};var NR_ROWS=15;var NR_COLS=100;// Tables to look up row from PAC data
|
|
|
var rowsLowCh1={0x11:1,0x12:3,0x15:5,0x16:7,0x17:9,0x10:11,0x13:12,0x14:14};var rowsHighCh1={0x11:2,0x12:4,0x15:6,0x16:8,0x17:10,0x13:13,0x14:15};var rowsLowCh2={0x19:1,0x1a:3,0x1d:5,0x1e:7,0x1f:9,0x18:11,0x1b:12,0x1c:14};var rowsHighCh2={0x19:2,0x1a:4,0x1d:6,0x1e:8,0x1f:10,0x1b:13,0x1c:15};var backgroundColors=['white','green','blue','cyan','red','yellow','magenta','black','transparent'];var VerboseLevel;(function(VerboseLevel){VerboseLevel[VerboseLevel["ERROR"]=0]="ERROR";VerboseLevel[VerboseLevel["TEXT"]=1]="TEXT";VerboseLevel[VerboseLevel["WARNING"]=2]="WARNING";VerboseLevel[VerboseLevel["INFO"]=2]="INFO";VerboseLevel[VerboseLevel["DEBUG"]=3]="DEBUG";VerboseLevel[VerboseLevel["DATA"]=3]="DATA";})(VerboseLevel||(VerboseLevel={}));var CaptionsLogger=/*#__PURE__*/function(){function CaptionsLogger(){this.time=null;this.verboseLevel=VerboseLevel.ERROR;}var _proto=CaptionsLogger.prototype;_proto.log=function log(severity,msg){if(this.verboseLevel>=severity){var m=typeof msg==='function'?msg():msg;_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log(this.time+" ["+severity+"] "+m);}};return CaptionsLogger;}();var numArrayToHexArray=function numArrayToHexArray(numArray){var hexArray=[];for(var j=0;j<numArray.length;j++){hexArray.push(numArray[j].toString(16));}return hexArray;};var PenState=/*#__PURE__*/function(){function PenState(foreground,underline,italics,background,flash){this.foreground=void 0;this.underline=void 0;this.italics=void 0;this.background=void 0;this.flash=void 0;this.foreground=foreground||'white';this.underline=underline||false;this.italics=italics||false;this.background=background||'black';this.flash=flash||false;}var _proto2=PenState.prototype;_proto2.reset=function reset(){this.foreground='white';this.underline=false;this.italics=false;this.background='black';this.flash=false;};_proto2.setStyles=function setStyles(styles){var attribs=['foreground','underline','italics','background','flash'];for(var i=0;i<attribs.length;i++){var style=attribs[i];if(styles.hasOwnProperty(style)){this[style]=styles[style];}}};_proto2.isDefault=function isDefault(){return this.foreground==='white'&&!this.underline&&!this.italics&&this.background==='black'&&!this.flash;};_proto2.equals=function equals(other){return this.foreground===other.foreground&&this.underline===other.underline&&this.italics===other.italics&&this.background===other.background&&this.flash===other.flash;};_proto2.copy=function copy(newPenState){this.foreground=newPenState.foreground;this.underline=newPenState.underline;this.italics=newPenState.italics;this.background=newPenState.background;this.flash=newPenState.flash;};_proto2.toString=function toString(){return'color='+this.foreground+', underline='+this.underline+', italics='+this.italics+', background='+this.background+', flash='+this.flash;};return PenState;}();/**
|
|
|
* Unicode character with styling and background.
|
|
|
* @constructor
|
|
|
*/var StyledUnicodeChar=/*#__PURE__*/function(){function StyledUnicodeChar(uchar,foreground,underline,italics,background,flash){this.uchar=void 0;this.penState=void 0;this.uchar=uchar||' ';// unicode character
|
|
|
this.penState=new PenState(foreground,underline,italics,background,flash);}var _proto3=StyledUnicodeChar.prototype;_proto3.reset=function reset(){this.uchar=' ';this.penState.reset();};_proto3.setChar=function setChar(uchar,newPenState){this.uchar=uchar;this.penState.copy(newPenState);};_proto3.setPenState=function setPenState(newPenState){this.penState.copy(newPenState);};_proto3.equals=function equals(other){return this.uchar===other.uchar&&this.penState.equals(other.penState);};_proto3.copy=function copy(newChar){this.uchar=newChar.uchar;this.penState.copy(newChar.penState);};_proto3.isEmpty=function isEmpty(){return this.uchar===' '&&this.penState.isDefault();};return StyledUnicodeChar;}();/**
|
|
|
* CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
|
|
|
* @constructor
|
|
|
*/var _Row=/*#__PURE__*/function(){function Row(logger){this.chars=void 0;this.pos=void 0;this.currPenState=void 0;this.cueStartTime=void 0;this.logger=void 0;this.chars=[];for(var i=0;i<NR_COLS;i++){this.chars.push(new StyledUnicodeChar());}this.logger=logger;this.pos=0;this.currPenState=new PenState();}var _proto4=Row.prototype;_proto4.equals=function equals(other){var equal=true;for(var i=0;i<NR_COLS;i++){if(!this.chars[i].equals(other.chars[i])){equal=false;break;}}return equal;};_proto4.copy=function copy(other){for(var i=0;i<NR_COLS;i++){this.chars[i].copy(other.chars[i]);}};_proto4.isEmpty=function isEmpty(){var empty=true;for(var i=0;i<NR_COLS;i++){if(!this.chars[i].isEmpty()){empty=false;break;}}return empty;}/**
|
|
|
* Set the cursor to a valid column.
|
|
|
*/;_proto4.setCursor=function setCursor(absPos){if(this.pos!==absPos){this.pos=absPos;}if(this.pos<0){this.logger.log(VerboseLevel.DEBUG,'Negative cursor position '+this.pos);this.pos=0;}else if(this.pos>NR_COLS){this.logger.log(VerboseLevel.DEBUG,'Too large cursor position '+this.pos);this.pos=NR_COLS;}}/**
|
|
|
* Move the cursor relative to current position.
|
|
|
*/;_proto4.moveCursor=function moveCursor(relPos){var newPos=this.pos+relPos;if(relPos>1){for(var i=this.pos+1;i<newPos+1;i++){this.chars[i].setPenState(this.currPenState);}}this.setCursor(newPos);}/**
|
|
|
* Backspace, move one step back and clear character.
|
|
|
*/;_proto4.backSpace=function backSpace(){this.moveCursor(-1);this.chars[this.pos].setChar(' ',this.currPenState);};_proto4.insertChar=function insertChar(_byte2){var _this=this;if(_byte2>=0x90){// Extended char
|
|
|
this.backSpace();}var _char=getCharForByte(_byte2);if(this.pos>=NR_COLS){this.logger.log(VerboseLevel.ERROR,function(){return'Cannot insert '+_byte2.toString(16)+' ('+_char+') at position '+_this.pos+'. Skipping it!';});return;}this.chars[this.pos].setChar(_char,this.currPenState);this.moveCursor(1);};_proto4.clearFromPos=function clearFromPos(startPos){var i;for(i=startPos;i<NR_COLS;i++){this.chars[i].reset();}};_proto4.clear=function clear(){this.clearFromPos(0);this.pos=0;this.currPenState.reset();};_proto4.clearToEndOfRow=function clearToEndOfRow(){this.clearFromPos(this.pos);};_proto4.getTextString=function getTextString(){var chars=[];var empty=true;for(var i=0;i<NR_COLS;i++){var _char2=this.chars[i].uchar;if(_char2!==' '){empty=false;}chars.push(_char2);}if(empty){return'';}else{return chars.join('');}};_proto4.setPenStyles=function setPenStyles(styles){this.currPenState.setStyles(styles);var currChar=this.chars[this.pos];currChar.setPenState(this.currPenState);};return Row;}();/**
|
|
|
* Keep a CEA-608 screen of 32x15 styled characters
|
|
|
* @constructor
|
|
|
*/var _CaptionScreen=/*#__PURE__*/function(){function CaptionScreen(logger){this.rows=void 0;this.currRow=void 0;this.nrRollUpRows=void 0;this.lastOutputScreen=void 0;this.logger=void 0;this.rows=[];for(var i=0;i<NR_ROWS;i++){this.rows.push(new _Row(logger));}// Note that we use zero-based numbering (0-14)
|
|
|
this.logger=logger;this.currRow=NR_ROWS-1;this.nrRollUpRows=null;this.lastOutputScreen=null;this.reset();}var _proto5=CaptionScreen.prototype;_proto5.reset=function reset(){for(var i=0;i<NR_ROWS;i++){this.rows[i].clear();}this.currRow=NR_ROWS-1;};_proto5.equals=function equals(other){var equal=true;for(var i=0;i<NR_ROWS;i++){if(!this.rows[i].equals(other.rows[i])){equal=false;break;}}return equal;};_proto5.copy=function copy(other){for(var i=0;i<NR_ROWS;i++){this.rows[i].copy(other.rows[i]);}};_proto5.isEmpty=function isEmpty(){var empty=true;for(var i=0;i<NR_ROWS;i++){if(!this.rows[i].isEmpty()){empty=false;break;}}return empty;};_proto5.backSpace=function backSpace(){var row=this.rows[this.currRow];row.backSpace();};_proto5.clearToEndOfRow=function clearToEndOfRow(){var row=this.rows[this.currRow];row.clearToEndOfRow();}/**
|
|
|
* Insert a character (without styling) in the current row.
|
|
|
*/;_proto5.insertChar=function insertChar(_char3){var row=this.rows[this.currRow];row.insertChar(_char3);};_proto5.setPen=function setPen(styles){var row=this.rows[this.currRow];row.setPenStyles(styles);};_proto5.moveCursor=function moveCursor(relPos){var row=this.rows[this.currRow];row.moveCursor(relPos);};_proto5.setCursor=function setCursor(absPos){this.logger.log(VerboseLevel.INFO,'setCursor: '+absPos);var row=this.rows[this.currRow];row.setCursor(absPos);};_proto5.setPAC=function setPAC(pacData){this.logger.log(VerboseLevel.INFO,function(){return'pacData = '+JSON.stringify(pacData);});var newRow=pacData.row-1;if(this.nrRollUpRows&&newRow<this.nrRollUpRows-1){newRow=this.nrRollUpRows-1;}// Make sure this only affects Roll-up Captions by checking this.nrRollUpRows
|
|
|
if(this.nrRollUpRows&&this.currRow!==newRow){// clear all rows first
|
|
|
for(var i=0;i<NR_ROWS;i++){this.rows[i].clear();}// Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location
|
|
|
// topRowIndex - the start of rows to copy (inclusive index)
|
|
|
var topRowIndex=this.currRow+1-this.nrRollUpRows;// We only copy if the last position was already shown.
|
|
|
// We use the cueStartTime value to check this.
|
|
|
var lastOutputScreen=this.lastOutputScreen;if(lastOutputScreen){var prevLineTime=lastOutputScreen.rows[topRowIndex].cueStartTime;var time=this.logger.time;if(prevLineTime&&time!==null&&prevLineTime<time){for(var _i=0;_i<this.nrRollUpRows;_i++){this.rows[newRow-this.nrRollUpRows+_i+1].copy(lastOutputScreen.rows[topRowIndex+_i]);}}}}this.currRow=newRow;var row=this.rows[this.currRow];if(pacData.indent!==null){var indent=pacData.indent;var prevPos=Math.max(indent-1,0);row.setCursor(pacData.indent);pacData.color=row.chars[prevPos].penState.foreground;}var styles={foreground:pacData.color,underline:pacData.underline,italics:pacData.italics,background:'black',flash:false};this.setPen(styles);}/**
|
|
|
* Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility).
|
|
|
*/;_proto5.setBkgData=function setBkgData(bkgData){this.logger.log(VerboseLevel.INFO,function(){return'bkgData = '+JSON.stringify(bkgData);});this.backSpace();this.setPen(bkgData);this.insertChar(0x20);// Space
|
|
|
};_proto5.setRollUpRows=function setRollUpRows(nrRows){this.nrRollUpRows=nrRows;};_proto5.rollUp=function rollUp(){var _this2=this;if(this.nrRollUpRows===null){this.logger.log(VerboseLevel.DEBUG,'roll_up but nrRollUpRows not set yet');return;// Not properly setup
|
|
|
}this.logger.log(VerboseLevel.TEXT,function(){return _this2.getDisplayText();});var topRowIndex=this.currRow+1-this.nrRollUpRows;var topRow=this.rows.splice(topRowIndex,1)[0];topRow.clear();this.rows.splice(this.currRow,0,topRow);this.logger.log(VerboseLevel.INFO,'Rolling up');// this.logger.log(VerboseLevel.TEXT, this.get_display_text())
|
|
|
}/**
|
|
|
* Get all non-empty rows with as unicode text.
|
|
|
*/;_proto5.getDisplayText=function getDisplayText(asOneRow){asOneRow=asOneRow||false;var displayText=[];var text='';var rowNr=-1;for(var i=0;i<NR_ROWS;i++){var rowText=this.rows[i].getTextString();if(rowText){rowNr=i+1;if(asOneRow){displayText.push('Row '+rowNr+": '"+rowText+"'");}else{displayText.push(rowText.trim());}}}if(displayText.length>0){if(asOneRow){text='['+displayText.join(' | ')+']';}else{text=displayText.join('\n');}}return text;};_proto5.getTextAndFormat=function getTextAndFormat(){return this.rows;};return CaptionScreen;}();// var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT'];
|
|
|
var Cea608Channel=/*#__PURE__*/function(){function Cea608Channel(channelNumber,outputFilter,logger){this.chNr=void 0;this.outputFilter=void 0;this.mode=void 0;this.verbose=void 0;this.displayedMemory=void 0;this.nonDisplayedMemory=void 0;this.lastOutputScreen=void 0;this.currRollUpRow=void 0;this.writeScreen=void 0;this.cueStartTime=void 0;this.logger=void 0;this.chNr=channelNumber;this.outputFilter=outputFilter;this.mode=null;this.verbose=0;this.displayedMemory=new _CaptionScreen(logger);this.nonDisplayedMemory=new _CaptionScreen(logger);this.lastOutputScreen=new _CaptionScreen(logger);this.currRollUpRow=this.displayedMemory.rows[NR_ROWS-1];this.writeScreen=this.displayedMemory;this.mode=null;this.cueStartTime=null;// Keeps track of where a cue started.
|
|
|
this.logger=logger;}var _proto6=Cea608Channel.prototype;_proto6.reset=function reset(){this.mode=null;this.displayedMemory.reset();this.nonDisplayedMemory.reset();this.lastOutputScreen.reset();this.outputFilter.reset();this.currRollUpRow=this.displayedMemory.rows[NR_ROWS-1];this.writeScreen=this.displayedMemory;this.mode=null;this.cueStartTime=null;};_proto6.getHandler=function getHandler(){return this.outputFilter;};_proto6.setHandler=function setHandler(newHandler){this.outputFilter=newHandler;};_proto6.setPAC=function setPAC(pacData){this.writeScreen.setPAC(pacData);};_proto6.setBkgData=function setBkgData(bkgData){this.writeScreen.setBkgData(bkgData);};_proto6.setMode=function setMode(newMode){if(newMode===this.mode){return;}this.mode=newMode;this.logger.log(VerboseLevel.INFO,function(){return'MODE='+newMode;});if(this.mode==='MODE_POP-ON'){this.writeScreen=this.nonDisplayedMemory;}else{this.writeScreen=this.displayedMemory;this.writeScreen.reset();}if(this.mode!=='MODE_ROLL-UP'){this.displayedMemory.nrRollUpRows=null;this.nonDisplayedMemory.nrRollUpRows=null;}this.mode=newMode;};_proto6.insertChars=function insertChars(chars){var _this3=this;for(var i=0;i<chars.length;i++){this.writeScreen.insertChar(chars[i]);}var screen=this.writeScreen===this.displayedMemory?'DISP':'NON_DISP';this.logger.log(VerboseLevel.INFO,function(){return screen+': '+_this3.writeScreen.getDisplayText(true);});if(this.mode==='MODE_PAINT-ON'||this.mode==='MODE_ROLL-UP'){this.logger.log(VerboseLevel.TEXT,function(){return'DISPLAYED: '+_this3.displayedMemory.getDisplayText(true);});this.outputDataUpdate();}};_proto6.ccRCL=function ccRCL(){// Resume Caption Loading (switch mode to Pop On)
|
|
|
this.logger.log(VerboseLevel.INFO,'RCL - Resume Caption Loading');this.setMode('MODE_POP-ON');};_proto6.ccBS=function ccBS(){// BackSpace
|
|
|
this.logger.log(VerboseLevel.INFO,'BS - BackSpace');if(this.mode==='MODE_TEXT'){return;}this.writeScreen.backSpace();if(this.writeScreen===this.displayedMemory){this.outputDataUpdate();}};_proto6.ccAOF=function ccAOF(){// Reserved (formerly Alarm Off)
|
|
|
};_proto6.ccAON=function ccAON(){// Reserved (formerly Alarm On)
|
|
|
};_proto6.ccDER=function ccDER(){// Delete to End of Row
|
|
|
this.logger.log(VerboseLevel.INFO,'DER- Delete to End of Row');this.writeScreen.clearToEndOfRow();this.outputDataUpdate();};_proto6.ccRU=function ccRU(nrRows){// Roll-Up Captions-2,3,or 4 Rows
|
|
|
this.logger.log(VerboseLevel.INFO,'RU('+nrRows+') - Roll Up');this.writeScreen=this.displayedMemory;this.setMode('MODE_ROLL-UP');this.writeScreen.setRollUpRows(nrRows);};_proto6.ccFON=function ccFON(){// Flash On
|
|
|
this.logger.log(VerboseLevel.INFO,'FON - Flash On');this.writeScreen.setPen({flash:true});};_proto6.ccRDC=function ccRDC(){// Resume Direct Captioning (switch mode to PaintOn)
|
|
|
this.logger.log(VerboseLevel.INFO,'RDC - Resume Direct Captioning');this.setMode('MODE_PAINT-ON');};_proto6.ccTR=function ccTR(){// Text Restart in text mode (not supported, however)
|
|
|
this.logger.log(VerboseLevel.INFO,'TR');this.setMode('MODE_TEXT');};_proto6.ccRTD=function ccRTD(){// Resume Text Display in Text mode (not supported, however)
|
|
|
this.logger.log(VerboseLevel.INFO,'RTD');this.setMode('MODE_TEXT');};_proto6.ccEDM=function ccEDM(){// Erase Displayed Memory
|
|
|
this.logger.log(VerboseLevel.INFO,'EDM - Erase Displayed Memory');this.displayedMemory.reset();this.outputDataUpdate(true);};_proto6.ccCR=function ccCR(){// Carriage Return
|
|
|
this.logger.log(VerboseLevel.INFO,'CR - Carriage Return');this.writeScreen.rollUp();this.outputDataUpdate(true);};_proto6.ccENM=function ccENM(){// Erase Non-Displayed Memory
|
|
|
this.logger.log(VerboseLevel.INFO,'ENM - Erase Non-displayed Memory');this.nonDisplayedMemory.reset();};_proto6.ccEOC=function ccEOC(){var _this4=this;// End of Caption (Flip Memories)
|
|
|
this.logger.log(VerboseLevel.INFO,'EOC - End Of Caption');if(this.mode==='MODE_POP-ON'){var tmp=this.displayedMemory;this.displayedMemory=this.nonDisplayedMemory;this.nonDisplayedMemory=tmp;this.writeScreen=this.nonDisplayedMemory;this.logger.log(VerboseLevel.TEXT,function(){return'DISP: '+_this4.displayedMemory.getDisplayText();});}this.outputDataUpdate(true);};_proto6.ccTO=function ccTO(nrCols){// Tab Offset 1,2, or 3 columns
|
|
|
this.logger.log(VerboseLevel.INFO,'TO('+nrCols+') - Tab Offset');this.writeScreen.moveCursor(nrCols);};_proto6.ccMIDROW=function ccMIDROW(secondByte){// Parse MIDROW command
|
|
|
var styles={flash:false};styles.underline=secondByte%2===1;styles.italics=secondByte>=0x2e;if(!styles.italics){var colorIndex=Math.floor(secondByte/2)-0x10;var colors=['white','green','blue','cyan','red','yellow','magenta'];styles.foreground=colors[colorIndex];}else{styles.foreground='white';}this.logger.log(VerboseLevel.INFO,'MIDROW: '+JSON.stringify(styles));this.writeScreen.setPen(styles);};_proto6.outputDataUpdate=function outputDataUpdate(dispatch){if(dispatch===void 0){dispatch=false;}var time=this.logger.time;if(time===null){return;}if(this.outputFilter){if(this.cueStartTime===null&&!this.displayedMemory.isEmpty()){// Start of a new cue
|
|
|
this.cueStartTime=time;}else{if(!this.displayedMemory.equals(this.lastOutputScreen)){this.outputFilter.newCue(this.cueStartTime,time,this.lastOutputScreen);if(dispatch&&this.outputFilter.dispatchCue){this.outputFilter.dispatchCue();}this.cueStartTime=this.displayedMemory.isEmpty()?null:time;}}this.lastOutputScreen.copy(this.displayedMemory);}};_proto6.cueSplitAtTime=function cueSplitAtTime(t){if(this.outputFilter){if(!this.displayedMemory.isEmpty()){if(this.outputFilter.newCue){this.outputFilter.newCue(this.cueStartTime,t,this.displayedMemory);}this.cueStartTime=t;}}};return Cea608Channel;}();var Cea608Parser=/*#__PURE__*/function(){function Cea608Parser(field,out1,out2){this.channels=void 0;this.currentChannel=0;this.cmdHistory=void 0;this.logger=void 0;var logger=new CaptionsLogger();this.channels=[null,new Cea608Channel(field,out1,logger),new Cea608Channel(field+1,out2,logger)];this.cmdHistory=createCmdHistory();this.logger=logger;}var _proto7=Cea608Parser.prototype;_proto7.getHandler=function getHandler(channel){return this.channels[channel].getHandler();};_proto7.setHandler=function setHandler(channel,newHandler){this.channels[channel].setHandler(newHandler);}/**
|
|
|
* Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs.
|
|
|
*/;_proto7.addData=function addData(time,byteList){var cmdFound;var a;var b;var charsFound=false;this.logger.time=time;for(var i=0;i<byteList.length;i+=2){a=byteList[i]&0x7f;b=byteList[i+1]&0x7f;if(a===0&&b===0){continue;}else{this.logger.log(VerboseLevel.DATA,'['+numArrayToHexArray([byteList[i],byteList[i+1]])+'] -> ('+numArrayToHexArray([a,b])+')');}cmdFound=this.parseCmd(a,b);if(!cmdFound){cmdFound=this.parseMidrow(a,b);}if(!cmdFound){cmdFound=this.parsePAC(a,b);}if(!cmdFound){cmdFound=this.parseBackgroundAttributes(a,b);}if(!cmdFound){charsFound=this.parseChars(a,b);if(charsFound){var currChNr=this.currentChannel;if(currChNr&&currChNr>0){var channel=this.channels[currChNr];channel.insertChars(charsFound);}else{this.logger.log(VerboseLevel.WARNING,'No channel found yet. TEXT-MODE?');}}}if(!cmdFound&&!charsFound){this.logger.log(VerboseLevel.WARNING,"Couldn't parse cleaned data "+numArrayToHexArray([a,b])+' orig: '+numArrayToHexArray([byteList[i],byteList[i+1]]));}}}/**
|
|
|
* Parse Command.
|
|
|
* @returns {Boolean} Tells if a command was found
|
|
|
*/;_proto7.parseCmd=function parseCmd(a,b){var cmdHistory=this.cmdHistory;var cond1=(a===0x14||a===0x1c||a===0x15||a===0x1d)&&b>=0x20&&b<=0x2f;var cond2=(a===0x17||a===0x1f)&&b>=0x21&&b<=0x23;if(!(cond1||cond2)){return false;}if(hasCmdRepeated(a,b,cmdHistory)){setLastCmd(null,null,cmdHistory);this.logger.log(VerboseLevel.DEBUG,'Repeated command ('+numArrayToHexArray([a,b])+') is dropped');return true;}var chNr=a===0x14||a===0x15||a===0x17?1:2;var channel=this.channels[chNr];if(a===0x14||a===0x15||a===0x1c||a===0x1d){if(b===0x20){channel.ccRCL();}else if(b===0x21){channel.ccBS();}else if(b===0x22){channel.ccAOF();}else if(b===0x23){channel.ccAON();}else if(b===0x24){channel.ccDER();}else if(b===0x25){channel.ccRU(2);}else if(b===0x26){channel.ccRU(3);}else if(b===0x27){channel.ccRU(4);}else if(b===0x28){channel.ccFON();}else if(b===0x29){channel.ccRDC();}else if(b===0x2a){channel.ccTR();}else if(b===0x2b){channel.ccRTD();}else if(b===0x2c){channel.ccEDM();}else if(b===0x2d){channel.ccCR();}else if(b===0x2e){channel.ccENM();}else if(b===0x2f){channel.ccEOC();}}else{// a == 0x17 || a == 0x1F
|
|
|
channel.ccTO(b-0x20);}setLastCmd(a,b,cmdHistory);this.currentChannel=chNr;return true;}/**
|
|
|
* Parse midrow styling command
|
|
|
* @returns {Boolean}
|
|
|
*/;_proto7.parseMidrow=function parseMidrow(a,b){var chNr=0;if((a===0x11||a===0x19)&&b>=0x20&&b<=0x2f){if(a===0x11){chNr=1;}else{chNr=2;}if(chNr!==this.currentChannel){this.logger.log(VerboseLevel.ERROR,'Mismatch channel in midrow parsing');return false;}var channel=this.channels[chNr];if(!channel){return false;}channel.ccMIDROW(b);this.logger.log(VerboseLevel.DEBUG,'MIDROW ('+numArrayToHexArray([a,b])+')');return true;}return false;}/**
|
|
|
* Parse Preable Access Codes (Table 53).
|
|
|
* @returns {Boolean} Tells if PAC found
|
|
|
*/;_proto7.parsePAC=function parsePAC(a,b){var row;var cmdHistory=this.cmdHistory;var case1=(a>=0x11&&a<=0x17||a>=0x19&&a<=0x1f)&&b>=0x40&&b<=0x7f;var case2=(a===0x10||a===0x18)&&b>=0x40&&b<=0x5f;if(!(case1||case2)){return false;}if(hasCmdRepeated(a,b,cmdHistory)){setLastCmd(null,null,cmdHistory);return true;// Repeated commands are dropped (once)
|
|
|
}var chNr=a<=0x17?1:2;if(b>=0x40&&b<=0x5f){row=chNr===1?rowsLowCh1[a]:rowsLowCh2[a];}else{// 0x60 <= b <= 0x7F
|
|
|
row=chNr===1?rowsHighCh1[a]:rowsHighCh2[a];}var channel=this.channels[chNr];if(!channel){return false;}channel.setPAC(this.interpretPAC(row,b));setLastCmd(a,b,cmdHistory);this.currentChannel=chNr;return true;}/**
|
|
|
* Interpret the second byte of the pac, and return the information.
|
|
|
* @returns {Object} pacData with style parameters.
|
|
|
*/;_proto7.interpretPAC=function interpretPAC(row,_byte3){var pacIndex;var pacData={color:null,italics:false,indent:null,underline:false,row:row};if(_byte3>0x5f){pacIndex=_byte3-0x60;}else{pacIndex=_byte3-0x40;}pacData.underline=(pacIndex&1)===1;if(pacIndex<=0xd){pacData.color=['white','green','blue','cyan','red','yellow','magenta','white'][Math.floor(pacIndex/2)];}else if(pacIndex<=0xf){pacData.italics=true;pacData.color='white';}else{pacData.indent=Math.floor((pacIndex-0x10)/2)*4;}return pacData;// Note that row has zero offset. The spec uses 1.
|
|
|
}/**
|
|
|
* Parse characters.
|
|
|
* @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise.
|
|
|
*/;_proto7.parseChars=function parseChars(a,b){var channelNr;var charCodes=null;var charCode1=null;if(a>=0x19){channelNr=2;charCode1=a-8;}else{channelNr=1;charCode1=a;}if(charCode1>=0x11&&charCode1<=0x13){// Special character
|
|
|
var oneCode;if(charCode1===0x11){oneCode=b+0x50;}else if(charCode1===0x12){oneCode=b+0x70;}else{oneCode=b+0x90;}this.logger.log(VerboseLevel.INFO,"Special char '"+getCharForByte(oneCode)+"' in channel "+channelNr);charCodes=[oneCode];}else if(a>=0x20&&a<=0x7f){charCodes=b===0?[a]:[a,b];}if(charCodes){var hexCodes=numArrayToHexArray(charCodes);this.logger.log(VerboseLevel.DEBUG,'Char codes = '+hexCodes.join(','));setLastCmd(a,b,this.cmdHistory);}return charCodes;}/**
|
|
|
* Parse extended background attributes as well as new foreground color black.
|
|
|
* @returns {Boolean} Tells if background attributes are found
|
|
|
*/;_proto7.parseBackgroundAttributes=function parseBackgroundAttributes(a,b){var case1=(a===0x10||a===0x18)&&b>=0x20&&b<=0x2f;var case2=(a===0x17||a===0x1f)&&b>=0x2d&&b<=0x2f;if(!(case1||case2)){return false;}var index;var bkgData={};if(a===0x10||a===0x18){index=Math.floor((b-0x20)/2);bkgData.background=backgroundColors[index];if(b%2===1){bkgData.background=bkgData.background+'_semi';}}else if(b===0x2d){bkgData.background='transparent';}else{bkgData.foreground='black';if(b===0x2f){bkgData.underline=true;}}var chNr=a<=0x17?1:2;var channel=this.channels[chNr];channel.setBkgData(bkgData);setLastCmd(a,b,this.cmdHistory);return true;}/**
|
|
|
* Reset state of parser and its channels.
|
|
|
*/;_proto7.reset=function reset(){for(var i=0;i<Object.keys(this.channels).length;i++){var channel=this.channels[i];if(channel){channel.reset();}}this.cmdHistory=createCmdHistory();}/**
|
|
|
* Trigger the generation of a cue, and the start of a new one if displayScreens are not empty.
|
|
|
*/;_proto7.cueSplitAtTime=function cueSplitAtTime(t){for(var i=0;i<this.channels.length;i++){var channel=this.channels[i];if(channel){channel.cueSplitAtTime(t);}}};return Cea608Parser;}();function setLastCmd(a,b,cmdHistory){cmdHistory.a=a;cmdHistory.b=b;}function hasCmdRepeated(a,b,cmdHistory){return cmdHistory.a===a&&cmdHistory.b===b;}function createCmdHistory(){return{a:null,b:null};}/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=Cea608Parser;/***/},/***/"./src/utils/codecs.ts":/*!*****************************!*\
|
|
|
!*** ./src/utils/codecs.ts ***!
|
|
|
\*****************************/ /***/function srcUtilsCodecsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_782126__){"use strict";__nested_webpack_require_782126__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_782126__.d(__webpack_exports__,{/* harmony export */"isCodecSupportedInMp4":function isCodecSupportedInMp4(){return(/* binding */_isCodecSupportedInMp);},/* harmony export */"isCodecType":function isCodecType(){return(/* binding */_isCodecType);}/* harmony export */});// from http://mp4ra.org/codecs.html
|
|
|
var sampleEntryCodesISO={audio:{a3ds:true,'ac-3':true,'ac-4':true,alac:true,alaw:true,dra1:true,'dts+':true,'dts-':true,dtsc:true,dtse:true,dtsh:true,'ec-3':true,enca:true,g719:true,g726:true,m4ae:true,mha1:true,mha2:true,mhm1:true,mhm2:true,mlpa:true,mp4a:true,'raw ':true,Opus:true,opus:true,// browsers expect this to be lowercase despite MP4RA says 'Opus'
|
|
|
samr:true,sawb:true,sawp:true,sevc:true,sqcp:true,ssmv:true,twos:true,ulaw:true},video:{avc1:true,avc2:true,avc3:true,avc4:true,avcp:true,av01:true,drac:true,dva1:true,dvav:true,dvh1:true,dvhe:true,encv:true,hev1:true,hvc1:true,mjp2:true,mp4v:true,mvc1:true,mvc2:true,mvc3:true,mvc4:true,resv:true,rv60:true,s263:true,svc1:true,svc2:true,'vc-1':true,vp08:true,vp09:true},text:{stpp:true,wvtt:true}};function _isCodecType(codec,type){var typeCodes=sampleEntryCodesISO[type];return!!typeCodes&&typeCodes[codec.slice(0,4)]===true;}function _isCodecSupportedInMp(codec,type){return MediaSource.isTypeSupported((type||'video')+"/mp4;codecs=\""+codec+"\"");}/***/},/***/"./src/utils/cues.ts":/*!***************************!*\
|
|
|
!*** ./src/utils/cues.ts ***!
|
|
|
\***************************/ /***/function srcUtilsCuesTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_783757__){"use strict";__nested_webpack_require_783757__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_783757__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _vttparser__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_783757__(/*! ./vttparser */"./src/utils/vttparser.ts");/* harmony import */var _webvtt_parser__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_783757__(/*! ./webvtt-parser */"./src/utils/webvtt-parser.ts");/* harmony import */var _texttrack_utils__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_783757__(/*! ./texttrack-utils */"./src/utils/texttrack-utils.ts");var WHITESPACE_CHAR=/\s/;var Cues={newCue:function newCue(track,startTime,endTime,captionScreen){var result=[];var row;// the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers
|
|
|
var cue;var indenting;var indent;var text;var Cue=self.VTTCue||self.TextTrackCue;for(var r=0;r<captionScreen.rows.length;r++){row=captionScreen.rows[r];indenting=true;indent=0;text='';if(!row.isEmpty()){for(var c=0;c<row.chars.length;c++){if(WHITESPACE_CHAR.test(row.chars[c].uchar)&&indenting){indent++;}else{text+=row.chars[c].uchar;indenting=false;}}// To be used for cleaning-up orphaned roll-up captions
|
|
|
row.cueStartTime=startTime;// Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
|
|
|
if(startTime===endTime){endTime+=0.0001;}if(indent>=16){indent--;}else{indent++;}var cueText=(0,_vttparser__WEBPACK_IMPORTED_MODULE_0__.fixLineBreaks)(text.trim());var id=(0,_webvtt_parser__WEBPACK_IMPORTED_MODULE_1__.generateCueId)(startTime,endTime,cueText);// If this cue already exists in the track do not push it
|
|
|
if(!track||!track.cues||!track.cues.getCueById(id)){cue=new Cue(startTime,endTime,cueText);cue.id=id;cue.line=r+1;cue.align='left';// Clamp the position between 10 and 80 percent (CEA-608 PAC indent code)
|
|
|
// https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/608toVTT.html#positioning-in-cea-608
|
|
|
// Firefox throws an exception and captions break with out of bounds 0-100 values
|
|
|
cue.position=10+Math.min(80,Math.floor(indent*8/32)*10);result.push(cue);}}}if(track&&result.length){// Sort bottom cues in reverse order so that they render in line order when overlapping in Chrome
|
|
|
result.sort(function(cueA,cueB){if(cueA.line==='auto'||cueB.line==='auto'){return 0;}if(cueA.line>8&&cueB.line>8){return cueB.line-cueA.line;}return cueA.line-cueB.line;});result.forEach(function(cue){return(0,_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.addCueToTrack)(track,cue);});}return result;}};/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=Cues;/***/},/***/"./src/utils/discontinuities.ts":/*!**************************************!*\
|
|
|
!*** ./src/utils/discontinuities.ts ***!
|
|
|
\**************************************/ /***/function srcUtilsDiscontinuitiesTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_786702__){"use strict";__nested_webpack_require_786702__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_786702__.d(__webpack_exports__,{/* harmony export */"adjustSlidingStart":function adjustSlidingStart(){return(/* binding */_adjustSlidingStart);},/* harmony export */"alignMediaPlaylistByPDT":function alignMediaPlaylistByPDT(){return(/* binding */_alignMediaPlaylistByPDT);},/* harmony export */"alignPDT":function alignPDT(){return(/* binding */_alignPDT);},/* harmony export */"alignStream":function alignStream(){return(/* binding */_alignStream);},/* harmony export */"findDiscontinuousReferenceFrag":function findDiscontinuousReferenceFrag(){return(/* binding */_findDiscontinuousReferenceFrag);},/* harmony export */"findFirstFragWithCC":function findFirstFragWithCC(){return(/* binding */_findFirstFragWithCC);},/* harmony export */"shouldAlignOnDiscontinuities":function shouldAlignOnDiscontinuities(){return(/* binding */_shouldAlignOnDiscontinuities);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_786702__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _logger__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_786702__(/*! ./logger */"./src/utils/logger.ts");/* harmony import */var _controller_level_helper__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_786702__(/*! ../controller/level-helper */"./src/controller/level-helper.ts");function _findFirstFragWithCC(fragments,cc){var firstFrag=null;for(var i=0,len=fragments.length;i<len;i++){var currentFrag=fragments[i];if(currentFrag&¤tFrag.cc===cc){firstFrag=currentFrag;break;}}return firstFrag;}function _shouldAlignOnDiscontinuities(lastFrag,lastLevel,details){if(lastLevel.details){if(details.endCC>details.startCC||lastFrag&&lastFrag.cc<details.startCC){return true;}}return false;}// Find the first frag in the previous level which matches the CC of the first frag of the new level
|
|
|
function _findDiscontinuousReferenceFrag(prevDetails,curDetails,referenceIndex){if(referenceIndex===void 0){referenceIndex=0;}var prevFrags=prevDetails.fragments;var curFrags=curDetails.fragments;if(!curFrags.length||!prevFrags.length){_logger__WEBPACK_IMPORTED_MODULE_1__.logger.log('No fragments to align');return;}var prevStartFrag=_findFirstFragWithCC(prevFrags,curFrags[0].cc);if(!prevStartFrag||prevStartFrag&&!prevStartFrag.startPTS){_logger__WEBPACK_IMPORTED_MODULE_1__.logger.log('No frag in previous level to align on');return;}return prevStartFrag;}function adjustFragmentStart(frag,sliding){if(frag){var start=frag.start+sliding;frag.start=frag.startPTS=start;frag.endPTS=start+frag.duration;}}function _adjustSlidingStart(sliding,details){// Update segments
|
|
|
var fragments=details.fragments;for(var i=0,len=fragments.length;i<len;i++){adjustFragmentStart(fragments[i],sliding);}// Update LL-HLS parts at the end of the playlist
|
|
|
if(details.fragmentHint){adjustFragmentStart(details.fragmentHint,sliding);}details.alignedSliding=true;}/**
|
|
|
* Using the parameters of the last level, this function computes PTS' of the new fragments so that they form a
|
|
|
* contiguous stream with the last fragments.
|
|
|
* The PTS of a fragment lets Hls.js know where it fits into a stream - by knowing every PTS, we know which fragment to
|
|
|
* download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time
|
|
|
* and an extra download.
|
|
|
* @param lastFrag
|
|
|
* @param lastLevel
|
|
|
* @param details
|
|
|
*/function _alignStream(lastFrag,lastLevel,details){if(!lastLevel){return;}alignDiscontinuities(lastFrag,details,lastLevel);if(!details.alignedSliding&&lastLevel.details){// If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level.
|
|
|
// Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same
|
|
|
// discontinuity sequence.
|
|
|
_alignPDT(details,lastLevel.details);}if(!details.alignedSliding&&lastLevel.details&&!details.skippedSegments){// Try to align on sn so that we pick a better start fragment.
|
|
|
// Do not perform this on playlists with delta updates as this is only to align levels on switch
|
|
|
// and adjustSliding only adjusts fragments after skippedSegments.
|
|
|
(0,_controller_level_helper__WEBPACK_IMPORTED_MODULE_2__.adjustSliding)(lastLevel.details,details);}}/**
|
|
|
* Computes the PTS if a new level's fragments using the PTS of a fragment in the last level which shares the same
|
|
|
* discontinuity sequence.
|
|
|
* @param lastFrag - The last Fragment which shares the same discontinuity sequence
|
|
|
* @param lastLevel - The details of the last loaded level
|
|
|
* @param details - The details of the new level
|
|
|
*/function alignDiscontinuities(lastFrag,details,lastLevel){if(_shouldAlignOnDiscontinuities(lastFrag,lastLevel,details)){var referenceFrag=_findDiscontinuousReferenceFrag(lastLevel.details,details);if(referenceFrag&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(referenceFrag.start)){_logger__WEBPACK_IMPORTED_MODULE_1__.logger.log("Adjusting PTS using last level due to CC increase within current level "+details.url);_adjustSlidingStart(referenceFrag.start,details);}}}/**
|
|
|
* Computes the PTS of a new level's fragments using the difference in Program Date Time from the last level.
|
|
|
* @param details - The details of the new level
|
|
|
* @param lastDetails - The details of the last loaded level
|
|
|
*/function _alignPDT(details,lastDetails){// This check protects the unsafe "!" usage below for null program date time access.
|
|
|
if(!lastDetails.fragments.length||!details.hasProgramDateTime||!lastDetails.hasProgramDateTime){return;}// if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM
|
|
|
// and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM
|
|
|
// then we can deduce that playlist B sliding is 1000+8 = 1008s
|
|
|
var lastPDT=lastDetails.fragments[0].programDateTime;// hasProgramDateTime check above makes this safe.
|
|
|
var newPDT=details.fragments[0].programDateTime;// date diff is in ms. frag.start is in seconds
|
|
|
var sliding=(newPDT-lastPDT)/1000+lastDetails.fragments[0].start;if(sliding&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(sliding)){_logger__WEBPACK_IMPORTED_MODULE_1__.logger.log("Adjusting PTS using programDateTime delta "+(newPDT-lastPDT)+"ms, sliding:"+sliding.toFixed(3)+" "+details.url+" ");_adjustSlidingStart(sliding,details);}}/**
|
|
|
* Ensures appropriate time-alignment between renditions based on PDT. Unlike `alignPDT`, which adjusts
|
|
|
* the timeline based on the delta between PDTs of the 0th fragment of two playlists/`LevelDetails`,
|
|
|
* this function assumes the timelines represented in `refDetails` are accurate, including the PDTs,
|
|
|
* and uses the "wallclock"/PDT timeline as a cross-reference to `details`, adjusting the presentation
|
|
|
* times/timelines of `details` accordingly.
|
|
|
* Given the asynchronous nature of fetches and initial loads of live `main` and audio/subtitle tracks,
|
|
|
* the primary purpose of this function is to ensure the "local timelines" of audio/subtitle tracks
|
|
|
* are aligned to the main/video timeline, using PDT as the cross-reference/"anchor" that should
|
|
|
* be consistent across playlists, per the HLS spec.
|
|
|
* @param details - The details of the rendition you'd like to time-align (e.g. an audio rendition).
|
|
|
* @param refDetails - The details of the reference rendition with start and PDT times for alignment.
|
|
|
*/function _alignMediaPlaylistByPDT(details,refDetails){if(!details.hasProgramDateTime||!refDetails.hasProgramDateTime){return;}var fragments=details.fragments;var refFragments=refDetails.fragments;if(!fragments.length||!refFragments.length){return;}// Calculate a delta to apply to all fragments according to the delta in PDT times and start times
|
|
|
// of a fragment in the reference details, and a fragment in the target details of the same discontinuity.
|
|
|
// If a fragment of the same discontinuity was not found use the middle fragment of both.
|
|
|
var middleFrag=Math.round(refFragments.length/2)-1;var refFrag=refFragments[middleFrag];var frag=_findFirstFragWithCC(fragments,refFrag.cc)||fragments[Math.round(fragments.length/2)-1];var refPDT=refFrag.programDateTime;var targetPDT=frag.programDateTime;if(refPDT===null||targetPDT===null){return;}var delta=(targetPDT-refPDT)/1000-(frag.start-refFrag.start);_adjustSlidingStart(delta,details);}/***/},/***/"./src/utils/ewma-bandwidth-estimator.ts":/*!***********************************************!*\
|
|
|
!*** ./src/utils/ewma-bandwidth-estimator.ts ***!
|
|
|
\***********************************************/ /***/function srcUtilsEwmaBandwidthEstimatorTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_795480__){"use strict";__nested_webpack_require_795480__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_795480__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _utils_ewma__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_795480__(/*! ../utils/ewma */"./src/utils/ewma.ts");/*
|
|
|
* EWMA Bandwidth Estimator
|
|
|
* - heavily inspired from shaka-player
|
|
|
* Tracks bandwidth samples and estimates available bandwidth.
|
|
|
* Based on the minimum of two exponentially-weighted moving averages with
|
|
|
* different half-lives.
|
|
|
*/var EwmaBandWidthEstimator=/*#__PURE__*/function(){function EwmaBandWidthEstimator(slow,fast,defaultEstimate){this.defaultEstimate_=void 0;this.minWeight_=void 0;this.minDelayMs_=void 0;this.slow_=void 0;this.fast_=void 0;this.defaultEstimate_=defaultEstimate;this.minWeight_=0.001;this.minDelayMs_=50;this.slow_=new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow);this.fast_=new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast);}var _proto=EwmaBandWidthEstimator.prototype;_proto.update=function update(slow,fast){var slow_=this.slow_,fast_=this.fast_;if(this.slow_.halfLife!==slow){this.slow_=new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow,slow_.getEstimate(),slow_.getTotalWeight());}if(this.fast_.halfLife!==fast){this.fast_=new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast,fast_.getEstimate(),fast_.getTotalWeight());}};_proto.sample=function sample(durationMs,numBytes){durationMs=Math.max(durationMs,this.minDelayMs_);var numBits=8*numBytes;// weight is duration in seconds
|
|
|
var durationS=durationMs/1000;// value is bandwidth in bits/s
|
|
|
var bandwidthInBps=numBits/durationS;this.fast_.sample(durationS,bandwidthInBps);this.slow_.sample(durationS,bandwidthInBps);};_proto.canEstimate=function canEstimate(){var fast=this.fast_;return fast&&fast.getTotalWeight()>=this.minWeight_;};_proto.getEstimate=function getEstimate(){if(this.canEstimate()){// console.log('slow estimate:'+ Math.round(this.slow_.getEstimate()));
|
|
|
// console.log('fast estimate:'+ Math.round(this.fast_.getEstimate()));
|
|
|
// Take the minimum of these two estimates. This should have the effect of
|
|
|
// adapting down quickly, but up more slowly.
|
|
|
return Math.min(this.fast_.getEstimate(),this.slow_.getEstimate());}else{return this.defaultEstimate_;}};_proto.destroy=function destroy(){};return EwmaBandWidthEstimator;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=EwmaBandWidthEstimator;/***/},/***/"./src/utils/ewma.ts":/*!***************************!*\
|
|
|
!*** ./src/utils/ewma.ts ***!
|
|
|
\***************************/ /***/function srcUtilsEwmaTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_798218__){"use strict";__nested_webpack_require_798218__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_798218__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/*
|
|
|
* compute an Exponential Weighted moving average
|
|
|
* - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
|
|
|
* - heavily inspired from shaka-player
|
|
|
*/var EWMA=/*#__PURE__*/function(){// About half of the estimated value will be from the last |halfLife| samples by weight.
|
|
|
function EWMA(halfLife,estimate,weight){if(estimate===void 0){estimate=0;}if(weight===void 0){weight=0;}this.halfLife=void 0;this.alpha_=void 0;this.estimate_=void 0;this.totalWeight_=void 0;this.halfLife=halfLife;// Larger values of alpha expire historical data more slowly.
|
|
|
this.alpha_=halfLife?Math.exp(Math.log(0.5)/halfLife):0;this.estimate_=estimate;this.totalWeight_=weight;}var _proto=EWMA.prototype;_proto.sample=function sample(weight,value){var adjAlpha=Math.pow(this.alpha_,weight);this.estimate_=value*(1-adjAlpha)+adjAlpha*this.estimate_;this.totalWeight_+=weight;};_proto.getTotalWeight=function getTotalWeight(){return this.totalWeight_;};_proto.getEstimate=function getEstimate(){if(this.alpha_){var zeroFactor=1-Math.pow(this.alpha_,this.totalWeight_);if(zeroFactor){return this.estimate_/zeroFactor;}}return this.estimate_;};return EWMA;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=EWMA;/***/},/***/"./src/utils/fetch-loader.ts":/*!***********************************!*\
|
|
|
!*** ./src/utils/fetch-loader.ts ***!
|
|
|
\***********************************/ /***/function srcUtilsFetchLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_799931__){"use strict";__nested_webpack_require_799931__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_799931__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;},/* harmony export */"fetchSupported":function fetchSupported(){return(/* binding */_fetchSupported);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_799931__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_799931__(/*! ../loader/load-stats */"./src/loader/load-stats.ts");/* harmony import */var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_799931__(/*! ../demux/chunk-cache */"./src/demux/chunk-cache.ts");function _inheritsLoose(subClass,superClass){subClass.prototype=Object.create(superClass.prototype);subClass.prototype.constructor=subClass;_setPrototypeOf(subClass,superClass);}function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map():undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function");}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper);}function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor);}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class);};return _wrapNativeSuper(Class);}function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct.bind();}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor();if(Class)_setPrototypeOf(instance,Class.prototype);return instance;};}return _construct.apply(null,arguments);}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1;}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _fetchSupported(){if(// @ts-ignore
|
|
|
self.fetch&&self.AbortController&&self.ReadableStream&&self.Request){try{new self.ReadableStream({});// eslint-disable-line no-new
|
|
|
return true;}catch(e){/* noop */}}return false;}var FetchLoader=/*#__PURE__*/function(){function FetchLoader(config/* HlsConfig */){this.fetchSetup=void 0;this.requestTimeout=void 0;this.request=void 0;this.response=void 0;this.controller=void 0;this.context=void 0;this.config=null;this.callbacks=null;this.stats=void 0;this.loader=null;this.fetchSetup=config.fetchSetup||getRequest;this.controller=new self.AbortController();this.stats=new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__.LoadStats();}var _proto=FetchLoader.prototype;_proto.destroy=function destroy(){this.loader=this.callbacks=null;this.abortInternal();};_proto.abortInternal=function abortInternal(){var response=this.response;if(!response||!response.ok){this.stats.aborted=true;this.controller.abort();}};_proto.abort=function abort(){var _this$callbacks;this.abortInternal();if((_this$callbacks=this.callbacks)!==null&&_this$callbacks!==void 0&&_this$callbacks.onAbort){this.callbacks.onAbort(this.stats,this.context,this.response);}};_proto.load=function load(context,config,callbacks){var _this=this;var stats=this.stats;if(stats.loading.start){throw new Error('Loader can only be used once.');}stats.loading.start=self.performance.now();var initParams=getRequestParameters(context,this.controller.signal);var onProgress=callbacks.onProgress;var isArrayBuffer=context.responseType==='arraybuffer';var LENGTH=isArrayBuffer?'byteLength':'length';this.context=context;this.config=config;this.callbacks=callbacks;this.request=this.fetchSetup(context,initParams);self.clearTimeout(this.requestTimeout);this.requestTimeout=self.setTimeout(function(){_this.abortInternal();callbacks.onTimeout(stats,context,_this.response);},config.timeout);self.fetch(this.request).then(function(response){_this.response=_this.loader=response;if(!response.ok){var status=response.status,statusText=response.statusText;throw new FetchError(statusText||'fetch, bad network response',status,response);}stats.loading.first=Math.max(self.performance.now(),stats.loading.start);stats.total=parseInt(response.headers.get('Content-Length')||'0');if(onProgress&&(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(config.highWaterMark)){return _this.loadProgressively(response,stats,context,config.highWaterMark,onProgress);}if(isArrayBuffer){return response.arrayBuffer();}return response.text();}).then(function(responseData){var response=_this.response;self.clearTimeout(_this.requestTimeout);stats.loading.end=Math.max(self.performance.now(),stats.loading.first);var total=responseData[LENGTH];if(total){stats.loaded=stats.total=total;}var loaderResponse={url:response.url,data:responseData};if(onProgress&&!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(config.highWaterMark)){onProgress(stats,context,responseData,response);}callbacks.onSuccess(loaderResponse,stats,context,response);})["catch"](function(error){self.clearTimeout(_this.requestTimeout);if(stats.aborted){return;}// CORS errors result in an undefined code. Set it to 0 here to align with XHR's behavior
|
|
|
// when destroying, 'error' itself can be undefined
|
|
|
var code=!error?0:error.code||0;var text=!error?null:error.message;callbacks.onError({code:code,text:text},context,error?error.details:null);});};_proto.getCacheAge=function getCacheAge(){var result=null;if(this.response){var ageHeader=this.response.headers.get('age');result=ageHeader?parseFloat(ageHeader):null;}return result;};_proto.loadProgressively=function loadProgressively(response,stats,context,highWaterMark,onProgress){if(highWaterMark===void 0){highWaterMark=0;}var chunkCache=new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__["default"]();var reader=response.body.getReader();var pump=function pump(){return reader.read().then(function(data){if(data.done){if(chunkCache.dataLength){onProgress(stats,context,chunkCache.flush(),response);}return Promise.resolve(new ArrayBuffer(0));}var chunk=data.value;var len=chunk.length;stats.loaded+=len;if(len<highWaterMark||chunkCache.dataLength){// The current chunk is too small to to be emitted or the cache already has data
|
|
|
// Push it to the cache
|
|
|
chunkCache.push(chunk);if(chunkCache.dataLength>=highWaterMark){// flush in order to join the typed arrays
|
|
|
onProgress(stats,context,chunkCache.flush(),response);}}else{// If there's nothing cached already, and the chache is large enough
|
|
|
// just emit the progress event
|
|
|
onProgress(stats,context,chunk,response);}return pump();})["catch"](function(){/* aborted */return Promise.reject();});};return pump();};return FetchLoader;}();function getRequestParameters(context,signal){var initParams={method:'GET',mode:'cors',credentials:'same-origin',signal:signal,headers:new self.Headers(_extends({},context.headers))};if(context.rangeEnd){initParams.headers.set('Range','bytes='+context.rangeStart+'-'+String(context.rangeEnd-1));}return initParams;}function getRequest(context,initParams){return new self.Request(context.url,initParams);}var FetchError=/*#__PURE__*/function(_Error){_inheritsLoose(FetchError,_Error);function FetchError(message,code,details){var _this2;_this2=_Error.call(this,message)||this;_this2.code=void 0;_this2.details=void 0;_this2.code=code;_this2.details=details;return _this2;}return FetchError;}(/*#__PURE__*/_wrapNativeSuper(Error));/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=FetchLoader;/***/},/***/"./src/utils/hex.ts":/*!**************************!*\
|
|
|
!*** ./src/utils/hex.ts ***!
|
|
|
\**************************/ /***/function srcUtilsHexTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_808873__){"use strict";__nested_webpack_require_808873__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_808873__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/**
|
|
|
* hex dump helper class
|
|
|
*/var Hex={hexDump:function hexDump(array){var str='';for(var i=0;i<array.length;i++){var h=array[i].toString(16);if(h.length<2){h='0'+h;}str+=h;}return str;}};/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=Hex;/***/},/***/"./src/utils/imsc1-ttml-parser.ts":/*!****************************************!*\
|
|
|
!*** ./src/utils/imsc1-ttml-parser.ts ***!
|
|
|
\****************************************/ /***/function srcUtilsImsc1TtmlParserTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_809643__){"use strict";__nested_webpack_require_809643__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_809643__.d(__webpack_exports__,{/* harmony export */"IMSC1_CODEC":function IMSC1_CODEC(){return(/* binding */_IMSC1_CODEC);},/* harmony export */"parseIMSC1":function parseIMSC1(){return(/* binding */_parseIMSC);}/* harmony export */});/* harmony import */var _mp4_tools__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_809643__(/*! ./mp4-tools */"./src/utils/mp4-tools.ts");/* harmony import */var _vttparser__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_809643__(/*! ./vttparser */"./src/utils/vttparser.ts");/* harmony import */var _vttcue__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_809643__(/*! ./vttcue */"./src/utils/vttcue.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_809643__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _timescale_conversion__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_809643__(/*! ./timescale-conversion */"./src/utils/timescale-conversion.ts");/* harmony import */var _webvtt_parser__WEBPACK_IMPORTED_MODULE_5__=__nested_webpack_require_809643__(/*! ./webvtt-parser */"./src/utils/webvtt-parser.ts");function _extends(){_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}var _IMSC1_CODEC='stpp.ttml.im1t';// Time format: h:m:s:frames(.subframes)
|
|
|
var HMSF_REGEX=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/;// Time format: hours, minutes, seconds, milliseconds, frames, ticks
|
|
|
var TIME_UNIT_REGEX=/^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/;var textAlignToLineAlign={left:'start',center:'center',right:'end',start:'start',end:'end'};function _parseIMSC(payload,initPTS,timescale,callBack,errorCallBack){var results=(0,_mp4_tools__WEBPACK_IMPORTED_MODULE_0__.findBox)(new Uint8Array(payload),['mdat']);if(results.length===0){errorCallBack(new Error('Could not parse IMSC1 mdat'));return;}var ttmlList=results.map(function(mdat){return(0,_demux_id3__WEBPACK_IMPORTED_MODULE_3__.utf8ArrayToStr)(mdat);});var syncTime=(0,_timescale_conversion__WEBPACK_IMPORTED_MODULE_4__.toTimescaleFromScale)(initPTS,1,timescale);try{ttmlList.forEach(function(ttml){return callBack(parseTTML(ttml,syncTime));});}catch(error){errorCallBack(error);}}function parseTTML(ttml,syncTime){var parser=new DOMParser();var xmlDoc=parser.parseFromString(ttml,'text/xml');var tt=xmlDoc.getElementsByTagName('tt')[0];if(!tt){throw new Error('Invalid ttml');}var defaultRateInfo={frameRate:30,subFrameRate:1,frameRateMultiplier:0,tickRate:0};var rateInfo=Object.keys(defaultRateInfo).reduce(function(result,key){result[key]=tt.getAttribute("ttp:"+key)||defaultRateInfo[key];return result;},{});var trim=tt.getAttribute('xml:space')!=='preserve';var styleElements=collectionToDictionary(getElementCollection(tt,'styling','style'));var regionElements=collectionToDictionary(getElementCollection(tt,'layout','region'));var cueElements=getElementCollection(tt,'body','[begin]');return[].map.call(cueElements,function(cueElement){var cueText=getTextContent(cueElement,trim);if(!cueText||!cueElement.hasAttribute('begin')){return null;}var startTime=parseTtmlTime(cueElement.getAttribute('begin'),rateInfo);var duration=parseTtmlTime(cueElement.getAttribute('dur'),rateInfo);var endTime=parseTtmlTime(cueElement.getAttribute('end'),rateInfo);if(startTime===null){throw timestampParsingError(cueElement);}if(endTime===null){if(duration===null){throw timestampParsingError(cueElement);}endTime=startTime+duration;}var cue=new _vttcue__WEBPACK_IMPORTED_MODULE_2__["default"](startTime-syncTime,endTime-syncTime,cueText);cue.id=(0,_webvtt_parser__WEBPACK_IMPORTED_MODULE_5__.generateCueId)(cue.startTime,cue.endTime,cue.text);var region=regionElements[cueElement.getAttribute('region')];var style=styleElements[cueElement.getAttribute('style')];// Apply styles to cue
|
|
|
var styles=getTtmlStyles(region,style,styleElements);var textAlign=styles.textAlign;if(textAlign){// cue.positionAlign not settable in FF~2016
|
|
|
var lineAlign=textAlignToLineAlign[textAlign];if(lineAlign){cue.lineAlign=lineAlign;}cue.align=textAlign;}_extends(cue,styles);return cue;}).filter(function(cue){return cue!==null;});}function getElementCollection(fromElement,parentName,childName){var parent=fromElement.getElementsByTagName(parentName)[0];if(parent){return[].slice.call(parent.querySelectorAll(childName));}return[];}function collectionToDictionary(elementsWithId){return elementsWithId.reduce(function(dict,element){var id=element.getAttribute('xml:id');if(id){dict[id]=element;}return dict;},{});}function getTextContent(element,trim){return[].slice.call(element.childNodes).reduce(function(str,node,i){var _node$childNodes;if(node.nodeName==='br'&&i){return str+'\n';}if((_node$childNodes=node.childNodes)!==null&&_node$childNodes!==void 0&&_node$childNodes.length){return getTextContent(node,trim);}else if(trim){return str+node.textContent.trim().replace(/\s+/g,' ');}return str+node.textContent;},'');}function getTtmlStyles(region,style,styleElements){var ttsNs='http://www.w3.org/ns/ttml#styling';var regionStyle=null;var styleAttributes=['displayAlign','textAlign','color','backgroundColor','fontSize','fontFamily'// 'fontWeight',
|
|
|
// 'lineHeight',
|
|
|
// 'wrapOption',
|
|
|
// 'fontStyle',
|
|
|
// 'direction',
|
|
|
// 'writingMode'
|
|
|
];var regionStyleName=region!==null&®ion!==void 0&®ion.hasAttribute('style')?region.getAttribute('style'):null;if(regionStyleName&&styleElements.hasOwnProperty(regionStyleName)){regionStyle=styleElements[regionStyleName];}return styleAttributes.reduce(function(styles,name){var value=getAttributeNS(style,ttsNs,name)||getAttributeNS(region,ttsNs,name)||getAttributeNS(regionStyle,ttsNs,name);if(value){styles[name]=value;}return styles;},{});}function getAttributeNS(element,ns,name){if(!element){return null;}return element.hasAttributeNS(ns,name)?element.getAttributeNS(ns,name):null;}function timestampParsingError(node){return new Error("Could not parse ttml timestamp "+node);}function parseTtmlTime(timeAttributeValue,rateInfo){if(!timeAttributeValue){return null;}var seconds=(0,_vttparser__WEBPACK_IMPORTED_MODULE_1__.parseTimeStamp)(timeAttributeValue);if(seconds===null){if(HMSF_REGEX.test(timeAttributeValue)){seconds=parseHoursMinutesSecondsFrames(timeAttributeValue,rateInfo);}else if(TIME_UNIT_REGEX.test(timeAttributeValue)){seconds=parseTimeUnits(timeAttributeValue,rateInfo);}}return seconds;}function parseHoursMinutesSecondsFrames(timeAttributeValue,rateInfo){var m=HMSF_REGEX.exec(timeAttributeValue);var frames=(m[4]|0)+(m[5]|0)/rateInfo.subFrameRate;return(m[1]|0)*3600+(m[2]|0)*60+(m[3]|0)+frames/rateInfo.frameRate;}function parseTimeUnits(timeAttributeValue,rateInfo){var m=TIME_UNIT_REGEX.exec(timeAttributeValue);var value=Number(m[1]);var unit=m[2];switch(unit){case'h':return value*3600;case'm':return value*60;case'ms':return value*1000;case'f':return value/rateInfo.frameRate;case't':return value/rateInfo.tickRate;}return value;}/***/},/***/"./src/utils/keysystem-util.ts":/*!*************************************!*\
|
|
|
!*** ./src/utils/keysystem-util.ts ***!
|
|
|
\*************************************/ /***/function srcUtilsKeysystemUtilTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_816995__){"use strict";__nested_webpack_require_816995__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_816995__.d(__webpack_exports__,{/* harmony export */"changeEndianness":function changeEndianness(){return(/* binding */_changeEndianness);},/* harmony export */"convertDataUriToArrayBytes":function convertDataUriToArrayBytes(){return(/* binding */_convertDataUriToArrayBytes);},/* harmony export */"strToUtf8array":function strToUtf8array(){return(/* binding */_strToUtf8array);}/* harmony export */});/* harmony import */var _numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_816995__(/*! ./numeric-encoding-utils */"./src/utils/numeric-encoding-utils.ts");function getKeyIdBytes(str){var keyIdbytes=_strToUtf8array(str).subarray(0,16);var paddedkeyIdbytes=new Uint8Array(16);paddedkeyIdbytes.set(keyIdbytes,16-keyIdbytes.length);return paddedkeyIdbytes;}function _changeEndianness(keyId){var swap=function swap(array,from,to){var cur=array[from];array[from]=array[to];array[to]=cur;};swap(keyId,0,3);swap(keyId,1,2);swap(keyId,4,5);swap(keyId,6,7);}function _convertDataUriToArrayBytes(uri){// data:[<media type][;attribute=value][;base64],<data>
|
|
|
var colonsplit=uri.split(':');var keydata=null;if(colonsplit[0]==='data'&&colonsplit.length===2){var semicolonsplit=colonsplit[1].split(';');var commasplit=semicolonsplit[semicolonsplit.length-1].split(',');if(commasplit.length===2){var isbase64=commasplit[0]==='base64';var data=commasplit[1];if(isbase64){semicolonsplit.splice(-1,1);// remove from processing
|
|
|
keydata=(0,_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_0__.base64Decode)(data);}else{keydata=getKeyIdBytes(data);}}}return keydata;}function _strToUtf8array(str){return Uint8Array.from(unescape(encodeURIComponent(str)),function(c){return c.charCodeAt(0);});}/***/},/***/"./src/utils/logger.ts":/*!*****************************!*\
|
|
|
!*** ./src/utils/logger.ts ***!
|
|
|
\*****************************/ /***/function srcUtilsLoggerTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_819004__){"use strict";__nested_webpack_require_819004__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_819004__.d(__webpack_exports__,{/* harmony export */"enableLogs":function enableLogs(){return(/* binding */_enableLogs);},/* harmony export */"logger":function logger(){return(/* binding */_logger);}/* harmony export */});var noop=function noop(){};var fakeLogger={trace:noop,debug:noop,log:noop,warn:noop,info:noop,error:noop};var exportedLogger=fakeLogger;// let lastCallTime;
|
|
|
// function formatMsgWithTimeInfo(type, msg) {
|
|
|
// const now = Date.now();
|
|
|
// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
|
|
|
// lastCallTime = now;
|
|
|
// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';
|
|
|
// return msg;
|
|
|
// }
|
|
|
function consolePrintFn(type){var func=self.console[type];if(func){return func.bind(self.console,"["+type+"] >");}return noop;}function exportLoggerFunctions(debugConfig){for(var _len=arguments.length,functions=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){functions[_key-1]=arguments[_key];}functions.forEach(function(type){exportedLogger[type]=debugConfig[type]?debugConfig[type].bind(debugConfig):consolePrintFn(type);});}function _enableLogs(debugConfig,id){// check that console is available
|
|
|
if(self.console&&debugConfig===true||_typeof(debugConfig)==='object'){exportLoggerFunctions(debugConfig,// Remove out from list here to hard-disable a log-level
|
|
|
// 'trace',
|
|
|
'debug','log','info','warn','error');// Some browsers don't allow to use bind on console object anyway
|
|
|
// fallback to default if needed
|
|
|
try{exportedLogger.log("Debug logs enabled for \""+id+"\"");}catch(e){exportedLogger=fakeLogger;}}else{exportedLogger=fakeLogger;}}var _logger=exportedLogger;/***/},/***/"./src/utils/mediakeys-helper.ts":/*!***************************************!*\
|
|
|
!*** ./src/utils/mediakeys-helper.ts ***!
|
|
|
\***************************************/ /***/function srcUtilsMediakeysHelperTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_821014__){"use strict";__nested_webpack_require_821014__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_821014__.d(__webpack_exports__,{/* harmony export */"KeySystemFormats":function KeySystemFormats(){return(/* binding */_KeySystemFormats);},/* harmony export */"KeySystemIds":function KeySystemIds(){return(/* binding */_KeySystemIds);},/* harmony export */"KeySystems":function KeySystems(){return(/* binding */_KeySystems);},/* harmony export */"getKeySystemsForConfig":function getKeySystemsForConfig(){return(/* binding */_getKeySystemsForConfig);},/* harmony export */"getSupportedMediaKeySystemConfigurations":function getSupportedMediaKeySystemConfigurations(){return(/* binding */_getSupportedMediaKeySystemConfigurations);},/* harmony export */"keySystemDomainToKeySystemFormat":function keySystemDomainToKeySystemFormat(){return(/* binding */_keySystemDomainToKeySystemFormat);},/* harmony export */"keySystemFormatToKeySystemDomain":function keySystemFormatToKeySystemDomain(){return(/* binding */_keySystemFormatToKeySystemDomain);},/* harmony export */"keySystemIdToKeySystemDomain":function keySystemIdToKeySystemDomain(){return(/* binding */_keySystemIdToKeySystemDomain);},/* harmony export */"requestMediaKeySystemAccess":function requestMediaKeySystemAccess(){return(/* binding */_requestMediaKeySystemAccess);}/* harmony export */});/**
|
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess
|
|
|
*/var _KeySystems;// Playlist #EXT-X-KEY KEYFORMAT values
|
|
|
(function(KeySystems){KeySystems["CLEARKEY"]="org.w3.clearkey";KeySystems["FAIRPLAY"]="com.apple.fps";KeySystems["PLAYREADY"]="com.microsoft.playready";KeySystems["WIDEVINE"]="com.widevine.alpha";})(_KeySystems||(_KeySystems={}));var _KeySystemFormats;(function(KeySystemFormats){KeySystemFormats["CLEARKEY"]="org.w3.clearkey";KeySystemFormats["FAIRPLAY"]="com.apple.streamingkeydelivery";KeySystemFormats["PLAYREADY"]="com.microsoft.playready";KeySystemFormats["WIDEVINE"]="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";})(_KeySystemFormats||(_KeySystemFormats={}));function _keySystemFormatToKeySystemDomain(format){switch(format){case _KeySystemFormats.FAIRPLAY:return _KeySystems.FAIRPLAY;case _KeySystemFormats.PLAYREADY:return _KeySystems.PLAYREADY;case _KeySystemFormats.WIDEVINE:return _KeySystems.WIDEVINE;case _KeySystemFormats.CLEARKEY:return _KeySystems.CLEARKEY;}}// System IDs for which we can extract a key ID from "encrypted" event PSSH
|
|
|
var _KeySystemIds;(function(KeySystemIds){KeySystemIds["WIDEVINE"]="edef8ba979d64acea3c827dcd51d21ed";})(_KeySystemIds||(_KeySystemIds={}));function _keySystemIdToKeySystemDomain(systemId){if(systemId===_KeySystemIds.WIDEVINE){return _KeySystems.WIDEVINE;// } else if (systemId === KeySystemIds.PLAYREADY) {
|
|
|
// return KeySystems.PLAYREADY;
|
|
|
// } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
|
|
|
// return KeySystems.CLEARKEY;
|
|
|
}}function _keySystemDomainToKeySystemFormat(keySystem){switch(keySystem){case _KeySystems.FAIRPLAY:return _KeySystemFormats.FAIRPLAY;case _KeySystems.PLAYREADY:return _KeySystemFormats.PLAYREADY;case _KeySystems.WIDEVINE:return _KeySystemFormats.WIDEVINE;case _KeySystems.CLEARKEY:return _KeySystemFormats.CLEARKEY;}}function _getKeySystemsForConfig(config){var drmSystems=config.drmSystems,widevineLicenseUrl=config.widevineLicenseUrl;var keySystemsToAttempt=drmSystems?[_KeySystems.FAIRPLAY,_KeySystems.WIDEVINE,_KeySystems.PLAYREADY,_KeySystems.CLEARKEY].filter(function(keySystem){return!!drmSystems[keySystem];}):[];if(!keySystemsToAttempt[_KeySystems.WIDEVINE]&&widevineLicenseUrl){keySystemsToAttempt.push(_KeySystems.WIDEVINE);}return keySystemsToAttempt;}var _requestMediaKeySystemAccess=function(){if(typeof self!=='undefined'&&self.navigator&&self.navigator.requestMediaKeySystemAccess){return self.navigator.requestMediaKeySystemAccess.bind(self.navigator);}else{return null;}}();/**
|
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemConfiguration
|
|
|
*/function _getSupportedMediaKeySystemConfigurations(keySystem,audioCodecs,videoCodecs,drmSystemOptions){var initDataTypes;switch(keySystem){case _KeySystems.FAIRPLAY:initDataTypes=['cenc','sinf'];break;case _KeySystems.WIDEVINE:case _KeySystems.PLAYREADY:initDataTypes=['cenc'];break;case _KeySystems.CLEARKEY:initDataTypes=['cenc','keyids'];break;default:throw new Error("Unknown key-system: "+keySystem);}return createMediaKeySystemConfigurations(initDataTypes,audioCodecs,videoCodecs,drmSystemOptions);}function createMediaKeySystemConfigurations(initDataTypes,audioCodecs,videoCodecs,drmSystemOptions){var baseConfig={initDataTypes:initDataTypes,persistentState:drmSystemOptions.persistentState||'not-allowed',distinctiveIdentifier:drmSystemOptions.distinctiveIdentifier||'not-allowed',sessionTypes:drmSystemOptions.sessionTypes||[drmSystemOptions.sessionType||'temporary'],audioCapabilities:audioCodecs.map(function(codec){return{contentType:"audio/mp4; codecs=\""+codec+"\"",robustness:drmSystemOptions.audioRobustness||'',encryptionScheme:drmSystemOptions.audioEncryptionScheme||null};}),videoCapabilities:videoCodecs.map(function(codec){return{contentType:"video/mp4; codecs=\""+codec+"\"",robustness:drmSystemOptions.videoRobustness||'',encryptionScheme:drmSystemOptions.videoEncryptionScheme||null};})};return[baseConfig];}/***/},/***/"./src/utils/mediasource-helper.ts":/*!*****************************************!*\
|
|
|
!*** ./src/utils/mediasource-helper.ts ***!
|
|
|
\*****************************************/ /***/function srcUtilsMediasourceHelperTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_826637__){"use strict";__nested_webpack_require_826637__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_826637__.d(__webpack_exports__,{/* harmony export */"getMediaSource":function getMediaSource(){return(/* binding */_getMediaSource);}/* harmony export */});/**
|
|
|
* MediaSource helper
|
|
|
*/function _getMediaSource(){return self.MediaSource||self.WebKitMediaSource;}/***/},/***/"./src/utils/mp4-tools.ts":/*!********************************!*\
|
|
|
!*** ./src/utils/mp4-tools.ts ***!
|
|
|
\********************************/ /***/function srcUtilsMp4ToolsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_827235__){"use strict";__nested_webpack_require_827235__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_827235__.d(__webpack_exports__,{/* harmony export */"RemuxerTrackIdConfig":function RemuxerTrackIdConfig(){return(/* binding */_RemuxerTrackIdConfig);},/* harmony export */"appendUint8Array":function appendUint8Array(){return(/* binding */_appendUint8Array);},/* harmony export */"bin2str":function bin2str(){return(/* binding */_bin2str);},/* harmony export */"computeRawDurationFromSamples":function computeRawDurationFromSamples(){return(/* binding */_computeRawDurationFromSamples);},/* harmony export */"discardEPB":function discardEPB(){return(/* binding */_discardEPB);},/* harmony export */"findBox":function findBox(){return(/* binding */_findBox);},/* harmony export */"getDuration":function getDuration(){return(/* binding */_getDuration);},/* harmony export */"getStartDTS":function getStartDTS(){return(/* binding */_getStartDTS);},/* harmony export */"mp4Box":function mp4Box(){return(/* binding */_mp4Box);},/* harmony export */"mp4pssh":function mp4pssh(){return(/* binding */_mp4pssh);},/* harmony export */"offsetStartDTS":function offsetStartDTS(){return(/* binding */_offsetStartDTS);},/* harmony export */"parseEmsg":function parseEmsg(){return(/* binding */_parseEmsg);},/* harmony export */"parseInitSegment":function parseInitSegment(){return(/* binding */_parseInitSegment);},/* harmony export */"parsePssh":function parsePssh(){return(/* binding */_parsePssh);},/* harmony export */"parseSEIMessageFromNALu":function parseSEIMessageFromNALu(){return(/* binding */_parseSEIMessageFromNALu);},/* harmony export */"parseSamples":function parseSamples(){return(/* binding */_parseSamples);},/* harmony export */"parseSegmentIndex":function parseSegmentIndex(){return(/* binding */_parseSegmentIndex);},/* harmony export */"parseSinf":function parseSinf(){return(/* binding */_parseSinf);},/* harmony export */"patchEncyptionData":function patchEncyptionData(){return(/* binding */_patchEncyptionData);},/* harmony export */"readSint32":function readSint32(){return(/* binding */_readSint);},/* harmony export */"readUint16":function readUint16(){return(/* binding */_readUint);},/* harmony export */"readUint32":function readUint32(){return(/* binding */_readUint2);},/* harmony export */"segmentValidRange":function segmentValidRange(){return(/* binding */_segmentValidRange);},/* harmony export */"writeUint32":function writeUint32(){return(/* binding */_writeUint);}/* harmony export */});/* harmony import */var _loader_fragment__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_827235__(/*! ../loader/fragment */"./src/loader/fragment.ts");/* harmony import */var _typed_array__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_827235__(/*! ./typed-array */"./src/utils/typed-array.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_827235__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_827235__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _hex__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_827235__(/*! ./hex */"./src/utils/hex.ts");var UINT32_MAX=Math.pow(2,32)-1;var push=[].push;// We are using fixed track IDs for driving the MP4 remuxer
|
|
|
// instead of following the TS PIDs.
|
|
|
// There is no reason not to do this and some browsers/SourceBuffer-demuxers
|
|
|
// may not like if there are TrackID "switches"
|
|
|
// See https://github.com/video-dev/hls.js/issues/1331
|
|
|
// Here we are mapping our internal track types to constant MP4 track IDs
|
|
|
// With MSE currently one can only have one track of each, and we are muxing
|
|
|
// whatever video/audio rendition in them.
|
|
|
var _RemuxerTrackIdConfig={video:1,audio:2,id3:3,text:4};function _bin2str(data){return String.fromCharCode.apply(null,data);}function _readUint(buffer,offset){var val=buffer[offset]<<8|buffer[offset+1];return val<0?65536+val:val;}function _readUint2(buffer,offset){var val=_readSint(buffer,offset);return val<0?4294967296+val:val;}function _readSint(buffer,offset){return buffer[offset]<<24|buffer[offset+1]<<16|buffer[offset+2]<<8|buffer[offset+3];}function _writeUint(buffer,offset,value){buffer[offset]=value>>24;buffer[offset+1]=value>>16&0xff;buffer[offset+2]=value>>8&0xff;buffer[offset+3]=value&0xff;}// Find the data for a box specified by its path
|
|
|
function _findBox(data,path){var results=[];if(!path.length){// short-circuit the search for empty paths
|
|
|
return results;}var end=data.byteLength;for(var i=0;i<end;){var size=_readUint2(data,i);var type=_bin2str(data.subarray(i+4,i+8));var endbox=size>1?i+size:end;if(type===path[0]){if(path.length===1){// this is the end of the path and we've found the box we were
|
|
|
// looking for
|
|
|
results.push(data.subarray(i+8,endbox));}else{// recursively search for the next box along the path
|
|
|
var subresults=_findBox(data.subarray(i+8,endbox),path.slice(1));if(subresults.length){push.apply(results,subresults);}}}i=endbox;}// we've finished searching all of data
|
|
|
return results;}function _parseSegmentIndex(sidx){var references=[];var version=sidx[0];// set initial offset, we skip the reference ID (not needed)
|
|
|
var index=8;var timescale=_readUint2(sidx,index);index+=4;// TODO: parse earliestPresentationTime and firstOffset
|
|
|
// usually zero in our case
|
|
|
var earliestPresentationTime=0;var firstOffset=0;if(version===0){index+=8;}else{index+=16;}// skip reserved
|
|
|
index+=2;var startByte=sidx.length+firstOffset;var referencesCount=_readUint(sidx,index);index+=2;for(var i=0;i<referencesCount;i++){var referenceIndex=index;var referenceInfo=_readUint2(sidx,referenceIndex);referenceIndex+=4;var referenceSize=referenceInfo&0x7fffffff;var referenceType=(referenceInfo&0x80000000)>>>31;if(referenceType===1){// eslint-disable-next-line no-console
|
|
|
console.warn('SIDX has hierarchical references (not supported)');return null;}var subsegmentDuration=_readUint2(sidx,referenceIndex);referenceIndex+=4;references.push({referenceSize:referenceSize,subsegmentDuration:subsegmentDuration,// unscaled
|
|
|
info:{duration:subsegmentDuration/timescale,start:startByte,end:startByte+referenceSize-1}});startByte+=referenceSize;// Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits
|
|
|
// for |sapDelta|.
|
|
|
referenceIndex+=4;// skip to next ref
|
|
|
index=referenceIndex;}return{earliestPresentationTime:earliestPresentationTime,timescale:timescale,version:version,referencesCount:referencesCount,references:references};}/**
|
|
|
* Parses an MP4 initialization segment and extracts stream type and
|
|
|
* timescale values for any declared tracks. Timescale values indicate the
|
|
|
* number of clock ticks per second to assume for time-based values
|
|
|
* elsewhere in the MP4.
|
|
|
*
|
|
|
* To determine the start time of an MP4, you need two pieces of
|
|
|
* information: the timescale unit and the earliest base media decode
|
|
|
* time. Multiple timescales can be specified within an MP4 but the
|
|
|
* base media decode time is always expressed in the timescale from
|
|
|
* the media header box for the track:
|
|
|
* ```
|
|
|
* moov > trak > mdia > mdhd.timescale
|
|
|
* moov > trak > mdia > hdlr
|
|
|
* ```
|
|
|
* @param initSegment {Uint8Array} the bytes of the init segment
|
|
|
* @return {InitData} a hash of track type to timescale values or null if
|
|
|
* the init segment is malformed.
|
|
|
*/function _parseInitSegment(initSegment){var result=[];var traks=_findBox(initSegment,['moov','trak']);for(var i=0;i<traks.length;i++){var trak=traks[i];var tkhd=_findBox(trak,['tkhd'])[0];if(tkhd){var version=tkhd[0];var _index=version===0?12:20;var trackId=_readUint2(tkhd,_index);var mdhd=_findBox(trak,['mdia','mdhd'])[0];if(mdhd){version=mdhd[0];_index=version===0?12:20;var timescale=_readUint2(mdhd,_index);var hdlr=_findBox(trak,['mdia','hdlr'])[0];if(hdlr){var hdlrType=_bin2str(hdlr.subarray(8,12));var type={soun:_loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.AUDIO,vide:_loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO}[hdlrType];if(type){// Parse codec details
|
|
|
var stsd=_findBox(trak,['mdia','minf','stbl','stsd'])[0];var codec=void 0;if(stsd){codec=_bin2str(stsd.subarray(12,16));// TODO: Parse codec details to be able to build MIME type.
|
|
|
// stsd.start += 8;
|
|
|
// const codecBox = findBox(stsd, [codec])[0];
|
|
|
// if (codecBox) {
|
|
|
// TODO: Codec parsing support for avc1, mp4a, hevc, av01...
|
|
|
// }
|
|
|
}result[trackId]={timescale:timescale,type:type};result[type]={timescale:timescale,id:trackId,codec:codec};}}}}}var trex=_findBox(initSegment,['moov','mvex','trex']);trex.forEach(function(trex){var trackId=_readUint2(trex,4);var track=result[trackId];if(track){track["default"]={duration:_readUint2(trex,12),flags:_readUint2(trex,20)};}});return result;}function _patchEncyptionData(initSegment,decryptdata){if(!initSegment||!decryptdata){return initSegment;}var keyId=decryptdata.keyId;if(keyId&&decryptdata.isCommonEncryption){var traks=_findBox(initSegment,['moov','trak']);traks.forEach(function(trak){var stsd=_findBox(trak,['mdia','minf','stbl','stsd'])[0];// skip the sample entry count
|
|
|
var sampleEntries=stsd.subarray(8);var encBoxes=_findBox(sampleEntries,['enca']);var isAudio=encBoxes.length>0;if(!isAudio){encBoxes=_findBox(sampleEntries,['encv']);}encBoxes.forEach(function(enc){var encBoxChildren=isAudio?enc.subarray(28):enc.subarray(78);var sinfBoxes=_findBox(encBoxChildren,['sinf']);sinfBoxes.forEach(function(sinf){var tenc=_parseSinf(sinf);if(tenc){// Look for default key id (keyID offset is always 8 within the tenc box):
|
|
|
var tencKeyId=tenc.subarray(8,24);if(!tencKeyId.some(function(b){return b!==0;})){_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[eme] Patching keyId in 'enc"+(isAudio?'a':'v')+">sinf>>tenc' box: "+_hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(tencKeyId)+" -> "+_hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(keyId));tenc.set(keyId,8);}}});});});}return initSegment;}function _parseSinf(sinf){var schm=_findBox(sinf,['schm'])[0];if(schm){var scheme=_bin2str(schm.subarray(4,8));if(scheme==='cbcs'||scheme==='cenc'){return _findBox(sinf,['schi','tenc'])[0];}}_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error("[eme] missing 'schm' box");return null;}/**
|
|
|
* Determine the base media decode start time, in seconds, for an MP4
|
|
|
* fragment. If multiple fragments are specified, the earliest time is
|
|
|
* returned.
|
|
|
*
|
|
|
* The base media decode time can be parsed from track fragment
|
|
|
* metadata:
|
|
|
* ```
|
|
|
* moof > traf > tfdt.baseMediaDecodeTime
|
|
|
* ```
|
|
|
* It requires the timescale value from the mdhd to interpret.
|
|
|
*
|
|
|
* @param initData {InitData} a hash of track type to timescale values
|
|
|
* @param fmp4 {Uint8Array} the bytes of the mp4 fragment
|
|
|
* @return {number} the earliest base media decode start time for the
|
|
|
* fragment, in seconds
|
|
|
*/function _getStartDTS(initData,fmp4){// we need info from two children of each track fragment box
|
|
|
return _findBox(fmp4,['moof','traf']).reduce(function(result,traf){var tfdt=_findBox(traf,['tfdt'])[0];var version=tfdt[0];var start=_findBox(traf,['tfhd']).reduce(function(result,tfhd){// get the track id from the tfhd
|
|
|
var id=_readUint2(tfhd,4);var track=initData[id];if(track){var baseTime=_readUint2(tfdt,4);if(version===1){baseTime*=Math.pow(2,32);baseTime+=_readUint2(tfdt,8);}// assume a 90kHz clock if no timescale was specified
|
|
|
var scale=track.timescale||90e3;// convert base time to seconds
|
|
|
var startTime=baseTime/scale;if(isFinite(startTime)&&(result===null||startTime<result)){return startTime;}}return result;},null);if(start!==null&&isFinite(start)&&(result===null||start<result)){return start;}return result;},null)||0;}/*
|
|
|
For Reference:
|
|
|
aligned(8) class TrackFragmentHeaderBox
|
|
|
extends FullBox(‘tfhd’, 0, tf_flags){
|
|
|
unsigned int(32) track_ID;
|
|
|
// all the following are optional fields
|
|
|
unsigned int(64) base_data_offset;
|
|
|
unsigned int(32) sample_description_index;
|
|
|
unsigned int(32) default_sample_duration;
|
|
|
unsigned int(32) default_sample_size;
|
|
|
unsigned int(32) default_sample_flags
|
|
|
}
|
|
|
*/function _getDuration(data,initData){var rawDuration=0;var videoDuration=0;var audioDuration=0;var trafs=_findBox(data,['moof','traf']);for(var i=0;i<trafs.length;i++){var traf=trafs[i];// There is only one tfhd & trun per traf
|
|
|
// This is true for CMAF style content, and we should perhaps check the ftyp
|
|
|
// and only look for a single trun then, but for ISOBMFF we should check
|
|
|
// for multiple track runs.
|
|
|
var tfhd=_findBox(traf,['tfhd'])[0];// get the track id from the tfhd
|
|
|
var id=_readUint2(tfhd,4);var track=initData[id];if(!track){continue;}var trackDefault=track["default"];var tfhdFlags=_readUint2(tfhd,0)|(trackDefault===null||trackDefault===void 0?void 0:trackDefault.flags);var sampleDuration=trackDefault===null||trackDefault===void 0?void 0:trackDefault.duration;if(tfhdFlags&0x000008){// 0x000008 indicates the presence of the default_sample_duration field
|
|
|
if(tfhdFlags&0x000002){// 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration
|
|
|
// If present, the default_sample_duration exists at byte offset 12
|
|
|
sampleDuration=_readUint2(tfhd,12);}else{// Otherwise, the duration is at byte offset 8
|
|
|
sampleDuration=_readUint2(tfhd,8);}}// assume a 90kHz clock if no timescale was specified
|
|
|
var timescale=track.timescale||90e3;var truns=_findBox(traf,['trun']);for(var j=0;j<truns.length;j++){rawDuration=_computeRawDurationFromSamples(truns[j]);if(!rawDuration&&sampleDuration){var sampleCount=_readUint2(truns[j],4);rawDuration=sampleDuration*sampleCount;}if(track.type===_loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO){videoDuration+=rawDuration/timescale;}else if(track.type===_loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.AUDIO){audioDuration+=rawDuration/timescale;}}}if(videoDuration===0&&audioDuration===0){// If duration samples are not available in the traf use sidx subsegment_duration
|
|
|
var sidxDuration=0;var sidxs=_findBox(data,['sidx']);for(var _i=0;_i<sidxs.length;_i++){var sidx=_parseSegmentIndex(sidxs[_i]);if(sidx!==null&&sidx!==void 0&&sidx.references){sidxDuration+=sidx.references.reduce(function(dur,ref){return dur+ref.info.duration||0;},0);}}return sidxDuration;}if(videoDuration){return videoDuration;}return audioDuration;}/*
|
|
|
For Reference:
|
|
|
aligned(8) class TrackRunBox
|
|
|
extends FullBox(‘trun’, version, tr_flags) {
|
|
|
unsigned int(32) sample_count;
|
|
|
// the following are optional fields
|
|
|
signed int(32) data_offset;
|
|
|
unsigned int(32) first_sample_flags;
|
|
|
// all fields in the following array are optional
|
|
|
{
|
|
|
unsigned int(32) sample_duration;
|
|
|
unsigned int(32) sample_size;
|
|
|
unsigned int(32) sample_flags
|
|
|
if (version == 0)
|
|
|
{ unsigned int(32)
|
|
|
else
|
|
|
{ signed int(32)
|
|
|
}[ sample_count ]
|
|
|
}
|
|
|
*/function _computeRawDurationFromSamples(trun){var flags=_readUint2(trun,0);// Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in.
|
|
|
// Each field is an int32, which is 4 bytes
|
|
|
var offset=8;// data-offset-present flag
|
|
|
if(flags&0x000001){offset+=4;}// first-sample-flags-present flag
|
|
|
if(flags&0x000004){offset+=4;}var duration=0;var sampleCount=_readUint2(trun,4);for(var i=0;i<sampleCount;i++){// sample-duration-present flag
|
|
|
if(flags&0x000100){var sampleDuration=_readUint2(trun,offset);duration+=sampleDuration;offset+=4;}// sample-size-present flag
|
|
|
if(flags&0x000200){offset+=4;}// sample-flags-present flag
|
|
|
if(flags&0x000400){offset+=4;}// sample-composition-time-offsets-present flag
|
|
|
if(flags&0x000800){offset+=4;}}return duration;}function _offsetStartDTS(initData,fmp4,timeOffset){_findBox(fmp4,['moof','traf']).forEach(function(traf){_findBox(traf,['tfhd']).forEach(function(tfhd){// get the track id from the tfhd
|
|
|
var id=_readUint2(tfhd,4);var track=initData[id];if(!track){return;}// assume a 90kHz clock if no timescale was specified
|
|
|
var timescale=track.timescale||90e3;// get the base media decode time from the tfdt
|
|
|
_findBox(traf,['tfdt']).forEach(function(tfdt){var version=tfdt[0];var baseMediaDecodeTime=_readUint2(tfdt,4);if(version===0){baseMediaDecodeTime-=timeOffset*timescale;baseMediaDecodeTime=Math.max(baseMediaDecodeTime,0);_writeUint(tfdt,4,baseMediaDecodeTime);}else{baseMediaDecodeTime*=Math.pow(2,32);baseMediaDecodeTime+=_readUint2(tfdt,8);baseMediaDecodeTime-=timeOffset*timescale;baseMediaDecodeTime=Math.max(baseMediaDecodeTime,0);var upper=Math.floor(baseMediaDecodeTime/(UINT32_MAX+1));var lower=Math.floor(baseMediaDecodeTime%(UINT32_MAX+1));_writeUint(tfdt,4,upper);_writeUint(tfdt,8,lower);}});});});}// TODO: Check if the last moof+mdat pair is part of the valid range
|
|
|
function _segmentValidRange(data){var segmentedRange={valid:null,remainder:null};var moofs=_findBox(data,['moof']);if(!moofs){return segmentedRange;}else if(moofs.length<2){segmentedRange.remainder=data;return segmentedRange;}var last=moofs[moofs.length-1];// Offset by 8 bytes; findBox offsets the start by as much
|
|
|
segmentedRange.valid=(0,_typed_array__WEBPACK_IMPORTED_MODULE_1__.sliceUint8)(data,0,last.byteOffset-8);segmentedRange.remainder=(0,_typed_array__WEBPACK_IMPORTED_MODULE_1__.sliceUint8)(data,last.byteOffset-8);return segmentedRange;}function _appendUint8Array(data1,data2){var temp=new Uint8Array(data1.length+data2.length);temp.set(data1);temp.set(data2,data1.length);return temp;}function _parseSamples(timeOffset,track){var seiSamples=[];var videoData=track.samples;var timescale=track.timescale;var trackId=track.id;var isHEVCFlavor=false;var moofs=_findBox(videoData,['moof']);moofs.map(function(moof){var moofOffset=moof.byteOffset-8;var trafs=_findBox(moof,['traf']);trafs.map(function(traf){// get the base media decode time from the tfdt
|
|
|
var baseTime=_findBox(traf,['tfdt']).map(function(tfdt){var version=tfdt[0];var result=_readUint2(tfdt,4);if(version===1){result*=Math.pow(2,32);result+=_readUint2(tfdt,8);}return result/timescale;})[0];if(baseTime!==undefined){timeOffset=baseTime;}return _findBox(traf,['tfhd']).map(function(tfhd){var id=_readUint2(tfhd,4);var tfhdFlags=_readUint2(tfhd,0)&0xffffff;var baseDataOffsetPresent=(tfhdFlags&0x000001)!==0;var sampleDescriptionIndexPresent=(tfhdFlags&0x000002)!==0;var defaultSampleDurationPresent=(tfhdFlags&0x000008)!==0;var defaultSampleDuration=0;var defaultSampleSizePresent=(tfhdFlags&0x000010)!==0;var defaultSampleSize=0;var defaultSampleFlagsPresent=(tfhdFlags&0x000020)!==0;var tfhdOffset=8;if(id===trackId){if(baseDataOffsetPresent){tfhdOffset+=8;}if(sampleDescriptionIndexPresent){tfhdOffset+=4;}if(defaultSampleDurationPresent){defaultSampleDuration=_readUint2(tfhd,tfhdOffset);tfhdOffset+=4;}if(defaultSampleSizePresent){defaultSampleSize=_readUint2(tfhd,tfhdOffset);tfhdOffset+=4;}if(defaultSampleFlagsPresent){tfhdOffset+=4;}if(track.type==='video'){isHEVCFlavor=isHEVC(track.codec);}_findBox(traf,['trun']).map(function(trun){var version=trun[0];var flags=_readUint2(trun,0)&0xffffff;var dataOffsetPresent=(flags&0x000001)!==0;var dataOffset=0;var firstSampleFlagsPresent=(flags&0x000004)!==0;var sampleDurationPresent=(flags&0x000100)!==0;var sampleDuration=0;var sampleSizePresent=(flags&0x000200)!==0;var sampleSize=0;var sampleFlagsPresent=(flags&0x000400)!==0;var sampleCompositionOffsetsPresent=(flags&0x000800)!==0;var compositionOffset=0;var sampleCount=_readUint2(trun,4);var trunOffset=8;// past version, flags, and sample count
|
|
|
if(dataOffsetPresent){dataOffset=_readUint2(trun,trunOffset);trunOffset+=4;}if(firstSampleFlagsPresent){trunOffset+=4;}var sampleOffset=dataOffset+moofOffset;for(var ix=0;ix<sampleCount;ix++){if(sampleDurationPresent){sampleDuration=_readUint2(trun,trunOffset);trunOffset+=4;}else{sampleDuration=defaultSampleDuration;}if(sampleSizePresent){sampleSize=_readUint2(trun,trunOffset);trunOffset+=4;}else{sampleSize=defaultSampleSize;}if(sampleFlagsPresent){trunOffset+=4;}if(sampleCompositionOffsetsPresent){if(version===0){compositionOffset=_readUint2(trun,trunOffset);}else{compositionOffset=_readSint(trun,trunOffset);}trunOffset+=4;}if(track.type===_loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO){var naluTotalSize=0;while(naluTotalSize<sampleSize){var naluSize=_readUint2(videoData,sampleOffset);sampleOffset+=4;if(isSEIMessage(isHEVCFlavor,videoData[sampleOffset])){var data=videoData.subarray(sampleOffset,sampleOffset+naluSize);_parseSEIMessageFromNALu(data,isHEVCFlavor?2:1,timeOffset+compositionOffset/timescale,seiSamples);}sampleOffset+=naluSize;naluTotalSize+=naluSize+4;}}timeOffset+=sampleDuration/timescale;}});}});});});return seiSamples;}function isHEVC(codec){if(!codec){return false;}var delimit=codec.indexOf('.');var baseCodec=delimit<0?codec:codec.substring(0,delimit);return baseCodec==='hvc1'||baseCodec==='hev1'||// Dolby Vision
|
|
|
baseCodec==='dvh1'||baseCodec==='dvhe';}function isSEIMessage(isHEVCFlavor,naluHeader){if(isHEVCFlavor){var naluType=naluHeader>>1&0x3f;return naluType===39||naluType===40;}else{var _naluType=naluHeader&0x1f;return _naluType===6;}}function _parseSEIMessageFromNALu(unescapedData,headerSize,pts,samples){var data=_discardEPB(unescapedData);var seiPtr=0;// skip nal header
|
|
|
seiPtr+=headerSize;var payloadType=0;var payloadSize=0;var endOfCaptions=false;var b=0;while(seiPtr<data.length){payloadType=0;do{if(seiPtr>=data.length){break;}b=data[seiPtr++];payloadType+=b;}while(b===0xff);// Parse payload size.
|
|
|
payloadSize=0;do{if(seiPtr>=data.length){break;}b=data[seiPtr++];payloadSize+=b;}while(b===0xff);var leftOver=data.length-seiPtr;if(!endOfCaptions&&payloadType===4&&seiPtr<data.length){endOfCaptions=true;var countryCode=data[seiPtr++];if(countryCode===181){var providerCode=_readUint(data,seiPtr);seiPtr+=2;if(providerCode===49){var userStructure=_readUint2(data,seiPtr);seiPtr+=4;if(userStructure===0x47413934){var userDataType=data[seiPtr++];// Raw CEA-608 bytes wrapped in CEA-708 packet
|
|
|
if(userDataType===3){var firstByte=data[seiPtr++];var totalCCs=0x1f&firstByte;var enabled=0x40&firstByte;var totalBytes=enabled?2+totalCCs*3:0;var byteArray=new Uint8Array(totalBytes);if(enabled){byteArray[0]=firstByte;for(var i=1;i<totalBytes;i++){byteArray[i]=data[seiPtr++];}}samples.push({type:userDataType,payloadType:payloadType,pts:pts,bytes:byteArray});}}}}}else if(payloadType===5&&payloadSize<leftOver){endOfCaptions=true;if(payloadSize>16){var uuidStrArray=[];for(var _i2=0;_i2<16;_i2++){var _b=data[seiPtr++].toString(16);uuidStrArray.push(_b.length==1?'0'+_b:_b);if(_i2===3||_i2===5||_i2===7||_i2===9){uuidStrArray.push('-');}}var length=payloadSize-16;var userDataBytes=new Uint8Array(length);for(var _i3=0;_i3<length;_i3++){userDataBytes[_i3]=data[seiPtr++];}samples.push({payloadType:payloadType,pts:pts,uuid:uuidStrArray.join(''),userData:(0,_demux_id3__WEBPACK_IMPORTED_MODULE_2__.utf8ArrayToStr)(userDataBytes),userDataBytes:userDataBytes});}}else if(payloadSize<leftOver){seiPtr+=payloadSize;}else if(payloadSize>leftOver){break;}}}/**
|
|
|
* remove Emulation Prevention bytes from a RBSP
|
|
|
*/function _discardEPB(data){var length=data.byteLength;var EPBPositions=[];var i=1;// Find all `Emulation Prevention Bytes`
|
|
|
while(i<length-2){if(data[i]===0&&data[i+1]===0&&data[i+2]===0x03){EPBPositions.push(i+2);i+=2;}else{i++;}}// If no Emulation Prevention Bytes were found just return the original
|
|
|
// array
|
|
|
if(EPBPositions.length===0){return data;}// Create a new array to hold the NAL unit data
|
|
|
var newLength=length-EPBPositions.length;var newData=new Uint8Array(newLength);var sourceIndex=0;for(i=0;i<newLength;sourceIndex++,i++){if(sourceIndex===EPBPositions[0]){// Skip this byte
|
|
|
sourceIndex++;// Remove this position index
|
|
|
EPBPositions.shift();}newData[i]=data[sourceIndex];}return newData;}function _parseEmsg(data){var version=data[0];var schemeIdUri='';var value='';var timeScale=0;var presentationTimeDelta=0;var presentationTime=0;var eventDuration=0;var id=0;var offset=0;if(version===0){while(_bin2str(data.subarray(offset,offset+1))!=='\0'){schemeIdUri+=_bin2str(data.subarray(offset,offset+1));offset+=1;}schemeIdUri+=_bin2str(data.subarray(offset,offset+1));offset+=1;while(_bin2str(data.subarray(offset,offset+1))!=='\0'){value+=_bin2str(data.subarray(offset,offset+1));offset+=1;}value+=_bin2str(data.subarray(offset,offset+1));offset+=1;timeScale=_readUint2(data,12);presentationTimeDelta=_readUint2(data,16);eventDuration=_readUint2(data,20);id=_readUint2(data,24);offset=28;}else if(version===1){offset+=4;timeScale=_readUint2(data,offset);offset+=4;var leftPresentationTime=_readUint2(data,offset);offset+=4;var rightPresentationTime=_readUint2(data,offset);offset+=4;presentationTime=Math.pow(2,32)*leftPresentationTime+rightPresentationTime;if(!Number.isSafeInteger(presentationTime)){presentationTime=Number.MAX_SAFE_INTEGER;// eslint-disable-next-line no-console
|
|
|
console.warn('Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box');}eventDuration=_readUint2(data,offset);offset+=4;id=_readUint2(data,offset);offset+=4;while(_bin2str(data.subarray(offset,offset+1))!=='\0'){schemeIdUri+=_bin2str(data.subarray(offset,offset+1));offset+=1;}schemeIdUri+=_bin2str(data.subarray(offset,offset+1));offset+=1;while(_bin2str(data.subarray(offset,offset+1))!=='\0'){value+=_bin2str(data.subarray(offset,offset+1));offset+=1;}value+=_bin2str(data.subarray(offset,offset+1));offset+=1;}var payload=data.subarray(offset,data.byteLength);return{schemeIdUri:schemeIdUri,value:value,timeScale:timeScale,presentationTime:presentationTime,presentationTimeDelta:presentationTimeDelta,eventDuration:eventDuration,id:id,payload:payload};}function _mp4Box(type){for(var _len=arguments.length,payload=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){payload[_key-1]=arguments[_key];}var len=payload.length;var size=8;var i=len;while(i--){size+=payload[i].byteLength;}var result=new Uint8Array(size);result[0]=size>>24&0xff;result[1]=size>>16&0xff;result[2]=size>>8&0xff;result[3]=size&0xff;result.set(type,4);for(i=0,size=8;i<len;i++){result.set(payload[i],size);size+=payload[i].byteLength;}return result;}function _mp4pssh(systemId,keyids,data){if(systemId.byteLength!==16){throw new RangeError('Invalid system id');}var version;var kids;if(keyids){version=1;kids=new Uint8Array(keyids.length*16);for(var ix=0;ix<keyids.length;ix++){var k=keyids[ix];// uint8array
|
|
|
if(k.byteLength!==16){throw new RangeError('Invalid key');}kids.set(k,ix*16);}}else{version=0;kids=new Uint8Array();}var kidCount;if(version>0){kidCount=new Uint8Array(4);if(keyids.length>0){new DataView(kidCount.buffer).setUint32(0,keyids.length,false);}}else{kidCount=new Uint8Array();}var dataSize=new Uint8Array(4);if(data&&data.byteLength>0){new DataView(dataSize.buffer).setUint32(0,data.byteLength,false);}return _mp4Box([112,115,115,104],new Uint8Array([version,0x00,0x00,0x00// Flags
|
|
|
]),systemId,// 16 bytes
|
|
|
kidCount,kids,dataSize,data||new Uint8Array());}function _parsePssh(initData){if(!(initData instanceof ArrayBuffer)||initData.byteLength<32){return null;}var result={version:0,systemId:'',kids:null,data:null};var view=new DataView(initData);var boxSize=view.getUint32(0);if(initData.byteLength!==boxSize&&boxSize>44){return null;}var type=view.getUint32(4);if(type!==0x70737368){return null;}result.version=view.getUint32(8)>>>24;if(result.version>1){return null;}result.systemId=_hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(new Uint8Array(initData,12,16));var dataSizeOrKidCount=view.getUint32(28);if(result.version===0){if(boxSize-32<dataSizeOrKidCount){return null;}result.data=new Uint8Array(initData,32,dataSizeOrKidCount);}else if(result.version===1){result.kids=[];for(var i=0;i<dataSizeOrKidCount;i++){result.kids.push(new Uint8Array(initData,32+i*16,16));}}return result;}/***/},/***/"./src/utils/numeric-encoding-utils.ts":/*!*********************************************!*\
|
|
|
!*** ./src/utils/numeric-encoding-utils.ts ***!
|
|
|
\*********************************************/ /***/function srcUtilsNumericEncodingUtilsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_855218__){"use strict";__nested_webpack_require_855218__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_855218__.d(__webpack_exports__,{/* harmony export */"base64Decode":function base64Decode(){return(/* binding */_base64Decode);},/* harmony export */"base64DecodeToStr":function base64DecodeToStr(){return(/* binding */_base64DecodeToStr);},/* harmony export */"base64Encode":function base64Encode(){return(/* binding */_base64Encode);},/* harmony export */"base64ToBase64Url":function base64ToBase64Url(){return(/* binding */_base64ToBase64Url);},/* harmony export */"base64UrlEncode":function base64UrlEncode(){return(/* binding */_base64UrlEncode);},/* harmony export */"strToBase64Encode":function strToBase64Encode(){return(/* binding */_strToBase64Encode);}/* harmony export */});function _base64ToBase64Url(base64encodedStr){return base64encodedStr.replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'');}function _strToBase64Encode(str){return btoa(str);}function _base64DecodeToStr(str){return atob(str);}function _base64Encode(input){return btoa(String.fromCharCode.apply(String,input));}function _base64UrlEncode(input){return _base64ToBase64Url(_base64Encode(input));}function _base64Decode(base64encodedStr){return Uint8Array.from(atob(base64encodedStr),function(c){return c.charCodeAt(0);});}/***/},/***/"./src/utils/output-filter.ts":/*!************************************!*\
|
|
|
!*** ./src/utils/output-filter.ts ***!
|
|
|
\************************************/ /***/function srcUtilsOutputFilterTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_856780__){"use strict";__nested_webpack_require_856780__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_856780__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return(/* binding */OutputFilter);}/* harmony export */});var OutputFilter=/*#__PURE__*/function(){function OutputFilter(timelineController,trackName){this.timelineController=void 0;this.cueRanges=[];this.trackName=void 0;this.startTime=null;this.endTime=null;this.screen=null;this.timelineController=timelineController;this.trackName=trackName;}var _proto=OutputFilter.prototype;_proto.dispatchCue=function dispatchCue(){if(this.startTime===null){return;}this.timelineController.addCues(this.trackName,this.startTime,this.endTime,this.screen,this.cueRanges);this.startTime=null;};_proto.newCue=function newCue(startTime,endTime,screen){if(this.startTime===null||this.startTime>startTime){this.startTime=startTime;}this.endTime=endTime;this.screen=screen;this.timelineController.createCaptionsTrack(this.trackName);};_proto.reset=function reset(){this.cueRanges=[];this.startTime=null;};return OutputFilter;}();/***/},/***/"./src/utils/texttrack-utils.ts":/*!**************************************!*\
|
|
|
!*** ./src/utils/texttrack-utils.ts ***!
|
|
|
\**************************************/ /***/function srcUtilsTexttrackUtilsTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_858140__){"use strict";__nested_webpack_require_858140__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_858140__.d(__webpack_exports__,{/* harmony export */"addCueToTrack":function addCueToTrack(){return(/* binding */_addCueToTrack);},/* harmony export */"clearCurrentCues":function clearCurrentCues(){return(/* binding */_clearCurrentCues);},/* harmony export */"getCuesInRange":function getCuesInRange(){return(/* binding */_getCuesInRange);},/* harmony export */"removeCuesInRange":function removeCuesInRange(){return(/* binding */_removeCuesInRange);},/* harmony export */"sendAddTrackEvent":function sendAddTrackEvent(){return(/* binding */_sendAddTrackEvent);}/* harmony export */});/* harmony import */var _logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_858140__(/*! ./logger */"./src/utils/logger.ts");function _sendAddTrackEvent(track,videoEl){var event;try{event=new Event('addtrack');}catch(err){// for IE11
|
|
|
event=document.createEvent('Event');event.initEvent('addtrack',false,false);}event.track=track;videoEl.dispatchEvent(event);}function _addCueToTrack(track,cue){// Sometimes there are cue overlaps on segmented vtts so the same
|
|
|
// cue can appear more than once in different vtt files.
|
|
|
// This avoid showing duplicated cues with same timecode and text.
|
|
|
var mode=track.mode;if(mode==='disabled'){track.mode='hidden';}if(track.cues&&!track.cues.getCueById(cue.id)){try{track.addCue(cue);if(!track.cues.getCueById(cue.id)){throw new Error("addCue is failed for: "+cue);}}catch(err){_logger__WEBPACK_IMPORTED_MODULE_0__.logger.debug("[texttrack-utils]: "+err);var textTrackCue=new self.TextTrackCue(cue.startTime,cue.endTime,cue.text);textTrackCue.id=cue.id;track.addCue(textTrackCue);}}if(mode==='disabled'){track.mode=mode;}}function _clearCurrentCues(track){// When track.mode is disabled, track.cues will be null.
|
|
|
// To guarantee the removal of cues, we need to temporarily
|
|
|
// change the mode to hidden
|
|
|
var mode=track.mode;if(mode==='disabled'){track.mode='hidden';}if(track.cues){for(var i=track.cues.length;i--;){track.removeCue(track.cues[i]);}}if(mode==='disabled'){track.mode=mode;}}function _removeCuesInRange(track,start,end,predicate){var mode=track.mode;if(mode==='disabled'){track.mode='hidden';}if(track.cues&&track.cues.length>0){var cues=_getCuesInRange(track.cues,start,end);for(var i=0;i<cues.length;i++){if(!predicate||predicate(cues[i])){track.removeCue(cues[i]);}}}if(mode==='disabled'){track.mode=mode;}}// Find first cue starting after given time.
|
|
|
// Modified version of binary search O(log(n)).
|
|
|
function getFirstCueIndexAfterTime(cues,time){// If first cue starts after time, start there
|
|
|
if(time<cues[0].startTime){return 0;}// If the last cue ends before time there is no overlap
|
|
|
var len=cues.length-1;if(time>cues[len].endTime){return-1;}var left=0;var right=len;while(left<=right){var mid=Math.floor((right+left)/2);if(time<cues[mid].startTime){right=mid-1;}else if(time>cues[mid].startTime&&left<len){left=mid+1;}else{// If it's not lower or higher, it must be equal.
|
|
|
return mid;}}// At this point, left and right have swapped.
|
|
|
// No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
|
|
|
return cues[left].startTime-time<time-cues[right].startTime?left:right;}function _getCuesInRange(cues,start,end){var cuesFound=[];var firstCueInRange=getFirstCueIndexAfterTime(cues,start);if(firstCueInRange>-1){for(var i=firstCueInRange,len=cues.length;i<len;i++){var _cue=cues[i];if(_cue.startTime>=start&&_cue.endTime<=end){cuesFound.push(_cue);}else if(_cue.startTime>end){return cuesFound;}}}return cuesFound;}/***/},/***/"./src/utils/time-ranges.ts":/*!**********************************!*\
|
|
|
!*** ./src/utils/time-ranges.ts ***!
|
|
|
\**********************************/ /***/function srcUtilsTimeRangesTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_861978__){"use strict";__nested_webpack_require_861978__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_861978__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/**
|
|
|
* TimeRanges to string helper
|
|
|
*/var TimeRanges={toString:function toString(r){var log='';var len=r.length;for(var i=0;i<len;i++){log+="["+r.start(i).toFixed(3)+"-"+r.end(i).toFixed(3)+"]";}return log;}};/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=TimeRanges;/***/},/***/"./src/utils/timescale-conversion.ts":/*!*******************************************!*\
|
|
|
!*** ./src/utils/timescale-conversion.ts ***!
|
|
|
\*******************************************/ /***/function srcUtilsTimescaleConversionTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_862790__){"use strict";__nested_webpack_require_862790__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_862790__.d(__webpack_exports__,{/* harmony export */"toMpegTsClockFromTimescale":function toMpegTsClockFromTimescale(){return(/* binding */_toMpegTsClockFromTimescale);},/* harmony export */"toMsFromMpegTsClock":function toMsFromMpegTsClock(){return(/* binding */_toMsFromMpegTsClock);},/* harmony export */"toTimescaleFromBase":function toTimescaleFromBase(){return(/* binding */_toTimescaleFromBase);},/* harmony export */"toTimescaleFromScale":function toTimescaleFromScale(){return(/* binding */_toTimescaleFromScale);}/* harmony export */});var MPEG_TS_CLOCK_FREQ_HZ=90000;function _toTimescaleFromBase(value,destScale,srcBase,round){if(srcBase===void 0){srcBase=1;}if(round===void 0){round=false;}var result=value*destScale*srcBase;// equivalent to `(value * scale) / (1 / base)`
|
|
|
return round?Math.round(result):result;}function _toTimescaleFromScale(value,destScale,srcScale,round){if(srcScale===void 0){srcScale=1;}if(round===void 0){round=false;}return _toTimescaleFromBase(value,destScale,1/srcScale,round);}function _toMsFromMpegTsClock(value,round){if(round===void 0){round=false;}return _toTimescaleFromBase(value,1000,1/MPEG_TS_CLOCK_FREQ_HZ,round);}function _toMpegTsClockFromTimescale(value,srcScale){if(srcScale===void 0){srcScale=1;}return _toTimescaleFromBase(value,MPEG_TS_CLOCK_FREQ_HZ,1/srcScale);}/***/},/***/"./src/utils/typed-array.ts":/*!**********************************!*\
|
|
|
!*** ./src/utils/typed-array.ts ***!
|
|
|
\**********************************/ /***/function srcUtilsTypedArrayTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_864457__){"use strict";__nested_webpack_require_864457__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_864457__.d(__webpack_exports__,{/* harmony export */"sliceUint8":function sliceUint8(){return(/* binding */_sliceUint);}/* harmony export */});function _sliceUint(array,start,end){// @ts-expect-error This polyfills IE11 usage of Uint8Array slice.
|
|
|
// It always exists in the TypeScript definition so fails, but it fails at runtime on IE11.
|
|
|
return Uint8Array.prototype.slice?array.slice(start,end):new Uint8Array(Array.prototype.slice.call(array,start,end));}/***/},/***/"./src/utils/vttcue.ts":/*!*****************************!*\
|
|
|
!*** ./src/utils/vttcue.ts ***!
|
|
|
\*****************************/ /***/function srcUtilsVttcueTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_865237__){"use strict";__nested_webpack_require_865237__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_865237__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/**
|
|
|
* Copyright 2013 vtt.js Contributors
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
* You may obtain a copy of the License at
|
|
|
*
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
*
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
*/ /* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=function(){if(typeof self!=='undefined'&&self.VTTCue){return self.VTTCue;}var AllowedDirections=['','lr','rl'];var AllowedAlignments=['start','middle','end','left','right'];function isAllowedValue(allowed,value){if(typeof value!=='string'){return false;}// necessary for assuring the generic conforms to the Array interface
|
|
|
if(!Array.isArray(allowed)){return false;}// reset the type so that the next narrowing works well
|
|
|
var lcValue=value.toLowerCase();// use the allow list to narrow the type to a specific subset of strings
|
|
|
if(~allowed.indexOf(lcValue)){return lcValue;}return false;}function findDirectionSetting(value){return isAllowedValue(AllowedDirections,value);}function findAlignSetting(value){return isAllowedValue(AllowedAlignments,value);}function extend(obj){for(var _len=arguments.length,rest=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){rest[_key-1]=arguments[_key];}var i=1;for(;i<arguments.length;i++){var cobj=arguments[i];for(var p in cobj){obj[p]=cobj[p];}}return obj;}function VTTCue(startTime,endTime,text){var cue=this;var baseObj={enumerable:true};/**
|
|
|
* Shim implementation specific properties. These properties are not in
|
|
|
* the spec.
|
|
|
*/ // Lets us know when the VTTCue's data has changed in such a way that we need
|
|
|
// to recompute its display state. This lets us compute its display state
|
|
|
// lazily.
|
|
|
cue.hasBeenReset=false;/**
|
|
|
* VTTCue and TextTrackCue properties
|
|
|
* http://dev.w3.org/html5/webvtt/#vttcue-interface
|
|
|
*/var _id='';var _pauseOnExit=false;var _startTime=startTime;var _endTime=endTime;var _text=text;var _region=null;var _vertical='';var _snapToLines=true;var _line='auto';var _lineAlign='start';var _position=50;var _positionAlign='middle';var _size=50;var _align='middle';Object.defineProperty(cue,'id',extend({},baseObj,{get:function get(){return _id;},set:function set(value){_id=''+value;}}));Object.defineProperty(cue,'pauseOnExit',extend({},baseObj,{get:function get(){return _pauseOnExit;},set:function set(value){_pauseOnExit=!!value;}}));Object.defineProperty(cue,'startTime',extend({},baseObj,{get:function get(){return _startTime;},set:function set(value){if(typeof value!=='number'){throw new TypeError('Start time must be set to a number.');}_startTime=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'endTime',extend({},baseObj,{get:function get(){return _endTime;},set:function set(value){if(typeof value!=='number'){throw new TypeError('End time must be set to a number.');}_endTime=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'text',extend({},baseObj,{get:function get(){return _text;},set:function set(value){_text=''+value;this.hasBeenReset=true;}}));// todo: implement VTTRegion polyfill?
|
|
|
Object.defineProperty(cue,'region',extend({},baseObj,{get:function get(){return _region;},set:function set(value){_region=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'vertical',extend({},baseObj,{get:function get(){return _vertical;},set:function set(value){var setting=findDirectionSetting(value);// Have to check for false because the setting an be an empty string.
|
|
|
if(setting===false){throw new SyntaxError('An invalid or illegal string was specified.');}_vertical=setting;this.hasBeenReset=true;}}));Object.defineProperty(cue,'snapToLines',extend({},baseObj,{get:function get(){return _snapToLines;},set:function set(value){_snapToLines=!!value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'line',extend({},baseObj,{get:function get(){return _line;},set:function set(value){if(typeof value!=='number'&&value!=='auto'){throw new SyntaxError('An invalid number or illegal string was specified.');}_line=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'lineAlign',extend({},baseObj,{get:function get(){return _lineAlign;},set:function set(value){var setting=findAlignSetting(value);if(!setting){throw new SyntaxError('An invalid or illegal string was specified.');}_lineAlign=setting;this.hasBeenReset=true;}}));Object.defineProperty(cue,'position',extend({},baseObj,{get:function get(){return _position;},set:function set(value){if(value<0||value>100){throw new Error('Position must be between 0 and 100.');}_position=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'positionAlign',extend({},baseObj,{get:function get(){return _positionAlign;},set:function set(value){var setting=findAlignSetting(value);if(!setting){throw new SyntaxError('An invalid or illegal string was specified.');}_positionAlign=setting;this.hasBeenReset=true;}}));Object.defineProperty(cue,'size',extend({},baseObj,{get:function get(){return _size;},set:function set(value){if(value<0||value>100){throw new Error('Size must be between 0 and 100.');}_size=value;this.hasBeenReset=true;}}));Object.defineProperty(cue,'align',extend({},baseObj,{get:function get(){return _align;},set:function set(value){var setting=findAlignSetting(value);if(!setting){throw new SyntaxError('An invalid or illegal string was specified.');}_align=setting;this.hasBeenReset=true;}}));/**
|
|
|
* Other <track> spec defined properties
|
|
|
*/ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
|
|
|
cue.displayState=undefined;}/**
|
|
|
* VTTCue methods
|
|
|
*/VTTCue.prototype.getCueAsHTML=function(){// Assume WebVTT.convertCueToDOMTree is on the global.
|
|
|
var WebVTT=self.WebVTT;return WebVTT.convertCueToDOMTree(self,this.text);};// this is a polyfill hack
|
|
|
return VTTCue;}();/***/},/***/"./src/utils/vttparser.ts":/*!********************************!*\
|
|
|
!*** ./src/utils/vttparser.ts ***!
|
|
|
\********************************/ /***/function srcUtilsVttparserTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_871823__){"use strict";__nested_webpack_require_871823__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_871823__.d(__webpack_exports__,{/* harmony export */"VTTParser":function VTTParser(){return(/* binding */_VTTParser);},/* harmony export */"fixLineBreaks":function fixLineBreaks(){return(/* binding */_fixLineBreaks);},/* harmony export */"parseTimeStamp":function parseTimeStamp(){return(/* binding */_parseTimeStamp);}/* harmony export */});/* harmony import */var _vttcue__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_871823__(/*! ./vttcue */"./src/utils/vttcue.ts");/*
|
|
|
* Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js
|
|
|
*/var StringDecoder=/*#__PURE__*/function(){function StringDecoder(){}var _proto=StringDecoder.prototype;// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
_proto.decode=function decode(data,options){if(!data){return'';}if(typeof data!=='string'){throw new Error('Error - expected string data.');}return decodeURIComponent(encodeURIComponent(data));};return StringDecoder;}();// Try to parse input as a time stamp.
|
|
|
function _parseTimeStamp(input){function computeSeconds(h,m,s,f){return(h|0)*3600+(m|0)*60+(s|0)+parseFloat(f||0);}var m=input.match(/^(?:(\d+):)?(\d{2}):(\d{2})(\.\d+)?/);if(!m){return null;}if(parseFloat(m[2])>59){// Timestamp takes the form of [hours]:[minutes].[milliseconds]
|
|
|
// First position is hours as it's over 59.
|
|
|
return computeSeconds(m[2],m[3],0,m[4]);}// Timestamp takes the form of [hours (optional)]:[minutes]:[seconds].[milliseconds]
|
|
|
return computeSeconds(m[1],m[2],m[3],m[4]);}// A settings object holds key/value pairs and will ignore anything but the first
|
|
|
// assignment to a specific key.
|
|
|
var Settings=/*#__PURE__*/function(){function Settings(){this.values=Object.create(null);}var _proto2=Settings.prototype;// Only accept the first assignment to any key.
|
|
|
_proto2.set=function set(k,v){if(!this.get(k)&&v!==''){this.values[k]=v;}}// Return the value for a key, or a default value.
|
|
|
// If 'defaultKey' is passed then 'dflt' is assumed to be an object with
|
|
|
// a number of possible default values as properties where 'defaultKey' is
|
|
|
// the key of the property that will be chosen; otherwise it's assumed to be
|
|
|
// a single value.
|
|
|
;_proto2.get=function get(k,dflt,defaultKey){if(defaultKey){return this.has(k)?this.values[k]:dflt[defaultKey];}return this.has(k)?this.values[k]:dflt;}// Check whether we have a value for a key.
|
|
|
;_proto2.has=function has(k){return k in this.values;}// Accept a setting if its one of the given alternatives.
|
|
|
;_proto2.alt=function alt(k,v,a){for(var n=0;n<a.length;++n){if(v===a[n]){this.set(k,v);break;}}}// Accept a setting if its a valid (signed) integer.
|
|
|
;_proto2.integer=function integer(k,v){if(/^-?\d+$/.test(v)){// integer
|
|
|
this.set(k,parseInt(v,10));}}// Accept a setting if its a valid percentage.
|
|
|
;_proto2.percent=function percent(k,v){if(/^([\d]{1,3})(\.[\d]*)?%$/.test(v)){var percent=parseFloat(v);if(percent>=0&&percent<=100){this.set(k,percent);return true;}}return false;};return Settings;}();// Helper function to parse input into groups separated by 'groupDelim', and
|
|
|
// interpret each group as a key/value pair separated by 'keyValueDelim'.
|
|
|
function parseOptions(input,callback,keyValueDelim,groupDelim){var groups=groupDelim?input.split(groupDelim):[input];for(var i in groups){if(typeof groups[i]!=='string'){continue;}var kv=groups[i].split(keyValueDelim);if(kv.length!==2){continue;}var _k=kv[0];var _v=kv[1];callback(_k,_v);}}var defaults=new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0,0,'');// 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244
|
|
|
// Safari doesn't yet support this change, but FF and Chrome do.
|
|
|
var center=defaults.align==='middle'?'middle':'center';function parseCue(input,cue,regionList){// Remember the original input if we need to throw an error.
|
|
|
var oInput=input;// 4.1 WebVTT timestamp
|
|
|
function consumeTimeStamp(){var ts=_parseTimeStamp(input);if(ts===null){throw new Error('Malformed timestamp: '+oInput);}// Remove time stamp from input.
|
|
|
input=input.replace(/^[^\sa-zA-Z-]+/,'');return ts;}// 4.4.2 WebVTT cue settings
|
|
|
function consumeCueSettings(input,cue){var settings=new Settings();parseOptions(input,function(k,v){var vals;switch(k){case'region':// Find the last region we parsed with the same region id.
|
|
|
for(var i=regionList.length-1;i>=0;i--){if(regionList[i].id===v){settings.set(k,regionList[i].region);break;}}break;case'vertical':settings.alt(k,v,['rl','lr']);break;case'line':vals=v.split(',');settings.integer(k,vals[0]);if(settings.percent(k,vals[0])){settings.set('snapToLines',false);}settings.alt(k,vals[0],['auto']);if(vals.length===2){settings.alt('lineAlign',vals[1],['start',center,'end']);}break;case'position':vals=v.split(',');settings.percent(k,vals[0]);if(vals.length===2){settings.alt('positionAlign',vals[1],['start',center,'end','line-left','line-right','auto']);}break;case'size':settings.percent(k,v);break;case'align':settings.alt(k,v,['start',center,'end','left','right']);break;}},/:/,/\s/);// Apply default values for any missing fields.
|
|
|
cue.region=settings.get('region',null);cue.vertical=settings.get('vertical','');var line=settings.get('line','auto');if(line==='auto'&&defaults.line===-1){// set numeric line number for Safari
|
|
|
line=-1;}cue.line=line;cue.lineAlign=settings.get('lineAlign','start');cue.snapToLines=settings.get('snapToLines',true);cue.size=settings.get('size',100);cue.align=settings.get('align',center);var position=settings.get('position','auto');if(position==='auto'&&defaults.position===50){// set numeric position for Safari
|
|
|
position=cue.align==='start'||cue.align==='left'?0:cue.align==='end'||cue.align==='right'?100:50;}cue.position=position;}function skipWhitespace(){input=input.replace(/^\s+/,'');}// 4.1 WebVTT cue timings.
|
|
|
skipWhitespace();cue.startTime=consumeTimeStamp();// (1) collect cue start time
|
|
|
skipWhitespace();if(input.slice(0,3)!=='-->'){// (3) next characters must match '-->'
|
|
|
throw new Error("Malformed time stamp (time stamps must be separated by '-->'): "+oInput);}input=input.slice(3);skipWhitespace();cue.endTime=consumeTimeStamp();// (5) collect cue end time
|
|
|
// 4.1 WebVTT cue settings list.
|
|
|
skipWhitespace();consumeCueSettings(input,cue);}function _fixLineBreaks(input){return input.replace(/<br(?: \/)?>/gi,'\n');}var _VTTParser=/*#__PURE__*/function(){function VTTParser(){this.state='INITIAL';this.buffer='';this.decoder=new StringDecoder();this.regionList=[];this.cue=null;this.oncue=void 0;this.onparsingerror=void 0;this.onflush=void 0;}var _proto3=VTTParser.prototype;_proto3.parse=function parse(data){var _this=this;// If there is no data then we won't decode it, but will just try to parse
|
|
|
// whatever is in buffer already. This may occur in circumstances, for
|
|
|
// example when flush() is called.
|
|
|
if(data){// Try to decode the data that we received.
|
|
|
_this.buffer+=_this.decoder.decode(data,{stream:true});}function collectNextLine(){var buffer=_this.buffer;var pos=0;buffer=_fixLineBreaks(buffer);while(pos<buffer.length&&buffer[pos]!=='\r'&&buffer[pos]!=='\n'){++pos;}var line=buffer.slice(0,pos);// Advance the buffer early in case we fail below.
|
|
|
if(buffer[pos]==='\r'){++pos;}if(buffer[pos]==='\n'){++pos;}_this.buffer=buffer.slice(pos);return line;}// 3.2 WebVTT metadata header syntax
|
|
|
function parseHeader(input){parseOptions(input,function(k,v){// switch (k) {
|
|
|
// case 'region':
|
|
|
// 3.3 WebVTT region metadata header syntax
|
|
|
// console.log('parse region', v);
|
|
|
// parseRegion(v);
|
|
|
// break;
|
|
|
// }
|
|
|
},/:/);}// 5.1 WebVTT file parsing.
|
|
|
try{var line='';if(_this.state==='INITIAL'){// We can't start parsing until we have the first line.
|
|
|
if(!/\r\n|\n/.test(_this.buffer)){return this;}line=collectNextLine();// strip of UTF-8 BOM if any
|
|
|
// https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
|
|
|
var m=line.match(/^()?WEBVTT([ \t].*)?$/);if(!m||!m[0]){throw new Error('Malformed WebVTT signature.');}_this.state='HEADER';}var alreadyCollectedLine=false;while(_this.buffer){// We can't parse a line until we have the full line.
|
|
|
if(!/\r\n|\n/.test(_this.buffer)){return this;}if(!alreadyCollectedLine){line=collectNextLine();}else{alreadyCollectedLine=false;}switch(_this.state){case'HEADER':// 13-18 - Allow a header (metadata) under the WEBVTT line.
|
|
|
if(/:/.test(line)){parseHeader(line);}else if(!line){// An empty line terminates the header and starts the body (cues).
|
|
|
_this.state='ID';}continue;case'NOTE':// Ignore NOTE blocks.
|
|
|
if(!line){_this.state='ID';}continue;case'ID':// Check for the start of NOTE blocks.
|
|
|
if(/^NOTE($|[ \t])/.test(line)){_this.state='NOTE';break;}// 19-29 - Allow any number of line terminators, then initialize new cue values.
|
|
|
if(!line){continue;}_this.cue=new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0,0,'');_this.state='CUE';// 30-39 - Check if self line contains an optional identifier or timing data.
|
|
|
if(line.indexOf('-->')===-1){_this.cue.id=line;continue;}// Process line as start of a cue.
|
|
|
/* falls through */case'CUE':// 40 - Collect cue timings and settings.
|
|
|
if(!_this.cue){_this.state='BADCUE';continue;}try{parseCue(line,_this.cue,_this.regionList);}catch(e){// In case of an error ignore rest of the cue.
|
|
|
_this.cue=null;_this.state='BADCUE';continue;}_this.state='CUETEXT';continue;case'CUETEXT':{var hasSubstring=line.indexOf('-->')!==-1;// 34 - If we have an empty line then report the cue.
|
|
|
// 35 - If we have the special substring '-->' then report the cue,
|
|
|
// but do not collect the line as we need to process the current
|
|
|
// one as a new cue.
|
|
|
if(!line||hasSubstring&&(alreadyCollectedLine=true)){// We are done parsing self cue.
|
|
|
if(_this.oncue&&_this.cue){_this.oncue(_this.cue);}_this.cue=null;_this.state='ID';continue;}if(_this.cue===null){continue;}if(_this.cue.text){_this.cue.text+='\n';}_this.cue.text+=line;}continue;case'BADCUE':// 54-62 - Collect and discard the remaining cue.
|
|
|
if(!line){_this.state='ID';}}}}catch(e){// If we are currently parsing a cue, report what we have.
|
|
|
if(_this.state==='CUETEXT'&&_this.cue&&_this.oncue){_this.oncue(_this.cue);}_this.cue=null;// Enter BADWEBVTT state if header was not parsed correctly otherwise
|
|
|
// another exception occurred so enter BADCUE state.
|
|
|
_this.state=_this.state==='INITIAL'?'BADWEBVTT':'BADCUE';}return this;};_proto3.flush=function flush(){var _this=this;try{// Finish decoding the stream.
|
|
|
// _this.buffer += _this.decoder.decode();
|
|
|
// Synthesize the end of the current cue or region.
|
|
|
if(_this.cue||_this.state==='HEADER'){_this.buffer+='\n\n';_this.parse();}// If we've flushed, parsed, and we're still on the INITIAL state then
|
|
|
// that means we don't have enough of the stream to parse the first
|
|
|
// line.
|
|
|
if(_this.state==='INITIAL'||_this.state==='BADWEBVTT'){throw new Error('Malformed WebVTT signature.');}}catch(e){if(_this.onparsingerror){_this.onparsingerror(e);}}if(_this.onflush){_this.onflush();}return this;};return VTTParser;}();/***/},/***/"./src/utils/webvtt-parser.ts":/*!************************************!*\
|
|
|
!*** ./src/utils/webvtt-parser.ts ***!
|
|
|
\************************************/ /***/function srcUtilsWebvttParserTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_882926__){"use strict";__nested_webpack_require_882926__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_882926__.d(__webpack_exports__,{/* harmony export */"generateCueId":function generateCueId(){return(/* binding */_generateCueId);},/* harmony export */"parseWebVTT":function parseWebVTT(){return(/* binding */_parseWebVTT);}/* harmony export */});/* harmony import */var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_882926__(/*! ./src/polyfills/number */"./src/polyfills/number.ts");/* harmony import */var _vttparser__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_882926__(/*! ./vttparser */"./src/utils/vttparser.ts");/* harmony import */var _demux_id3__WEBPACK_IMPORTED_MODULE_2__=__nested_webpack_require_882926__(/*! ../demux/id3 */"./src/demux/id3.ts");/* harmony import */var _timescale_conversion__WEBPACK_IMPORTED_MODULE_3__=__nested_webpack_require_882926__(/*! ./timescale-conversion */"./src/utils/timescale-conversion.ts");/* harmony import */var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__=__nested_webpack_require_882926__(/*! ../remux/mp4-remuxer */"./src/remux/mp4-remuxer.ts");var LINEBREAKS=/\r\n|\n\r|\n|\r/g;// String.prototype.startsWith is not supported in IE11
|
|
|
var startsWith=function startsWith(inputString,searchString,position){if(position===void 0){position=0;}return inputString.slice(position,position+searchString.length)===searchString;};var cueString2millis=function cueString2millis(timeString){var ts=parseInt(timeString.slice(-3));var secs=parseInt(timeString.slice(-6,-4));var mins=parseInt(timeString.slice(-9,-7));var hours=timeString.length>9?parseInt(timeString.substring(0,timeString.indexOf(':'))):0;if(!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(ts)||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(secs)||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mins)||!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(hours)){throw Error("Malformed X-TIMESTAMP-MAP: Local:"+timeString);}ts+=1000*secs;ts+=60*1000*mins;ts+=60*60*1000*hours;return ts;};// From https://github.com/darkskyapp/string-hash
|
|
|
var hash=function hash(text){var hash=5381;var i=text.length;while(i){hash=hash*33^text.charCodeAt(--i);}return(hash>>>0).toString();};// Create a unique hash id for a cue based on start/end times and text.
|
|
|
// This helps timeline-controller to avoid showing repeated captions.
|
|
|
function _generateCueId(startTime,endTime,text){return hash(startTime.toString())+hash(endTime.toString())+hash(text);}var calculateOffset=function calculateOffset(vttCCs,cc,presentationTime){var currCC=vttCCs[cc];var prevCC=vttCCs[currCC.prevCC];// This is the first discontinuity or cues have been processed since the last discontinuity
|
|
|
// Offset = current discontinuity time
|
|
|
if(!prevCC||!prevCC["new"]&&currCC["new"]){vttCCs.ccOffset=vttCCs.presentationOffset=currCC.start;currCC["new"]=false;return;}// There have been discontinuities since cues were last parsed.
|
|
|
// Offset = time elapsed
|
|
|
while((_prevCC=prevCC)!==null&&_prevCC!==void 0&&_prevCC["new"]){var _prevCC;vttCCs.ccOffset+=currCC.start-prevCC.start;currCC["new"]=false;currCC=prevCC;prevCC=vttCCs[currCC.prevCC];}vttCCs.presentationOffset=presentationTime;};function _parseWebVTT(vttByteArray,initPTS,timescale,vttCCs,cc,timeOffset,callBack,errorCallBack){var parser=new _vttparser__WEBPACK_IMPORTED_MODULE_1__.VTTParser();// Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character.
|
|
|
// Uint8Array.prototype.reduce is not implemented in IE11
|
|
|
var vttLines=(0,_demux_id3__WEBPACK_IMPORTED_MODULE_2__.utf8ArrayToStr)(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS,'\n').split('\n');var cues=[];var initPTS90Hz=(0,_timescale_conversion__WEBPACK_IMPORTED_MODULE_3__.toMpegTsClockFromTimescale)(initPTS,timescale);var cueTime='00:00.000';var timestampMapMPEGTS=0;var timestampMapLOCAL=0;var parsingError;var inHeader=true;parser.oncue=function(cue){// Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline.
|
|
|
var currCC=vttCCs[cc];var cueOffset=vttCCs.ccOffset;// Calculate subtitle PTS offset
|
|
|
var webVttMpegTsMapOffset=(timestampMapMPEGTS-initPTS90Hz)/90000;// Update offsets for new discontinuities
|
|
|
if(currCC!==null&&currCC!==void 0&&currCC["new"]){if(timestampMapLOCAL!==undefined){// When local time is provided, offset = discontinuity start time - local time
|
|
|
cueOffset=vttCCs.ccOffset=currCC.start;}else{calculateOffset(vttCCs,cc,webVttMpegTsMapOffset);}}if(webVttMpegTsMapOffset){// If we have MPEGTS, offset = presentation time + discontinuity offset
|
|
|
cueOffset=webVttMpegTsMapOffset-vttCCs.presentationOffset;}var duration=cue.endTime-cue.startTime;var startTime=(0,_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__.normalizePts)((cue.startTime+cueOffset-timestampMapLOCAL)*90000,timeOffset*90000)/90000;cue.startTime=Math.max(startTime,0);cue.endTime=Math.max(startTime+duration,0);//trim trailing webvtt block whitespaces
|
|
|
var text=cue.text.trim();// Fix encoding of special characters
|
|
|
cue.text=decodeURIComponent(encodeURIComponent(text));// If the cue was not assigned an id from the VTT file (line above the content), create one.
|
|
|
if(!cue.id){cue.id=_generateCueId(cue.startTime,cue.endTime,text);}if(cue.endTime>0){cues.push(cue);}};parser.onparsingerror=function(error){parsingError=error;};parser.onflush=function(){if(parsingError){errorCallBack(parsingError);return;}callBack(cues);};// Go through contents line by line.
|
|
|
vttLines.forEach(function(line){if(inHeader){// Look for X-TIMESTAMP-MAP in header.
|
|
|
if(startsWith(line,'X-TIMESTAMP-MAP=')){// Once found, no more are allowed anyway, so stop searching.
|
|
|
inHeader=false;// Extract LOCAL and MPEGTS.
|
|
|
line.slice(16).split(',').forEach(function(timestamp){if(startsWith(timestamp,'LOCAL:')){cueTime=timestamp.slice(6);}else if(startsWith(timestamp,'MPEGTS:')){timestampMapMPEGTS=parseInt(timestamp.slice(7));}});try{// Convert cue time to seconds
|
|
|
timestampMapLOCAL=cueString2millis(cueTime)/1000;}catch(error){parsingError=error;}// Return without parsing X-TIMESTAMP-MAP line.
|
|
|
return;}else if(line===''){inHeader=false;}}// Parse line by default.
|
|
|
parser.parse(line+'\n');});parser.flush();}/***/},/***/"./src/utils/xhr-loader.ts":/*!*********************************!*\
|
|
|
!*** ./src/utils/xhr-loader.ts ***!
|
|
|
\*********************************/ /***/function srcUtilsXhrLoaderTs(__unused_webpack_module,__webpack_exports__,__nested_webpack_require_889529__){"use strict";__nested_webpack_require_889529__.r(__webpack_exports__);/* harmony export */__nested_webpack_require_889529__.d(__webpack_exports__,{/* harmony export */"default":function _default(){return __WEBPACK_DEFAULT_EXPORT__;}/* harmony export */});/* harmony import */var _utils_logger__WEBPACK_IMPORTED_MODULE_0__=__nested_webpack_require_889529__(/*! ../utils/logger */"./src/utils/logger.ts");/* harmony import */var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__=__nested_webpack_require_889529__(/*! ../loader/load-stats */"./src/loader/load-stats.ts");var AGE_HEADER_LINE_REGEX=/^age:\s*[\d.]+\s*$/m;var XhrLoader=/*#__PURE__*/function(){function XhrLoader(config/* HlsConfig */){this.xhrSetup=void 0;this.requestTimeout=void 0;this.retryTimeout=void 0;this.retryDelay=void 0;this.config=null;this.callbacks=null;this.context=void 0;this.loader=null;this.stats=void 0;this.xhrSetup=config?config.xhrSetup:null;this.stats=new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__.LoadStats();this.retryDelay=0;}var _proto=XhrLoader.prototype;_proto.destroy=function destroy(){this.callbacks=null;this.abortInternal();this.loader=null;this.config=null;};_proto.abortInternal=function abortInternal(){var loader=this.loader;self.clearTimeout(this.requestTimeout);self.clearTimeout(this.retryTimeout);if(loader){loader.onreadystatechange=null;loader.onprogress=null;if(loader.readyState!==4){this.stats.aborted=true;loader.abort();}}};_proto.abort=function abort(){var _this$callbacks;this.abortInternal();if((_this$callbacks=this.callbacks)!==null&&_this$callbacks!==void 0&&_this$callbacks.onAbort){this.callbacks.onAbort(this.stats,this.context,this.loader);}};_proto.load=function load(context,config,callbacks){if(this.stats.loading.start){throw new Error('Loader can only be used once.');}this.stats.loading.start=self.performance.now();this.context=context;this.config=config;this.callbacks=callbacks;this.retryDelay=config.retryDelay;this.loadInternal();};_proto.loadInternal=function loadInternal(){var config=this.config,context=this.context;if(!config){return;}var xhr=this.loader=new self.XMLHttpRequest();var stats=this.stats;stats.loading.first=0;stats.loaded=0;var xhrSetup=this.xhrSetup;try{if(xhrSetup){try{xhrSetup(xhr,context.url);}catch(e){// fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");}
|
|
|
// not working, as xhr.setRequestHeader expects xhr.readyState === OPEN
|
|
|
xhr.open('GET',context.url,true);xhrSetup(xhr,context.url);}}if(!xhr.readyState){xhr.open('GET',context.url,true);}var headers=this.context.headers;if(headers){for(var header in headers){xhr.setRequestHeader(header,headers[header]);}}}catch(e){// IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS
|
|
|
this.callbacks.onError({code:xhr.status,text:e.message},context,xhr);return;}if(context.rangeEnd){xhr.setRequestHeader('Range','bytes='+context.rangeStart+'-'+(context.rangeEnd-1));}xhr.onreadystatechange=this.readystatechange.bind(this);xhr.onprogress=this.loadprogress.bind(this);xhr.responseType=context.responseType;// setup timeout before we perform request
|
|
|
self.clearTimeout(this.requestTimeout);this.requestTimeout=self.setTimeout(this.loadtimeout.bind(this),config.timeout);xhr.send();};_proto.readystatechange=function readystatechange(){var context=this.context,xhr=this.loader,stats=this.stats;if(!context||!xhr){return;}var readyState=xhr.readyState;var config=this.config;// don't proceed if xhr has been aborted
|
|
|
if(stats.aborted){return;}// >= HEADERS_RECEIVED
|
|
|
if(readyState>=2){// clear xhr timeout and rearm it if readyState less than 4
|
|
|
self.clearTimeout(this.requestTimeout);if(stats.loading.first===0){stats.loading.first=Math.max(self.performance.now(),stats.loading.start);}if(readyState===4){xhr.onreadystatechange=null;xhr.onprogress=null;var status=xhr.status;// http status between 200 to 299 are all successful
|
|
|
var isArrayBuffer=xhr.responseType==='arraybuffer';if(status>=200&&status<300&&(isArrayBuffer&&xhr.response||xhr.responseText!==null)){stats.loading.end=Math.max(self.performance.now(),stats.loading.first);var data;var len;if(isArrayBuffer){data=xhr.response;len=data.byteLength;}else{data=xhr.responseText;len=data.length;}stats.loaded=stats.total=len;if(!this.callbacks){return;}var onProgress=this.callbacks.onProgress;if(onProgress){onProgress(stats,context,data,xhr);}if(!this.callbacks){return;}var response={url:xhr.responseURL,data:data};this.callbacks.onSuccess(response,stats,context,xhr);}else{// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
|
|
|
if(stats.retry>=config.maxRetry||status>=400&&status<499){_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.error(status+" while loading "+context.url);this.callbacks.onError({code:status,text:xhr.statusText},context,xhr);}else{// retry
|
|
|
_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn(status+" while loading "+context.url+", retrying in "+this.retryDelay+"...");// abort and reset internal state
|
|
|
this.abortInternal();this.loader=null;// schedule retry
|
|
|
self.clearTimeout(this.retryTimeout);this.retryTimeout=self.setTimeout(this.loadInternal.bind(this),this.retryDelay);// set exponential backoff
|
|
|
this.retryDelay=Math.min(2*this.retryDelay,config.maxRetryDelay);stats.retry++;}}}else{// readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet
|
|
|
self.clearTimeout(this.requestTimeout);this.requestTimeout=self.setTimeout(this.loadtimeout.bind(this),config.timeout);}}};_proto.loadtimeout=function loadtimeout(){_utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn("timeout while loading "+this.context.url);var callbacks=this.callbacks;if(callbacks){this.abortInternal();callbacks.onTimeout(this.stats,this.context,this.loader);}};_proto.loadprogress=function loadprogress(event){var stats=this.stats;stats.loaded=event.loaded;if(event.lengthComputable){stats.total=event.total;}};_proto.getCacheAge=function getCacheAge(){var result=null;if(this.loader&&AGE_HEADER_LINE_REGEX.test(this.loader.getAllResponseHeaders())){var ageHeader=this.loader.getResponseHeader('age');result=ageHeader?parseFloat(ageHeader):null;}return result;};return XhrLoader;}();/* harmony default export */var __WEBPACK_DEFAULT_EXPORT__=XhrLoader;/***/},/***/"./node_modules/eventemitter3/index.js":/*!*********************************************!*\
|
|
|
!*** ./node_modules/eventemitter3/index.js ***!
|
|
|
\*********************************************/ /***/function node_modulesEventemitter3IndexJs(module){"use strict";var has=Object.prototype.hasOwnProperty,prefix='~';/**
|
|
|
* Constructor to create a storage for our `EE` objects.
|
|
|
* An `Events` instance is a plain object whose properties are event names.
|
|
|
*
|
|
|
* @constructor
|
|
|
* @private
|
|
|
*/function Events(){}//
|
|
|
// We try to not inherit from `Object.prototype`. In some engines creating an
|
|
|
// instance in this way is faster than calling `Object.create(null)` directly.
|
|
|
// If `Object.create(null)` is not supported we prefix the event names with a
|
|
|
// character to make sure that the built-in object properties are not
|
|
|
// overridden or used as an attack vector.
|
|
|
//
|
|
|
if(Object.create){Events.prototype=Object.create(null);//
|
|
|
// This hack is needed because the `__proto__` property is still inherited in
|
|
|
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
|
|
|
//
|
|
|
if(!new Events().__proto__)prefix=false;}/**
|
|
|
* Representation of a single event listener.
|
|
|
*
|
|
|
* @param {Function} fn The listener function.
|
|
|
* @param {*} context The context to invoke the listener with.
|
|
|
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
|
|
|
* @constructor
|
|
|
* @private
|
|
|
*/function EE(fn,context,once){this.fn=fn;this.context=context;this.once=once||false;}/**
|
|
|
* Add a listener for a given event.
|
|
|
*
|
|
|
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @param {Function} fn The listener function.
|
|
|
* @param {*} context The context to invoke the listener with.
|
|
|
* @param {Boolean} once Specify if the listener is a one-time listener.
|
|
|
* @returns {EventEmitter}
|
|
|
* @private
|
|
|
*/function addListener(emitter,event,fn,context,once){if(typeof fn!=='function'){throw new TypeError('The listener must be a function');}var listener=new EE(fn,context||emitter,once),evt=prefix?prefix+event:event;if(!emitter._events[evt])emitter._events[evt]=listener,emitter._eventsCount++;else if(!emitter._events[evt].fn)emitter._events[evt].push(listener);else emitter._events[evt]=[emitter._events[evt],listener];return emitter;}/**
|
|
|
* Clear event by name.
|
|
|
*
|
|
|
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
|
|
* @param {(String|Symbol)} evt The Event name.
|
|
|
* @private
|
|
|
*/function clearEvent(emitter,evt){if(--emitter._eventsCount===0)emitter._events=new Events();else delete emitter._events[evt];}/**
|
|
|
* Minimal `EventEmitter` interface that is molded against the Node.js
|
|
|
* `EventEmitter` interface.
|
|
|
*
|
|
|
* @constructor
|
|
|
* @public
|
|
|
*/function EventEmitter(){this._events=new Events();this._eventsCount=0;}/**
|
|
|
* Return an array listing the events for which the emitter has registered
|
|
|
* listeners.
|
|
|
*
|
|
|
* @returns {Array}
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.eventNames=function eventNames(){var names=[],events,name;if(this._eventsCount===0)return names;for(name in events=this._events){if(has.call(events,name))names.push(prefix?name.slice(1):name);}if(Object.getOwnPropertySymbols){return names.concat(Object.getOwnPropertySymbols(events));}return names;};/**
|
|
|
* Return the listeners registered for a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @returns {Array} The registered listeners.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.listeners=function listeners(event){var evt=prefix?prefix+event:event,handlers=this._events[evt];if(!handlers)return[];if(handlers.fn)return[handlers.fn];for(var i=0,l=handlers.length,ee=new Array(l);i<l;i++){ee[i]=handlers[i].fn;}return ee;};/**
|
|
|
* Return the number of listeners listening to a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @returns {Number} The number of listeners.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.listenerCount=function listenerCount(event){var evt=prefix?prefix+event:event,listeners=this._events[evt];if(!listeners)return 0;if(listeners.fn)return 1;return listeners.length;};/**
|
|
|
* Calls each of the listeners registered for a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @returns {Boolean} `true` if the event had listeners, else `false`.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.emit=function emit(event,a1,a2,a3,a4,a5){var evt=prefix?prefix+event:event;if(!this._events[evt])return false;var listeners=this._events[evt],len=arguments.length,args,i;if(listeners.fn){if(listeners.once)this.removeListener(event,listeners.fn,undefined,true);switch(len){case 1:return listeners.fn.call(listeners.context),true;case 2:return listeners.fn.call(listeners.context,a1),true;case 3:return listeners.fn.call(listeners.context,a1,a2),true;case 4:return listeners.fn.call(listeners.context,a1,a2,a3),true;case 5:return listeners.fn.call(listeners.context,a1,a2,a3,a4),true;case 6:return listeners.fn.call(listeners.context,a1,a2,a3,a4,a5),true;}for(i=1,args=new Array(len-1);i<len;i++){args[i-1]=arguments[i];}listeners.fn.apply(listeners.context,args);}else{var length=listeners.length,j;for(i=0;i<length;i++){if(listeners[i].once)this.removeListener(event,listeners[i].fn,undefined,true);switch(len){case 1:listeners[i].fn.call(listeners[i].context);break;case 2:listeners[i].fn.call(listeners[i].context,a1);break;case 3:listeners[i].fn.call(listeners[i].context,a1,a2);break;case 4:listeners[i].fn.call(listeners[i].context,a1,a2,a3);break;default:if(!args)for(j=1,args=new Array(len-1);j<len;j++){args[j-1]=arguments[j];}listeners[i].fn.apply(listeners[i].context,args);}}}return true;};/**
|
|
|
* Add a listener for a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @param {Function} fn The listener function.
|
|
|
* @param {*} [context=this] The context to invoke the listener with.
|
|
|
* @returns {EventEmitter} `this`.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.on=function on(event,fn,context){return addListener(this,event,fn,context,false);};/**
|
|
|
* Add a one-time listener for a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @param {Function} fn The listener function.
|
|
|
* @param {*} [context=this] The context to invoke the listener with.
|
|
|
* @returns {EventEmitter} `this`.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.once=function once(event,fn,context){return addListener(this,event,fn,context,true);};/**
|
|
|
* Remove the listeners of a given event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} event The event name.
|
|
|
* @param {Function} fn Only remove the listeners that match this function.
|
|
|
* @param {*} context Only remove the listeners that have this context.
|
|
|
* @param {Boolean} once Only remove one-time listeners.
|
|
|
* @returns {EventEmitter} `this`.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.removeListener=function removeListener(event,fn,context,once){var evt=prefix?prefix+event:event;if(!this._events[evt])return this;if(!fn){clearEvent(this,evt);return this;}var listeners=this._events[evt];if(listeners.fn){if(listeners.fn===fn&&(!once||listeners.once)&&(!context||listeners.context===context)){clearEvent(this,evt);}}else{for(var i=0,events=[],length=listeners.length;i<length;i++){if(listeners[i].fn!==fn||once&&!listeners[i].once||context&&listeners[i].context!==context){events.push(listeners[i]);}}//
|
|
|
// Reset the array, or remove it completely if we have no more listeners.
|
|
|
//
|
|
|
if(events.length)this._events[evt]=events.length===1?events[0]:events;else clearEvent(this,evt);}return this;};/**
|
|
|
* Remove all listeners, or those of the specified event.
|
|
|
*
|
|
|
* @param {(String|Symbol)} [event] The event name.
|
|
|
* @returns {EventEmitter} `this`.
|
|
|
* @public
|
|
|
*/EventEmitter.prototype.removeAllListeners=function removeAllListeners(event){var evt;if(event){evt=prefix?prefix+event:event;if(this._events[evt])clearEvent(this,evt);}else{this._events=new Events();this._eventsCount=0;}return this;};//
|
|
|
// Alias methods names because people roll like that.
|
|
|
//
|
|
|
EventEmitter.prototype.off=EventEmitter.prototype.removeListener;EventEmitter.prototype.addListener=EventEmitter.prototype.on;//
|
|
|
// Expose the prefix.
|
|
|
//
|
|
|
EventEmitter.prefixed=prefix;//
|
|
|
// Allow `EventEmitter` to be imported as module namespace.
|
|
|
//
|
|
|
EventEmitter.EventEmitter=EventEmitter;//
|
|
|
// Expose the module.
|
|
|
//
|
|
|
if(true){module.exports=EventEmitter;}/***/},/***/"./node_modules/url-toolkit/src/url-toolkit.js":/*!*****************************************************!*\
|
|
|
!*** ./node_modules/url-toolkit/src/url-toolkit.js ***!
|
|
|
\*****************************************************/ /***/function node_modulesUrlToolkitSrcUrlToolkitJs(module){// see https://tools.ietf.org/html/rfc1808
|
|
|
(function(root){var URL_REGEX=/^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/;var FIRST_SEGMENT_REGEX=/^(?=([^\/?#]*))\1([^]*)$/;var SLASH_DOT_REGEX=/(?:\/|^)\.(?=\/)/g;var SLASH_DOT_DOT_REGEX=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g;var URLToolkit={// If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //
|
|
|
// E.g
|
|
|
// With opts.alwaysNormalize = false (default, spec compliant)
|
|
|
// http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g
|
|
|
// With opts.alwaysNormalize = true (not spec compliant)
|
|
|
// http://a.com/b/cd + /e/f/../g => http://a.com/e/g
|
|
|
buildAbsoluteURL:function buildAbsoluteURL(baseURL,relativeURL,opts){opts=opts||{};// remove any remaining space and CRLF
|
|
|
baseURL=baseURL.trim();relativeURL=relativeURL.trim();if(!relativeURL){// 2a) If the embedded URL is entirely empty, it inherits the
|
|
|
// entire base URL (i.e., is set equal to the base URL)
|
|
|
// and we are done.
|
|
|
if(!opts.alwaysNormalize){return baseURL;}var basePartsForNormalise=URLToolkit.parseURL(baseURL);if(!basePartsForNormalise){throw new Error('Error trying to parse base URL.');}basePartsForNormalise.path=URLToolkit.normalizePath(basePartsForNormalise.path);return URLToolkit.buildURLFromParts(basePartsForNormalise);}var relativeParts=URLToolkit.parseURL(relativeURL);if(!relativeParts){throw new Error('Error trying to parse relative URL.');}if(relativeParts.scheme){// 2b) If the embedded URL starts with a scheme name, it is
|
|
|
// interpreted as an absolute URL and we are done.
|
|
|
if(!opts.alwaysNormalize){return relativeURL;}relativeParts.path=URLToolkit.normalizePath(relativeParts.path);return URLToolkit.buildURLFromParts(relativeParts);}var baseParts=URLToolkit.parseURL(baseURL);if(!baseParts){throw new Error('Error trying to parse base URL.');}if(!baseParts.netLoc&&baseParts.path&&baseParts.path[0]!=='/'){// If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc
|
|
|
// This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'
|
|
|
var pathParts=FIRST_SEGMENT_REGEX.exec(baseParts.path);baseParts.netLoc=pathParts[1];baseParts.path=pathParts[2];}if(baseParts.netLoc&&!baseParts.path){baseParts.path='/';}var builtParts={// 2c) Otherwise, the embedded URL inherits the scheme of
|
|
|
// the base URL.
|
|
|
scheme:baseParts.scheme,netLoc:relativeParts.netLoc,path:null,params:relativeParts.params,query:relativeParts.query,fragment:relativeParts.fragment};if(!relativeParts.netLoc){// 3) If the embedded URL's <net_loc> is non-empty, we skip to
|
|
|
// Step 7. Otherwise, the embedded URL inherits the <net_loc>
|
|
|
// (if any) of the base URL.
|
|
|
builtParts.netLoc=baseParts.netLoc;// 4) If the embedded URL path is preceded by a slash "/", the
|
|
|
// path is not relative and we skip to Step 7.
|
|
|
if(relativeParts.path[0]!=='/'){if(!relativeParts.path){// 5) If the embedded URL path is empty (and not preceded by a
|
|
|
// slash), then the embedded URL inherits the base URL path
|
|
|
builtParts.path=baseParts.path;// 5a) if the embedded URL's <params> is non-empty, we skip to
|
|
|
// step 7; otherwise, it inherits the <params> of the base
|
|
|
// URL (if any) and
|
|
|
if(!relativeParts.params){builtParts.params=baseParts.params;// 5b) if the embedded URL's <query> is non-empty, we skip to
|
|
|
// step 7; otherwise, it inherits the <query> of the base
|
|
|
// URL (if any) and we skip to step 7.
|
|
|
if(!relativeParts.query){builtParts.query=baseParts.query;}}}else{// 6) The last segment of the base URL's path (anything
|
|
|
// following the rightmost slash "/", or the entire path if no
|
|
|
// slash is present) is removed and the embedded URL's path is
|
|
|
// appended in its place.
|
|
|
var baseURLPath=baseParts.path;var newPath=baseURLPath.substring(0,baseURLPath.lastIndexOf('/')+1)+relativeParts.path;builtParts.path=URLToolkit.normalizePath(newPath);}}}if(builtParts.path===null){builtParts.path=opts.alwaysNormalize?URLToolkit.normalizePath(relativeParts.path):relativeParts.path;}return URLToolkit.buildURLFromParts(builtParts);},parseURL:function parseURL(url){var parts=URL_REGEX.exec(url);if(!parts){return null;}return{scheme:parts[1]||'',netLoc:parts[2]||'',path:parts[3]||'',params:parts[4]||'',query:parts[5]||'',fragment:parts[6]||''};},normalizePath:function normalizePath(path){// The following operations are
|
|
|
// then applied, in order, to the new path:
|
|
|
// 6a) All occurrences of "./", where "." is a complete path
|
|
|
// segment, are removed.
|
|
|
// 6b) If the path ends with "." as a complete path segment,
|
|
|
// that "." is removed.
|
|
|
path=path.split('').reverse().join('').replace(SLASH_DOT_REGEX,'');// 6c) All occurrences of "<segment>/../", where <segment> is a
|
|
|
// complete path segment not equal to "..", are removed.
|
|
|
// Removal of these path segments is performed iteratively,
|
|
|
// removing the leftmost matching pattern on each iteration,
|
|
|
// until no matching pattern remains.
|
|
|
// 6d) If the path ends with "<segment>/..", where <segment> is a
|
|
|
// complete path segment not equal to "..", that
|
|
|
// "<segment>/.." is removed.
|
|
|
while(path.length!==(path=path.replace(SLASH_DOT_DOT_REGEX,'')).length){}return path.split('').reverse().join('');},buildURLFromParts:function buildURLFromParts(parts){return parts.scheme+parts.netLoc+parts.path+parts.params+parts.query+parts.fragment;}};if(true)module.exports=URLToolkit;else{}})(this);/***/}/******/};/************************************************************************/ /******/ // The module cache
|
|
|
/******/var __webpack_module_cache__={};/******/ /******/ // The require function
|
|
|
/******/function __nested_webpack_require_909968__(moduleId){/******/ // Check if module is in cache
|
|
|
/******/var cachedModule=__webpack_module_cache__[moduleId];/******/if(cachedModule!==undefined){/******/return cachedModule.exports;/******/}/******/ // Create a new module (and put it into the cache)
|
|
|
/******/var module=__webpack_module_cache__[moduleId]={/******/ // no module.id needed
|
|
|
/******/ // no module.loaded needed
|
|
|
/******/exports:{}/******/};/******/ /******/ // Execute the module function
|
|
|
/******/__webpack_modules__[moduleId].call(module.exports,module,module.exports,__nested_webpack_require_909968__);/******/ /******/ // Return the exports of the module
|
|
|
/******/return module.exports;/******/}/******/ /******/ // expose the modules object (__webpack_modules__)
|
|
|
/******/__nested_webpack_require_909968__.m=__webpack_modules__;/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/(function(){/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
|
/******/__nested_webpack_require_909968__.n=function(module){/******/var getter=module&&module.__esModule?/******/function(){return module['default'];}:/******/function(){return module;};/******/__nested_webpack_require_909968__.d(getter,{a:getter});/******/return getter;/******/};/******/})();/******/ /******/ /* webpack/runtime/define property getters */ /******/(function(){/******/ // define getter functions for harmony exports
|
|
|
/******/__nested_webpack_require_909968__.d=function(exports,definition){/******/for(var key in definition){/******/if(__nested_webpack_require_909968__.o(definition,key)&&!__nested_webpack_require_909968__.o(exports,key)){/******/Object.defineProperty(exports,key,{enumerable:true,get:definition[key]});/******/}/******/}/******/};/******/})();/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/(function(){/******/__nested_webpack_require_909968__.o=function(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop);};/******/})();/******/ /******/ /* webpack/runtime/make namespace object */ /******/(function(){/******/ // define __esModule on exports
|
|
|
/******/__nested_webpack_require_909968__.r=function(exports){/******/if(typeof Symbol!=='undefined'&&Symbol.toStringTag){/******/Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});/******/}/******/Object.defineProperty(exports,'__esModule',{value:true});/******/};/******/})();/******/ /************************************************************************/ /******/ /******/ // module factories are used so entry inlining is disabled
|
|
|
/******/ // startup
|
|
|
/******/ // Load entry module and return exports
|
|
|
/******/var __webpack_exports__=__nested_webpack_require_909968__("./src/hls.ts");/******/__webpack_exports__=__webpack_exports__["default"];/******/ /******/return __webpack_exports__;/******/}());});
|
|
|
|
|
|
/***/ })
|
|
|
|
|
|
}]); |