@remotion/media-parser 4.0.191
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/.eslintrc +8 -0
- package/LICENSE.md +49 -0
- package/README.md +18 -0
- package/dist/boxes/iso-base-media/base-type.d.ts +4 -0
- package/dist/boxes/iso-base-media/base-type.js +2 -0
- package/dist/boxes/iso-base-media/ftyp.d.ts +13 -0
- package/dist/boxes/iso-base-media/ftyp.js +22 -0
- package/dist/boxes/iso-base-media/moov/moov.d.ts +12 -0
- package/dist/boxes/iso-base-media/moov/moov.js +22 -0
- package/dist/boxes/iso-base-media/mvhd.d.ts +30 -0
- package/dist/boxes/iso-base-media/mvhd.js +59 -0
- package/dist/boxes/iso-base-media/process-box.d.ts +8 -0
- package/dist/boxes/iso-base-media/process-box.js +174 -0
- package/dist/boxes/iso-base-media/stsd/keys.d.ts +5 -0
- package/dist/boxes/iso-base-media/stsd/keys.js +21 -0
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +14 -0
- package/dist/boxes/iso-base-media/stsd/mebx.js +27 -0
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +48 -0
- package/dist/boxes/iso-base-media/stsd/samples.js +215 -0
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +13 -0
- package/dist/boxes/iso-base-media/stsd/stsd.js +26 -0
- package/dist/boxes/iso-base-media/stts/stts.d.ts +15 -0
- package/dist/boxes/iso-base-media/stts/stts.js +35 -0
- package/dist/boxes/iso-base-media/tkhd.d.ts +22 -0
- package/dist/boxes/iso-base-media/tkhd.js +63 -0
- package/dist/boxes/iso-base-media/to-date.d.ts +1 -0
- package/dist/boxes/iso-base-media/to-date.js +11 -0
- package/dist/boxes/iso-base-media/trak/trak.d.ts +12 -0
- package/dist/boxes/iso-base-media/trak/trak.js +22 -0
- package/dist/boxes/webm/parse-webm-header.d.ts +3 -0
- package/dist/boxes/webm/parse-webm-header.js +16 -0
- package/dist/boxes/webm/segments/duration.d.ts +6 -0
- package/dist/boxes/webm/segments/duration.js +15 -0
- package/dist/boxes/webm/segments/info.d.ts +8 -0
- package/dist/boxes/webm/segments/info.js +14 -0
- package/dist/boxes/webm/segments/main.d.ts +7 -0
- package/dist/boxes/webm/segments/main.js +13 -0
- package/dist/boxes/webm/segments/muxing.d.ts +6 -0
- package/dist/boxes/webm/segments/muxing.js +12 -0
- package/dist/boxes/webm/segments/parse-children.d.ts +3 -0
- package/dist/boxes/webm/segments/parse-children.js +17 -0
- package/dist/boxes/webm/segments/seek-head.d.ts +8 -0
- package/dist/boxes/webm/segments/seek-head.js +13 -0
- package/dist/boxes/webm/segments/seek-position.d.ts +6 -0
- package/dist/boxes/webm/segments/seek-position.js +12 -0
- package/dist/boxes/webm/segments/seek.d.ts +8 -0
- package/dist/boxes/webm/segments/seek.js +16 -0
- package/dist/boxes/webm/segments/timestamp-scale.d.ts +6 -0
- package/dist/boxes/webm/segments/timestamp-scale.js +11 -0
- package/dist/boxes/webm/segments/track-entry.d.ts +71 -0
- package/dist/boxes/webm/segments/track-entry.js +175 -0
- package/dist/boxes/webm/segments/tracks.d.ts +7 -0
- package/dist/boxes/webm/segments/tracks.js +13 -0
- package/dist/boxes/webm/segments/unknown.d.ts +6 -0
- package/dist/boxes/webm/segments/unknown.js +11 -0
- package/dist/boxes/webm/segments/void.d.ts +6 -0
- package/dist/boxes/webm/segments/void.js +12 -0
- package/dist/boxes/webm/segments/writing.d.ts +6 -0
- package/dist/boxes/webm/segments/writing.js +12 -0
- package/dist/boxes/webm/segments.d.ts +16 -0
- package/dist/boxes/webm/segments.js +106 -0
- package/dist/buffer-iterator.d.ts +36 -0
- package/dist/buffer-iterator.js +263 -0
- package/dist/from-node.d.ts +2 -0
- package/dist/from-node.js +19 -0
- package/dist/from-web.d.ts +2 -0
- package/dist/from-web.js +40 -0
- package/dist/get-dimensions.d.ts +7 -0
- package/dist/get-dimensions.js +104 -0
- package/dist/get-duration.d.ts +3 -0
- package/dist/get-duration.js +61 -0
- package/dist/get-fps.d.ts +3 -0
- package/dist/get-fps.js +70 -0
- package/dist/has-all-info.d.ts +3 -0
- package/dist/has-all-info.js +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/options.d.ts +19 -0
- package/dist/options.js +2 -0
- package/dist/parse-media.d.ts +2 -0
- package/dist/parse-media.js +44 -0
- package/dist/parse-result.d.ts +29 -0
- package/dist/parse-result.js +2 -0
- package/dist/parse-video.d.ts +10 -0
- package/dist/parse-video.js +29 -0
- package/dist/reader.d.ts +7 -0
- package/dist/reader.js +2 -0
- package/package.json +47 -0
- package/src/boxes/iso-base-media/base-type.ts +4 -0
- package/src/boxes/iso-base-media/ftyp.ts +39 -0
- package/src/boxes/iso-base-media/moov/moov.ts +37 -0
- package/src/boxes/iso-base-media/mvhd.ts +107 -0
- package/src/boxes/iso-base-media/process-box.ts +236 -0
- package/src/boxes/iso-base-media/stsd/keys.ts +25 -0
- package/src/boxes/iso-base-media/stsd/mebx.ts +46 -0
- package/src/boxes/iso-base-media/stsd/samples.ts +298 -0
- package/src/boxes/iso-base-media/stsd/stsd.ts +48 -0
- package/src/boxes/iso-base-media/stts/stts.ts +62 -0
- package/src/boxes/iso-base-media/tkhd.ts +105 -0
- package/src/boxes/iso-base-media/to-date.ts +9 -0
- package/src/boxes/iso-base-media/trak/trak.ts +37 -0
- package/src/boxes/webm/parse-webm-header.ts +18 -0
- package/src/boxes/webm/segments/duration.ts +22 -0
- package/src/boxes/webm/segments/info.ts +20 -0
- package/src/boxes/webm/segments/main.ts +19 -0
- package/src/boxes/webm/segments/muxing.ts +18 -0
- package/src/boxes/webm/segments/parse-children.ts +21 -0
- package/src/boxes/webm/segments/seek-head.ts +21 -0
- package/src/boxes/webm/segments/seek-position.ts +19 -0
- package/src/boxes/webm/segments/seek.ts +23 -0
- package/src/boxes/webm/segments/timestamp-scale.ts +17 -0
- package/src/boxes/webm/segments/track-entry.ts +295 -0
- package/src/boxes/webm/segments/tracks.ts +22 -0
- package/src/boxes/webm/segments/unknown.ts +19 -0
- package/src/boxes/webm/segments/void.ts +16 -0
- package/src/boxes/webm/segments/writing.ts +18 -0
- package/src/boxes/webm/segments.ts +206 -0
- package/src/buffer-iterator.ts +305 -0
- package/src/from-node.ts +22 -0
- package/src/from-web.ts +53 -0
- package/src/get-dimensions.ts +147 -0
- package/src/get-duration.ts +73 -0
- package/src/get-fps.ts +92 -0
- package/src/has-all-info.ts +34 -0
- package/src/index.ts +1 -0
- package/src/options.ts +38 -0
- package/src/parse-media.ts +57 -0
- package/src/parse-result.ts +44 -0
- package/src/parse-video.ts +41 -0
- package/src/reader.ts +10 -0
- package/src/test/duration.test.ts +34 -0
- package/src/test/keys.test.ts +47 -0
- package/src/test/matroska.test.ts +163 -0
- package/src/test/mvhd.test.ts +89 -0
- package/src/test/parse-stts.test.ts +38 -0
- package/src/test/parse-video.test.ts +113 -0
- package/src/test/parse-webm.test.ts +15 -0
- package/src/test/stream-local.test.ts +105 -0
- package/src/test/stream-remote.test.ts +12 -0
- package/src/test/stsd.test.ts +162 -0
- package/src/test/tkhd.test.ts +84 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSamples = exports.processSample = void 0;
|
|
4
|
+
// https://developer.apple.com/documentation/quicktime-file-format/video_sample_description
|
|
5
|
+
const videoTags = [
|
|
6
|
+
'cvid',
|
|
7
|
+
'jpeg',
|
|
8
|
+
'smc ',
|
|
9
|
+
'rle ',
|
|
10
|
+
'rpza',
|
|
11
|
+
'kpcd',
|
|
12
|
+
'png ',
|
|
13
|
+
'mjpa',
|
|
14
|
+
'mjpb',
|
|
15
|
+
'SVQ1',
|
|
16
|
+
'SVQ3',
|
|
17
|
+
'mp4v',
|
|
18
|
+
'avc1',
|
|
19
|
+
'dvc ',
|
|
20
|
+
'dvcp',
|
|
21
|
+
'gif ',
|
|
22
|
+
'h263',
|
|
23
|
+
'tiff',
|
|
24
|
+
'raw ',
|
|
25
|
+
'2vuY',
|
|
26
|
+
'yuv2',
|
|
27
|
+
'v308',
|
|
28
|
+
'v408',
|
|
29
|
+
'v216',
|
|
30
|
+
'v410',
|
|
31
|
+
'v210',
|
|
32
|
+
'hvc1',
|
|
33
|
+
];
|
|
34
|
+
// https://developer.apple.com/documentation/quicktime-file-format/sound_sample_descriptions
|
|
35
|
+
const audioTags = [
|
|
36
|
+
0x00000000,
|
|
37
|
+
'NONE',
|
|
38
|
+
'raw ',
|
|
39
|
+
'twos',
|
|
40
|
+
'sowt',
|
|
41
|
+
'MAC3 ',
|
|
42
|
+
'MAC6 ',
|
|
43
|
+
'ima4',
|
|
44
|
+
'fl32',
|
|
45
|
+
'fl64',
|
|
46
|
+
'in24',
|
|
47
|
+
'in32',
|
|
48
|
+
'ulaw',
|
|
49
|
+
'alaw',
|
|
50
|
+
0x6d730002,
|
|
51
|
+
0x6d730011,
|
|
52
|
+
'dvca',
|
|
53
|
+
'QDMC',
|
|
54
|
+
'QDM2',
|
|
55
|
+
'Qclp',
|
|
56
|
+
0x6d730055,
|
|
57
|
+
'.mp3',
|
|
58
|
+
'mp4a',
|
|
59
|
+
'ac-3',
|
|
60
|
+
];
|
|
61
|
+
const processSample = ({ iterator, }) => {
|
|
62
|
+
const fileOffset = iterator.counter.getOffset();
|
|
63
|
+
const bytesRemaining = iterator.bytesRemaining();
|
|
64
|
+
const boxSize = iterator.getUint32();
|
|
65
|
+
if (bytesRemaining < boxSize) {
|
|
66
|
+
throw new Error(`Expected box size of ${bytesRemaining}, got ${boxSize}`);
|
|
67
|
+
}
|
|
68
|
+
const boxFormat = iterator.getAtom();
|
|
69
|
+
const isVideo = videoTags.includes(boxFormat);
|
|
70
|
+
const isAudio = audioTags.includes(boxFormat) || audioTags.includes(Number(boxFormat));
|
|
71
|
+
// 6 reserved bytes
|
|
72
|
+
iterator.discard(6);
|
|
73
|
+
const dataReferenceIndex = iterator.getUint16();
|
|
74
|
+
const version = iterator.getUint16();
|
|
75
|
+
const revisionLevel = iterator.getUint16();
|
|
76
|
+
const vendor = iterator.getSlice(4);
|
|
77
|
+
if (!isVideo && !isAudio) {
|
|
78
|
+
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
79
|
+
iterator.discard(bytesRemainingInBox);
|
|
80
|
+
return {
|
|
81
|
+
sample: {
|
|
82
|
+
type: 'unknown',
|
|
83
|
+
offset: fileOffset,
|
|
84
|
+
dataReferenceIndex,
|
|
85
|
+
version,
|
|
86
|
+
revisionLevel,
|
|
87
|
+
vendor: [...Array.from(new Uint8Array(vendor))],
|
|
88
|
+
size: boxSize,
|
|
89
|
+
format: boxFormat,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (isAudio) {
|
|
94
|
+
if (version === 0) {
|
|
95
|
+
const numberOfChannels = iterator.getUint16();
|
|
96
|
+
const sampleSize = iterator.getUint16();
|
|
97
|
+
const compressionId = iterator.getUint16();
|
|
98
|
+
const packetSize = iterator.getUint16();
|
|
99
|
+
const sampleRate = iterator.getFixedPoint1616Number();
|
|
100
|
+
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
101
|
+
iterator.discard(bytesRemainingInBox);
|
|
102
|
+
return {
|
|
103
|
+
sample: {
|
|
104
|
+
format: boxFormat,
|
|
105
|
+
offset: fileOffset,
|
|
106
|
+
dataReferenceIndex,
|
|
107
|
+
version,
|
|
108
|
+
revisionLevel,
|
|
109
|
+
vendor: [...Array.from(new Uint8Array(vendor))],
|
|
110
|
+
size: boxSize,
|
|
111
|
+
type: 'audio',
|
|
112
|
+
numberOfChannels,
|
|
113
|
+
sampleSize,
|
|
114
|
+
compressionId,
|
|
115
|
+
packetSize,
|
|
116
|
+
sampleRate,
|
|
117
|
+
samplesPerPacket: null,
|
|
118
|
+
bytesPerPacket: null,
|
|
119
|
+
bytesPerFrame: null,
|
|
120
|
+
bitsPerSample: null,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (version === 1) {
|
|
125
|
+
const numberOfChannels = iterator.getUint16();
|
|
126
|
+
const sampleSize = iterator.getUint16();
|
|
127
|
+
const compressionId = iterator.getUint16();
|
|
128
|
+
const packetSize = iterator.getUint16();
|
|
129
|
+
const sampleRate = iterator.getFixedPoint1616Number();
|
|
130
|
+
const samplesPerPacket = iterator.getUint16();
|
|
131
|
+
const bytesPerPacket = iterator.getUint16();
|
|
132
|
+
const bytesPerFrame = iterator.getUint16();
|
|
133
|
+
const bitsPerSample = iterator.getUint16();
|
|
134
|
+
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
135
|
+
iterator.discard(bytesRemainingInBox);
|
|
136
|
+
return {
|
|
137
|
+
sample: {
|
|
138
|
+
format: boxFormat,
|
|
139
|
+
offset: fileOffset,
|
|
140
|
+
dataReferenceIndex,
|
|
141
|
+
version,
|
|
142
|
+
revisionLevel,
|
|
143
|
+
vendor: [...Array.from(new Uint8Array(vendor))],
|
|
144
|
+
size: boxSize,
|
|
145
|
+
type: 'audio',
|
|
146
|
+
numberOfChannels,
|
|
147
|
+
sampleSize,
|
|
148
|
+
compressionId,
|
|
149
|
+
packetSize,
|
|
150
|
+
sampleRate,
|
|
151
|
+
samplesPerPacket,
|
|
152
|
+
bytesPerPacket,
|
|
153
|
+
bytesPerFrame,
|
|
154
|
+
bitsPerSample,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`Unsupported version ${version}`);
|
|
159
|
+
}
|
|
160
|
+
if (isVideo) {
|
|
161
|
+
const temporalQuality = iterator.getUint32();
|
|
162
|
+
const spacialQuality = iterator.getUint32();
|
|
163
|
+
const width = iterator.getUint16();
|
|
164
|
+
const height = iterator.getUint16();
|
|
165
|
+
const horizontalResolution = iterator.getFixedPoint1616Number();
|
|
166
|
+
const verticalResolution = iterator.getFixedPoint1616Number();
|
|
167
|
+
const dataSize = iterator.getUint32();
|
|
168
|
+
const frameCountPerSample = iterator.getUint16();
|
|
169
|
+
const compressorName = iterator.getPascalString();
|
|
170
|
+
const depth = iterator.getUint16();
|
|
171
|
+
const colorTableId = iterator.getInt16();
|
|
172
|
+
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
173
|
+
iterator.discard(bytesRemainingInBox);
|
|
174
|
+
return {
|
|
175
|
+
sample: {
|
|
176
|
+
format: boxFormat,
|
|
177
|
+
offset: fileOffset,
|
|
178
|
+
dataReferenceIndex,
|
|
179
|
+
version,
|
|
180
|
+
revisionLevel,
|
|
181
|
+
vendor: [...Array.from(new Uint8Array(vendor))],
|
|
182
|
+
size: boxSize,
|
|
183
|
+
type: 'video',
|
|
184
|
+
width,
|
|
185
|
+
height,
|
|
186
|
+
horizontalResolutionPpi: horizontalResolution,
|
|
187
|
+
verticalResolutionPpi: verticalResolution,
|
|
188
|
+
spacialQuality,
|
|
189
|
+
temporalQuality,
|
|
190
|
+
dataSize,
|
|
191
|
+
frameCountPerSample,
|
|
192
|
+
compressorName,
|
|
193
|
+
depth,
|
|
194
|
+
colorTableId,
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
throw new Error(`Unknown sample format ${boxFormat}`);
|
|
199
|
+
};
|
|
200
|
+
exports.processSample = processSample;
|
|
201
|
+
const parseSamples = (iterator, maxBytes) => {
|
|
202
|
+
const samples = [];
|
|
203
|
+
const initialOffset = iterator.counter.getOffset();
|
|
204
|
+
while (iterator.bytesRemaining() > 0 &&
|
|
205
|
+
iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
206
|
+
const { sample } = (0, exports.processSample)({
|
|
207
|
+
iterator,
|
|
208
|
+
});
|
|
209
|
+
if (sample) {
|
|
210
|
+
samples.push(sample);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return samples;
|
|
214
|
+
};
|
|
215
|
+
exports.parseSamples = parseSamples;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { BaseBox } from '../base-type';
|
|
3
|
+
import type { Sample } from './samples';
|
|
4
|
+
export interface StsdBox extends BaseBox {
|
|
5
|
+
type: 'stsd-box';
|
|
6
|
+
numberOfEntries: number;
|
|
7
|
+
samples: Sample[];
|
|
8
|
+
}
|
|
9
|
+
export declare const parseStsd: ({ iterator, offset, size, }: {
|
|
10
|
+
iterator: BufferIterator;
|
|
11
|
+
offset: number;
|
|
12
|
+
size: number;
|
|
13
|
+
}) => StsdBox;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStsd = void 0;
|
|
4
|
+
const samples_1 = require("./samples");
|
|
5
|
+
const parseStsd = ({ iterator, offset, size, }) => {
|
|
6
|
+
const version = iterator.getUint8();
|
|
7
|
+
if (version !== 0) {
|
|
8
|
+
throw new Error(`Unsupported STSD version ${version}`);
|
|
9
|
+
}
|
|
10
|
+
// flags, we discard them
|
|
11
|
+
iterator.discard(3);
|
|
12
|
+
const numberOfEntries = iterator.getUint32();
|
|
13
|
+
const bytesRemainingInBox = size - (iterator.counter.getOffset() - offset);
|
|
14
|
+
const boxes = (0, samples_1.parseSamples)(iterator, bytesRemainingInBox);
|
|
15
|
+
if (boxes.length !== numberOfEntries) {
|
|
16
|
+
throw new Error(`Expected ${numberOfEntries} sample descriptions, got ${boxes.length}`);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
type: 'stsd-box',
|
|
20
|
+
boxSize: size,
|
|
21
|
+
offset,
|
|
22
|
+
numberOfEntries,
|
|
23
|
+
samples: boxes,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.parseStsd = parseStsd;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
export interface SttsBox {
|
|
3
|
+
type: 'stts-box';
|
|
4
|
+
sampleDistribution: SampleDistribution[];
|
|
5
|
+
}
|
|
6
|
+
type SampleDistribution = {
|
|
7
|
+
sampleCount: number;
|
|
8
|
+
sampleDelta: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const parseStts: ({ data, size, fileOffset, }: {
|
|
11
|
+
data: BufferIterator;
|
|
12
|
+
size: number;
|
|
13
|
+
fileOffset: number;
|
|
14
|
+
}) => SttsBox;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStts = void 0;
|
|
4
|
+
const parseStts = ({ data, size, fileOffset, }) => {
|
|
5
|
+
const initialOffset = data.counter.getOffset();
|
|
6
|
+
const initialCounter = initialOffset - fileOffset;
|
|
7
|
+
const version = data.getUint8();
|
|
8
|
+
if (version !== 0) {
|
|
9
|
+
throw new Error(`Unsupported STTS version ${version}`);
|
|
10
|
+
}
|
|
11
|
+
// flags, we discard them
|
|
12
|
+
data.discard(3);
|
|
13
|
+
// entry count
|
|
14
|
+
const entryCount = data.getUint32();
|
|
15
|
+
const sampleDistributions = [];
|
|
16
|
+
// entries
|
|
17
|
+
for (let i = 0; i < entryCount; i++) {
|
|
18
|
+
const sampleCount = data.getUint32();
|
|
19
|
+
const sampleDelta = data.getUint32();
|
|
20
|
+
const sampleDistribution = {
|
|
21
|
+
sampleCount,
|
|
22
|
+
sampleDelta,
|
|
23
|
+
};
|
|
24
|
+
sampleDistributions.push(sampleDistribution);
|
|
25
|
+
}
|
|
26
|
+
const bytesUsed = data.counter.getOffset() - initialOffset + initialCounter;
|
|
27
|
+
if (bytesUsed !== size) {
|
|
28
|
+
throw new Error(`Expected stts box to be ${size} bytes, but was ${bytesUsed} bytes`);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
type: 'stts-box',
|
|
32
|
+
sampleDistribution: sampleDistributions,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
exports.parseStts = parseStts;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { BaseBox } from './base-type';
|
|
3
|
+
import type { ThreeDMatrix } from './mvhd';
|
|
4
|
+
export interface TkhdBox extends BaseBox {
|
|
5
|
+
type: 'tkhd-box';
|
|
6
|
+
alternateGroup: number;
|
|
7
|
+
creationTime: number | null;
|
|
8
|
+
duration: number;
|
|
9
|
+
modificationTime: number | null;
|
|
10
|
+
trackId: number;
|
|
11
|
+
version: number;
|
|
12
|
+
layer: number;
|
|
13
|
+
volume: number;
|
|
14
|
+
matrix: ThreeDMatrix;
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const parseTkhd: ({ iterator, offset, size, }: {
|
|
19
|
+
iterator: BufferIterator;
|
|
20
|
+
offset: number;
|
|
21
|
+
size: number;
|
|
22
|
+
}) => TkhdBox;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTkhd = void 0;
|
|
4
|
+
const to_date_1 = require("./to-date");
|
|
5
|
+
const parseTkhd = ({ iterator, offset, size, }) => {
|
|
6
|
+
if (size !== 92) {
|
|
7
|
+
throw new Error(`Expected tkhd size of version 0 to be 92, got ${size}`);
|
|
8
|
+
}
|
|
9
|
+
const version = iterator.getUint8();
|
|
10
|
+
if (version !== 0) {
|
|
11
|
+
throw new Error(`Unsupported TKHD version ${version}`);
|
|
12
|
+
}
|
|
13
|
+
// Flags, we discard them
|
|
14
|
+
iterator.discard(3);
|
|
15
|
+
const creationTime = iterator.getUint32();
|
|
16
|
+
const modificationTime = iterator.getUint32();
|
|
17
|
+
const trackId = iterator.getUint32();
|
|
18
|
+
// reserved
|
|
19
|
+
iterator.discard(4);
|
|
20
|
+
const duration = iterator.getUint32();
|
|
21
|
+
// reserved 2
|
|
22
|
+
iterator.discard(4);
|
|
23
|
+
// reserved 3
|
|
24
|
+
iterator.discard(4);
|
|
25
|
+
const layer = iterator.getUint16();
|
|
26
|
+
const alternateGroup = iterator.getUint16();
|
|
27
|
+
const volume = iterator.getUint16();
|
|
28
|
+
// reserved 4
|
|
29
|
+
iterator.discard(2);
|
|
30
|
+
const matrix = [
|
|
31
|
+
iterator.getUint32(),
|
|
32
|
+
iterator.getUint32(),
|
|
33
|
+
iterator.getUint32(),
|
|
34
|
+
iterator.getUint32(),
|
|
35
|
+
iterator.getUint32(),
|
|
36
|
+
iterator.getUint32(),
|
|
37
|
+
iterator.getUint32(),
|
|
38
|
+
iterator.getUint32(),
|
|
39
|
+
iterator.getUint32(),
|
|
40
|
+
];
|
|
41
|
+
const widthWithoutRotationApplied = iterator.getUint32() / (matrix[0] === 0 ? 1 : matrix[0]);
|
|
42
|
+
const heightWithoutRotationApplied = iterator.getUint32() / (matrix[4] === 0 ? 1 : matrix[4]);
|
|
43
|
+
// TODO: This is not correct, HEVC videos with matrix is wrong
|
|
44
|
+
const width = widthWithoutRotationApplied / (matrix[1] === 0 ? 1 : matrix[1]);
|
|
45
|
+
const height = heightWithoutRotationApplied / (matrix[1] === 0 ? 1 : matrix[1]);
|
|
46
|
+
return {
|
|
47
|
+
offset,
|
|
48
|
+
boxSize: size,
|
|
49
|
+
type: 'tkhd-box',
|
|
50
|
+
creationTime: (0, to_date_1.toUnixTimestamp)(creationTime),
|
|
51
|
+
modificationTime: (0, to_date_1.toUnixTimestamp)(modificationTime),
|
|
52
|
+
trackId,
|
|
53
|
+
duration,
|
|
54
|
+
layer,
|
|
55
|
+
alternateGroup,
|
|
56
|
+
volume,
|
|
57
|
+
matrix: matrix,
|
|
58
|
+
width,
|
|
59
|
+
height,
|
|
60
|
+
version,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
exports.parseTkhd = parseTkhd;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const toUnixTimestamp: (value: number) => number | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toUnixTimestamp = void 0;
|
|
4
|
+
const toUnixTimestamp = (value) => {
|
|
5
|
+
if (value === 0) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const baseDate = new Date('1904-01-01T00:00:00Z');
|
|
9
|
+
return Math.floor(value + baseDate.getTime() / 1000) * 1000;
|
|
10
|
+
};
|
|
11
|
+
exports.toUnixTimestamp = toUnixTimestamp;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { AnySegment } from '../../../parse-result';
|
|
3
|
+
import type { BaseBox } from '../base-type';
|
|
4
|
+
export interface TrakBox extends BaseBox {
|
|
5
|
+
type: 'trak-box';
|
|
6
|
+
children: AnySegment[];
|
|
7
|
+
}
|
|
8
|
+
export declare const parseTrak: ({ data, size, offsetAtStart, }: {
|
|
9
|
+
data: BufferIterator;
|
|
10
|
+
size: number;
|
|
11
|
+
offsetAtStart: number;
|
|
12
|
+
}) => TrakBox;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTrak = void 0;
|
|
4
|
+
const process_box_1 = require("../process-box");
|
|
5
|
+
const parseTrak = ({ data, size, offsetAtStart, }) => {
|
|
6
|
+
const children = (0, process_box_1.parseBoxes)({
|
|
7
|
+
iterator: data,
|
|
8
|
+
maxBytes: size - (data.counter.getOffset() - offsetAtStart),
|
|
9
|
+
allowIncompleteBoxes: false,
|
|
10
|
+
initialBoxes: [],
|
|
11
|
+
});
|
|
12
|
+
if (children.status === 'incomplete') {
|
|
13
|
+
throw new Error('Incomplete boxes are not allowed');
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
offset: offsetAtStart,
|
|
17
|
+
boxSize: size,
|
|
18
|
+
type: 'trak-box',
|
|
19
|
+
children: children.segments,
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
exports.parseTrak = parseTrak;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseWebm = void 0;
|
|
4
|
+
const segments_1 = require("./segments");
|
|
5
|
+
// Parsing according to https://darkcoding.net/software/reading-mediarecorders-webm-opus-output/
|
|
6
|
+
const parseWebm = (counter) => {
|
|
7
|
+
counter.discard(4);
|
|
8
|
+
const length = counter.getEBML();
|
|
9
|
+
if (length !== 31) {
|
|
10
|
+
throw new Error(`Expected header length 31, got ${length}`);
|
|
11
|
+
}
|
|
12
|
+
// Discard header for now
|
|
13
|
+
counter.discard(31);
|
|
14
|
+
return { status: 'done', segments: [(0, segments_1.expectSegment)(counter)] };
|
|
15
|
+
};
|
|
16
|
+
exports.parseWebm = parseWebm;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDurationSegment = void 0;
|
|
4
|
+
const parseDurationSegment = (iterator) => {
|
|
5
|
+
const length = iterator.getVint();
|
|
6
|
+
if (length !== 8) {
|
|
7
|
+
throw new Error('Expected duration segment to be 8 bytes');
|
|
8
|
+
}
|
|
9
|
+
const duration = iterator.getFloat64();
|
|
10
|
+
return {
|
|
11
|
+
type: 'duration-segment',
|
|
12
|
+
duration,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
exports.parseDurationSegment = parseDurationSegment;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { MatroskaSegment } from '../segments';
|
|
3
|
+
export type InfoSegment = {
|
|
4
|
+
type: 'info-segment';
|
|
5
|
+
length: number;
|
|
6
|
+
children: MatroskaSegment[];
|
|
7
|
+
};
|
|
8
|
+
export declare const parseInfoSegment: (iterator: BufferIterator) => InfoSegment;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseInfoSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./parse-children");
|
|
5
|
+
const parseInfoSegment = (iterator) => {
|
|
6
|
+
const length = iterator.getVint();
|
|
7
|
+
const children = (0, parse_children_1.expectChildren)(iterator, length);
|
|
8
|
+
return {
|
|
9
|
+
type: 'info-segment',
|
|
10
|
+
length,
|
|
11
|
+
children,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
exports.parseInfoSegment = parseInfoSegment;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import { type MatroskaSegment } from '../segments';
|
|
3
|
+
export type MainSegment = {
|
|
4
|
+
type: 'main-segment';
|
|
5
|
+
children: MatroskaSegment[];
|
|
6
|
+
};
|
|
7
|
+
export declare const parseMainSegment: (iterator: BufferIterator) => MainSegment;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMainSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./parse-children");
|
|
5
|
+
const parseMainSegment = (iterator) => {
|
|
6
|
+
const length = iterator.getVint();
|
|
7
|
+
const children = (0, parse_children_1.expectChildren)(iterator, length);
|
|
8
|
+
return {
|
|
9
|
+
type: 'main-segment',
|
|
10
|
+
children,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.parseMainSegment = parseMainSegment;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMuxingSegment = void 0;
|
|
4
|
+
const parseMuxingSegment = (iterator) => {
|
|
5
|
+
const length = iterator.getVint();
|
|
6
|
+
const value = iterator.getByteString(length);
|
|
7
|
+
return {
|
|
8
|
+
type: 'muxing-app-segment',
|
|
9
|
+
value,
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
exports.parseMuxingSegment = parseMuxingSegment;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expectChildren = void 0;
|
|
4
|
+
const segments_1 = require("../segments");
|
|
5
|
+
const expectChildren = (iterator, length) => {
|
|
6
|
+
const children = [];
|
|
7
|
+
const startOffset = iterator.counter.getOffset();
|
|
8
|
+
while (iterator.counter.getOffset() < startOffset + length) {
|
|
9
|
+
const child = (0, segments_1.expectSegment)(iterator);
|
|
10
|
+
children.push(child);
|
|
11
|
+
if (child.type === 'unknown-segment') {
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return children;
|
|
16
|
+
};
|
|
17
|
+
exports.expectChildren = expectChildren;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import { type MatroskaSegment } from '../segments';
|
|
3
|
+
export type SeekHeadSegment = {
|
|
4
|
+
type: 'seek-head-segment';
|
|
5
|
+
children: MatroskaSegment[];
|
|
6
|
+
length: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const parseSeekHeadSegment: (iterator: BufferIterator) => SeekHeadSegment;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSeekHeadSegment = void 0;
|
|
4
|
+
const parse_children_1 = require("./parse-children");
|
|
5
|
+
const parseSeekHeadSegment = (iterator) => {
|
|
6
|
+
const length = iterator.getVint();
|
|
7
|
+
return {
|
|
8
|
+
type: 'seek-head-segment',
|
|
9
|
+
length,
|
|
10
|
+
children: (0, parse_children_1.expectChildren)(iterator, length),
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.parseSeekHeadSegment = parseSeekHeadSegment;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSeekPositionSegment = void 0;
|
|
4
|
+
const parseSeekPositionSegment = (iterator) => {
|
|
5
|
+
const length = iterator.getVint();
|
|
6
|
+
const seekPosition = iterator.getDecimalBytes(length);
|
|
7
|
+
return {
|
|
8
|
+
type: 'seek-position-segment',
|
|
9
|
+
seekPosition,
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
exports.parseSeekPositionSegment = parseSeekPositionSegment;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
import type { MatroskaSegment } from '../segments';
|
|
3
|
+
export type SeekSegment = {
|
|
4
|
+
type: 'seek-segment';
|
|
5
|
+
seekId: string;
|
|
6
|
+
child: MatroskaSegment;
|
|
7
|
+
};
|
|
8
|
+
export declare const parseSeekSegment: (iterator: BufferIterator) => SeekSegment;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSeekSegment = void 0;
|
|
4
|
+
const segments_1 = require("../segments");
|
|
5
|
+
const parseSeekSegment = (iterator) => {
|
|
6
|
+
// length
|
|
7
|
+
iterator.discard(4);
|
|
8
|
+
const seekId = iterator.getMatroskaSegmentId();
|
|
9
|
+
const child = (0, segments_1.expectSegment)(iterator);
|
|
10
|
+
return {
|
|
11
|
+
type: 'seek-segment',
|
|
12
|
+
seekId,
|
|
13
|
+
child,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
exports.parseSeekSegment = parseSeekSegment;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../../buffer-iterator';
|
|
2
|
+
export type TimestampScaleSegment = {
|
|
3
|
+
type: 'timestamp-scale-segment';
|
|
4
|
+
timestampScale: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const parseTimestampScaleSegment: (iterator: BufferIterator) => TimestampScaleSegment;
|