@remotion/media-parser 4.0.193 → 4.0.194
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/dist/boxes/iso-base-media/esds-descriptors.d.ts +21 -0
- package/dist/boxes/iso-base-media/esds-descriptors.js +62 -0
- package/dist/boxes/iso-base-media/esds.d.ts +15 -0
- package/dist/boxes/iso-base-media/esds.js +27 -0
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +12 -0
- package/dist/boxes/iso-base-media/mdat/mdat.js +13 -0
- package/dist/boxes/iso-base-media/process-box.js +50 -0
- package/dist/boxes/iso-base-media/stsd/stco.d.ts +14 -0
- package/dist/boxes/iso-base-media/stsd/stco.js +30 -0
- package/dist/boxes/iso-base-media/stsd/stsc.d.ts +19 -0
- package/dist/boxes/iso-base-media/stsd/stsc.js +34 -0
- package/dist/boxes/iso-base-media/stsd/stsz.d.ts +15 -0
- package/dist/boxes/iso-base-media/stsd/stsz.js +32 -0
- package/dist/buffer-iterator.d.ts +1 -0
- package/dist/buffer-iterator.js +14 -0
- package/dist/from-node.js +6 -2
- package/dist/from-web.js +9 -6
- package/dist/get-codec.d.ts +4 -0
- package/dist/get-codec.js +22 -0
- package/dist/get-sample-positions.d.ts +12 -0
- package/dist/get-sample-positions.js +25 -0
- package/dist/get-samples.d.ts +0 -0
- package/dist/get-samples.js +1 -0
- package/dist/get-tracks.d.ts +10 -0
- package/dist/get-tracks.js +66 -0
- package/dist/parse-media.js +14 -3
- package/dist/parse-result.d.ts +1 -0
- package/dist/parse-video.d.ts +1 -0
- package/dist/parse-video.js +1 -0
- package/dist/reader.d.ts +1 -1
- package/dist/traversal.d.ts +19 -0
- package/dist/traversal.js +88 -0
- package/package.json +2 -2
- package/src/boxes/iso-base-media/process-box.ts +55 -0
- package/src/buffer-iterator.ts +20 -0
- package/src/from-node.ts +7 -2
- package/src/from-web.ts +9 -6
- package/src/parse-media.ts +21 -3
- package/src/parse-result.ts +1 -0
- package/src/parse-video.ts +2 -0
- package/src/reader.ts +1 -1
- package/src/test/stream-local.test.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
- package/dist/boxes/iso-base-media/ftype.js +0 -31
- package/dist/get-video-metadata.d.ts +0 -2
- package/dist/get-video-metadata.js +0 -44
- package/dist/read-and-increment-offset.d.ts +0 -28
- package/dist/read-and-increment-offset.js +0 -177
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
type AudioObjectType = 'aac' | 'mp3' | 'unknown';
|
|
3
|
+
type DecoderConfigDescriptor = {
|
|
4
|
+
type: 'decoder-config-descriptor';
|
|
5
|
+
objectTypeIndication: AudioObjectType;
|
|
6
|
+
};
|
|
7
|
+
type SlConfigDescriptor = {
|
|
8
|
+
type: 'sl-config-descriptor';
|
|
9
|
+
};
|
|
10
|
+
type UnknownDescriptor = {
|
|
11
|
+
type: 'unknown-descriptor';
|
|
12
|
+
};
|
|
13
|
+
export type Descriptor = DecoderConfigDescriptor | SlConfigDescriptor | UnknownDescriptor;
|
|
14
|
+
type DescriptorAndNext = {
|
|
15
|
+
descriptor: Descriptor | null;
|
|
16
|
+
};
|
|
17
|
+
export declare const processDescriptor: ({ iterator, }: {
|
|
18
|
+
iterator: BufferIterator;
|
|
19
|
+
}) => DescriptorAndNext;
|
|
20
|
+
export declare const parseDescriptors: (iterator: BufferIterator, maxBytes: number) => Descriptor[];
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDescriptors = exports.processDescriptor = void 0;
|
|
4
|
+
const mapToObjectAudioIndicator = (num) => {
|
|
5
|
+
// https://chromium.googlesource.com/chromium/src/media/+/master/formats/mp4/es_descriptor.h
|
|
6
|
+
// http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf
|
|
7
|
+
// Page 42, table 8
|
|
8
|
+
if (num === 0x40) {
|
|
9
|
+
return 'aac';
|
|
10
|
+
}
|
|
11
|
+
if (num === 0x6b) {
|
|
12
|
+
return 'mp3';
|
|
13
|
+
}
|
|
14
|
+
return 'unknown';
|
|
15
|
+
};
|
|
16
|
+
const processDescriptor = ({ iterator, }) => {
|
|
17
|
+
const tag = iterator.getUint8();
|
|
18
|
+
if (tag === 4) {
|
|
19
|
+
const size = iterator.getPaddedFourByteNumber();
|
|
20
|
+
const initialOffset = iterator.counter.getOffset();
|
|
21
|
+
const objectTypeIndication = iterator.getUint8();
|
|
22
|
+
const remaining = size - (iterator.counter.getOffset() - initialOffset);
|
|
23
|
+
iterator.discard(remaining);
|
|
24
|
+
return {
|
|
25
|
+
descriptor: {
|
|
26
|
+
type: 'decoder-config-descriptor',
|
|
27
|
+
objectTypeIndication: mapToObjectAudioIndicator(objectTypeIndication),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (tag === 6) {
|
|
32
|
+
const size = iterator.getPaddedFourByteNumber();
|
|
33
|
+
iterator.discard(size);
|
|
34
|
+
return {
|
|
35
|
+
descriptor: {
|
|
36
|
+
type: 'sl-config-descriptor',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
descriptor: null,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
exports.processDescriptor = processDescriptor;
|
|
45
|
+
const parseDescriptors = (iterator, maxBytes) => {
|
|
46
|
+
const descriptors = [];
|
|
47
|
+
const initialOffset = iterator.counter.getOffset();
|
|
48
|
+
while (iterator.bytesRemaining() > 0 &&
|
|
49
|
+
iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
50
|
+
const { descriptor } = (0, exports.processDescriptor)({
|
|
51
|
+
iterator,
|
|
52
|
+
});
|
|
53
|
+
if (descriptor) {
|
|
54
|
+
descriptors.push(descriptor);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return descriptors;
|
|
61
|
+
};
|
|
62
|
+
exports.parseDescriptors = parseDescriptors;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Descriptor } from './esds-descriptors';
|
|
3
|
+
export interface EsdsBox {
|
|
4
|
+
type: 'esds-box';
|
|
5
|
+
version: number;
|
|
6
|
+
tag: number;
|
|
7
|
+
sizeOfInstance: number;
|
|
8
|
+
esId: number;
|
|
9
|
+
descriptors: Descriptor[];
|
|
10
|
+
}
|
|
11
|
+
export declare const parseEsds: ({ data, size, fileOffset, }: {
|
|
12
|
+
data: BufferIterator;
|
|
13
|
+
size: number;
|
|
14
|
+
fileOffset: number;
|
|
15
|
+
}) => EsdsBox;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseEsds = void 0;
|
|
4
|
+
const esds_descriptors_1 = require("./esds-descriptors");
|
|
5
|
+
const parseEsds = ({ data, size, fileOffset, }) => {
|
|
6
|
+
const version = data.getUint8();
|
|
7
|
+
// Flags, we discard them
|
|
8
|
+
data.discard(3);
|
|
9
|
+
const tag = data.getUint8();
|
|
10
|
+
const sizeOfInstance = data.getPaddedFourByteNumber();
|
|
11
|
+
const esId = data.getUint16();
|
|
12
|
+
// disard 1 byte, currently unknown
|
|
13
|
+
data.discard(1);
|
|
14
|
+
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
15
|
+
const descriptors = (0, esds_descriptors_1.parseDescriptors)(data, remaining);
|
|
16
|
+
const remainingNow = size - (data.counter.getOffset() - fileOffset);
|
|
17
|
+
data.discard(remainingNow);
|
|
18
|
+
return {
|
|
19
|
+
type: 'esds-box',
|
|
20
|
+
version,
|
|
21
|
+
tag,
|
|
22
|
+
sizeOfInstance,
|
|
23
|
+
esId,
|
|
24
|
+
descriptors,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.parseEsds = parseEsds;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { AnySegment } from '../../../parse-result';
|
|
3
|
+
export interface MdatBox {
|
|
4
|
+
type: 'mdat-box';
|
|
5
|
+
boxSize: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const parseMdat: ({ data, size, fileOffset, }: {
|
|
8
|
+
data: BufferIterator;
|
|
9
|
+
size: number;
|
|
10
|
+
fileOffset: number;
|
|
11
|
+
existingBoxes: AnySegment[];
|
|
12
|
+
}) => MdatBox;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMdat = void 0;
|
|
4
|
+
const parseMdat = ({ data, size, fileOffset, }) => {
|
|
5
|
+
// TODO: Do something cool with it
|
|
6
|
+
// const tracks = getTracks(existingBoxes);
|
|
7
|
+
data.discard(size - (data.counter.getOffset() - fileOffset));
|
|
8
|
+
return {
|
|
9
|
+
type: 'mdat-box',
|
|
10
|
+
boxSize: size,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.parseMdat = parseMdat;
|
|
@@ -44,6 +44,29 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
44
44
|
throw new Error(`Expected box size of not 0, got ${boxSize}`);
|
|
45
45
|
}
|
|
46
46
|
if (bytesRemaining < boxSize) {
|
|
47
|
+
if (bytesRemaining >= 4) {
|
|
48
|
+
const type = iterator.getByteString(4);
|
|
49
|
+
iterator.counter.decrement(4);
|
|
50
|
+
if (type === 'mdat') {
|
|
51
|
+
const skipTo = fileOffset + boxSize;
|
|
52
|
+
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
53
|
+
// If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
|
|
54
|
+
if (bytesToSkip > 1000000) {
|
|
55
|
+
return {
|
|
56
|
+
type: 'complete',
|
|
57
|
+
box: {
|
|
58
|
+
type: 'regular-box',
|
|
59
|
+
boxType: 'mdat',
|
|
60
|
+
children: [],
|
|
61
|
+
boxSize,
|
|
62
|
+
offset: fileOffset,
|
|
63
|
+
},
|
|
64
|
+
size: boxSize,
|
|
65
|
+
skipTo: fileOffset + boxSize,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
47
70
|
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
48
71
|
if (allowIncompleteBoxes) {
|
|
49
72
|
return {
|
|
@@ -59,6 +82,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
59
82
|
type: 'complete',
|
|
60
83
|
box,
|
|
61
84
|
size: boxSize,
|
|
85
|
+
skipTo: null,
|
|
62
86
|
};
|
|
63
87
|
}
|
|
64
88
|
if (boxType === 'mvhd') {
|
|
@@ -67,6 +91,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
67
91
|
type: 'complete',
|
|
68
92
|
box,
|
|
69
93
|
size: boxSize,
|
|
94
|
+
skipTo: null,
|
|
70
95
|
};
|
|
71
96
|
}
|
|
72
97
|
if (boxType === 'tkhd') {
|
|
@@ -75,6 +100,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
75
100
|
type: 'complete',
|
|
76
101
|
box,
|
|
77
102
|
size: boxSize,
|
|
103
|
+
skipTo: null,
|
|
78
104
|
};
|
|
79
105
|
}
|
|
80
106
|
if (boxType === 'stsd') {
|
|
@@ -83,6 +109,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
83
109
|
type: 'complete',
|
|
84
110
|
box,
|
|
85
111
|
size: boxSize,
|
|
112
|
+
skipTo: null,
|
|
86
113
|
};
|
|
87
114
|
}
|
|
88
115
|
if (boxType === 'mebx') {
|
|
@@ -91,6 +118,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
91
118
|
type: 'complete',
|
|
92
119
|
box,
|
|
93
120
|
size: boxSize,
|
|
121
|
+
skipTo: null,
|
|
94
122
|
};
|
|
95
123
|
}
|
|
96
124
|
if (boxType === 'moov') {
|
|
@@ -99,6 +127,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
99
127
|
type: 'complete',
|
|
100
128
|
box,
|
|
101
129
|
size: boxSize,
|
|
130
|
+
skipTo: null,
|
|
102
131
|
};
|
|
103
132
|
}
|
|
104
133
|
if (boxType === 'trak') {
|
|
@@ -111,6 +140,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
111
140
|
type: 'complete',
|
|
112
141
|
box,
|
|
113
142
|
size: boxSize,
|
|
143
|
+
skipTo: null,
|
|
114
144
|
};
|
|
115
145
|
}
|
|
116
146
|
if (boxType === 'stts') {
|
|
@@ -123,6 +153,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
123
153
|
type: 'complete',
|
|
124
154
|
box,
|
|
125
155
|
size: boxSize,
|
|
156
|
+
skipTo: null,
|
|
126
157
|
};
|
|
127
158
|
}
|
|
128
159
|
if (boxType === 'mdhd') {
|
|
@@ -135,6 +166,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
135
166
|
type: 'complete',
|
|
136
167
|
box,
|
|
137
168
|
size: boxSize,
|
|
169
|
+
skipTo: null,
|
|
138
170
|
};
|
|
139
171
|
}
|
|
140
172
|
if (boxType === 'esds') {
|
|
@@ -147,6 +179,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
147
179
|
type: 'complete',
|
|
148
180
|
box,
|
|
149
181
|
size: boxSize,
|
|
182
|
+
skipTo: null,
|
|
150
183
|
};
|
|
151
184
|
}
|
|
152
185
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
@@ -165,6 +198,7 @@ const processBox = ({ iterator, allowIncompleteBoxes, }) => {
|
|
|
165
198
|
offset: fileOffset,
|
|
166
199
|
},
|
|
167
200
|
size: boxSize,
|
|
201
|
+
skipTo: null,
|
|
168
202
|
};
|
|
169
203
|
};
|
|
170
204
|
const parseBoxes = ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, }) => {
|
|
@@ -191,9 +225,25 @@ const parseBoxes = ({ iterator, maxBytes, allowIncompleteBoxes, initialBoxes, })
|
|
|
191
225
|
initialBoxes: boxes,
|
|
192
226
|
});
|
|
193
227
|
},
|
|
228
|
+
skipTo: null,
|
|
194
229
|
};
|
|
195
230
|
}
|
|
196
231
|
boxes.push(result.box);
|
|
232
|
+
if (result.skipTo !== null) {
|
|
233
|
+
return {
|
|
234
|
+
status: 'incomplete',
|
|
235
|
+
segments: boxes,
|
|
236
|
+
continueParsing: () => {
|
|
237
|
+
return (0, exports.parseBoxes)({
|
|
238
|
+
iterator,
|
|
239
|
+
maxBytes,
|
|
240
|
+
allowIncompleteBoxes,
|
|
241
|
+
initialBoxes: boxes,
|
|
242
|
+
});
|
|
243
|
+
},
|
|
244
|
+
skipTo: result.skipTo,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
197
247
|
iterator.discardFirstBytes();
|
|
198
248
|
}
|
|
199
249
|
return {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { BaseBox } from '../base-type';
|
|
3
|
+
export interface StcoBox extends BaseBox {
|
|
4
|
+
type: 'stco-box';
|
|
5
|
+
version: number;
|
|
6
|
+
flags: number[];
|
|
7
|
+
entryCount: number;
|
|
8
|
+
entries: number[];
|
|
9
|
+
}
|
|
10
|
+
export declare const parseStco: ({ iterator, offset, size, }: {
|
|
11
|
+
iterator: BufferIterator;
|
|
12
|
+
offset: number;
|
|
13
|
+
size: number;
|
|
14
|
+
}) => StcoBox;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStco = void 0;
|
|
4
|
+
const parseStco = ({ iterator, offset, size, }) => {
|
|
5
|
+
const version = iterator.getUint8();
|
|
6
|
+
if (version !== 0) {
|
|
7
|
+
throw new Error(`Unsupported STSD version ${version}`);
|
|
8
|
+
}
|
|
9
|
+
const flags = iterator.getSlice(3);
|
|
10
|
+
const entryCount = iterator.getUint32();
|
|
11
|
+
const entries = [];
|
|
12
|
+
for (let i = 0; i < entryCount; i++) {
|
|
13
|
+
const bytesRemaining = size - (iterator.counter.getOffset() - offset);
|
|
14
|
+
if (bytesRemaining < 4) {
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
entries.push(iterator.getUint32());
|
|
18
|
+
}
|
|
19
|
+
iterator.discard(size - (iterator.counter.getOffset() - offset));
|
|
20
|
+
return {
|
|
21
|
+
type: 'stco-box',
|
|
22
|
+
boxSize: size,
|
|
23
|
+
offset,
|
|
24
|
+
version,
|
|
25
|
+
flags: [...flags],
|
|
26
|
+
entries,
|
|
27
|
+
entryCount,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
exports.parseStco = parseStco;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { BaseBox } from '../base-type';
|
|
3
|
+
type StscEntry = {
|
|
4
|
+
firstChunk: number;
|
|
5
|
+
samplesPerChunk: number;
|
|
6
|
+
};
|
|
7
|
+
export interface StscBox extends BaseBox {
|
|
8
|
+
type: 'stsc-box';
|
|
9
|
+
version: number;
|
|
10
|
+
flags: number[];
|
|
11
|
+
entryCount: number;
|
|
12
|
+
entries: StscEntry[];
|
|
13
|
+
}
|
|
14
|
+
export declare const parseStsc: ({ iterator, offset, size, }: {
|
|
15
|
+
iterator: BufferIterator;
|
|
16
|
+
offset: number;
|
|
17
|
+
size: number;
|
|
18
|
+
}) => StscBox;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStsc = void 0;
|
|
4
|
+
const parseStsc = ({ iterator, offset, size, }) => {
|
|
5
|
+
const version = iterator.getUint8();
|
|
6
|
+
if (version !== 0) {
|
|
7
|
+
throw new Error(`Unsupported STSD version ${version}`);
|
|
8
|
+
}
|
|
9
|
+
const flags = iterator.getSlice(3);
|
|
10
|
+
const entryCount = iterator.getUint32();
|
|
11
|
+
const entries = [];
|
|
12
|
+
for (let i = 0; i < entryCount; i++) {
|
|
13
|
+
const firstChunk = iterator.getUint32();
|
|
14
|
+
const samplesPerChunk = iterator.getUint32();
|
|
15
|
+
const sampleDescriptionIndex = iterator.getUint32();
|
|
16
|
+
if (sampleDescriptionIndex !== 1) {
|
|
17
|
+
throw new Error(`Expected sampleDescriptionIndex to be 1, but got ${sampleDescriptionIndex}`);
|
|
18
|
+
}
|
|
19
|
+
entries.push({
|
|
20
|
+
firstChunk,
|
|
21
|
+
samplesPerChunk,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
type: 'stsc-box',
|
|
26
|
+
boxSize: size,
|
|
27
|
+
offset,
|
|
28
|
+
version,
|
|
29
|
+
flags: [...flags],
|
|
30
|
+
entryCount,
|
|
31
|
+
entries,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
exports.parseStsc = parseStsc;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { BaseBox } from '../base-type';
|
|
3
|
+
export type StszBox = BaseBox & {
|
|
4
|
+
type: 'stsz-box';
|
|
5
|
+
version: number;
|
|
6
|
+
flags: number[];
|
|
7
|
+
sampleSize: number;
|
|
8
|
+
sampleCount: number;
|
|
9
|
+
samples: number[];
|
|
10
|
+
};
|
|
11
|
+
export declare const parseStsz: ({ iterator, offset, size, }: {
|
|
12
|
+
iterator: BufferIterator;
|
|
13
|
+
offset: number;
|
|
14
|
+
size: number;
|
|
15
|
+
}) => StszBox;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStsz = void 0;
|
|
4
|
+
const parseStsz = ({ iterator, offset, size, }) => {
|
|
5
|
+
const version = iterator.getUint8();
|
|
6
|
+
if (version !== 0) {
|
|
7
|
+
throw new Error(`Unsupported STSD version ${version}`);
|
|
8
|
+
}
|
|
9
|
+
const flags = iterator.getSlice(3);
|
|
10
|
+
const sampleSize = iterator.getUint32();
|
|
11
|
+
const sampleCount = iterator.getUint32();
|
|
12
|
+
const samples = [];
|
|
13
|
+
for (let i = 0; i < sampleCount; i++) {
|
|
14
|
+
const bytesRemaining = size - (iterator.counter.getOffset() - offset);
|
|
15
|
+
if (bytesRemaining < 4) {
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
samples.push(iterator.getUint32());
|
|
19
|
+
}
|
|
20
|
+
iterator.discard(size - (iterator.counter.getOffset() - offset));
|
|
21
|
+
return {
|
|
22
|
+
type: 'stsz-box',
|
|
23
|
+
boxSize: size,
|
|
24
|
+
offset,
|
|
25
|
+
version,
|
|
26
|
+
flags: [...flags],
|
|
27
|
+
sampleSize,
|
|
28
|
+
sampleCount,
|
|
29
|
+
samples,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
exports.parseStsz = parseStsz;
|
|
@@ -8,6 +8,7 @@ export declare class OffsetCounter {
|
|
|
8
8
|
decrement(amount: number): void;
|
|
9
9
|
}
|
|
10
10
|
export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes?: number) => {
|
|
11
|
+
skipTo: (offset: number) => void;
|
|
11
12
|
addData: (newData: Uint8Array) => void;
|
|
12
13
|
counter: OffsetCounter;
|
|
13
14
|
byteLength: () => number;
|
package/dist/buffer-iterator.js
CHANGED
|
@@ -58,6 +58,9 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
58
58
|
const buf = new ArrayBuffer(initialData.byteLength, {
|
|
59
59
|
maxByteLength: maxBytes !== null && maxBytes !== void 0 ? maxBytes : 1000000000,
|
|
60
60
|
});
|
|
61
|
+
if (!buf.resize) {
|
|
62
|
+
throw new Error('`ArrayBuffer.resize` is not supported in this Runtime. Use at least Node.js 20 or Bun.');
|
|
63
|
+
}
|
|
61
64
|
let data = new Uint8Array(buf);
|
|
62
65
|
data.set(initialData);
|
|
63
66
|
let view = new DataView(data.buffer);
|
|
@@ -110,13 +113,24 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
110
113
|
};
|
|
111
114
|
const removeBytesRead = () => {
|
|
112
115
|
const bytesToRemove = counter.getDiscardedOffset();
|
|
116
|
+
// Only to this operation if it is really worth it 😇
|
|
117
|
+
if (bytesToRemove < 100000) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
113
120
|
counter.discardBytes(bytesToRemove);
|
|
114
121
|
const newData = data.slice(bytesToRemove);
|
|
115
122
|
data.set(newData);
|
|
116
123
|
buf.resize(newData.byteLength);
|
|
117
124
|
view = new DataView(data.buffer);
|
|
118
125
|
};
|
|
126
|
+
const skipTo = (offset) => {
|
|
127
|
+
buf.resize(offset);
|
|
128
|
+
const currentOffset = counter.getOffset();
|
|
129
|
+
counter.increment(offset - currentOffset);
|
|
130
|
+
removeBytesRead();
|
|
131
|
+
};
|
|
119
132
|
return {
|
|
133
|
+
skipTo,
|
|
120
134
|
addData,
|
|
121
135
|
counter,
|
|
122
136
|
byteLength,
|
package/dist/from-node.js
CHANGED
|
@@ -7,8 +7,12 @@ const stream_1 = require("stream");
|
|
|
7
7
|
exports.nodeReader = {
|
|
8
8
|
read: async (src, range) => {
|
|
9
9
|
const stream = (0, fs_1.createReadStream)(src, {
|
|
10
|
-
start: range === null ? 0 : range[0],
|
|
11
|
-
end: range === null
|
|
10
|
+
start: range === null ? 0 : typeof range === 'number' ? range : range[0],
|
|
11
|
+
end: range === null
|
|
12
|
+
? Infinity
|
|
13
|
+
: typeof range === 'number'
|
|
14
|
+
? Infinity
|
|
15
|
+
: range[1],
|
|
12
16
|
});
|
|
13
17
|
const stats = await (0, promises_1.stat)(src);
|
|
14
18
|
return {
|
package/dist/from-web.js
CHANGED
|
@@ -14,17 +14,20 @@ exports.webReader = {
|
|
|
14
14
|
const res = await fetch(resolvedUrl, {
|
|
15
15
|
headers: range === null
|
|
16
16
|
? {}
|
|
17
|
-
:
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
: typeof range === 'number'
|
|
18
|
+
? {
|
|
19
|
+
Range: `bytes=${range}`,
|
|
20
|
+
}
|
|
21
|
+
: {
|
|
22
|
+
Range: `bytes=${`${range[0]}-${range[1]}`}`,
|
|
23
|
+
},
|
|
24
|
+
// Disable Next.js caching
|
|
25
|
+
cache: 'no-store',
|
|
20
26
|
});
|
|
21
27
|
if (!res.body) {
|
|
22
28
|
throw new Error('No body');
|
|
23
29
|
}
|
|
24
30
|
const length = res.headers.get('content-length');
|
|
25
|
-
if (!length) {
|
|
26
|
-
throw new Error('No content-length');
|
|
27
|
-
}
|
|
28
31
|
const contentLength = length === null ? null : parseInt(length, 10);
|
|
29
32
|
const reader = res.body.getReader();
|
|
30
33
|
return { reader, contentLength };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getVideoCodec = exports.hasVideoCodec = void 0;
|
|
4
|
+
const hasVideoCodec = (boxes) => {
|
|
5
|
+
try {
|
|
6
|
+
return boxes.some((b) => b.type === 'ftyp-box');
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
exports.hasVideoCodec = hasVideoCodec;
|
|
13
|
+
const getVideoCodec = (boxes) => {
|
|
14
|
+
const ftypBox = boxes.find((b) => b.type === 'ftyp-box');
|
|
15
|
+
if (ftypBox && ftypBox.type === 'ftyp-box') {
|
|
16
|
+
if (ftypBox.compatibleBrands.find((b) => b === 'avc1')) {
|
|
17
|
+
return 'h264';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
exports.getVideoCodec = getVideoCodec;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StcoBox } from './boxes/iso-base-media/stsd/stco';
|
|
2
|
+
import type { StscBox } from './boxes/iso-base-media/stsd/stsc';
|
|
3
|
+
import type { StszBox } from './boxes/iso-base-media/stsd/stsz';
|
|
4
|
+
export type SamplePosition = {
|
|
5
|
+
offset: number;
|
|
6
|
+
size: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const getSamplePositions: ({ stcoBox, stszBox, stscBox, }: {
|
|
9
|
+
stcoBox: StcoBox;
|
|
10
|
+
stszBox: StszBox;
|
|
11
|
+
stscBox: StscBox;
|
|
12
|
+
}) => SamplePosition[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSamplePositions = void 0;
|
|
4
|
+
const getSamplePositions = ({ stcoBox, stszBox, stscBox, }) => {
|
|
5
|
+
const chunks = stcoBox.entries;
|
|
6
|
+
const samples = [];
|
|
7
|
+
let samplesPerChunk = 1;
|
|
8
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
9
|
+
const hasEntry = stscBox.entries.find((entry) => entry.firstChunk === i + 1);
|
|
10
|
+
if (hasEntry) {
|
|
11
|
+
samplesPerChunk = hasEntry.samplesPerChunk;
|
|
12
|
+
}
|
|
13
|
+
let offsetInThisChunk = 0;
|
|
14
|
+
for (let j = 0; j < samplesPerChunk; j++) {
|
|
15
|
+
const size = stszBox.samples[samples.length];
|
|
16
|
+
samples.push({
|
|
17
|
+
offset: chunks[i] + offsetInThisChunk,
|
|
18
|
+
size,
|
|
19
|
+
});
|
|
20
|
+
offsetInThisChunk += size;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return samples;
|
|
24
|
+
};
|
|
25
|
+
exports.getSamplePositions = getSamplePositions;
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SamplePosition } from './get-sample-positions';
|
|
2
|
+
import type { AnySegment } from './parse-result';
|
|
3
|
+
type Track = {
|
|
4
|
+
type: 'audio' | 'video';
|
|
5
|
+
samplePositions: SamplePosition[];
|
|
6
|
+
trackId: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const getNumberOfTracks: (segments: AnySegment[]) => number;
|
|
9
|
+
export declare const getTracks: (segments: AnySegment[]) => Track[];
|
|
10
|
+
export {};
|