-
Notifications
You must be signed in to change notification settings - Fork 9
/
fetch.js
119 lines (115 loc) · 2.72 KB
/
fetch.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
115
116
117
118
119
/**
* fetch firfox 直播 点播
* author songguangyu
* email 522963130@qq.com
*/
import handleQuery from './handleQuery';
import {CustEvent} from 'chimee-helper-events';
import Log from 'chimee-helper-log';
import {ERRORNO} from '$const';
/**
* FetchLoader
* @class FetchLoader
* @param {string} video url
* @param {object} range.from range.to
*/
export default class FetchLoader extends CustEvent {
/**
* broswer is support moz-chunk
*/
static isSupport () {
if(self.fetch && self.ReadableStream) {
return true;
} else {
return false;
}
}
constructor (src, config) {
super();
this.tag = 'fetch';
this.fetching = false;
this.config = config;
this.range = {
from: 0,
to: 524288
};
this.src = src;
this.totalRange = null;
this.block = 524288;
this.reader = null;
this.requestAbort = false;
this.arrivalDataCallback = null;
this.bytesStart = 0;
this.heartbeat = null;
}
/**
* if don't need range don't set
* @param {object} range.from range.to
*/
open (range, keyframePoint) {
this.requestAbort = false;
const reqHeaders = new Headers();
const r = range || {from: 0, to: -1};
if(!this.config.isLive) {
this.range.from = r.from;
this.range.to = r.to;
const queryResult = handleQuery(r, this.config);
if(typeof queryResult === 'string') {
this.src = this.config.src + queryResult;
} else {
for(const i in queryResult) {
reqHeaders.append(i, queryResult[i]);
}
}
}
if(keyframePoint) {
this.bytesStart = 0;
}
this.bytesStart = range.from;
const params = {
method: 'GET',
headers: reqHeaders,
mode: 'cors',
cache: 'default',
referrerPolicy: 'no-referrer-when-downgrade'
};
fetch(this.src, params).then((res)=>{
if(res.ok) {
const reader = res.body.getReader();
return this.pump(reader, keyframePoint);
}
}).catch((e)=>{
this.emit('error', {errno: ERRORNO.NET_ERROR, errmsg: e});
});
}
/**
* pause video
*/
pause () {
this.requestAbort = true;
}
/**
* pump data
*/
pump (reader, keyframePoint) { // ReadableStreamReader
return reader.read().then((result) => {
if (result.done) {
this.emit('end');
Log.verbose(this.tag, 'load end');
} else {
if (this.requestAbort === true) {
this.requestAbort = false;
return reader.cancel();
}
const chunk = result.value.buffer;
if(this.arrivalDataCallback) {
this.arrivalDataCallback(chunk, this.bytesStart, keyframePoint);
this.bytesStart += chunk.byteLength;
}
return this.pump(reader);
}
}).catch((e) => {
this.emit('error', {errno: ERRORNO.NET_ERROR, errmsg: e.message});
});
}
}