@remotion/media-parser 4.0.209 → 4.0.210
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/buffer.js +2 -0
- package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +1 -1
- package/dist/boxes/iso-base-media/make-track.js +14 -2
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +8 -3
- package/dist/boxes/iso-base-media/moov/moov.d.ts +2 -1
- package/dist/boxes/iso-base-media/moov/moov.js +2 -1
- package/dist/boxes/iso-base-media/process-box.d.ts +6 -3
- package/dist/boxes/iso-base-media/process-box.js +20 -5
- package/dist/boxes/iso-base-media/stsd/avcc.d.ts +1 -1
- package/dist/boxes/iso-base-media/stsd/avcc.js +2 -2
- package/dist/boxes/iso-base-media/stsd/ctts.js +2 -5
- package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +1 -1
- package/dist/boxes/iso-base-media/stsd/hvcc.js +2 -2
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +4 -2
- package/dist/boxes/iso-base-media/stsd/samples.js +69 -11
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +2 -1
- package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
- package/dist/boxes/iso-base-media/trak/trak.d.ts +2 -1
- package/dist/boxes/iso-base-media/trak/trak.js +2 -1
- package/dist/boxes/iso-base-media/traversal.d.ts +44 -0
- package/dist/boxes/iso-base-media/traversal.js +211 -0
- package/dist/boxes/webm/color.d.ts +4 -0
- package/dist/boxes/webm/color.js +120 -0
- package/dist/boxes/webm/description.js +1 -1
- package/dist/boxes/webm/get-ready-tracks.js +3 -3
- package/dist/boxes/webm/get-sample-from-block.js +1 -1
- package/dist/boxes/webm/get-track.js +16 -1
- package/dist/boxes/webm/make-track.d.ts +9 -0
- package/dist/boxes/webm/make-track.js +260 -0
- package/dist/boxes/webm/parse-ebml.js +2 -2
- package/dist/boxes/webm/segments/all-segments.d.ts +36 -3
- package/dist/boxes/webm/segments/all-segments.js +34 -6
- package/dist/boxes/webm/traversal.d.ts +26 -1
- package/dist/boxes/webm/traversal.js +214 -1
- package/dist/create/cluster-segment.js +0 -2
- package/dist/create/cluster.d.ts +10 -2
- package/dist/create/cluster.js +16 -10
- package/dist/create/create-media.d.ts +4 -2
- package/dist/create/create-media.js +76 -14
- package/dist/create/cues.d.ts +0 -0
- package/dist/create/cues.js +1 -0
- package/dist/create/make-duration-with-padding.d.ts +1 -1
- package/dist/create/make-duration-with-padding.js +3 -3
- package/dist/create/matroska-cues.d.ts +6 -0
- package/dist/create/matroska-cues.js +50 -0
- package/dist/create/matroska-info.js +1 -1
- package/dist/create/matroska-seek.d.ts +6 -0
- package/dist/create/matroska-seek.js +32 -0
- package/dist/create/matroska-segment.d.ts +1 -0
- package/dist/create/matroska-segment.js +3 -2
- package/dist/create/matroska-trackentry.d.ts +9 -14
- package/dist/create/matroska-trackentry.js +79 -94
- package/dist/emit-available-info.d.ts +12 -0
- package/dist/emit-available-info.js +133 -0
- package/dist/esm/buffer.mjs +57 -0
- package/dist/esm/from-fetch.mjs +72 -0
- package/dist/esm/from-node.mjs +48 -0
- package/dist/esm/from-web-file.mjs +48 -0
- package/dist/esm/index.mjs +6689 -0
- package/dist/esm/web-fs.mjs +67 -0
- package/dist/get-audio-codec.d.ts +5 -5
- package/dist/get-audio-codec.js +41 -57
- package/dist/get-container.d.ts +4 -0
- package/dist/get-container.js +26 -0
- package/dist/get-duration.js +1 -1
- package/dist/get-fps.js +1 -1
- package/dist/get-sample-aspect-ratio.d.ts +1 -1
- package/dist/get-sample-aspect-ratio.js +19 -19
- package/dist/get-tracks.d.ts +13 -0
- package/dist/get-tracks.js +8 -8
- package/dist/get-video-codec.d.ts +5 -2
- package/dist/get-video-codec.js +111 -21
- package/dist/has-all-info.d.ts +2 -2
- package/dist/has-all-info.js +23 -9
- package/dist/index.d.ts +3 -1
- package/dist/options.d.ts +97 -30
- package/dist/parse-media.js +43 -62
- package/dist/parse-video.d.ts +2 -1
- package/dist/parse-video.js +3 -1
- package/dist/parser-state.js +1 -2
- package/dist/readers/from-fetch.js +24 -4
- package/dist/readers/from-node.js +13 -3
- package/dist/readers/from-web-file.js +14 -2
- package/dist/readers/reader.d.ts +6 -1
- package/dist/samples-from-moof.js +1 -1
- package/dist/traversal.d.ts +0 -21
- package/dist/traversal.js +1 -158
- package/dist/truthy.d.ts +3 -0
- package/dist/truthy.js +7 -0
- package/dist/writers/buffer.d.ts +2 -0
- package/dist/writers/buffer.js +58 -0
- package/dist/writers/web-fs.d.ts +1 -0
- package/dist/writers/web-fs.js +42 -18
- package/dist/writers/writer.d.ts +4 -2
- package/fetch.js +2 -0
- package/node.js +2 -0
- package/package.json +43 -8
- package/web-file.js +2 -0
- package/web-fs.js +2 -0
- package/.eslintrc +0 -8
- package/input.webm +0 -0
- package/src/add-new-matroska-tracks.ts +0 -23
- package/src/boxes/iso-base-media/base-type.ts +0 -4
- package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +0 -68
- package/src/boxes/iso-base-media/esds/esds-descriptors.ts +0 -135
- package/src/boxes/iso-base-media/esds/esds.ts +0 -49
- package/src/boxes/iso-base-media/ftyp.ts +0 -39
- package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +0 -69
- package/src/boxes/iso-base-media/make-track.ts +0 -116
- package/src/boxes/iso-base-media/mdat/mdat.ts +0 -140
- package/src/boxes/iso-base-media/mdhd.ts +0 -59
- package/src/boxes/iso-base-media/moov/moov.ts +0 -43
- package/src/boxes/iso-base-media/mvhd.ts +0 -114
- package/src/boxes/iso-base-media/process-box.ts +0 -748
- package/src/boxes/iso-base-media/stsd/av1c.ts +0 -19
- package/src/boxes/iso-base-media/stsd/avcc.ts +0 -36
- package/src/boxes/iso-base-media/stsd/colr.ts +0 -49
- package/src/boxes/iso-base-media/stsd/ctts.ts +0 -64
- package/src/boxes/iso-base-media/stsd/hvcc.ts +0 -32
- package/src/boxes/iso-base-media/stsd/keys.ts +0 -27
- package/src/boxes/iso-base-media/stsd/mebx.ts +0 -54
- package/src/boxes/iso-base-media/stsd/pasp.ts +0 -32
- package/src/boxes/iso-base-media/stsd/samples.ts +0 -359
- package/src/boxes/iso-base-media/stsd/stco.ts +0 -52
- package/src/boxes/iso-base-media/stsd/stsc.ts +0 -61
- package/src/boxes/iso-base-media/stsd/stsd.ts +0 -55
- package/src/boxes/iso-base-media/stsd/stss.ts +0 -47
- package/src/boxes/iso-base-media/stsd/stsz.ts +0 -75
- package/src/boxes/iso-base-media/stsd/stts.ts +0 -62
- package/src/boxes/iso-base-media/tfdt.ts +0 -37
- package/src/boxes/iso-base-media/tfhd.ts +0 -66
- package/src/boxes/iso-base-media/tkhd.ts +0 -150
- package/src/boxes/iso-base-media/to-date.ts +0 -9
- package/src/boxes/iso-base-media/trak/trak.ts +0 -43
- package/src/boxes/iso-base-media/trun.ts +0 -74
- package/src/boxes/iso-base-media/void-box.ts +0 -4
- package/src/boxes/webm/allowed-partial-segments.ts +0 -1
- package/src/boxes/webm/av1-codec-private.ts +0 -113
- package/src/boxes/webm/description.ts +0 -104
- package/src/boxes/webm/ebml.ts +0 -98
- package/src/boxes/webm/get-ready-tracks.ts +0 -36
- package/src/boxes/webm/get-sample-from-block.ts +0 -125
- package/src/boxes/webm/get-track.ts +0 -257
- package/src/boxes/webm/make-header.ts +0 -253
- package/src/boxes/webm/parse-ebml.ts +0 -259
- package/src/boxes/webm/parse-webm-header.ts +0 -18
- package/src/boxes/webm/segments/all-segments.ts +0 -888
- package/src/boxes/webm/segments/block-simple-block-flags.ts +0 -52
- package/src/boxes/webm/segments/parse-children.ts +0 -144
- package/src/boxes/webm/segments/track-entry.ts +0 -38
- package/src/boxes/webm/segments.ts +0 -147
- package/src/boxes/webm/traversal.ts +0 -45
- package/src/buffer-iterator.ts +0 -555
- package/src/create/cluster-segment.ts +0 -62
- package/src/create/cluster.ts +0 -64
- package/src/create/create-media.ts +0 -136
- package/src/create/make-duration-with-padding.ts +0 -15
- package/src/create/matroska-header.ts +0 -63
- package/src/create/matroska-info.ts +0 -30
- package/src/create/matroska-segment.ts +0 -10
- package/src/create/matroska-trackentry.ts +0 -325
- package/src/create/timescale.ts +0 -1
- package/src/get-audio-codec.ts +0 -270
- package/src/get-dimensions.ts +0 -47
- package/src/get-duration.ts +0 -103
- package/src/get-fps.ts +0 -113
- package/src/get-sample-aspect-ratio.ts +0 -204
- package/src/get-sample-positions.ts +0 -93
- package/src/get-tracks.ts +0 -147
- package/src/get-video-codec.ts +0 -117
- package/src/has-all-info.ts +0 -81
- package/src/index.ts +0 -18
- package/src/make-hvc1-codec-strings.ts +0 -55
- package/src/options.ts +0 -118
- package/src/parse-media.ts +0 -183
- package/src/parse-result.ts +0 -79
- package/src/parse-video.ts +0 -83
- package/src/parser-context.ts +0 -10
- package/src/parser-state.ts +0 -178
- package/src/readers/from-fetch.ts +0 -90
- package/src/readers/from-node.ts +0 -51
- package/src/readers/from-web-file.ts +0 -49
- package/src/readers/reader.ts +0 -15
- package/src/samples-from-moof.ts +0 -102
- package/src/test/aspect-ratio.test.ts +0 -42
- package/src/test/av1.test.ts +0 -108
- package/src/test/create-matroska.test.ts +0 -287
- package/src/test/duration.test.ts +0 -18
- package/src/test/keys.test.ts +0 -47
- package/src/test/matroska.test.ts +0 -463
- package/src/test/mvhd.test.ts +0 -94
- package/src/test/parse-esds.test.ts +0 -98
- package/src/test/parse-stco.test.ts +0 -61
- package/src/test/parse-stsc.test.ts +0 -104
- package/src/test/parse-stsz.test.ts +0 -57
- package/src/test/parse-stts.test.ts +0 -38
- package/src/test/parse-video.test.ts +0 -101
- package/src/test/parse-webm.test.ts +0 -17
- package/src/test/samples-from-moof.test.ts +0 -2496
- package/src/test/stream-local.test.ts +0 -743
- package/src/test/stream-remote.test.ts +0 -59
- package/src/test/stream-samples.test.ts +0 -181
- package/src/test/stsd.test.ts +0 -265
- package/src/test/tkhd.test.ts +0 -87
- package/src/traversal.ts +0 -528
- package/src/webcodec-sample-types.ts +0 -29
- package/src/writers/web-fs.ts +0 -50
- package/src/writers/writer.ts +0 -12
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
package/src/get-audio-codec.ts
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-depth */
|
|
2
|
-
import type {EsdsBox} from './boxes/iso-base-media/esds/esds';
|
|
3
|
-
import type {MoovBox} from './boxes/iso-base-media/moov/moov';
|
|
4
|
-
import type {AudioSample} from './boxes/iso-base-media/stsd/samples';
|
|
5
|
-
import type {TrakBox} from './boxes/iso-base-media/trak/trak';
|
|
6
|
-
import type {MainSegment} from './boxes/webm/segments/all-segments';
|
|
7
|
-
import {trakBoxContainsAudio} from './get-fps';
|
|
8
|
-
import type {KnownAudioCodecs} from './options';
|
|
9
|
-
import type {AnySegment} from './parse-result';
|
|
10
|
-
import {getMoovBox, getStsdBox, getTraks} from './traversal';
|
|
11
|
-
|
|
12
|
-
export const hasAudioCodec = (boxes: AnySegment[]): boolean => {
|
|
13
|
-
try {
|
|
14
|
-
return getAudioCodec(boxes) !== null;
|
|
15
|
-
} catch (e) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const getCodecSpecificatorFromEsdsBox = ({
|
|
21
|
-
child,
|
|
22
|
-
}: {
|
|
23
|
-
child: EsdsBox;
|
|
24
|
-
}): {
|
|
25
|
-
primary: number;
|
|
26
|
-
secondary: number | null;
|
|
27
|
-
description: Uint8Array | undefined;
|
|
28
|
-
} => {
|
|
29
|
-
const descriptor = child.descriptors.find(
|
|
30
|
-
(d) => d.type === 'decoder-config-descriptor',
|
|
31
|
-
);
|
|
32
|
-
if (!descriptor) {
|
|
33
|
-
throw new Error('No decoder-config-descriptor');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (descriptor.type !== 'decoder-config-descriptor') {
|
|
37
|
-
throw new Error('Expected decoder-config-descriptor');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (descriptor.asNumber !== 0x40) {
|
|
41
|
-
return {
|
|
42
|
-
primary: descriptor.asNumber,
|
|
43
|
-
secondary: null,
|
|
44
|
-
description: undefined,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const audioSpecificConfig = descriptor.decoderSpecificConfigs.find((d) => {
|
|
49
|
-
return d.type === 'audio-specific-config' ? d : null;
|
|
50
|
-
});
|
|
51
|
-
if (
|
|
52
|
-
!audioSpecificConfig ||
|
|
53
|
-
audioSpecificConfig.type !== 'audio-specific-config'
|
|
54
|
-
) {
|
|
55
|
-
throw new Error('No audio-specific-config');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
primary: descriptor.asNumber,
|
|
60
|
-
secondary: audioSpecificConfig.audioObjectType,
|
|
61
|
-
description: audioSpecificConfig.asBytes,
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
type AudioCodecInfo = {
|
|
66
|
-
format: string;
|
|
67
|
-
primarySpecificator: number | null;
|
|
68
|
-
secondarySpecificator: number | null;
|
|
69
|
-
description: Uint8Array | undefined;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const onSample = (
|
|
73
|
-
sample: AudioSample,
|
|
74
|
-
children: AnySegment[],
|
|
75
|
-
): AudioCodecInfo | null => {
|
|
76
|
-
const child = children.find((c) => c.type === 'esds-box');
|
|
77
|
-
|
|
78
|
-
if (child && child.type === 'esds-box') {
|
|
79
|
-
const ret = getCodecSpecificatorFromEsdsBox({child});
|
|
80
|
-
return {
|
|
81
|
-
format: sample.format,
|
|
82
|
-
primarySpecificator: ret.primary,
|
|
83
|
-
secondarySpecificator: ret.secondary,
|
|
84
|
-
description: ret.description,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
format: sample.format,
|
|
90
|
-
primarySpecificator: null,
|
|
91
|
-
secondarySpecificator: null,
|
|
92
|
-
description: undefined,
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export const getNumberOfChannelsFromTrak = (trak: TrakBox): number | null => {
|
|
97
|
-
const stsdBox = getStsdBox(trak);
|
|
98
|
-
if (!stsdBox) {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
103
|
-
if (!sample || sample.type !== 'audio') {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return sample.numberOfChannels;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export const getSampleRate = (trak: TrakBox): number | null => {
|
|
111
|
-
const stsdBox = getStsdBox(trak);
|
|
112
|
-
if (!stsdBox) {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
117
|
-
if (!sample || sample.type !== 'audio') {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return sample.sampleRate;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export const getAudioCodecFromTrak = (trak: TrakBox): AudioCodecInfo | null => {
|
|
125
|
-
const stsdBox = getStsdBox(trak);
|
|
126
|
-
if (!stsdBox) {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
131
|
-
if (!sample || sample.type !== 'audio') {
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const waveBox = sample.children.find(
|
|
136
|
-
(b) => b.type === 'regular-box' && b.boxType === 'wave',
|
|
137
|
-
);
|
|
138
|
-
if (waveBox && waveBox.type === 'regular-box' && waveBox.boxType === 'wave') {
|
|
139
|
-
const esdsSample = onSample(sample, waveBox.children);
|
|
140
|
-
if (esdsSample) {
|
|
141
|
-
return esdsSample;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const ret = onSample(sample, sample.children);
|
|
146
|
-
if (ret) {
|
|
147
|
-
return ret;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return null;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export const getAudioCodecFromIso = (moov: MoovBox) => {
|
|
154
|
-
const traks = getTraks(moov);
|
|
155
|
-
const trakBox = traks.find(
|
|
156
|
-
(b) => b.type === 'trak-box' && trakBoxContainsAudio(b),
|
|
157
|
-
);
|
|
158
|
-
if (!trakBox) {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return getAudioCodecFromTrak(trakBox);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
export const getAudioCodecFromMatroska = (mainSegment: MainSegment) => {
|
|
166
|
-
const tracksSegment = mainSegment.value.find((b) => b.type === 'Tracks');
|
|
167
|
-
if (!tracksSegment || tracksSegment.type !== 'Tracks') {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
for (const track of tracksSegment.value) {
|
|
172
|
-
if (track.type === 'TrackEntry') {
|
|
173
|
-
const trackType = track.value.find((b) => b.type === 'CodecID');
|
|
174
|
-
if (trackType && trackType.type === 'CodecID') {
|
|
175
|
-
if (trackType.value === 'A_OPUS') {
|
|
176
|
-
return 'opus';
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (trackType.value === 'A_VORBIS') {
|
|
180
|
-
return 'vorbis';
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (trackType.value === 'A_PCM/INT/LIT') {
|
|
184
|
-
return 'pcm';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (trackType.value === 'A_AAC') {
|
|
188
|
-
return 'aac';
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (trackType.value === 'A_MPEG/L3') {
|
|
192
|
-
return 'mp3';
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return null;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
export const getAudioCodecStringFromTrak = (
|
|
202
|
-
trak: TrakBox,
|
|
203
|
-
): {codecString: string; description: Uint8Array | undefined} => {
|
|
204
|
-
const codec = getAudioCodecFromTrak(trak);
|
|
205
|
-
if (!codec) {
|
|
206
|
-
throw new Error('Expected codec');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const codecStringWithoutMp3Exception = (
|
|
210
|
-
[
|
|
211
|
-
codec.format,
|
|
212
|
-
codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
|
|
213
|
-
codec.secondarySpecificator
|
|
214
|
-
? codec.secondarySpecificator.toString().padStart(2, '0')
|
|
215
|
-
: null,
|
|
216
|
-
].filter(Boolean) as string[]
|
|
217
|
-
).join('.');
|
|
218
|
-
|
|
219
|
-
// Really, MP3? 😔
|
|
220
|
-
const codecString =
|
|
221
|
-
codecStringWithoutMp3Exception === 'mp4a.6b'
|
|
222
|
-
? 'mp3' // or "mp4a.6B" would also work, with the uppercasing, but mp3 is probably more obvious
|
|
223
|
-
: codecStringWithoutMp3Exception;
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
codecString,
|
|
227
|
-
description: codec.description,
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
export const getAudioCodec = (boxes: AnySegment[]): KnownAudioCodecs | null => {
|
|
232
|
-
const moovBox = getMoovBox(boxes);
|
|
233
|
-
|
|
234
|
-
if (moovBox) {
|
|
235
|
-
const codec = getAudioCodecFromIso(moovBox);
|
|
236
|
-
|
|
237
|
-
if (!codec) {
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (codec.format === 'sowt') {
|
|
242
|
-
return 'aiff';
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (codec.format === 'mp4a') {
|
|
246
|
-
if (codec.primarySpecificator === 0x40) {
|
|
247
|
-
return 'aac';
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (codec.primarySpecificator === 0x6b) {
|
|
251
|
-
return 'mp3';
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (codec.primarySpecificator === null) {
|
|
255
|
-
return 'aac';
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
throw new Error('Unknown mp4a codec: ' + codec.primarySpecificator);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
throw new Error('Unknown audio format: ' + codec.format);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const mainSegment = boxes.find((b) => b.type === 'Segment');
|
|
265
|
-
if (!mainSegment || mainSegment.type !== 'Segment') {
|
|
266
|
-
return null;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return getAudioCodecFromMatroska(mainSegment);
|
|
270
|
-
};
|
package/src/get-dimensions.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import {getTracks} from './get-tracks';
|
|
2
|
-
import type {AnySegment} from './parse-result';
|
|
3
|
-
import type {ParserState} from './parser-state';
|
|
4
|
-
|
|
5
|
-
export type Dimensions = {
|
|
6
|
-
width: number;
|
|
7
|
-
height: number;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type ExpandedDimensions = Dimensions & {
|
|
11
|
-
rotation: number;
|
|
12
|
-
unrotatedWidth: number;
|
|
13
|
-
unrotatedHeight: number;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const getDimensions = (
|
|
17
|
-
boxes: AnySegment[],
|
|
18
|
-
state: ParserState,
|
|
19
|
-
): ExpandedDimensions => {
|
|
20
|
-
const {videoTracks} = getTracks(boxes, state);
|
|
21
|
-
if (!videoTracks.length) {
|
|
22
|
-
throw new Error('Expected video track');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const firstVideoTrack = videoTracks[0];
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
width: firstVideoTrack.width,
|
|
29
|
-
height: firstVideoTrack.height,
|
|
30
|
-
rotation: firstVideoTrack.rotation,
|
|
31
|
-
unrotatedHeight: firstVideoTrack.displayAspectHeight,
|
|
32
|
-
unrotatedWidth: firstVideoTrack.displayAspectWidth,
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
// TODO: An audio track should return 'hasDimensions' = true on an audio file
|
|
37
|
-
// and stop parsing
|
|
38
|
-
export const hasDimensions = (
|
|
39
|
-
boxes: AnySegment[],
|
|
40
|
-
state: ParserState,
|
|
41
|
-
): boolean => {
|
|
42
|
-
try {
|
|
43
|
-
return getDimensions(boxes, state) !== null;
|
|
44
|
-
} catch (err) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
};
|
package/src/get-duration.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {getSamplePositionsFromTrack} from './boxes/iso-base-media/get-sample-positions-from-track';
|
|
2
|
-
import type {TrakBox} from './boxes/iso-base-media/trak/trak';
|
|
3
|
-
import type {DurationSegment} from './boxes/webm/segments/all-segments';
|
|
4
|
-
import {getTracks} from './get-tracks';
|
|
5
|
-
import type {AnySegment} from './parse-result';
|
|
6
|
-
import type {ParserState} from './parser-state';
|
|
7
|
-
import {getMoofBox, getMoovBox, getMvhdBox} from './traversal';
|
|
8
|
-
|
|
9
|
-
const getDurationFromMatroska = (segments: AnySegment[]): number | null => {
|
|
10
|
-
const mainSegment = segments.find((s) => s.type === 'Segment');
|
|
11
|
-
if (!mainSegment || mainSegment.type !== 'Segment') {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const {value: children} = mainSegment;
|
|
16
|
-
if (!children) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const infoSegment = children.find((s) => s.type === 'Info');
|
|
21
|
-
|
|
22
|
-
const relevantBoxes = [
|
|
23
|
-
...mainSegment.value,
|
|
24
|
-
...(infoSegment && infoSegment.type === 'Info' ? infoSegment.value : []),
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
const timestampScale = relevantBoxes.find((s) => s.type === 'TimestampScale');
|
|
28
|
-
if (!timestampScale || timestampScale.type !== 'TimestampScale') {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const duration = relevantBoxes.find(
|
|
33
|
-
(s) => s.type === 'Duration',
|
|
34
|
-
) as DurationSegment;
|
|
35
|
-
if (!duration || duration.type !== 'Duration') {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (duration.value.value / timestampScale.value.value) * 1000;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const getDuration = (
|
|
43
|
-
boxes: AnySegment[],
|
|
44
|
-
parserState: ParserState,
|
|
45
|
-
): number | null => {
|
|
46
|
-
const matroskaBox = boxes.find((b) => b.type === 'Segment');
|
|
47
|
-
if (matroskaBox) {
|
|
48
|
-
return getDurationFromMatroska(boxes);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const moovBox = getMoovBox(boxes);
|
|
52
|
-
if (!moovBox) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const moofBox = getMoofBox(boxes);
|
|
57
|
-
const mvhdBox = getMvhdBox(moovBox);
|
|
58
|
-
|
|
59
|
-
if (!mvhdBox) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (mvhdBox.type !== 'mvhd-box') {
|
|
64
|
-
throw new Error('Expected mvhd-box');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (mvhdBox.durationInSeconds > 0) {
|
|
68
|
-
return mvhdBox.durationInSeconds;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const tracks = getTracks(boxes, parserState);
|
|
72
|
-
const allTracks = [
|
|
73
|
-
...tracks.videoTracks,
|
|
74
|
-
...tracks.audioTracks,
|
|
75
|
-
...tracks.otherTracks,
|
|
76
|
-
];
|
|
77
|
-
const allSamples = allTracks.map((t) => {
|
|
78
|
-
const {timescale: ts} = t;
|
|
79
|
-
const samplePositions = getSamplePositionsFromTrack(
|
|
80
|
-
t.trakBox as TrakBox,
|
|
81
|
-
moofBox,
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
const highest = samplePositions
|
|
85
|
-
?.map((sp) => (sp.cts + sp.duration) / ts)
|
|
86
|
-
.reduce((a, b) => Math.max(a, b), 0);
|
|
87
|
-
return highest ?? 0;
|
|
88
|
-
});
|
|
89
|
-
const highestTimestamp = Math.max(...allSamples);
|
|
90
|
-
return highestTimestamp;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const hasDuration = (
|
|
94
|
-
boxes: AnySegment[],
|
|
95
|
-
parserState: ParserState,
|
|
96
|
-
): boolean => {
|
|
97
|
-
try {
|
|
98
|
-
const duration = getDuration(boxes, parserState);
|
|
99
|
-
return getDuration(boxes, parserState) !== null && duration !== 0;
|
|
100
|
-
} catch (err) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
};
|
package/src/get-fps.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import type {SttsBox} from './boxes/iso-base-media/stsd/stts';
|
|
2
|
-
import type {TrakBox} from './boxes/iso-base-media/trak/trak';
|
|
3
|
-
import type {AnySegment} from './parse-result';
|
|
4
|
-
import {
|
|
5
|
-
getMdhdBox,
|
|
6
|
-
getMoovBox,
|
|
7
|
-
getStsdBox,
|
|
8
|
-
getSttsBox,
|
|
9
|
-
getTraks,
|
|
10
|
-
} from './traversal';
|
|
11
|
-
|
|
12
|
-
const calculateFps = ({
|
|
13
|
-
sttsBox,
|
|
14
|
-
timeScale,
|
|
15
|
-
durationInSamples,
|
|
16
|
-
}: {
|
|
17
|
-
sttsBox: SttsBox;
|
|
18
|
-
timeScale: number;
|
|
19
|
-
durationInSamples: number;
|
|
20
|
-
}) => {
|
|
21
|
-
let totalSamples = 0;
|
|
22
|
-
|
|
23
|
-
for (const sample of sttsBox.sampleDistribution) {
|
|
24
|
-
totalSamples += sample.sampleCount;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const durationInSeconds = durationInSamples / timeScale;
|
|
28
|
-
const fps = totalSamples / durationInSeconds;
|
|
29
|
-
|
|
30
|
-
return fps;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
type TimescaleAndDuration = {
|
|
34
|
-
timescale: number;
|
|
35
|
-
duration: number;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const trakBoxContainsAudio = (trakBox: TrakBox): boolean => {
|
|
39
|
-
const stsd = getStsdBox(trakBox);
|
|
40
|
-
if (!stsd) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const videoSample = stsd.samples.find((s) => s.type === 'audio');
|
|
45
|
-
if (!videoSample || videoSample.type !== 'audio') {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return true;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const trakBoxContainsVideo = (trakBox: TrakBox): boolean => {
|
|
53
|
-
const stsd = getStsdBox(trakBox);
|
|
54
|
-
if (!stsd) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const videoSample = stsd.samples.find((s) => s.type === 'video');
|
|
59
|
-
if (!videoSample || videoSample.type !== 'video') {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return true;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const getTimescaleAndDuration = (
|
|
67
|
-
trakBox: TrakBox,
|
|
68
|
-
): TimescaleAndDuration | null => {
|
|
69
|
-
const mdhdBox = getMdhdBox(trakBox);
|
|
70
|
-
if (mdhdBox) {
|
|
71
|
-
return {timescale: mdhdBox.timescale, duration: mdhdBox.duration};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return null;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const getFps = (segments: AnySegment[]) => {
|
|
78
|
-
const moovBox = getMoovBox(segments);
|
|
79
|
-
if (!moovBox) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const trackBoxes = getTraks(moovBox);
|
|
84
|
-
|
|
85
|
-
const trackBox = trackBoxes.find(trakBoxContainsVideo);
|
|
86
|
-
if (!trackBox) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const timescaleAndDuration = getTimescaleAndDuration(trackBox);
|
|
91
|
-
if (!timescaleAndDuration) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const sttsBox = getSttsBox(trackBox);
|
|
96
|
-
if (!sttsBox) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return calculateFps({
|
|
101
|
-
sttsBox,
|
|
102
|
-
timeScale: timescaleAndDuration.timescale,
|
|
103
|
-
durationInSamples: timescaleAndDuration.duration,
|
|
104
|
-
});
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export const hasFps = (boxes: AnySegment[]): boolean => {
|
|
108
|
-
try {
|
|
109
|
-
return getFps(boxes) !== null;
|
|
110
|
-
} catch (err) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
};
|