@remotion/media-parser 4.0.194 → 4.0.196
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/add-new-matroska-tracks.d.ts +8 -0
- package/dist/add-new-matroska-tracks.js +14 -0
- package/dist/av1-codec-string.d.ts +3 -0
- package/dist/av1-codec-string.js +91 -0
- package/dist/boxes/iso-base-media/esds/decoder-specific-config.d.ts +14 -0
- package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +38 -0
- package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +8 -0
- package/dist/boxes/iso-base-media/esds/esds-descriptors.js +22 -2
- package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
- package/dist/boxes/iso-base-media/ftype.js +31 -0
- package/dist/boxes/iso-base-media/make-track.d.ts +3 -0
- package/dist/boxes/iso-base-media/make-track.js +112 -0
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +6 -2
- package/dist/boxes/iso-base-media/mdat/mdat.js +90 -6
- package/dist/boxes/iso-base-media/moov/moov.d.ts +4 -2
- package/dist/boxes/iso-base-media/moov/moov.js +4 -2
- package/dist/boxes/iso-base-media/mvhd.js +7 -1
- package/dist/boxes/iso-base-media/process-box.d.ts +20 -3
- package/dist/boxes/iso-base-media/process-box.js +322 -34
- package/dist/boxes/iso-base-media/stsd/av1c.d.ts +9 -0
- package/dist/boxes/iso-base-media/stsd/av1c.js +10 -0
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +20 -0
- package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +73 -0
- package/dist/boxes/iso-base-media/stsd/avcc.d.ts +10 -0
- package/dist/boxes/iso-base-media/stsd/avcc.js +21 -0
- package/dist/boxes/iso-base-media/stsd/colr.d.ts +11 -0
- package/dist/boxes/iso-base-media/stsd/colr.js +35 -0
- package/dist/boxes/iso-base-media/stsd/ctts.d.ts +19 -0
- package/dist/boxes/iso-base-media/stsd/ctts.js +30 -0
- package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +11 -0
- package/dist/boxes/iso-base-media/stsd/hvcc.js +17 -0
- package/dist/boxes/iso-base-media/stsd/keys.js +1 -0
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +4 -2
- package/dist/boxes/iso-base-media/stsd/mebx.js +4 -2
- package/dist/boxes/iso-base-media/stsd/pasp.d.ts +12 -0
- package/dist/boxes/iso-base-media/stsd/pasp.js +17 -0
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +12 -5
- package/dist/boxes/iso-base-media/stsd/samples.js +27 -10
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +4 -2
- package/dist/boxes/iso-base-media/stsd/stsd.js +6 -2
- package/dist/boxes/iso-base-media/stsd/stss.d.ts +13 -0
- package/dist/boxes/iso-base-media/stsd/stss.js +28 -0
- package/dist/boxes/iso-base-media/stsd/stsz.d.ts +9 -3
- package/dist/boxes/iso-base-media/stsd/stsz.js +14 -2
- package/dist/boxes/iso-base-media/stsd/stts.d.ts +15 -0
- package/dist/boxes/iso-base-media/stsd/stts.js +35 -0
- package/dist/boxes/iso-base-media/tkhd.d.ts +3 -0
- package/dist/boxes/iso-base-media/tkhd.js +41 -14
- package/dist/boxes/iso-base-media/trak/trak.d.ts +4 -2
- package/dist/boxes/iso-base-media/trak/trak.js +4 -2
- package/dist/boxes/iso-base-media/void-box.d.ts +4 -0
- package/dist/boxes/iso-base-media/void-box.js +2 -0
- package/dist/boxes/webm/allowed-partial-segments.d.ts +1 -0
- package/dist/boxes/webm/allowed-partial-segments.js +4 -0
- package/dist/boxes/webm/av1-codec-private.d.ts +2 -0
- package/dist/boxes/webm/av1-codec-private.js +95 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +14 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +67 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +11 -0
- package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +14 -0
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +6 -0
- package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +9 -0
- package/dist/boxes/webm/bitstream/av1/color-config.d.ts +16 -0
- package/dist/boxes/webm/bitstream/av1/color-config.js +103 -0
- package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +14 -0
- package/dist/boxes/webm/bitstream/av1/color-primaries.js +17 -0
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +9 -0
- package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +17 -0
- package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +51 -0
- package/dist/boxes/webm/bitstream/av1/header-segment.js +183 -0
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +17 -0
- package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +20 -0
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +10 -0
- package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +15 -0
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +5 -0
- package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +8 -0
- package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +8 -0
- package/dist/boxes/webm/bitstream/av1/timing-info.js +20 -0
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +21 -0
- package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +24 -0
- package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +2 -0
- package/dist/boxes/webm/bitstream/av1/uvlc.js +20 -0
- package/dist/boxes/webm/bitstream/av1.d.ts +20 -0
- package/dist/boxes/webm/bitstream/av1.js +118 -0
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
- package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +1 -0
- package/dist/boxes/webm/description.d.ts +2 -0
- package/dist/boxes/webm/description.js +83 -0
- package/dist/boxes/webm/get-ready-tracks.d.ts +3 -0
- package/dist/boxes/webm/get-ready-tracks.js +29 -0
- package/dist/boxes/webm/get-track.d.ts +6 -0
- package/dist/boxes/webm/get-track.js +183 -0
- package/dist/boxes/webm/parse-webm-header.d.ts +2 -1
- package/dist/boxes/webm/parse-webm-header.js +2 -2
- package/dist/boxes/webm/segments/all-segments.d.ts +269 -0
- package/dist/boxes/webm/segments/all-segments.js +277 -0
- package/dist/boxes/webm/segments/duration.d.ts +1 -1
- package/dist/boxes/webm/segments/duration.js +13 -9
- package/dist/boxes/webm/segments/info.d.ts +2 -1
- package/dist/boxes/webm/segments/info.js +12 -4
- package/dist/boxes/webm/segments/main.d.ts +0 -2
- package/dist/boxes/webm/segments/main.js +0 -11
- package/dist/boxes/webm/segments/muxing.d.ts +1 -1
- package/dist/boxes/webm/segments/muxing.js +1 -2
- package/dist/boxes/webm/segments/parse-children.d.ts +11 -1
- package/dist/boxes/webm/segments/parse-children.js +82 -6
- package/dist/boxes/webm/segments/seek-head.d.ts +2 -1
- package/dist/boxes/webm/segments/seek-head.js +12 -3
- package/dist/boxes/webm/segments/seek-position.d.ts +1 -1
- package/dist/boxes/webm/segments/seek-position.js +1 -2
- package/dist/boxes/webm/segments/seek.d.ts +7 -2
- package/dist/boxes/webm/segments/seek.js +22 -9
- package/dist/boxes/webm/segments/track-entry.d.ts +102 -22
- package/dist/boxes/webm/segments/track-entry.js +269 -57
- package/dist/boxes/webm/segments/tracks.d.ts +2 -1
- package/dist/boxes/webm/segments/tracks.js +12 -4
- package/dist/boxes/webm/segments/void.d.ts +1 -1
- package/dist/boxes/webm/segments/void.js +1 -2
- package/dist/boxes/webm/segments/writing.d.ts +1 -1
- package/dist/boxes/webm/segments/writing.js +1 -2
- package/dist/boxes/webm/segments.d.ts +8 -4
- package/dist/boxes/webm/segments.js +176 -40
- package/dist/boxes/webm/traversal.d.ts +7 -0
- package/dist/boxes/webm/traversal.js +25 -0
- package/dist/buffer-iterator.d.ts +15 -1
- package/dist/buffer-iterator.js +115 -46
- package/dist/combine-uint8array.d.ts +1 -0
- package/dist/combine-uint8array.js +13 -0
- package/dist/from-fetch.d.ts +2 -0
- package/dist/from-fetch.js +54 -0
- package/dist/from-node.js +6 -0
- package/dist/from-web-file.d.ts +2 -0
- package/dist/from-web-file.js +34 -0
- package/dist/from-web.js +6 -9
- package/dist/get-audio-codec.d.ts +19 -0
- package/dist/get-audio-codec.js +153 -60
- package/dist/get-dimensions.d.ts +8 -2
- package/dist/get-dimensions.js +13 -91
- package/dist/get-duration.js +4 -7
- package/dist/get-fps.d.ts +4 -3
- package/dist/get-fps.js +17 -116
- package/dist/get-sample-aspect-ratio.d.ts +37 -0
- package/dist/get-sample-aspect-ratio.js +137 -0
- package/dist/get-sample-positions.d.ts +11 -1
- package/dist/get-sample-positions.js +31 -2
- package/dist/get-tracks.d.ts +44 -5
- package/dist/get-tracks.js +66 -48
- package/dist/get-video-codec.d.ts +2 -0
- package/dist/get-video-codec.js +47 -31
- package/dist/get-video-metadata.d.ts +2 -0
- package/dist/get-video-metadata.js +44 -0
- package/dist/has-all-info.d.ts +2 -1
- package/dist/has-all-info.js +14 -5
- package/dist/index.d.ts +1 -0
- package/dist/make-hvc1-codec-strings.d.ts +2 -0
- package/dist/make-hvc1-codec-strings.js +47 -0
- package/dist/options.d.ts +26 -4
- package/dist/parse-media.js +62 -17
- package/dist/parse-result.d.ts +16 -5
- package/dist/parse-video.d.ts +11 -2
- package/dist/parse-video.js +14 -6
- package/dist/parser-context.d.ts +8 -0
- package/dist/parser-context.js +2 -0
- package/dist/parser-state.d.ts +23 -0
- package/dist/parser-state.js +112 -0
- package/dist/read-and-increment-offset.d.ts +28 -0
- package/dist/read-and-increment-offset.js +177 -0
- package/dist/reader.d.ts +2 -2
- package/dist/traversal.d.ts +37 -0
- package/dist/traversal.js +244 -1
- package/dist/understand-vorbis.d.ts +1 -0
- package/dist/understand-vorbis.js +12 -0
- package/dist/webcodec-sample-types.d.ts +21 -0
- package/dist/webcodec-sample-types.js +2 -0
- package/package.json +10 -2
- package/src/add-new-matroska-tracks.ts +23 -0
- package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +61 -0
- package/src/boxes/iso-base-media/esds/esds-descriptors.ts +33 -2
- package/src/boxes/iso-base-media/make-track.ts +157 -0
- package/src/boxes/iso-base-media/mdat/mdat.ts +131 -0
- package/src/boxes/iso-base-media/moov/moov.ts +8 -3
- package/src/boxes/iso-base-media/mvhd.ts +7 -1
- package/src/boxes/iso-base-media/process-box.ts +388 -38
- package/src/boxes/iso-base-media/stsd/av1c.ts +19 -0
- package/src/boxes/iso-base-media/stsd/avcc.ts +36 -0
- package/src/boxes/iso-base-media/stsd/colr.ts +49 -0
- package/src/boxes/iso-base-media/stsd/ctts.ts +55 -0
- package/src/boxes/iso-base-media/stsd/hvcc.ts +32 -0
- package/src/boxes/iso-base-media/stsd/keys.ts +2 -0
- package/src/boxes/iso-base-media/stsd/mebx.ts +8 -3
- package/src/boxes/iso-base-media/stsd/pasp.ts +32 -0
- package/src/boxes/iso-base-media/stsd/samples.ts +43 -16
- package/src/boxes/iso-base-media/stsd/stco.ts +50 -0
- package/src/boxes/iso-base-media/stsd/stsc.ts +61 -0
- package/src/boxes/iso-base-media/stsd/stsd.ts +10 -3
- package/src/boxes/iso-base-media/stsd/stss.ts +47 -0
- package/src/boxes/iso-base-media/stsd/stsz.ts +75 -0
- package/src/boxes/iso-base-media/tkhd.ts +63 -16
- package/src/boxes/iso-base-media/trak/trak.ts +8 -3
- package/src/boxes/iso-base-media/void-box.ts +4 -0
- package/src/boxes/webm/allowed-partial-segments.ts +1 -0
- package/src/boxes/webm/av1-codec-private.ts +113 -0
- package/src/boxes/webm/description.ts +101 -0
- package/src/boxes/webm/get-ready-tracks.ts +36 -0
- package/src/boxes/webm/get-track.ts +250 -0
- package/src/boxes/webm/parse-webm-header.ts +6 -2
- package/src/boxes/webm/segments/all-segments.ts +285 -0
- package/src/boxes/webm/segments/duration.ts +15 -8
- package/src/boxes/webm/segments/info.ts +18 -4
- package/src/boxes/webm/segments/main.ts +0 -13
- package/src/boxes/webm/segments/muxing.ts +1 -1
- package/src/boxes/webm/segments/parse-children.ts +132 -9
- package/src/boxes/webm/segments/seek-head.ts +17 -4
- package/src/boxes/webm/segments/seek-position.ts +1 -2
- package/src/boxes/webm/segments/seek.ts +31 -9
- package/src/boxes/webm/segments/track-entry.ts +475 -65
- package/src/boxes/webm/segments/tracks.ts +17 -7
- package/src/boxes/webm/segments/void.ts +4 -2
- package/src/boxes/webm/segments/writing.ts +1 -1
- package/src/boxes/webm/segments.ts +266 -42
- package/src/boxes/webm/traversal.ts +32 -0
- package/src/buffer-iterator.ts +140 -45
- package/src/combine-uint8array.ts +13 -0
- package/src/{from-web.ts → from-fetch.ts} +9 -1
- package/src/from-node.ts +8 -0
- package/src/from-web-file.ts +39 -0
- package/src/get-audio-codec.ts +213 -84
- package/src/get-dimensions.ts +25 -132
- package/src/get-duration.ts +4 -8
- package/src/get-fps.ts +27 -172
- package/src/get-sample-aspect-ratio.ts +204 -0
- package/src/get-sample-positions.ts +93 -0
- package/src/get-tracks.ts +147 -0
- package/src/get-video-codec.ts +62 -47
- package/src/has-all-info.ts +35 -5
- package/src/index.ts +8 -0
- package/src/make-hvc1-codec-strings.ts +55 -0
- package/src/options.ts +48 -9
- package/src/parse-media.ts +90 -21
- package/src/parse-result.ts +28 -4
- package/src/parse-video.ts +30 -7
- package/src/parser-context.ts +9 -0
- package/src/parser-state.ts +151 -0
- package/src/reader.ts +2 -2
- package/src/test/aspect-ratio.test.ts +42 -0
- package/src/test/av1.test.ts +108 -0
- package/src/test/duration.test.ts +5 -21
- package/src/test/matroska.test.ts +350 -31
- package/src/test/mvhd.test.ts +6 -1
- package/src/test/parse-esds.test.ts +29 -6
- package/src/test/parse-stco.test.ts +59 -0
- package/src/test/parse-stsc.test.ts +104 -0
- package/src/test/parse-stsz.test.ts +57 -0
- package/src/test/parse-stts.test.ts +1 -1
- package/src/test/parse-video.test.ts +23 -35
- package/src/test/parse-webm.test.ts +5 -5
- package/src/test/stream-local.test.ts +542 -46
- package/src/test/stream-remote.test.ts +15 -13
- package/src/test/stream-samples.test.ts +259 -0
- package/src/test/stsd.test.ts +60 -8
- package/src/test/tkhd.test.ts +4 -1
- package/src/traversal.ts +496 -0
- package/src/webcodec-sample-types.ts +30 -0
- package/tsconfig.json +5 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/boxes.json +0 -1
- package/dist/boxes/iso-base-media/esds-descriptors.d.ts +0 -21
- package/dist/boxes/iso-base-media/esds-descriptors.js +0 -62
- package/dist/boxes/iso-base-media/esds.d.ts +0 -15
- package/dist/boxes/iso-base-media/esds.js +0 -27
- package/dist/get-codec.d.ts +0 -4
- package/dist/get-codec.js +0 -22
- /package/dist/{get-samples.d.ts → boxes/webm/bitstream/av1/frame.d.ts} +0 -0
- /package/dist/{get-samples.js → boxes/webm/bitstream/av1/frame.js} +0 -0
- /package/src/boxes/iso-base-media/{stts → stsd}/stts.ts +0 -0
package/src/get-audio-codec.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/* eslint-disable max-depth */
|
|
2
|
-
import type {
|
|
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/main';
|
|
3
7
|
import {trakBoxContainsAudio} from './get-fps';
|
|
4
8
|
import type {KnownAudioCodecs} from './options';
|
|
5
9
|
import type {AnySegment} from './parse-result';
|
|
10
|
+
import {getMoovBox, getStsdBox, getTraks} from './traversal';
|
|
6
11
|
|
|
7
12
|
export const hasAudioCodec = (boxes: AnySegment[]): boolean => {
|
|
8
13
|
try {
|
|
@@ -12,111 +17,152 @@ export const hasAudioCodec = (boxes: AnySegment[]): boolean => {
|
|
|
12
17
|
}
|
|
13
18
|
};
|
|
14
19
|
|
|
15
|
-
const
|
|
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
|
+
|
|
16
78
|
if (child && child.type === 'esds-box') {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
79
|
+
const ret = getCodecSpecificatorFromEsdsBox({child});
|
|
80
|
+
return {
|
|
81
|
+
format: sample.format,
|
|
82
|
+
primarySpecificator: ret.primary,
|
|
83
|
+
secondarySpecificator: ret.secondary,
|
|
84
|
+
description: ret.description,
|
|
85
|
+
};
|
|
23
86
|
}
|
|
24
87
|
|
|
25
|
-
return
|
|
88
|
+
return {
|
|
89
|
+
format: sample.format,
|
|
90
|
+
primarySpecificator: null,
|
|
91
|
+
secondarySpecificator: null,
|
|
92
|
+
description: undefined,
|
|
93
|
+
};
|
|
26
94
|
};
|
|
27
95
|
|
|
28
|
-
const
|
|
29
|
-
|
|
96
|
+
export const getNumberOfChannelsFromTrak = (trak: TrakBox): number | null => {
|
|
97
|
+
const stsdBox = getStsdBox(trak);
|
|
98
|
+
if (!stsdBox) {
|
|
30
99
|
return null;
|
|
31
100
|
}
|
|
32
101
|
|
|
33
|
-
|
|
102
|
+
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
103
|
+
if (!sample || sample.type !== 'audio') {
|
|
34
104
|
return null;
|
|
35
105
|
}
|
|
36
106
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
107
|
+
return sample.numberOfChannels;
|
|
108
|
+
};
|
|
40
109
|
|
|
41
|
-
|
|
110
|
+
export const getSampleRate = (trak: TrakBox): number | null => {
|
|
111
|
+
const stsdBox = getStsdBox(trak);
|
|
112
|
+
if (!stsdBox) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
42
115
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return ret;
|
|
47
|
-
}
|
|
116
|
+
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
117
|
+
if (!sample || sample.type !== 'audio') {
|
|
118
|
+
return null;
|
|
48
119
|
}
|
|
120
|
+
|
|
121
|
+
return sample.sampleRate;
|
|
49
122
|
};
|
|
50
123
|
|
|
51
|
-
export const
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
minfBox &&
|
|
71
|
-
minfBox.type === 'regular-box' &&
|
|
72
|
-
minfBox.boxType === 'minf'
|
|
73
|
-
) {
|
|
74
|
-
const stblBox = minfBox?.children.find(
|
|
75
|
-
(b) => b.type === 'regular-box' && b.boxType === 'stbl',
|
|
76
|
-
);
|
|
77
|
-
if (stblBox && stblBox.type === 'regular-box') {
|
|
78
|
-
const stsdBox = stblBox?.children.find(
|
|
79
|
-
(b) => b.type === 'stsd-box',
|
|
80
|
-
);
|
|
81
|
-
if (stsdBox && stsdBox.type === 'stsd-box') {
|
|
82
|
-
const sample = stsdBox.samples.find((s) => s.type === 'audio');
|
|
83
|
-
if (sample && sample.type === 'audio') {
|
|
84
|
-
const ret = onSample(sample);
|
|
85
|
-
if (ret) {
|
|
86
|
-
return ret;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const waveBox = sample.children.find(
|
|
90
|
-
(b) => b.type === 'regular-box' && b.boxType === 'wave',
|
|
91
|
-
);
|
|
92
|
-
if (
|
|
93
|
-
waveBox &&
|
|
94
|
-
waveBox.type === 'regular-box' &&
|
|
95
|
-
waveBox.boxType === 'wave'
|
|
96
|
-
) {
|
|
97
|
-
const esdsBox = waveBox.children.find(
|
|
98
|
-
(b) => b.type === 'esds-box',
|
|
99
|
-
);
|
|
100
|
-
if (esdsBox && esdsBox.type === 'esds-box') {
|
|
101
|
-
const ret2 = onEsdsBox(esdsBox);
|
|
102
|
-
if (ret2) {
|
|
103
|
-
return ret2;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
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;
|
|
112
142
|
}
|
|
113
143
|
}
|
|
114
144
|
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
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) {
|
|
117
159
|
return null;
|
|
118
160
|
}
|
|
119
161
|
|
|
162
|
+
return getAudioCodecFromTrak(trakBox);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const getAudioCodecFromMatroska = (mainSegment: MainSegment) => {
|
|
120
166
|
const tracksSegment = mainSegment.children.find(
|
|
121
167
|
(b) => b.type === 'tracks-segment',
|
|
122
168
|
);
|
|
@@ -132,12 +178,95 @@ export const getAudioCodec = (boxes: AnySegment[]): KnownAudioCodecs | null => {
|
|
|
132
178
|
return 'opus';
|
|
133
179
|
}
|
|
134
180
|
|
|
181
|
+
if (trackType.codec === 'A_VORBIS') {
|
|
182
|
+
return 'vorbis';
|
|
183
|
+
}
|
|
184
|
+
|
|
135
185
|
if (trackType.codec === 'A_PCM/INT/LIT') {
|
|
136
186
|
return 'pcm';
|
|
137
187
|
}
|
|
188
|
+
|
|
189
|
+
if (trackType.codec === 'A_AAC') {
|
|
190
|
+
return 'aac';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (trackType.codec === 'A_MPEG/L3') {
|
|
194
|
+
return 'mp3';
|
|
195
|
+
}
|
|
138
196
|
}
|
|
139
197
|
}
|
|
140
198
|
}
|
|
141
199
|
|
|
142
200
|
return null;
|
|
143
201
|
};
|
|
202
|
+
|
|
203
|
+
export const getAudioCodecStringFromTrak = (
|
|
204
|
+
trak: TrakBox,
|
|
205
|
+
): {codecString: string; description: Uint8Array | undefined} => {
|
|
206
|
+
const codec = getAudioCodecFromTrak(trak);
|
|
207
|
+
if (!codec) {
|
|
208
|
+
throw new Error('Expected codec');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const codecStringWithoutMp3Exception = (
|
|
212
|
+
[
|
|
213
|
+
codec.format,
|
|
214
|
+
codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
|
|
215
|
+
codec.secondarySpecificator
|
|
216
|
+
? codec.secondarySpecificator.toString().padStart(2, '0')
|
|
217
|
+
: null,
|
|
218
|
+
].filter(Boolean) as string[]
|
|
219
|
+
).join('.');
|
|
220
|
+
|
|
221
|
+
// Really, MP3? 😔
|
|
222
|
+
const codecString =
|
|
223
|
+
codecStringWithoutMp3Exception === 'mp4a.6b'
|
|
224
|
+
? 'mp3' // or "mp4a.6B" would also work, with the uppercasing, but mp3 is probably more obvious
|
|
225
|
+
: codecStringWithoutMp3Exception;
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
codecString,
|
|
229
|
+
description: codec.description,
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export const getAudioCodec = (boxes: AnySegment[]): KnownAudioCodecs | null => {
|
|
234
|
+
const moovBox = getMoovBox(boxes);
|
|
235
|
+
|
|
236
|
+
if (moovBox) {
|
|
237
|
+
const codec = getAudioCodecFromIso(moovBox);
|
|
238
|
+
|
|
239
|
+
if (!codec) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (codec.format === 'sowt') {
|
|
244
|
+
return 'aiff';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (codec.format === 'mp4a') {
|
|
248
|
+
if (codec.primarySpecificator === 0x40) {
|
|
249
|
+
return 'aac';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (codec.primarySpecificator === 0x6b) {
|
|
253
|
+
return 'mp3';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (codec.primarySpecificator === null) {
|
|
257
|
+
return 'aac';
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
throw new Error('Unknown mp4a codec: ' + codec.primarySpecificator);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
throw new Error('Unknown audio format: ' + codec.format);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const mainSegment = boxes.find((b) => b.type === 'main-segment');
|
|
267
|
+
if (!mainSegment || mainSegment.type !== 'main-segment') {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return getAudioCodecFromMatroska(mainSegment);
|
|
272
|
+
};
|
package/src/get-dimensions.ts
CHANGED
|
@@ -1,153 +1,46 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {getTracks} from './get-tracks';
|
|
2
2
|
import type {AnySegment} from './parse-result';
|
|
3
|
+
import type {ParserState} from './parser-state';
|
|
3
4
|
|
|
4
5
|
export type Dimensions = {
|
|
5
6
|
width: number;
|
|
6
7
|
height: number;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
throw new Error('No tracks segment');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const trackEntrySegment = tracksSegment.children.find((b) => {
|
|
18
|
-
if (b.type !== 'track-entry-segment') {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
b.children.find(
|
|
24
|
-
(c) => c.type === 'codec-segment' && c.codec.startsWith('V_'),
|
|
25
|
-
) !== undefined
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
if (!trackEntrySegment || trackEntrySegment.type !== 'track-entry-segment') {
|
|
29
|
-
throw new Error('No track entry segment');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const videoSegment = trackEntrySegment.children.find(
|
|
33
|
-
(b) => b.type === 'video-segment',
|
|
34
|
-
);
|
|
35
|
-
if (!videoSegment || videoSegment.type !== 'video-segment') {
|
|
36
|
-
throw new Error('No video segment');
|
|
37
|
-
}
|
|
10
|
+
export type ExpandedDimensions = Dimensions & {
|
|
11
|
+
rotation: number;
|
|
12
|
+
unrotatedWidth: number;
|
|
13
|
+
unrotatedHeight: number;
|
|
14
|
+
};
|
|
38
15
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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');
|
|
44
23
|
}
|
|
45
24
|
|
|
46
|
-
const
|
|
47
|
-
(b) => b.type === 'height-segment',
|
|
48
|
-
);
|
|
49
|
-
if (!heightSegment || heightSegment.type !== 'height-segment') {
|
|
50
|
-
throw new Error('No height segment');
|
|
51
|
-
}
|
|
25
|
+
const firstVideoTrack = videoTracks[0];
|
|
52
26
|
|
|
53
27
|
return {
|
|
54
|
-
width:
|
|
55
|
-
height:
|
|
28
|
+
width: firstVideoTrack.width,
|
|
29
|
+
height: firstVideoTrack.height,
|
|
30
|
+
rotation: firstVideoTrack.rotation,
|
|
31
|
+
unrotatedHeight: firstVideoTrack.displayAspectHeight,
|
|
32
|
+
unrotatedWidth: firstVideoTrack.displayAspectWidth,
|
|
56
33
|
};
|
|
57
34
|
};
|
|
58
35
|
|
|
59
|
-
export const getDimensions = (boxes: AnySegment[]): Dimensions => {
|
|
60
|
-
const matroskaBox = boxes.find((b) => b.type === 'main-segment');
|
|
61
|
-
if (matroskaBox && matroskaBox.type === 'main-segment') {
|
|
62
|
-
return getDimensionsFromMatroska(matroskaBox);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const moovBox = boxes.find((b) => b.type === 'moov-box');
|
|
66
|
-
if (!moovBox || moovBox.type !== 'moov-box') {
|
|
67
|
-
throw new Error('Expected moov box');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const {children} = moovBox;
|
|
71
|
-
if (!children) {
|
|
72
|
-
throw new Error('Expected moov box children');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const t = children.find((b) => b.type === 'trak-box');
|
|
76
|
-
|
|
77
|
-
if (!t || t.type !== 'trak-box') {
|
|
78
|
-
throw new Error('Expected trak box');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const mdiaBox = t.children.find(
|
|
82
|
-
(c) => c.type === 'regular-box' && c.boxType === 'mdia',
|
|
83
|
-
);
|
|
84
|
-
const tkhdBox = t.children.find((c) => c.type === 'tkhd-box');
|
|
85
|
-
if (tkhdBox && tkhdBox.type === 'tkhd-box') {
|
|
86
|
-
return {
|
|
87
|
-
width: tkhdBox.width,
|
|
88
|
-
height: tkhdBox.height,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!mdiaBox) {
|
|
93
|
-
throw new Error('Expected mdia box');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (mdiaBox.type !== 'regular-box') {
|
|
97
|
-
throw new Error('Expected mdia box');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const minfBox = mdiaBox.children.find(
|
|
101
|
-
(c) => c.type === 'regular-box' && c.boxType === 'minf',
|
|
102
|
-
);
|
|
103
|
-
if (!minfBox) {
|
|
104
|
-
throw new Error('Expected minf box');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (minfBox.type !== 'regular-box') {
|
|
108
|
-
throw new Error('Expected minf box');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const stblBox = minfBox.children.find(
|
|
112
|
-
(c) => c.type === 'regular-box' && c.boxType === 'stbl',
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
if (!stblBox) {
|
|
116
|
-
throw new Error('Expected stbl box');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (stblBox.type !== 'regular-box') {
|
|
120
|
-
throw new Error('Expected stbl box');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const stsdBox = stblBox.children.find((c) => c.type === 'stsd-box');
|
|
124
|
-
|
|
125
|
-
if (!stsdBox) {
|
|
126
|
-
throw new Error('Expected stsd box');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (stsdBox.type !== 'stsd-box') {
|
|
130
|
-
throw new Error('Expected stsd box');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const videoSamples = stsdBox.samples.filter((s) => s.type === 'video');
|
|
134
|
-
if (videoSamples.length === 0) {
|
|
135
|
-
throw new Error('Has no video stream');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const [firstTrack] = videoSamples;
|
|
139
|
-
if (firstTrack.type !== 'video') {
|
|
140
|
-
throw new Error('Expected video track');
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {width: firstTrack.width, height: firstTrack.height};
|
|
144
|
-
};
|
|
145
|
-
|
|
146
36
|
// TODO: An audio track should return 'hasDimensions' = true on an audio file
|
|
147
37
|
// and stop parsing
|
|
148
|
-
export const hasDimensions = (
|
|
38
|
+
export const hasDimensions = (
|
|
39
|
+
boxes: AnySegment[],
|
|
40
|
+
state: ParserState,
|
|
41
|
+
): boolean => {
|
|
149
42
|
try {
|
|
150
|
-
return getDimensions(boxes) !== null;
|
|
43
|
+
return getDimensions(boxes, state) !== null;
|
|
151
44
|
} catch (err) {
|
|
152
45
|
return false;
|
|
153
46
|
}
|
package/src/get-duration.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {AnySegment} from './parse-result';
|
|
2
|
+
import {getMoovBox, getMvhdBox} from './traversal';
|
|
2
3
|
|
|
3
4
|
const getDurationFromMatroska = (segments: AnySegment[]): number | null => {
|
|
4
5
|
const mainSegment = segments.find((s) => s.type === 'main-segment');
|
|
@@ -41,17 +42,12 @@ export const getDuration = (boxes: AnySegment[]): number | null => {
|
|
|
41
42
|
return getDurationFromMatroska(boxes);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const moovBox = boxes
|
|
45
|
-
if (!moovBox
|
|
45
|
+
const moovBox = getMoovBox(boxes);
|
|
46
|
+
if (!moovBox) {
|
|
46
47
|
return null;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
-
if (!children) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const mvhdBox = children.find((b) => b.type === 'mvhd-box');
|
|
50
|
+
const mvhdBox = getMvhdBox(moovBox);
|
|
55
51
|
|
|
56
52
|
if (!mvhdBox) {
|
|
57
53
|
return null;
|