# 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;