@alessmicrosystems/mpegts.js 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +158 -0
- package/README_ja.md +153 -0
- package/README_zh.md +157 -0
- package/d.ts/mpegts.d.ts +524 -0
- package/d.ts/src/core/mse-events.d.ts +9 -0
- package/d.ts/src/core/transmuxing-events.d.ts +24 -0
- package/d.ts/src/demux/aac.d.ts +44 -0
- package/d.ts/src/demux/ac3.d.ts +70 -0
- package/d.ts/src/demux/av1-parser.d.ts +77 -0
- package/d.ts/src/demux/av1.d.ts +11 -0
- package/d.ts/src/demux/base-demuxer.d.ts +55 -0
- package/d.ts/src/demux/h264.d.ts +40 -0
- package/d.ts/src/demux/h265.d.ts +65 -0
- package/d.ts/src/demux/klv.d.ts +17 -0
- package/d.ts/src/demux/mp3.d.ts +6 -0
- package/d.ts/src/demux/mpeg4-audio.d.ts +28 -0
- package/d.ts/src/demux/pat-pmt-pes.d.ts +106 -0
- package/d.ts/src/demux/patpmt.d.ts +40 -0
- package/d.ts/src/demux/pes-private-data.d.ts +14 -0
- package/d.ts/src/demux/pgs-data.d.ts +9 -0
- package/d.ts/src/demux/scte35.d.ts +250 -0
- package/d.ts/src/demux/sei.d.ts +8 -0
- package/d.ts/src/demux/smpte2038.d.ts +22 -0
- package/d.ts/src/demux/ts-demuxer.d.ts +124 -0
- package/d.ts/src/player/live-latency-chaser.d.ts +10 -0
- package/d.ts/src/player/live-latency-synchronizer.d.ts +10 -0
- package/d.ts/src/player/loading-controller.d.ts +19 -0
- package/d.ts/src/player/mse-player.d.ts +30 -0
- package/d.ts/src/player/player-engine-dedicated-thread-worker.d.ts +2 -0
- package/d.ts/src/player/player-engine-dedicated-thread.d.ts +48 -0
- package/d.ts/src/player/player-engine-main-thread.d.ts +50 -0
- package/d.ts/src/player/player-engine-worker-cmd-def.d.ts +25 -0
- package/d.ts/src/player/player-engine-worker-msg-def.d.ts +54 -0
- package/d.ts/src/player/player-engine-worker.d.ts +2 -0
- package/d.ts/src/player/player-engine.d.ts +16 -0
- package/d.ts/src/player/player-events.d.ts +21 -0
- package/d.ts/src/player/seeking-handler.d.ts +22 -0
- package/d.ts/src/player/startup-stall-jumper.d.ts +14 -0
- package/d.ts/src/utils/typedarray-equality.d.ts +2 -0
- package/dist/mpegts.js +3 -0
- package/dist/mpegts.js.LICENSE.txt +7 -0
- package/dist/mpegts.js.map +1 -0
- package/package.json +53 -0
- package/src/config.js +67 -0
- package/src/core/features.js +88 -0
- package/src/core/media-info.js +127 -0
- package/src/core/media-segment-info.js +230 -0
- package/src/core/mse-controller.js +599 -0
- package/src/core/mse-events.ts +28 -0
- package/src/core/transmuxer.js +346 -0
- package/src/core/transmuxing-controller.js +628 -0
- package/src/core/transmuxing-events.ts +43 -0
- package/src/core/transmuxing-worker.js +286 -0
- package/src/demux/aac.ts +397 -0
- package/src/demux/ac3.ts +335 -0
- package/src/demux/amf-parser.js +243 -0
- package/src/demux/av1-parser.ts +629 -0
- package/src/demux/av1.ts +103 -0
- package/src/demux/base-demuxer.ts +69 -0
- package/src/demux/demux-errors.js +26 -0
- package/src/demux/exp-golomb.js +116 -0
- package/src/demux/flv-demuxer.js +1854 -0
- package/src/demux/h264.ts +187 -0
- package/src/demux/h265-parser.js +501 -0
- package/src/demux/h265.ts +214 -0
- package/src/demux/klv.ts +40 -0
- package/src/demux/mp3.ts +7 -0
- package/src/demux/mpeg4-audio.ts +45 -0
- package/src/demux/pat-pmt-pes.ts +132 -0
- package/src/demux/pes-private-data.ts +16 -0
- package/src/demux/pgs-data.ts +11 -0
- package/src/demux/scte35.ts +723 -0
- package/src/demux/sei.ts +99 -0
- package/src/demux/smpte2038.ts +89 -0
- package/src/demux/sps-parser.js +298 -0
- package/src/demux/ts-demuxer.ts +2405 -0
- package/src/index.js +4 -0
- package/src/io/fetch-stream-loader.js +266 -0
- package/src/io/io-controller.js +647 -0
- package/src/io/loader.js +134 -0
- package/src/io/param-seek-handler.js +85 -0
- package/src/io/range-seek-handler.js +52 -0
- package/src/io/speed-sampler.js +93 -0
- package/src/io/websocket-loader.js +151 -0
- package/src/io/xhr-moz-chunked-loader.js +211 -0
- package/src/io/xhr-msstream-loader.js +307 -0
- package/src/io/xhr-range-loader.js +366 -0
- package/src/mpegts.js +95 -0
- package/src/player/live-latency-chaser.ts +66 -0
- package/src/player/live-latency-synchronizer.ts +79 -0
- package/src/player/loading-controller.ts +142 -0
- package/src/player/mse-player.ts +150 -0
- package/src/player/native-player.js +262 -0
- package/src/player/player-engine-dedicated-thread.ts +479 -0
- package/src/player/player-engine-main-thread.ts +463 -0
- package/src/player/player-engine-worker-cmd-def.ts +62 -0
- package/src/player/player-engine-worker-msg-def.ts +102 -0
- package/src/player/player-engine-worker.ts +370 -0
- package/src/player/player-engine.ts +35 -0
- package/src/player/player-errors.js +39 -0
- package/src/player/player-events.ts +40 -0
- package/src/player/seeking-handler.ts +205 -0
- package/src/player/startup-stall-jumper.ts +86 -0
- package/src/remux/aac-silent.js +56 -0
- package/src/remux/mp4-generator.js +866 -0
- package/src/remux/mp4-remuxer.js +778 -0
- package/src/utils/browser.js +128 -0
- package/src/utils/exception.js +73 -0
- package/src/utils/logger.js +140 -0
- package/src/utils/logging-control.js +165 -0
- package/src/utils/polyfill.js +68 -0
- package/src/utils/typedarray-equality.ts +69 -0
- package/src/utils/utf8-conv.js +84 -0
- package/src/utils/webworkify-webpack.js +202 -0
- package/tsconfig.json +16 -0
- package/tslint.json +1 -0
- package/types/index.d.ts +3 -0
- package/types/test-flv.ts +8 -0
- package/types/tsconfig.json +24 -0
- package/webpack.config.js +55 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2016 Bilibili. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* @author zheng qian <xqq@xqq.im>
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import Log from '../utils/logger.js';
|
|
20
|
+
import Browser from '../utils/browser.js';
|
|
21
|
+
import {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';
|
|
22
|
+
import {RuntimeException} from '../utils/exception.js';
|
|
23
|
+
|
|
24
|
+
/* fetch + stream IO loader. Currently working on chrome 43+.
|
|
25
|
+
* fetch provides a better alternative http API to XMLHttpRequest
|
|
26
|
+
*
|
|
27
|
+
* fetch spec https://fetch.spec.whatwg.org/
|
|
28
|
+
* stream spec https://streams.spec.whatwg.org/
|
|
29
|
+
*/
|
|
30
|
+
class FetchStreamLoader extends BaseLoader {
|
|
31
|
+
|
|
32
|
+
static isSupported() {
|
|
33
|
+
try {
|
|
34
|
+
// fetch + stream is broken on Microsoft Edge. Disable before build 15048.
|
|
35
|
+
// see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/
|
|
36
|
+
// Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.
|
|
37
|
+
let isWorkWellEdge = Browser.msedge && Browser.version.minor >= 15048;
|
|
38
|
+
let browserNotBlacklisted = Browser.msedge ? isWorkWellEdge : true;
|
|
39
|
+
return (self.fetch && self.ReadableStream && browserNotBlacklisted);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
constructor(seekHandler, config) {
|
|
46
|
+
super('fetch-stream-loader');
|
|
47
|
+
this.TAG = 'FetchStreamLoader';
|
|
48
|
+
|
|
49
|
+
this._seekHandler = seekHandler;
|
|
50
|
+
this._config = config;
|
|
51
|
+
this._needStash = true;
|
|
52
|
+
|
|
53
|
+
this._requestAbort = false;
|
|
54
|
+
this._abortController = null;
|
|
55
|
+
this._contentLength = null;
|
|
56
|
+
this._receivedLength = 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
destroy() {
|
|
60
|
+
if (this.isWorking()) {
|
|
61
|
+
this.abort();
|
|
62
|
+
}
|
|
63
|
+
super.destroy();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
open(dataSource, range) {
|
|
67
|
+
this._dataSource = dataSource;
|
|
68
|
+
this._range = range;
|
|
69
|
+
|
|
70
|
+
let sourceURL = dataSource.url;
|
|
71
|
+
if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {
|
|
72
|
+
sourceURL = dataSource.redirectedURL;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let seekConfig = this._seekHandler.getConfig(sourceURL, range);
|
|
76
|
+
|
|
77
|
+
let headers = new self.Headers();
|
|
78
|
+
|
|
79
|
+
if (typeof seekConfig.headers === 'object') {
|
|
80
|
+
let configHeaders = seekConfig.headers;
|
|
81
|
+
for (let key in configHeaders) {
|
|
82
|
+
if (configHeaders.hasOwnProperty(key)) {
|
|
83
|
+
headers.append(key, configHeaders[key]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let params = {
|
|
89
|
+
method: 'GET',
|
|
90
|
+
headers: headers,
|
|
91
|
+
mode: 'cors',
|
|
92
|
+
cache: 'default',
|
|
93
|
+
// The default policy of Fetch API in the whatwg standard
|
|
94
|
+
// Safari incorrectly indicates 'no-referrer' as default policy, fuck it
|
|
95
|
+
referrerPolicy: 'no-referrer-when-downgrade'
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// add additional headers
|
|
99
|
+
if (typeof this._config.headers === 'object') {
|
|
100
|
+
for (let key in this._config.headers) {
|
|
101
|
+
headers.append(key, this._config.headers[key]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// cors is enabled by default
|
|
106
|
+
if (dataSource.cors === false) {
|
|
107
|
+
// no-cors means 'disregard cors policy', which can only be used in ServiceWorker
|
|
108
|
+
params.mode = 'same-origin';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// withCredentials is disabled by default
|
|
112
|
+
if (dataSource.withCredentials) {
|
|
113
|
+
params.credentials = 'include';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// referrerPolicy from config
|
|
117
|
+
if (dataSource.referrerPolicy) {
|
|
118
|
+
params.referrerPolicy = dataSource.referrerPolicy;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (self.AbortController) {
|
|
122
|
+
this._abortController = new self.AbortController();
|
|
123
|
+
params.signal = this._abortController.signal;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this._status = LoaderStatus.kConnecting;
|
|
127
|
+
self.fetch(seekConfig.url, params).then((res) => {
|
|
128
|
+
if (this._requestAbort) {
|
|
129
|
+
this._status = LoaderStatus.kIdle;
|
|
130
|
+
res.body.cancel();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (res.ok && (res.status >= 200 && res.status <= 299)) {
|
|
134
|
+
if (res.url !== seekConfig.url) {
|
|
135
|
+
if (this._onURLRedirect) {
|
|
136
|
+
let redirectedURL = this._seekHandler.removeURLParameters(res.url);
|
|
137
|
+
this._onURLRedirect(redirectedURL);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let lengthHeader = res.headers.get('Content-Length');
|
|
142
|
+
if (lengthHeader != null) {
|
|
143
|
+
this._contentLength = parseInt(lengthHeader);
|
|
144
|
+
if (this._contentLength !== 0) {
|
|
145
|
+
if (this._onContentLengthKnown) {
|
|
146
|
+
this._onContentLengthKnown(this._contentLength);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return this._pump.call(this, res.body.getReader());
|
|
152
|
+
} else {
|
|
153
|
+
this._status = LoaderStatus.kError;
|
|
154
|
+
if (this._onError) {
|
|
155
|
+
this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: res.status, msg: res.statusText});
|
|
156
|
+
} else {
|
|
157
|
+
throw new RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}).catch((e) => {
|
|
161
|
+
if (this._abortController && this._abortController.signal.aborted) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this._status = LoaderStatus.kError;
|
|
166
|
+
if (this._onError) {
|
|
167
|
+
this._onError(LoaderErrors.EXCEPTION, {code: -1, msg: e.message});
|
|
168
|
+
} else {
|
|
169
|
+
throw e;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
abort() {
|
|
175
|
+
this._requestAbort = true;
|
|
176
|
+
|
|
177
|
+
if (this._status !== LoaderStatus.kBuffering || !Browser.chrome) {
|
|
178
|
+
// Chrome may throw Exception-like things here, avoid using if is buffering
|
|
179
|
+
if (this._abortController) {
|
|
180
|
+
try {
|
|
181
|
+
this._abortController.abort();
|
|
182
|
+
} catch (e) {}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
_pump(reader) { // ReadableStreamReader
|
|
188
|
+
return reader.read().then((result) => {
|
|
189
|
+
if (result.done) {
|
|
190
|
+
// First check received length
|
|
191
|
+
if (this._contentLength !== null && this._receivedLength < this._contentLength) {
|
|
192
|
+
// Report Early-EOF
|
|
193
|
+
this._status = LoaderStatus.kError;
|
|
194
|
+
let type = LoaderErrors.EARLY_EOF;
|
|
195
|
+
let info = {code: -1, msg: 'Fetch stream meet Early-EOF'};
|
|
196
|
+
if (this._onError) {
|
|
197
|
+
this._onError(type, info);
|
|
198
|
+
} else {
|
|
199
|
+
throw new RuntimeException(info.msg);
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
// OK. Download complete
|
|
203
|
+
this._status = LoaderStatus.kComplete;
|
|
204
|
+
if (this._onComplete) {
|
|
205
|
+
this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
if (this._abortController && this._abortController.signal.aborted) {
|
|
210
|
+
this._status = LoaderStatus.kComplete;
|
|
211
|
+
return;
|
|
212
|
+
} else if (this._requestAbort === true) {
|
|
213
|
+
this._status = LoaderStatus.kComplete;
|
|
214
|
+
return reader.cancel();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this._status = LoaderStatus.kBuffering;
|
|
218
|
+
|
|
219
|
+
let chunk = result.value.buffer;
|
|
220
|
+
let byteStart = this._range.from + this._receivedLength;
|
|
221
|
+
this._receivedLength += chunk.byteLength;
|
|
222
|
+
|
|
223
|
+
if (this._onDataArrival) {
|
|
224
|
+
this._onDataArrival(chunk, byteStart, this._receivedLength);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this._pump(reader);
|
|
228
|
+
}
|
|
229
|
+
}).catch((e) => {
|
|
230
|
+
if (this._abortController && this._abortController.signal.aborted) {
|
|
231
|
+
this._status = LoaderStatus.kComplete;
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (e.code === 11 && Browser.msedge) { // InvalidStateError on Microsoft Edge
|
|
236
|
+
// Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call
|
|
237
|
+
// Ignore the unknown exception.
|
|
238
|
+
// Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this._status = LoaderStatus.kError;
|
|
243
|
+
let type = 0;
|
|
244
|
+
let info = null;
|
|
245
|
+
|
|
246
|
+
if ((e.code === 19 || e.message === 'network error') && // NETWORK_ERR
|
|
247
|
+
(this._contentLength === null ||
|
|
248
|
+
(this._contentLength !== null && this._receivedLength < this._contentLength))) {
|
|
249
|
+
type = LoaderErrors.EARLY_EOF;
|
|
250
|
+
info = {code: e.code, msg: 'Fetch stream meet Early-EOF'};
|
|
251
|
+
} else {
|
|
252
|
+
type = LoaderErrors.EXCEPTION;
|
|
253
|
+
info = {code: e.code, msg: e.message};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (this._onError) {
|
|
257
|
+
this._onError(type, info);
|
|
258
|
+
} else {
|
|
259
|
+
throw new RuntimeException(info.msg);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export default FetchStreamLoader;
|