mirror of https://bitbucket.org/ausocean/av.git
117 lines
3.4 KiB
JavaScript
117 lines
3.4 KiB
JavaScript
/*
|
|
* 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];
|
|
if (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;
|
|
|
|
if (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;
|
|
if (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;
|