# All files / src/loader fragment-loader.js

54.17% Statements 26/48
27.78% Branches 5/18
57.14% Functions 4/7
55.32% Lines 26/47

    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

    77x
    77x

    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 (!isNaN(start) && !isNaN(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) {
        let loader = context.loader;
        Iif (loader) {
          loader.abort();
        }

        this.loaders[context.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) {
        let loader = context.loader;
        if (loader) {
          loader.abort();
        }

        this.loaders[context.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;