forked from video-dev/hls.js
-
Notifications
You must be signed in to change notification settings - Fork 7
/
fragment-loader.js
114 lines (92 loc) · 3.28 KB
/
fragment-loader.js
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
/*
* 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 (!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;
if (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;