1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 85x 85x 9x 9x 9x 9x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x | /* * Fragment Loader */ import Event from '../events'; import EventHandler from '../event-handler'; import { ErrorTypes, ErrorDetails } from '../errors'; import { logger } from '../utils/logger'; class FragmentLoader extends EventHandler { constructor (hls) { super(hls, Event.FRAG_LOADING); this.loaders = {}; } destroy () { let loaders = this.loaders; for (let loaderName in loaders) { let loader = loaders[loaderName]; if (loader) { loader.destroy(); } } this.loaders = {}; super.destroy(); } onFragLoading (data) { const frag = data.frag, type = frag.type, loaders = this.loaders, config = this.hls.config, FragmentILoader = config.fLoader, DefaultILoader = config.loader; // reset fragment state frag.loaded = 0; let loader = loaders[type]; Iif (loader) { logger.warn(`abort previous fragment loader for type: ${type}`); loader.abort(); } loader = loaders[type] = frag.loader = config.fLoader ? new FragmentILoader(config) : new DefaultILoader(config); let loaderContext, loaderConfig, loaderCallbacks; loaderContext = { url: frag.url, frag: frag, responseType: 'arraybuffer', progressData: false }; let start = frag.byteRangeStartOffset, end = frag.byteRangeEndOffset; Iif (Number.isFinite(start) && Number.isFinite(end)) { loaderContext.rangeStart = start; loaderContext.rangeEnd = end; } loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: 0, retryDelay: 0, maxRetryDelay: config.fragLoadingMaxRetryTimeout }; loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this), onProgress: this.loadprogress.bind(this) }; loader.load(loaderContext, loaderConfig, loaderCallbacks); } loadsuccess (response, stats, context, networkDetails = null) { let payload = response.data, frag = context.frag; // detach fragment loader on load success frag.loader = undefined; this.loaders[frag.type] = undefined; this.hls.trigger(Event.FRAG_LOADED, { payload: payload, frag: frag, stats: stats, networkDetails: networkDetails }); } loaderror (response, context, networkDetails = null) { const frag = context.frag; let loader = frag.loader; Eif (loader) { loader.abort(); } this.loaders[frag.type] = undefined; this.hls.trigger(Event.ERROR, { type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.FRAG_LOAD_ERROR, fatal: false, frag: context.frag, response: response, networkDetails: networkDetails }); } loadtimeout (stats, context, networkDetails = null) { const frag = context.frag; let loader = frag.loader; if (loader) { loader.abort(); } this.loaders[frag.type] = undefined; this.hls.trigger(Event.ERROR, { type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.FRAG_LOAD_TIMEOUT, fatal: false, frag: context.frag, networkDetails: networkDetails }); } // data will be used for progressive parsing loadprogress (stats, context, data, networkDetails = null) { // jshint ignore:line let frag = context.frag; frag.loaded = stats.loaded; this.hls.trigger(Event.FRAG_LOAD_PROGRESS, { frag: frag, stats: stats, networkDetails: networkDetails }); } } export default FragmentLoader; |