@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,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTracks = exports.getNumberOfTracks = void 0;
|
|
4
|
+
const get_fps_1 = require("./get-fps");
|
|
5
|
+
const get_sample_positions_1 = require("./get-sample-positions");
|
|
6
|
+
const traversal_1 = require("./traversal");
|
|
7
|
+
// TODO: Use this to determine if all tracks are present
|
|
8
|
+
const getNumberOfTracks = (segments) => {
|
|
9
|
+
const moovBox = (0, traversal_1.getMoovBox)(segments);
|
|
10
|
+
if (!moovBox) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
const mvHdBox = (0, traversal_1.getMvhdBox)(moovBox);
|
|
14
|
+
if (!mvHdBox) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
return mvHdBox.nextTrackId - 1;
|
|
18
|
+
};
|
|
19
|
+
exports.getNumberOfTracks = getNumberOfTracks;
|
|
20
|
+
const getTracks = (segments) => {
|
|
21
|
+
const moovBox = (0, traversal_1.getMoovBox)(segments);
|
|
22
|
+
if (!moovBox) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const foundTracks = [];
|
|
26
|
+
const tracks = (0, traversal_1.getTraks)(moovBox);
|
|
27
|
+
for (const track of tracks) {
|
|
28
|
+
const stszBox = (0, traversal_1.getStszBox)(track);
|
|
29
|
+
const stcoBox = (0, traversal_1.getStcoBox)(track);
|
|
30
|
+
const stscBox = (0, traversal_1.getStscBox)(track);
|
|
31
|
+
const tkhdBox = (0, traversal_1.getTkhdBox)(track);
|
|
32
|
+
if (!tkhdBox) {
|
|
33
|
+
throw new Error('Expected tkhd box in trak box');
|
|
34
|
+
}
|
|
35
|
+
if (!stszBox) {
|
|
36
|
+
throw new Error('Expected stsz box in trak box');
|
|
37
|
+
}
|
|
38
|
+
if (!stcoBox) {
|
|
39
|
+
throw new Error('Expected stco box in trak box');
|
|
40
|
+
}
|
|
41
|
+
if (!stscBox) {
|
|
42
|
+
throw new Error('Expected stsc box in trak box');
|
|
43
|
+
}
|
|
44
|
+
const samplePositions = (0, get_sample_positions_1.getSamplePositions)({
|
|
45
|
+
stcoBox,
|
|
46
|
+
stscBox,
|
|
47
|
+
stszBox,
|
|
48
|
+
});
|
|
49
|
+
if ((0, get_fps_1.trakBoxContainsAudio)(track)) {
|
|
50
|
+
foundTracks.push({
|
|
51
|
+
type: 'audio',
|
|
52
|
+
samplePositions,
|
|
53
|
+
trackId: tkhdBox.trackId,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if ((0, get_fps_1.trakBoxContainsVideo)(track)) {
|
|
57
|
+
foundTracks.push({
|
|
58
|
+
type: 'video',
|
|
59
|
+
samplePositions,
|
|
60
|
+
trackId: tkhdBox.trackId,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return foundTracks;
|
|
65
|
+
};
|
|
66
|
+
exports.getTracks = getTracks;
|
package/dist/parse-media.js
CHANGED
|
@@ -12,11 +12,12 @@ const has_all_info_1 = require("./has-all-info");
|
|
|
12
12
|
const parse_video_1 = require("./parse-video");
|
|
13
13
|
const parseMedia = async (src, options, readerInterface = from_web_1.webReader) => {
|
|
14
14
|
const { reader, contentLength } = await readerInterface.read(src, null);
|
|
15
|
+
let currentReader = reader;
|
|
15
16
|
const returnValue = {};
|
|
16
17
|
let iterator = null;
|
|
17
18
|
let parseResult = null;
|
|
18
19
|
while (parseResult === null || parseResult.status === 'incomplete') {
|
|
19
|
-
const result = await
|
|
20
|
+
const result = await currentReader.read();
|
|
20
21
|
if (result.done) {
|
|
21
22
|
break;
|
|
22
23
|
}
|
|
@@ -33,11 +34,21 @@ const parseMedia = async (src, options, readerInterface = from_web_1.webReader)
|
|
|
33
34
|
parseResult = (0, parse_video_1.parseVideo)(iterator);
|
|
34
35
|
}
|
|
35
36
|
if ((0, has_all_info_1.hasAllInfo)(options, parseResult)) {
|
|
36
|
-
if (!
|
|
37
|
-
|
|
37
|
+
if (!currentReader.closed) {
|
|
38
|
+
currentReader.cancel(new Error('has all information'));
|
|
38
39
|
}
|
|
39
40
|
break;
|
|
40
41
|
}
|
|
42
|
+
if (parseResult &&
|
|
43
|
+
parseResult.status === 'incomplete' &&
|
|
44
|
+
parseResult.skipTo !== null) {
|
|
45
|
+
if (!currentReader.closed) {
|
|
46
|
+
currentReader.cancel(new Error('skipped ahead'));
|
|
47
|
+
}
|
|
48
|
+
const { reader: newReader } = await readerInterface.read(src, parseResult.skipTo);
|
|
49
|
+
currentReader = newReader;
|
|
50
|
+
iterator.skipTo(parseResult.skipTo);
|
|
51
|
+
}
|
|
41
52
|
}
|
|
42
53
|
if (!parseResult) {
|
|
43
54
|
throw new Error('Could not parse video');
|
package/dist/parse-result.d.ts
CHANGED
package/dist/parse-video.d.ts
CHANGED
package/dist/parse-video.js
CHANGED
package/dist/reader.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ type ReadResult = {
|
|
|
2
2
|
reader: ReadableStreamDefaultReader<Uint8Array>;
|
|
3
3
|
contentLength: number | null;
|
|
4
4
|
};
|
|
5
|
-
type ReadContent = (src: string, range: [number, number] | null) => Promise<ReadResult>;
|
|
5
|
+
type ReadContent = (src: string, range: [number, number] | number | null) => Promise<ReadResult>;
|
|
6
6
|
type GetLength = (src: string) => Promise<number>;
|
|
7
7
|
export type ReaderInterface = {
|
|
8
8
|
read: ReadContent;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MoovBox } from './boxes/iso-base-media/moov/moov';
|
|
2
|
+
import type { MvhdBox } from './boxes/iso-base-media/mvhd';
|
|
3
|
+
import type { StcoBox } from './boxes/iso-base-media/stsd/stco';
|
|
4
|
+
import type { StscBox } from './boxes/iso-base-media/stsd/stsc';
|
|
5
|
+
import type { StsdBox } from './boxes/iso-base-media/stsd/stsd';
|
|
6
|
+
import type { StszBox } from './boxes/iso-base-media/stsd/stsz';
|
|
7
|
+
import type { TkhdBox } from './boxes/iso-base-media/tkhd';
|
|
8
|
+
import type { TrakBox } from './boxes/iso-base-media/trak/trak';
|
|
9
|
+
import type { AnySegment, RegularBox } from './parse-result';
|
|
10
|
+
export declare const getMoovBox: (segments: AnySegment[]) => MoovBox | null;
|
|
11
|
+
export declare const getMvhdBox: (moovBox: MoovBox) => MvhdBox | null;
|
|
12
|
+
export declare const getTraks: (moovBox: MoovBox) => TrakBox[];
|
|
13
|
+
export declare const getTkhdBox: (trakBox: TrakBox) => TkhdBox | null;
|
|
14
|
+
export declare const getMdiaBox: (trakBox: TrakBox) => RegularBox | null;
|
|
15
|
+
export declare const getStblBox: (trakBox: TrakBox) => RegularBox | null;
|
|
16
|
+
export declare const getStsdBox: (trakBox: TrakBox) => StsdBox | null;
|
|
17
|
+
export declare const getStcoBox: (trakBox: TrakBox) => StcoBox | null;
|
|
18
|
+
export declare const getStszBox: (trakBox: TrakBox) => StszBox | null;
|
|
19
|
+
export declare const getStscBox: (trakBox: TrakBox) => StscBox | null;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStscBox = exports.getStszBox = exports.getStcoBox = exports.getStsdBox = exports.getStblBox = exports.getMdiaBox = exports.getTkhdBox = exports.getTraks = exports.getMvhdBox = exports.getMoovBox = void 0;
|
|
4
|
+
const getMoovBox = (segments) => {
|
|
5
|
+
const moovBox = segments.find((s) => s.type === 'moov-box');
|
|
6
|
+
if (!moovBox || moovBox.type !== 'moov-box') {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return moovBox;
|
|
10
|
+
};
|
|
11
|
+
exports.getMoovBox = getMoovBox;
|
|
12
|
+
const getMvhdBox = (moovBox) => {
|
|
13
|
+
const mvHdBox = moovBox.children.find((s) => s.type === 'mvhd-box');
|
|
14
|
+
if (!mvHdBox || mvHdBox.type !== 'mvhd-box') {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return mvHdBox;
|
|
18
|
+
};
|
|
19
|
+
exports.getMvhdBox = getMvhdBox;
|
|
20
|
+
const getTraks = (moovBox) => {
|
|
21
|
+
return moovBox.children.filter((s) => s.type === 'trak-box');
|
|
22
|
+
};
|
|
23
|
+
exports.getTraks = getTraks;
|
|
24
|
+
const getTkhdBox = (trakBox) => {
|
|
25
|
+
const tkhdBox = trakBox.children.find((s) => s.type === 'tkhd-box');
|
|
26
|
+
return tkhdBox;
|
|
27
|
+
};
|
|
28
|
+
exports.getTkhdBox = getTkhdBox;
|
|
29
|
+
const getMdiaBox = (trakBox) => {
|
|
30
|
+
const mdiaBox = trakBox.children.find((s) => s.type === 'regular-box' && s.boxType === 'mdia');
|
|
31
|
+
if (!mdiaBox || mdiaBox.type !== 'regular-box') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return mdiaBox;
|
|
35
|
+
};
|
|
36
|
+
exports.getMdiaBox = getMdiaBox;
|
|
37
|
+
const getStblBox = (trakBox) => {
|
|
38
|
+
const mdiaBox = (0, exports.getMdiaBox)(trakBox);
|
|
39
|
+
if (!mdiaBox) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const minfBox = mdiaBox.children.find((s) => s.type === 'regular-box' && s.boxType === 'minf');
|
|
43
|
+
if (!minfBox || minfBox.type !== 'regular-box') {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const stblBox = minfBox.children.find((s) => s.type === 'regular-box' && s.boxType === 'stbl');
|
|
47
|
+
if (!stblBox || stblBox.type !== 'regular-box') {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return stblBox;
|
|
51
|
+
};
|
|
52
|
+
exports.getStblBox = getStblBox;
|
|
53
|
+
const getStsdBox = (trakBox) => {
|
|
54
|
+
const stblBox = (0, exports.getStblBox)(trakBox);
|
|
55
|
+
if (!stblBox || stblBox.type !== 'regular-box') {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const stsdBox = stblBox.children.find((s) => s.type === 'stsd-box');
|
|
59
|
+
return stsdBox;
|
|
60
|
+
};
|
|
61
|
+
exports.getStsdBox = getStsdBox;
|
|
62
|
+
const getStcoBox = (trakBox) => {
|
|
63
|
+
const stblBox = (0, exports.getStblBox)(trakBox);
|
|
64
|
+
if (!stblBox || stblBox.type !== 'regular-box') {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const stcoBox = stblBox.children.find((s) => s.type === 'stco-box');
|
|
68
|
+
return stcoBox;
|
|
69
|
+
};
|
|
70
|
+
exports.getStcoBox = getStcoBox;
|
|
71
|
+
const getStszBox = (trakBox) => {
|
|
72
|
+
const stblBox = (0, exports.getStblBox)(trakBox);
|
|
73
|
+
if (!stblBox || stblBox.type !== 'regular-box') {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const stszBox = stblBox.children.find((s) => s.type === 'stsz-box');
|
|
77
|
+
return stszBox;
|
|
78
|
+
};
|
|
79
|
+
exports.getStszBox = getStszBox;
|
|
80
|
+
const getStscBox = (trakBox) => {
|
|
81
|
+
const stblBox = (0, exports.getStblBox)(trakBox);
|
|
82
|
+
if (!stblBox || stblBox.type !== 'regular-box') {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const stcoBox = stblBox.children.find((b) => b.type === 'stsc-box');
|
|
86
|
+
return stcoBox;
|
|
87
|
+
};
|
|
88
|
+
exports.getStscBox = getStscBox;
|
package/package.json
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/media-parser",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.194",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@remotion/renderer": "4.0.
|
|
10
|
+
"@remotion/renderer": "4.0.194"
|
|
11
11
|
},
|
|
12
12
|
"publishConfig": {
|
|
13
13
|
"access": "public"
|
|
@@ -68,6 +68,32 @@ const processBox = ({
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
if (bytesRemaining < boxSize) {
|
|
71
|
+
if (bytesRemaining >= 4) {
|
|
72
|
+
const type = iterator.getByteString(4);
|
|
73
|
+
iterator.counter.decrement(4);
|
|
74
|
+
|
|
75
|
+
if (type === 'mdat') {
|
|
76
|
+
const skipTo = fileOffset + boxSize;
|
|
77
|
+
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
78
|
+
|
|
79
|
+
// If there is a huge mdat chunk, we can skip it because we don't need it for the metadata
|
|
80
|
+
if (bytesToSkip > 1_000_000) {
|
|
81
|
+
return {
|
|
82
|
+
type: 'complete',
|
|
83
|
+
box: {
|
|
84
|
+
type: 'regular-box',
|
|
85
|
+
boxType: 'mdat',
|
|
86
|
+
children: [],
|
|
87
|
+
boxSize,
|
|
88
|
+
offset: fileOffset,
|
|
89
|
+
},
|
|
90
|
+
size: boxSize,
|
|
91
|
+
skipTo: fileOffset + boxSize,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
71
97
|
iterator.counter.decrement(iterator.counter.getOffset() - fileOffset);
|
|
72
98
|
if (allowIncompleteBoxes) {
|
|
73
99
|
return {
|
|
@@ -88,6 +114,7 @@ const processBox = ({
|
|
|
88
114
|
type: 'complete',
|
|
89
115
|
box,
|
|
90
116
|
size: boxSize,
|
|
117
|
+
skipTo: null,
|
|
91
118
|
};
|
|
92
119
|
}
|
|
93
120
|
|
|
@@ -98,6 +125,7 @@ const processBox = ({
|
|
|
98
125
|
type: 'complete',
|
|
99
126
|
box,
|
|
100
127
|
size: boxSize,
|
|
128
|
+
skipTo: null,
|
|
101
129
|
};
|
|
102
130
|
}
|
|
103
131
|
|
|
@@ -108,6 +136,7 @@ const processBox = ({
|
|
|
108
136
|
type: 'complete',
|
|
109
137
|
box,
|
|
110
138
|
size: boxSize,
|
|
139
|
+
skipTo: null,
|
|
111
140
|
};
|
|
112
141
|
}
|
|
113
142
|
|
|
@@ -118,6 +147,7 @@ const processBox = ({
|
|
|
118
147
|
type: 'complete',
|
|
119
148
|
box,
|
|
120
149
|
size: boxSize,
|
|
150
|
+
skipTo: null,
|
|
121
151
|
};
|
|
122
152
|
}
|
|
123
153
|
|
|
@@ -128,6 +158,7 @@ const processBox = ({
|
|
|
128
158
|
type: 'complete',
|
|
129
159
|
box,
|
|
130
160
|
size: boxSize,
|
|
161
|
+
skipTo: null,
|
|
131
162
|
};
|
|
132
163
|
}
|
|
133
164
|
|
|
@@ -138,6 +169,7 @@ const processBox = ({
|
|
|
138
169
|
type: 'complete',
|
|
139
170
|
box,
|
|
140
171
|
size: boxSize,
|
|
172
|
+
skipTo: null,
|
|
141
173
|
};
|
|
142
174
|
}
|
|
143
175
|
|
|
@@ -152,6 +184,7 @@ const processBox = ({
|
|
|
152
184
|
type: 'complete',
|
|
153
185
|
box,
|
|
154
186
|
size: boxSize,
|
|
187
|
+
skipTo: null,
|
|
155
188
|
};
|
|
156
189
|
}
|
|
157
190
|
|
|
@@ -166,6 +199,7 @@ const processBox = ({
|
|
|
166
199
|
type: 'complete',
|
|
167
200
|
box,
|
|
168
201
|
size: boxSize,
|
|
202
|
+
skipTo: null,
|
|
169
203
|
};
|
|
170
204
|
}
|
|
171
205
|
|
|
@@ -180,6 +214,7 @@ const processBox = ({
|
|
|
180
214
|
type: 'complete',
|
|
181
215
|
box,
|
|
182
216
|
size: boxSize,
|
|
217
|
+
skipTo: null,
|
|
183
218
|
};
|
|
184
219
|
}
|
|
185
220
|
|
|
@@ -194,6 +229,7 @@ const processBox = ({
|
|
|
194
229
|
type: 'complete',
|
|
195
230
|
box,
|
|
196
231
|
size: boxSize,
|
|
232
|
+
skipTo: null,
|
|
197
233
|
};
|
|
198
234
|
}
|
|
199
235
|
|
|
@@ -216,6 +252,7 @@ const processBox = ({
|
|
|
216
252
|
offset: fileOffset,
|
|
217
253
|
},
|
|
218
254
|
size: boxSize,
|
|
255
|
+
skipTo: null,
|
|
219
256
|
};
|
|
220
257
|
};
|
|
221
258
|
|
|
@@ -257,10 +294,28 @@ export const parseBoxes = ({
|
|
|
257
294
|
initialBoxes: boxes,
|
|
258
295
|
});
|
|
259
296
|
},
|
|
297
|
+
skipTo: null,
|
|
260
298
|
};
|
|
261
299
|
}
|
|
262
300
|
|
|
263
301
|
boxes.push(result.box);
|
|
302
|
+
|
|
303
|
+
if (result.skipTo !== null) {
|
|
304
|
+
return {
|
|
305
|
+
status: 'incomplete',
|
|
306
|
+
segments: boxes,
|
|
307
|
+
continueParsing: () => {
|
|
308
|
+
return parseBoxes({
|
|
309
|
+
iterator,
|
|
310
|
+
maxBytes,
|
|
311
|
+
allowIncompleteBoxes,
|
|
312
|
+
initialBoxes: boxes,
|
|
313
|
+
});
|
|
314
|
+
},
|
|
315
|
+
skipTo: result.skipTo,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
264
319
|
iterator.discardFirstBytes();
|
|
265
320
|
}
|
|
266
321
|
|
package/src/buffer-iterator.ts
CHANGED
|
@@ -55,6 +55,12 @@ export const getArrayBufferIterator = (
|
|
|
55
55
|
const buf = new ArrayBuffer(initialData.byteLength, {
|
|
56
56
|
maxByteLength: maxBytes ?? 1_000_000_000,
|
|
57
57
|
});
|
|
58
|
+
if (!buf.resize) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
'`ArrayBuffer.resize` is not supported in this Runtime. Use at least Node.js 20 or Bun.',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
58
64
|
let data = new Uint8Array(buf);
|
|
59
65
|
data.set(initialData);
|
|
60
66
|
|
|
@@ -127,6 +133,12 @@ export const getArrayBufferIterator = (
|
|
|
127
133
|
|
|
128
134
|
const removeBytesRead = () => {
|
|
129
135
|
const bytesToRemove = counter.getDiscardedOffset();
|
|
136
|
+
|
|
137
|
+
// Only to this operation if it is really worth it 😇
|
|
138
|
+
if (bytesToRemove < 100_000) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
130
142
|
counter.discardBytes(bytesToRemove);
|
|
131
143
|
const newData = data.slice(bytesToRemove);
|
|
132
144
|
data.set(newData);
|
|
@@ -134,7 +146,15 @@ export const getArrayBufferIterator = (
|
|
|
134
146
|
view = new DataView(data.buffer);
|
|
135
147
|
};
|
|
136
148
|
|
|
149
|
+
const skipTo = (offset: number) => {
|
|
150
|
+
buf.resize(offset);
|
|
151
|
+
const currentOffset = counter.getOffset();
|
|
152
|
+
counter.increment(offset - currentOffset);
|
|
153
|
+
removeBytesRead();
|
|
154
|
+
};
|
|
155
|
+
|
|
137
156
|
return {
|
|
157
|
+
skipTo,
|
|
138
158
|
addData,
|
|
139
159
|
counter,
|
|
140
160
|
byteLength,
|
package/src/from-node.ts
CHANGED
|
@@ -6,8 +6,13 @@ import type {ReaderInterface} from './reader';
|
|
|
6
6
|
export const nodeReader: ReaderInterface = {
|
|
7
7
|
read: async (src, range) => {
|
|
8
8
|
const stream = createReadStream(src, {
|
|
9
|
-
start: range === null ? 0 : range[0],
|
|
10
|
-
end:
|
|
9
|
+
start: range === null ? 0 : typeof range === 'number' ? range : range[0],
|
|
10
|
+
end:
|
|
11
|
+
range === null
|
|
12
|
+
? Infinity
|
|
13
|
+
: typeof range === 'number'
|
|
14
|
+
? Infinity
|
|
15
|
+
: range[1],
|
|
11
16
|
});
|
|
12
17
|
const stats = await stat(src);
|
|
13
18
|
return {
|
package/src/from-web.ts
CHANGED
|
@@ -23,18 +23,21 @@ export const webReader: ReaderInterface = {
|
|
|
23
23
|
headers:
|
|
24
24
|
range === null
|
|
25
25
|
? {}
|
|
26
|
-
:
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
: typeof range === 'number'
|
|
27
|
+
? {
|
|
28
|
+
Range: `bytes=${range}`,
|
|
29
|
+
}
|
|
30
|
+
: {
|
|
31
|
+
Range: `bytes=${`${range[0]}-${range[1]}`}`,
|
|
32
|
+
},
|
|
33
|
+
// Disable Next.js caching
|
|
34
|
+
cache: 'no-store',
|
|
29
35
|
});
|
|
30
36
|
if (!res.body) {
|
|
31
37
|
throw new Error('No body');
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
const length = res.headers.get('content-length');
|
|
35
|
-
if (!length) {
|
|
36
|
-
throw new Error('No content-length');
|
|
37
|
-
}
|
|
38
41
|
|
|
39
42
|
const contentLength = length === null ? null : parseInt(length, 10);
|
|
40
43
|
|
package/src/parse-media.ts
CHANGED
|
@@ -17,6 +17,7 @@ export const parseMedia: ParseMedia = async (
|
|
|
17
17
|
readerInterface = webReader,
|
|
18
18
|
) => {
|
|
19
19
|
const {reader, contentLength} = await readerInterface.read(src, null);
|
|
20
|
+
let currentReader = reader;
|
|
20
21
|
|
|
21
22
|
const returnValue = {} as Metadata<true, true, true, true, true, true>;
|
|
22
23
|
|
|
@@ -24,7 +25,7 @@ export const parseMedia: ParseMedia = async (
|
|
|
24
25
|
let parseResult: ParseResult | null = null;
|
|
25
26
|
|
|
26
27
|
while (parseResult === null || parseResult.status === 'incomplete') {
|
|
27
|
-
const result = await
|
|
28
|
+
const result = await currentReader.read();
|
|
28
29
|
if (result.done) {
|
|
29
30
|
break;
|
|
30
31
|
}
|
|
@@ -45,12 +46,29 @@ export const parseMedia: ParseMedia = async (
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
if (hasAllInfo(options, parseResult)) {
|
|
48
|
-
if (!
|
|
49
|
-
|
|
49
|
+
if (!currentReader.closed) {
|
|
50
|
+
currentReader.cancel(new Error('has all information'));
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
break;
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
if (
|
|
57
|
+
parseResult &&
|
|
58
|
+
parseResult.status === 'incomplete' &&
|
|
59
|
+
parseResult.skipTo !== null
|
|
60
|
+
) {
|
|
61
|
+
if (!currentReader.closed) {
|
|
62
|
+
currentReader.cancel(new Error('skipped ahead'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const {reader: newReader} = await readerInterface.read(
|
|
66
|
+
src,
|
|
67
|
+
parseResult.skipTo,
|
|
68
|
+
);
|
|
69
|
+
currentReader = newReader;
|
|
70
|
+
iterator.skipTo(parseResult.skipTo);
|
|
71
|
+
}
|
|
54
72
|
}
|
|
55
73
|
|
|
56
74
|
if (!parseResult) {
|
package/src/parse-result.ts
CHANGED
package/src/parse-video.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type BoxAndNext =
|
|
|
8
8
|
type: 'complete';
|
|
9
9
|
box: IsoBaseMediaBox;
|
|
10
10
|
size: number;
|
|
11
|
+
skipTo: number | null;
|
|
11
12
|
}
|
|
12
13
|
| {
|
|
13
14
|
type: 'incomplete';
|
|
@@ -21,6 +22,7 @@ export const parseVideo = (iterator: BufferIterator): ParseResult => {
|
|
|
21
22
|
continueParsing: () => {
|
|
22
23
|
return parseVideo(iterator);
|
|
23
24
|
},
|
|
25
|
+
skipTo: null,
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
|
package/src/reader.ts
CHANGED