All files / src/loader fragment-loader.js

64% Statements 32/50
27.78% Branches 5/18
71.43% Functions 5/7
65.31% Lines 32/49
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;