dasha 3.1.5 → 4.0.0-alpha.2
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/README.md +25 -11
- package/dist/dasha.cjs +1188 -0
- package/dist/dasha.d.cts +179 -0
- package/dist/dasha.d.ts +179 -0
- package/dist/dasha.js +1155 -0
- package/package.json +37 -21
- package/dasha.js +0 -29
- package/lib/audio.js +0 -148
- package/lib/dash.js +0 -516
- package/lib/hls.js +0 -234
- package/lib/subtitle.js +0 -137
- package/lib/track.js +0 -127
- package/lib/util.js +0 -98
- package/lib/video.js +0 -200
- package/lib/xml.js +0 -310
- package/types/dasha.d.ts +0 -161
package/lib/video.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
const { parseBitrate, getQualityLabel, parseSize } = require('./util');
|
|
2
|
-
|
|
3
|
-
const VIDEO_CODECS = {
|
|
4
|
-
avc: 'H.264',
|
|
5
|
-
hevc: 'H.265',
|
|
6
|
-
vc1: 'VC-1',
|
|
7
|
-
vp8: 'VP8',
|
|
8
|
-
vp9: 'VP9',
|
|
9
|
-
av1: 'AV1',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const DYNAMIC_RANGE = {
|
|
13
|
-
sdr: 'SDR', // Standart Dynamic Range
|
|
14
|
-
hlg: 'HLG', // Hybrid log-gamma (HDR)
|
|
15
|
-
hdr10: 'HDR10',
|
|
16
|
-
hdr10p: 'HDR10+',
|
|
17
|
-
dv: 'DV', // Dolby Vision
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const PRIMARIES = {
|
|
21
|
-
Unspecified: 0,
|
|
22
|
-
BT_709: 1,
|
|
23
|
-
BT_601_625: 5,
|
|
24
|
-
BT_601_525: 6,
|
|
25
|
-
BT_2020_and_2100: 9,
|
|
26
|
-
SMPTE_ST_2113_and_EG_4321: 12, // P3D65
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const TRANSFER = {
|
|
30
|
-
Unspecified: 0,
|
|
31
|
-
BT_709: 1,
|
|
32
|
-
BT_601: 6,
|
|
33
|
-
BT_2020: 14,
|
|
34
|
-
BT_2100: 15,
|
|
35
|
-
BT_2100_PQ: 16,
|
|
36
|
-
BT_2100_HLG: 18,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const MATRIX = {
|
|
40
|
-
RGB: 0,
|
|
41
|
-
YCbCr_BT_709: 1,
|
|
42
|
-
YCbCr_BT_601_625: 5,
|
|
43
|
-
YCbCr_BT_601_525: 6,
|
|
44
|
-
YCbCr_BT_2020_and_2100: 9, // YCbCr BT.2100 shares the same CP
|
|
45
|
-
ICtCp_BT_2100: 14,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const parseVideoCodecFromMime = (mime) => {
|
|
49
|
-
const target = mime.toLowerCase().trim().split('.')[0];
|
|
50
|
-
const avc = ['avc1', 'avc2', 'avc3', 'dva1', 'dvav'];
|
|
51
|
-
const hevc = [
|
|
52
|
-
'hev1',
|
|
53
|
-
'hev2',
|
|
54
|
-
'hev3',
|
|
55
|
-
'hvc1',
|
|
56
|
-
'hvc2',
|
|
57
|
-
'hvc3',
|
|
58
|
-
'dvh1',
|
|
59
|
-
'dvhe',
|
|
60
|
-
'lhv1',
|
|
61
|
-
'lhe1',
|
|
62
|
-
];
|
|
63
|
-
const vc1 = ['vc-1'];
|
|
64
|
-
const vp8 = ['vp08', 'vp8'];
|
|
65
|
-
const vp9 = ['vp09', 'vp9'];
|
|
66
|
-
const av1 = ['av01'];
|
|
67
|
-
if (avc.includes(target)) return VIDEO_CODECS.avc;
|
|
68
|
-
if (hevc.includes(target)) return VIDEO_CODECS.hevc;
|
|
69
|
-
if (vc1.includes(target)) return VIDEO_CODECS.hevc;
|
|
70
|
-
if (vp8.includes(target)) return VIDEO_CODECS.vp8;
|
|
71
|
-
if (vp9.includes(target)) return VIDEO_CODECS.vp9;
|
|
72
|
-
if (av1.includes(target)) return VIDEO_CODECS.av1;
|
|
73
|
-
throw new Error(`The MIME ${mime} is not supported as video codec`);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const parseDynamicRangeFromCicp = (primaries, transfer, matrix) => {
|
|
77
|
-
// While not part of any standard, it is typically used as a PAL variant of Transfer.BT_601=6.
|
|
78
|
-
// i.e. where Transfer 6 would be for BT.601-NTSC and Transfer 5 would be for BT.601-PAL.
|
|
79
|
-
// The codebase is currently agnostic to either, so a manual conversion to 6 is done.
|
|
80
|
-
if (transfer == 5) transfer = TRANSFER.BT_601;
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
primaries == PRIMARIES.Unspecified &&
|
|
84
|
-
transfer == TRANSFER.Unspecified &&
|
|
85
|
-
matrix == MATRIX.RGB
|
|
86
|
-
)
|
|
87
|
-
return DYNAMIC_RANGE.sdr;
|
|
88
|
-
else if ([PRIMARIES.BT_601_625, PRIMARIES.BT_601_525].includes(primaries))
|
|
89
|
-
return DYNAMIC_RANGE.sdr;
|
|
90
|
-
else if (TRANSFER.BT_2100_PQ === transfer) return DYNAMIC_RANGE.hdr10;
|
|
91
|
-
else if (TRANSFER.BT_2100_HLG === transfer) return DYNAMIC_RANGE.hlg;
|
|
92
|
-
else return DYNAMIC_RANGE.sdr;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const createVideoTrack = ({
|
|
96
|
-
id,
|
|
97
|
-
label,
|
|
98
|
-
type,
|
|
99
|
-
codec,
|
|
100
|
-
dynamicRange,
|
|
101
|
-
contentProtection,
|
|
102
|
-
bitrate,
|
|
103
|
-
duration,
|
|
104
|
-
width,
|
|
105
|
-
height,
|
|
106
|
-
fps,
|
|
107
|
-
language,
|
|
108
|
-
segments,
|
|
109
|
-
}) => {
|
|
110
|
-
const parsedBitrate = parseBitrate(Number(bitrate));
|
|
111
|
-
const parsedWidth = Number(width);
|
|
112
|
-
const parsedHeight = Number(height);
|
|
113
|
-
const size = duration
|
|
114
|
-
? parseSize(Number(bitrate), Number(duration))
|
|
115
|
-
: undefined;
|
|
116
|
-
return {
|
|
117
|
-
id,
|
|
118
|
-
label,
|
|
119
|
-
type,
|
|
120
|
-
codec,
|
|
121
|
-
bitrate: parsedBitrate,
|
|
122
|
-
size,
|
|
123
|
-
protection: contentProtection,
|
|
124
|
-
segments,
|
|
125
|
-
dynamicRange,
|
|
126
|
-
language,
|
|
127
|
-
width: parsedWidth,
|
|
128
|
-
height: parsedHeight,
|
|
129
|
-
fps: Number(fps),
|
|
130
|
-
quality: getQualityLabel({ width: parsedWidth, height: parsedHeight }),
|
|
131
|
-
toString() {
|
|
132
|
-
return [
|
|
133
|
-
'VIDEO',
|
|
134
|
-
`[${codec}, ${dynamicRange}]`,
|
|
135
|
-
language,
|
|
136
|
-
`${width}x${height} @ ${parsedBitrate.kbps} kb/s, ${fps} FPS`,
|
|
137
|
-
].join(' | ');
|
|
138
|
-
},
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const parseVideoCodec = (codecs) => {
|
|
143
|
-
for (const codec of codecs.toLowerCase().split(',')) {
|
|
144
|
-
const mime = codec.trim().split('.')[0];
|
|
145
|
-
try {
|
|
146
|
-
return parseVideoCodecFromMime(mime);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
throw new Error(
|
|
152
|
-
`No MIME types matched any supported Video Codecs in ${codecs}`,
|
|
153
|
-
);
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
const tryParseVideoCodec = (codecs) => {
|
|
157
|
-
try {
|
|
158
|
-
return parseVideoCodec(codecs);
|
|
159
|
-
} catch (e) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
const parseDynamicRange = (
|
|
165
|
-
codecs,
|
|
166
|
-
supplementalProps = [],
|
|
167
|
-
essentialProps = [],
|
|
168
|
-
) => {
|
|
169
|
-
const dv = ['dva1', 'dvav', 'dvhe', 'dvh1'];
|
|
170
|
-
if (dv.some((value) => codecs.startsWith(value))) return DYNAMIC_RANGE.dv;
|
|
171
|
-
const primariesScheme = 'urn:mpeg:mpegB:cicp:ColourPrimaries';
|
|
172
|
-
const transferScheme = 'urn:mpeg:mpegB:cicp:TransferCharacteristics';
|
|
173
|
-
const matrixScheme = 'urn:mpeg:mpegB:cicp:MatrixCoefficients';
|
|
174
|
-
const allProps = [...essentialProps, ...supplementalProps];
|
|
175
|
-
const getValues = (scheme) =>
|
|
176
|
-
allProps
|
|
177
|
-
.filter((prop) => prop.attributes.schemeIdUri === scheme)
|
|
178
|
-
.map((prop) => parseInt(prop.attributes.value));
|
|
179
|
-
const primaries = getValues(primariesScheme).reduce(
|
|
180
|
-
(acc, current) => acc + current,
|
|
181
|
-
0,
|
|
182
|
-
);
|
|
183
|
-
const transfer = getValues(transferScheme).reduce(
|
|
184
|
-
(acc, current) => acc + current,
|
|
185
|
-
0,
|
|
186
|
-
);
|
|
187
|
-
const matrix = getValues(matrixScheme).reduce(
|
|
188
|
-
(acc, current) => acc + current,
|
|
189
|
-
0,
|
|
190
|
-
);
|
|
191
|
-
return parseDynamicRangeFromCicp(primaries, transfer, matrix);
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
module.exports = {
|
|
195
|
-
parseVideoCodec,
|
|
196
|
-
tryParseVideoCodec,
|
|
197
|
-
parseDynamicRange,
|
|
198
|
-
createVideoTrack,
|
|
199
|
-
VIDEO_CODECS,
|
|
200
|
-
};
|
package/lib/xml.js
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
function parse(text, options = {}) {
|
|
2
|
-
var pos = options.pos || 0;
|
|
3
|
-
var keepComments = !!options.keepComments;
|
|
4
|
-
var keepWhitespace = !!options.keepWhitespace;
|
|
5
|
-
|
|
6
|
-
var openBracket = '<';
|
|
7
|
-
var openBracketCC = '<'.charCodeAt(0);
|
|
8
|
-
var closeBracket = '>';
|
|
9
|
-
var closeBracketCC = '>'.charCodeAt(0);
|
|
10
|
-
var minusCC = '-'.charCodeAt(0);
|
|
11
|
-
var slashCC = '/'.charCodeAt(0);
|
|
12
|
-
var exclamationCC = '!'.charCodeAt(0);
|
|
13
|
-
var singleQuoteCC = "'".charCodeAt(0);
|
|
14
|
-
var doubleQuoteCC = '"'.charCodeAt(0);
|
|
15
|
-
var openCornerBracketCC = '['.charCodeAt(0);
|
|
16
|
-
var closeCornerBracketCC = ']'.charCodeAt(0);
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* parsing a list of entries
|
|
20
|
-
*/
|
|
21
|
-
function parseChildren(tagName) {
|
|
22
|
-
var children = [];
|
|
23
|
-
while (text[pos]) {
|
|
24
|
-
if (text.charCodeAt(pos) == openBracketCC) {
|
|
25
|
-
if (text.charCodeAt(pos + 1) === slashCC) {
|
|
26
|
-
var closeStart = pos + 2;
|
|
27
|
-
pos = text.indexOf(closeBracket, pos);
|
|
28
|
-
|
|
29
|
-
var closeTag = text.substring(closeStart, pos);
|
|
30
|
-
if (closeTag.indexOf(tagName) == -1) {
|
|
31
|
-
const parsedText = text.substring(0, pos).split('\n');
|
|
32
|
-
throw new Error(
|
|
33
|
-
'Unexpected close tag\nLine: ' +
|
|
34
|
-
(parsedText.length - 1) +
|
|
35
|
-
'\nColumn: ' +
|
|
36
|
-
(parsedText[parsedText.length - 1].length + 1) +
|
|
37
|
-
'\nChar: ' +
|
|
38
|
-
text[pos],
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (pos + 1) pos += 1;
|
|
43
|
-
|
|
44
|
-
return children;
|
|
45
|
-
} else if (text.charCodeAt(pos + 1) === exclamationCC) {
|
|
46
|
-
if (text.charCodeAt(pos + 2) == minusCC) {
|
|
47
|
-
//comment support
|
|
48
|
-
const startCommentPos = pos;
|
|
49
|
-
while (
|
|
50
|
-
pos !== -1 &&
|
|
51
|
-
!(
|
|
52
|
-
text.charCodeAt(pos) === closeBracketCC &&
|
|
53
|
-
text.charCodeAt(pos - 1) == minusCC &&
|
|
54
|
-
text.charCodeAt(pos - 2) == minusCC &&
|
|
55
|
-
pos != -1
|
|
56
|
-
)
|
|
57
|
-
) {
|
|
58
|
-
pos = text.indexOf(closeBracket, pos + 1);
|
|
59
|
-
}
|
|
60
|
-
if (pos === -1) {
|
|
61
|
-
pos = text.length;
|
|
62
|
-
}
|
|
63
|
-
if (keepComments) {
|
|
64
|
-
children.push(text.substring(startCommentPos, pos + 1));
|
|
65
|
-
}
|
|
66
|
-
} else if (
|
|
67
|
-
text.charCodeAt(pos + 2) === openCornerBracketCC &&
|
|
68
|
-
text.charCodeAt(pos + 8) === openCornerBracketCC &&
|
|
69
|
-
text.substr(pos + 3, 5).toLowerCase() === 'cdata'
|
|
70
|
-
) {
|
|
71
|
-
// cdata
|
|
72
|
-
var cdataEndIndex = text.indexOf(']]>', pos);
|
|
73
|
-
if (cdataEndIndex == -1) {
|
|
74
|
-
children.push(text.substr(pos + 9));
|
|
75
|
-
pos = text.length;
|
|
76
|
-
} else {
|
|
77
|
-
children.push(text.substring(pos + 9, cdataEndIndex));
|
|
78
|
-
pos = cdataEndIndex + 3;
|
|
79
|
-
}
|
|
80
|
-
continue;
|
|
81
|
-
} else {
|
|
82
|
-
// doctypesupport
|
|
83
|
-
const startDoctype = pos + 1;
|
|
84
|
-
pos += 2;
|
|
85
|
-
var encapsuled = false;
|
|
86
|
-
while (
|
|
87
|
-
(text.charCodeAt(pos) !== closeBracketCC ||
|
|
88
|
-
encapsuled === true) &&
|
|
89
|
-
text[pos]
|
|
90
|
-
) {
|
|
91
|
-
if (text.charCodeAt(pos) === openCornerBracketCC) {
|
|
92
|
-
encapsuled = true;
|
|
93
|
-
} else if (
|
|
94
|
-
encapsuled === true &&
|
|
95
|
-
text.charCodeAt(pos) === closeCornerBracketCC
|
|
96
|
-
) {
|
|
97
|
-
encapsuled = false;
|
|
98
|
-
}
|
|
99
|
-
pos++;
|
|
100
|
-
}
|
|
101
|
-
children.push(text.substring(startDoctype, pos));
|
|
102
|
-
}
|
|
103
|
-
pos++;
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
var node = parseNode();
|
|
107
|
-
children.push(node);
|
|
108
|
-
if (node.tagName[0] === '?') {
|
|
109
|
-
children.push(...node.children);
|
|
110
|
-
node.children = [];
|
|
111
|
-
}
|
|
112
|
-
} else {
|
|
113
|
-
const parsedText = parseText();
|
|
114
|
-
if (keepWhitespace) {
|
|
115
|
-
if (parsedText.length > 0) {
|
|
116
|
-
children.push(parsedText);
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
var trimmed = parsedText.trim();
|
|
120
|
-
if (trimmed.length > 0) {
|
|
121
|
-
children.push(trimmed);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
pos++;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return children;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* returns the text outside of texts until the first '<'
|
|
132
|
-
*/
|
|
133
|
-
function parseText() {
|
|
134
|
-
var start = pos;
|
|
135
|
-
pos = text.indexOf(openBracket, pos) - 1;
|
|
136
|
-
if (pos === -2) pos = text.length;
|
|
137
|
-
return text.slice(start, pos + 1);
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* returns text until the first nonAlphabetic letter
|
|
141
|
-
*/
|
|
142
|
-
var nameSpacer = '\r\n\t>/= ';
|
|
143
|
-
|
|
144
|
-
function parseName() {
|
|
145
|
-
var start = pos;
|
|
146
|
-
while (nameSpacer.indexOf(text[pos]) === -1 && text[pos]) {
|
|
147
|
-
pos++;
|
|
148
|
-
}
|
|
149
|
-
return text.slice(start, pos);
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* is parsing a node, including tagName, Attributes and its children,
|
|
153
|
-
* to parse children it uses the parseChildren again, that makes the parsing recursive
|
|
154
|
-
*/
|
|
155
|
-
var NoChildNodes = options.noChildNodes || [
|
|
156
|
-
'img',
|
|
157
|
-
'br',
|
|
158
|
-
'input',
|
|
159
|
-
'meta',
|
|
160
|
-
'link',
|
|
161
|
-
'hr',
|
|
162
|
-
];
|
|
163
|
-
|
|
164
|
-
function parseNode() {
|
|
165
|
-
pos++;
|
|
166
|
-
const tagName = parseName();
|
|
167
|
-
const attributes = {};
|
|
168
|
-
let children = [];
|
|
169
|
-
|
|
170
|
-
// parsing attributes
|
|
171
|
-
while (text.charCodeAt(pos) !== closeBracketCC && text[pos]) {
|
|
172
|
-
var c = text.charCodeAt(pos);
|
|
173
|
-
if ((c > 64 && c < 91) || (c > 96 && c < 123)) {
|
|
174
|
-
//if('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(S[pos])!==-1 ){
|
|
175
|
-
var name = parseName();
|
|
176
|
-
// search beginning of the string
|
|
177
|
-
var code = text.charCodeAt(pos);
|
|
178
|
-
while (
|
|
179
|
-
code &&
|
|
180
|
-
code !== singleQuoteCC &&
|
|
181
|
-
code !== doubleQuoteCC &&
|
|
182
|
-
!((code > 64 && code < 91) || (code > 96 && code < 123)) &&
|
|
183
|
-
code !== closeBracketCC
|
|
184
|
-
) {
|
|
185
|
-
pos++;
|
|
186
|
-
code = text.charCodeAt(pos);
|
|
187
|
-
}
|
|
188
|
-
if (code === singleQuoteCC || code === doubleQuoteCC) {
|
|
189
|
-
var value = parseString();
|
|
190
|
-
if (pos === -1) {
|
|
191
|
-
return {
|
|
192
|
-
tagName,
|
|
193
|
-
attributes,
|
|
194
|
-
children,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
value = null;
|
|
199
|
-
pos--;
|
|
200
|
-
}
|
|
201
|
-
attributes[name] = value;
|
|
202
|
-
}
|
|
203
|
-
pos++;
|
|
204
|
-
}
|
|
205
|
-
// optional parsing of children
|
|
206
|
-
if (text.charCodeAt(pos - 1) !== slashCC) {
|
|
207
|
-
if (tagName == 'script') {
|
|
208
|
-
const start = pos + 1;
|
|
209
|
-
pos = text.indexOf('</script>', pos);
|
|
210
|
-
children = [text.slice(start, pos)];
|
|
211
|
-
pos += 9;
|
|
212
|
-
} else if (tagName == 'style') {
|
|
213
|
-
const start = pos + 1;
|
|
214
|
-
pos = text.indexOf('</style>', pos);
|
|
215
|
-
children = [text.slice(start, pos)];
|
|
216
|
-
pos += 8;
|
|
217
|
-
} else if (NoChildNodes.indexOf(tagName) === -1) {
|
|
218
|
-
pos++;
|
|
219
|
-
children = parseChildren(tagName);
|
|
220
|
-
} else {
|
|
221
|
-
pos++;
|
|
222
|
-
}
|
|
223
|
-
} else {
|
|
224
|
-
pos++;
|
|
225
|
-
}
|
|
226
|
-
return {
|
|
227
|
-
tagName,
|
|
228
|
-
attributes,
|
|
229
|
-
children,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* is parsing a string, that starts with a char and with the same usually ' or "
|
|
235
|
-
*/
|
|
236
|
-
|
|
237
|
-
function parseString() {
|
|
238
|
-
var startChar = text[pos];
|
|
239
|
-
var startpos = pos + 1;
|
|
240
|
-
pos = text.indexOf(startChar, startpos);
|
|
241
|
-
return text.slice(startpos, pos);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
*
|
|
246
|
-
*/
|
|
247
|
-
function findElements() {
|
|
248
|
-
var r = new RegExp(
|
|
249
|
-
'\\s' + options.attrName + '\\s*=[\'"]' + options.attrValue + '[\'"]',
|
|
250
|
-
).exec(text);
|
|
251
|
-
if (r) {
|
|
252
|
-
return r.index;
|
|
253
|
-
} else {
|
|
254
|
-
return -1;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
let out = null;
|
|
259
|
-
if (options.attrValue !== undefined) {
|
|
260
|
-
options.attrName = options.attrName || 'id';
|
|
261
|
-
out = [];
|
|
262
|
-
|
|
263
|
-
while ((pos = findElements()) !== -1) {
|
|
264
|
-
pos = text.lastIndexOf('<', pos);
|
|
265
|
-
if (pos !== -1) {
|
|
266
|
-
out.push(parseNode());
|
|
267
|
-
}
|
|
268
|
-
text = text.substr(pos);
|
|
269
|
-
pos = 0;
|
|
270
|
-
}
|
|
271
|
-
} else if (options.parseNode) {
|
|
272
|
-
out = parseNode();
|
|
273
|
-
} else {
|
|
274
|
-
out = parseChildren('');
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
if (options.filter) {
|
|
278
|
-
out = filter(out, options.filter);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (options.setPos) {
|
|
282
|
-
out.pos = pos;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return out;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* behaves the same way as Array.filter, if the filter method return true, the element is in the resultList
|
|
290
|
-
* @params children{Array} the children of a node
|
|
291
|
-
* @param f{function} the filter method
|
|
292
|
-
*/
|
|
293
|
-
function filter(children, f, dept = 0, path = '') {
|
|
294
|
-
var out = [];
|
|
295
|
-
children.forEach(function (child, i) {
|
|
296
|
-
if (typeof child === 'object' && f(child, i, dept, path)) out.push(child);
|
|
297
|
-
if (child.children) {
|
|
298
|
-
var kids = filter(
|
|
299
|
-
child.children,
|
|
300
|
-
f,
|
|
301
|
-
dept + 1,
|
|
302
|
-
(path ? path + '.' : '') + i + '.' + child.tagName,
|
|
303
|
-
);
|
|
304
|
-
out = out.concat(kids);
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
return out;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
module.exports = { parse, filter };
|
package/types/dasha.d.ts
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
export function parse(
|
|
2
|
-
text: string,
|
|
3
|
-
url?: string,
|
|
4
|
-
fallbackLanguage?: string,
|
|
5
|
-
): Promise<Manifest>;
|
|
6
|
-
|
|
7
|
-
export interface Manifest {
|
|
8
|
-
duration?: number;
|
|
9
|
-
tracks: {
|
|
10
|
-
all: (VideoTrack | AudioTrack | SubtitleTrack)[];
|
|
11
|
-
videos: VideoTrack[];
|
|
12
|
-
audios: AudioTrack[];
|
|
13
|
-
subtitles: SubtitleTrack[];
|
|
14
|
-
withResolution(resolution: {
|
|
15
|
-
width?: string;
|
|
16
|
-
height?: string;
|
|
17
|
-
}): VideoTrack[];
|
|
18
|
-
withVideoCodecs(codecs: VideoCodec[]): VideoTrack[];
|
|
19
|
-
withVideoQuality(quality: number | string): VideoTrack[];
|
|
20
|
-
withAudioCodecs(codecs: AudioCodec[]): AudioTrack[];
|
|
21
|
-
withAudioLanguages(
|
|
22
|
-
languages: string[],
|
|
23
|
-
maxTracksPerLanguage?: number,
|
|
24
|
-
): AudioTrack[];
|
|
25
|
-
withSubtitleLanguages(languages: string[]): SubtitleTrack[];
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function filterByResolution(resolution: {
|
|
30
|
-
width?: string;
|
|
31
|
-
height?: string;
|
|
32
|
-
}): VideoTrack[];
|
|
33
|
-
export function filterByCodecs(
|
|
34
|
-
tracks: VideoTrack[],
|
|
35
|
-
codecs: VideoCodec[],
|
|
36
|
-
): VideoTrack[];
|
|
37
|
-
export function filterByCodecs(
|
|
38
|
-
tracks: AudioTrack[],
|
|
39
|
-
codecs: AudioCodec[],
|
|
40
|
-
): AudioTrack[];
|
|
41
|
-
export function filterByQuality(
|
|
42
|
-
tracks: VideoTrack[],
|
|
43
|
-
quality: number | string,
|
|
44
|
-
): VideoTrack[];
|
|
45
|
-
export function filterByLanguages(
|
|
46
|
-
tracks: AudioTrack[],
|
|
47
|
-
languages: string[],
|
|
48
|
-
maxTracksPerLanguage?: number,
|
|
49
|
-
): AudioTrack[];
|
|
50
|
-
export function filterByChannels(
|
|
51
|
-
tracks: AudioTrack[],
|
|
52
|
-
channels: number | string,
|
|
53
|
-
): AudioTrack[];
|
|
54
|
-
|
|
55
|
-
export interface Track {
|
|
56
|
-
id: string;
|
|
57
|
-
type: 'video' | 'audio' | 'text';
|
|
58
|
-
segments: Segment[];
|
|
59
|
-
size?: Size;
|
|
60
|
-
label?: string;
|
|
61
|
-
protection?: TrackProtection;
|
|
62
|
-
toString: () => string;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface Bitrate {
|
|
66
|
-
bps: number;
|
|
67
|
-
kbps: number;
|
|
68
|
-
mbps: number;
|
|
69
|
-
gbps: number;
|
|
70
|
-
toString: () => string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface Size {
|
|
74
|
-
b: number;
|
|
75
|
-
kb: number;
|
|
76
|
-
mb: number;
|
|
77
|
-
gb: number;
|
|
78
|
-
toString: () => string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface Segment {
|
|
82
|
-
url: string;
|
|
83
|
-
range?: string;
|
|
84
|
-
init?: boolean;
|
|
85
|
-
duration?: number;
|
|
86
|
-
number?: number;
|
|
87
|
-
presentationTime?: number;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export interface TrackProtection {
|
|
91
|
-
common?: { id: string; value: 'cenc' | 'cbcs'; defaultKeyId?: string };
|
|
92
|
-
playready?: { id: string; pssh?: string; value?: string };
|
|
93
|
-
widevine?: { id: string; pssh: string; defaultKeyId?: string };
|
|
94
|
-
fairplay?: { keyFormat: string; uri: string; method: string };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export type VideoCodec = 'H.264' | 'H.265' | 'VC-1' | 'VP8' | 'VP9' | 'AV1';
|
|
98
|
-
export type DynamicRange = 'SDR' | 'HLG' | 'HDR10' | 'HDR10+' | 'DV';
|
|
99
|
-
|
|
100
|
-
export interface VideoTrack extends Track {
|
|
101
|
-
type: 'video';
|
|
102
|
-
codec: VideoCodec;
|
|
103
|
-
bitrate: Bitrate;
|
|
104
|
-
width: number;
|
|
105
|
-
height: number;
|
|
106
|
-
quality:
|
|
107
|
-
| '144p'
|
|
108
|
-
| '240p'
|
|
109
|
-
| '360p'
|
|
110
|
-
| '480p'
|
|
111
|
-
| '720p'
|
|
112
|
-
| '1080p'
|
|
113
|
-
| '2160p'
|
|
114
|
-
| '4320p'
|
|
115
|
-
| string;
|
|
116
|
-
dynamicRange: DynamicRange;
|
|
117
|
-
fps?: string;
|
|
118
|
-
language?: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export type AudioCodec =
|
|
122
|
-
| 'AAC'
|
|
123
|
-
| 'DD'
|
|
124
|
-
| 'DD+'
|
|
125
|
-
| 'OPUS'
|
|
126
|
-
| 'VORB'
|
|
127
|
-
| 'DTS'
|
|
128
|
-
| 'ALAC'
|
|
129
|
-
| 'FLAC';
|
|
130
|
-
|
|
131
|
-
export interface AudioTrack extends Track {
|
|
132
|
-
type: 'audio';
|
|
133
|
-
codec: AudioCodec;
|
|
134
|
-
bitrate: Bitrate;
|
|
135
|
-
language: string;
|
|
136
|
-
channels?: number;
|
|
137
|
-
jointObjectCoding?: number;
|
|
138
|
-
isDescriptive?: boolean;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export type SubtitleCodec =
|
|
142
|
-
| 'SRT' // https://wikipedia.org/wiki/SubRip
|
|
143
|
-
| 'SSA' // https://wikipedia.org/wiki/SubStation_Alpha
|
|
144
|
-
| 'ASS' // https://wikipedia.org/wiki/SubStation_Alpha#Advanced_SubStation_Alpha=
|
|
145
|
-
| 'TTML' // https://wikipedia.org/wiki/Timed_Text_Markup_Language
|
|
146
|
-
| 'VTT' // https://wikipedia.org/wiki/WebVTT
|
|
147
|
-
// MPEG-DASH box-encapsulated subtitle formats
|
|
148
|
-
| 'STPP' // https://www.w3.org/TR/2018/REC-ttml-imsc1.0.1-20180424
|
|
149
|
-
| 'WVTT'; // https://www.w3.org/TR/webvtt1
|
|
150
|
-
|
|
151
|
-
export interface SubtitleTrack extends Track {
|
|
152
|
-
type: 'text';
|
|
153
|
-
codec: SubtitleCodec;
|
|
154
|
-
bitrate?: Bitrate;
|
|
155
|
-
language: string;
|
|
156
|
-
isClosedCaption?: boolean;
|
|
157
|
-
isSdh?: boolean;
|
|
158
|
-
isForced?: boolean;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export type AnyTrack = VideoTrack | AudioTrack | SubtitleTrack;
|