@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
|
@@ -16,8 +16,47 @@ export interface TkhdBox extends BaseBox {
|
|
|
16
16
|
matrix: ThreeDMatrix;
|
|
17
17
|
width: number;
|
|
18
18
|
height: number;
|
|
19
|
+
unrotatedWidth: number;
|
|
20
|
+
unrotatedHeight: number;
|
|
21
|
+
rotation: number;
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
type Matrix2x2 = readonly [number, number, number, number];
|
|
25
|
+
|
|
26
|
+
function getRotationAngleFromMatrix(matrix: Matrix2x2): number {
|
|
27
|
+
// Extract elements from the matrix
|
|
28
|
+
const [a, b, c, d] = matrix;
|
|
29
|
+
|
|
30
|
+
// Check if the matrix is a valid rotation matrix
|
|
31
|
+
if (Math.round(a * a + b * b) !== 1 || Math.round(c * c + d * d) !== 1) {
|
|
32
|
+
throw new Error('The provided matrix is not a valid rotation matrix.');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Calculate the angle using the atan2 function
|
|
36
|
+
const angleRadians = Math.atan2(c, a); // atan2(sin(θ), cos(θ))
|
|
37
|
+
const angleDegrees = angleRadians * (180 / Math.PI); // Convert radians to degrees
|
|
38
|
+
|
|
39
|
+
return angleDegrees;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const applyRotation = ({
|
|
43
|
+
matrix,
|
|
44
|
+
width,
|
|
45
|
+
height,
|
|
46
|
+
}: {
|
|
47
|
+
matrix: Matrix2x2;
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
}) => {
|
|
51
|
+
const newWidth = matrix[0] * width + matrix[1] * height; // 0*3840 + 1*2160
|
|
52
|
+
const newHeight = matrix[2] * width + matrix[3] * height; // -1*3840 + 0*2160
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
width: Math.abs(newWidth),
|
|
56
|
+
height: Math.abs(newHeight),
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
21
60
|
export const parseTkhd = ({
|
|
22
61
|
iterator,
|
|
23
62
|
offset,
|
|
@@ -66,25 +105,30 @@ export const parseTkhd = ({
|
|
|
66
105
|
iterator.discard(2);
|
|
67
106
|
|
|
68
107
|
const matrix = [
|
|
69
|
-
iterator.
|
|
70
|
-
iterator.
|
|
71
|
-
iterator.
|
|
72
|
-
iterator.
|
|
73
|
-
iterator.
|
|
74
|
-
iterator.
|
|
75
|
-
iterator.
|
|
76
|
-
iterator.
|
|
77
|
-
iterator.
|
|
108
|
+
iterator.getFixedPointSigned1616Number(),
|
|
109
|
+
iterator.getFixedPointSigned1616Number(),
|
|
110
|
+
iterator.getFixedPointSigned230Number(),
|
|
111
|
+
iterator.getFixedPointSigned1616Number(),
|
|
112
|
+
iterator.getFixedPointSigned1616Number(),
|
|
113
|
+
iterator.getFixedPointSigned230Number(),
|
|
114
|
+
iterator.getFixedPointSigned1616Number(),
|
|
115
|
+
iterator.getFixedPointSigned1616Number(),
|
|
116
|
+
iterator.getFixedPointSigned230Number(),
|
|
78
117
|
];
|
|
118
|
+
|
|
119
|
+
const rotationMatrix = [matrix[0], matrix[1], matrix[3], matrix[4]] as const;
|
|
120
|
+
|
|
79
121
|
const widthWithoutRotationApplied =
|
|
80
|
-
iterator.
|
|
81
|
-
const heightWithoutRotationApplied =
|
|
82
|
-
|
|
122
|
+
iterator.getFixedPointUnsigned1616Number();
|
|
123
|
+
const heightWithoutRotationApplied = iterator.getFixedPointSigned1616Number();
|
|
124
|
+
|
|
125
|
+
const {width, height} = applyRotation({
|
|
126
|
+
matrix: rotationMatrix,
|
|
127
|
+
width: widthWithoutRotationApplied,
|
|
128
|
+
height: heightWithoutRotationApplied,
|
|
129
|
+
});
|
|
83
130
|
|
|
84
|
-
|
|
85
|
-
const width = widthWithoutRotationApplied / (matrix[1] === 0 ? 1 : matrix[1]);
|
|
86
|
-
const height =
|
|
87
|
-
heightWithoutRotationApplied / (matrix[1] === 0 ? 1 : matrix[1]);
|
|
131
|
+
const rotation = getRotationAngleFromMatrix(rotationMatrix);
|
|
88
132
|
|
|
89
133
|
return {
|
|
90
134
|
offset,
|
|
@@ -101,5 +145,8 @@ export const parseTkhd = ({
|
|
|
101
145
|
width,
|
|
102
146
|
height,
|
|
103
147
|
version,
|
|
148
|
+
rotation,
|
|
149
|
+
unrotatedWidth: widthWithoutRotationApplied,
|
|
150
|
+
unrotatedHeight: heightWithoutRotationApplied,
|
|
104
151
|
};
|
|
105
152
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {BufferIterator} from '../../../buffer-iterator';
|
|
2
2
|
import type {AnySegment} from '../../../parse-result';
|
|
3
|
+
import type {ParserContext} from '../../../parser-context';
|
|
3
4
|
import type {BaseBox} from '../base-type';
|
|
4
5
|
import {parseBoxes} from '../process-box';
|
|
5
6
|
|
|
@@ -8,20 +9,24 @@ export interface TrakBox extends BaseBox {
|
|
|
8
9
|
children: AnySegment[];
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export const parseTrak = ({
|
|
12
|
+
export const parseTrak = async ({
|
|
12
13
|
data,
|
|
13
14
|
size,
|
|
14
15
|
offsetAtStart,
|
|
16
|
+
options,
|
|
15
17
|
}: {
|
|
16
18
|
data: BufferIterator;
|
|
17
19
|
size: number;
|
|
18
20
|
offsetAtStart: number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
options: ParserContext;
|
|
22
|
+
}): Promise<TrakBox> => {
|
|
23
|
+
const children = await parseBoxes({
|
|
21
24
|
iterator: data,
|
|
22
25
|
maxBytes: size - (data.counter.getOffset() - offsetAtStart),
|
|
23
26
|
allowIncompleteBoxes: false,
|
|
24
27
|
initialBoxes: [],
|
|
28
|
+
options,
|
|
29
|
+
continueMdat: false,
|
|
25
30
|
});
|
|
26
31
|
|
|
27
32
|
if (children.status === 'incomplete') {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const allowedPartialSegments = ['0x1f43b675', '0x18538067'];
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {getArrayBufferIterator} from '../../buffer-iterator';
|
|
2
|
+
import type {ColorParameterBox} from '../iso-base-media/stsd/colr';
|
|
3
|
+
|
|
4
|
+
export const parseAv1PrivateData = (
|
|
5
|
+
data: Uint8Array,
|
|
6
|
+
colrAtom: ColorParameterBox | null,
|
|
7
|
+
) => {
|
|
8
|
+
const iterator = getArrayBufferIterator(data);
|
|
9
|
+
iterator.startReadingBits();
|
|
10
|
+
if (iterator.getBits(1) !== 1) {
|
|
11
|
+
iterator.destroy();
|
|
12
|
+
throw new Error('Expected av1 private data to be version 1');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const version = iterator.getBits(7);
|
|
16
|
+
if (version !== 1) {
|
|
17
|
+
iterator.destroy();
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Expected av1 private data to be version 1, got ${version}`,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let str = 'av01.';
|
|
24
|
+
|
|
25
|
+
// https://aomediacodec.github.io/av1-isobmff/#codecsparam
|
|
26
|
+
|
|
27
|
+
const seqProfile = iterator.getBits(3);
|
|
28
|
+
// Profile
|
|
29
|
+
str += seqProfile;
|
|
30
|
+
str += '.';
|
|
31
|
+
|
|
32
|
+
const seq_level_idx = iterator.getBits(5);
|
|
33
|
+
const seq_tier_0 = iterator.getBits(1);
|
|
34
|
+
// Level
|
|
35
|
+
// The level parameter value SHALL equal the first level value indicated by seq_level_idx in the Sequence Header OBU
|
|
36
|
+
str += seq_level_idx.toString(16).padStart(2, '0');
|
|
37
|
+
str += seq_tier_0 ? 'H' : 'M';
|
|
38
|
+
str += '.';
|
|
39
|
+
|
|
40
|
+
// bitDepth
|
|
41
|
+
// The bitDepth parameter value SHALL equal the value of BitDepth variable as defined in [AV1] derived from the Sequence Header OBU
|
|
42
|
+
const high_bitdepth = iterator.getBits(1);
|
|
43
|
+
const twelve_bit = iterator.getBits(1);
|
|
44
|
+
const bitDepth =
|
|
45
|
+
high_bitdepth && seqProfile === 2
|
|
46
|
+
? twelve_bit
|
|
47
|
+
? 12
|
|
48
|
+
: 10
|
|
49
|
+
: high_bitdepth
|
|
50
|
+
? 10
|
|
51
|
+
: 8;
|
|
52
|
+
str += bitDepth.toString().padStart(2, '0');
|
|
53
|
+
str += '.';
|
|
54
|
+
|
|
55
|
+
// monochrome
|
|
56
|
+
// The monochrome parameter value, represented by a single digit decimal, SHALL equal the value of mono_chrome in the Sequence Header OBU
|
|
57
|
+
const mono_chrome = iterator.getBits(1);
|
|
58
|
+
str += mono_chrome ? '1' : '0';
|
|
59
|
+
str += '.';
|
|
60
|
+
|
|
61
|
+
// The chromaSubsampling parameter value, represented by a three-digit decimal,
|
|
62
|
+
// SHALL have its first digit equal to subsampling_x
|
|
63
|
+
const subsampling_x = iterator.getBits(1);
|
|
64
|
+
str += subsampling_x ? '1' : '0';
|
|
65
|
+
|
|
66
|
+
// and its second digit equal to subsampling_y.
|
|
67
|
+
const subsampling_y = iterator.getBits(1);
|
|
68
|
+
str += subsampling_y ? '1' : '0';
|
|
69
|
+
|
|
70
|
+
// If both subsampling_x and subsampling_y are set to 1, then the third digit SHALL be equal to chroma_sample_position, otherwise it SHALL be set to 0
|
|
71
|
+
const chroma_sample_position = iterator.getBits(2);
|
|
72
|
+
str +=
|
|
73
|
+
subsampling_x && subsampling_y
|
|
74
|
+
? chroma_sample_position === 1
|
|
75
|
+
? '1'
|
|
76
|
+
: '0'
|
|
77
|
+
: '0';
|
|
78
|
+
str += '.';
|
|
79
|
+
|
|
80
|
+
if (colrAtom) {
|
|
81
|
+
str += colrAtom.primaries.toString().padStart(2, '0');
|
|
82
|
+
str += '.';
|
|
83
|
+
str += colrAtom.transfer.toString().padStart(2, '0');
|
|
84
|
+
str += '.';
|
|
85
|
+
str += colrAtom.matrixIndex.toString().padStart(2, '0');
|
|
86
|
+
str += '.';
|
|
87
|
+
str += colrAtom.fullRangeFlag ? '1' : '0';
|
|
88
|
+
} else {
|
|
89
|
+
// Otherwise, the color_description_present_flag is set to 0 in the Sequence Header OBU. The colorPrimaries, transferCharacteristics, and matrixCoefficients parameter values SHOULD be set to the default values below.
|
|
90
|
+
// colorPrimaries 01 (ITU-R BT.709)
|
|
91
|
+
str += '01';
|
|
92
|
+
str += '.';
|
|
93
|
+
// transferCharacteristics 01 (ITU-R BT.709)
|
|
94
|
+
str += '01';
|
|
95
|
+
str += '.';
|
|
96
|
+
// matrixCoefficients 00 (ITU-R BT.709)
|
|
97
|
+
str += '01';
|
|
98
|
+
str += '.';
|
|
99
|
+
// videoFullRangeFlag 0 (studio swing representation)
|
|
100
|
+
str += '0';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// If the codecs parameter string ends with ".0.110.01.01.01.0" (containing all the default values below), that trailing part of the string SHOULD be omitted.
|
|
104
|
+
const suffix = '.0.110.01.01.01.0';
|
|
105
|
+
|
|
106
|
+
if (str.endsWith(suffix)) {
|
|
107
|
+
str = str.slice(0, -suffix.length);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
iterator.destroy();
|
|
111
|
+
|
|
112
|
+
return str;
|
|
113
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {getArrayBufferIterator} from '../../buffer-iterator';
|
|
2
|
+
import {getCodecSegment, getPrivateData} from '../../traversal';
|
|
3
|
+
import type {TrackEntrySegment} from './segments/track-entry';
|
|
4
|
+
|
|
5
|
+
export const getAudioDescription = (
|
|
6
|
+
track: TrackEntrySegment,
|
|
7
|
+
): undefined | Uint8Array => {
|
|
8
|
+
const codec = getCodecSegment(track);
|
|
9
|
+
if (!codec || codec.codec !== 'A_VORBIS') {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// how to parse vorbis private
|
|
14
|
+
// https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java#L2466
|
|
15
|
+
const privateData = getPrivateData(track);
|
|
16
|
+
if (!privateData) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (privateData[0] !== 2) {
|
|
21
|
+
throw new Error('Expected vorbis private data version 2');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let offset = 1;
|
|
25
|
+
let vorbisInfoLength = 0;
|
|
26
|
+
let vorbisSkipLength = 0;
|
|
27
|
+
|
|
28
|
+
while ((privateData[offset] & 0xff) === 0xff) {
|
|
29
|
+
vorbisInfoLength += 0xff;
|
|
30
|
+
offset++;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
vorbisInfoLength += privateData[offset++] & 0xff;
|
|
34
|
+
|
|
35
|
+
while ((privateData[offset] & 0xff) === 0xff) {
|
|
36
|
+
vorbisSkipLength += 0xff;
|
|
37
|
+
offset++;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
vorbisSkipLength += privateData[offset++] & 0xff;
|
|
41
|
+
|
|
42
|
+
if (privateData[offset] !== 0x01) {
|
|
43
|
+
throw new Error('Error parsing vorbis codec private');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const vorbisInfo = privateData.slice(offset, offset + vorbisInfoLength);
|
|
47
|
+
offset += vorbisInfoLength;
|
|
48
|
+
|
|
49
|
+
if (privateData[offset] !== 0x03) {
|
|
50
|
+
throw new Error('Error parsing vorbis codec private');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const vorbisComments = privateData.slice(offset, offset + vorbisSkipLength);
|
|
54
|
+
offset += vorbisSkipLength;
|
|
55
|
+
|
|
56
|
+
if (privateData[offset] !== 0x05) {
|
|
57
|
+
throw new Error('Error parsing vorbis codec private');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const vorbisBooks = privateData.slice(offset);
|
|
61
|
+
|
|
62
|
+
const bufferIterator = getArrayBufferIterator(vorbisInfo.slice(0));
|
|
63
|
+
|
|
64
|
+
// type
|
|
65
|
+
bufferIterator.getUint8();
|
|
66
|
+
// vorbis
|
|
67
|
+
const vorbis = bufferIterator.getByteString(6);
|
|
68
|
+
if (vorbis !== 'vorbis') {
|
|
69
|
+
throw new Error('Error parsing vorbis codec private');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const vorbisVersion = bufferIterator.getUint32Le();
|
|
73
|
+
if (vorbisVersion !== 0) {
|
|
74
|
+
throw new Error('Error parsing vorbis codec private');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const vorbisDescription = new Uint8Array([
|
|
78
|
+
// constructing the vorbis description
|
|
79
|
+
// This format consists in the page_segments field
|
|
80
|
+
/**
|
|
81
|
+
* The number of segment entries to appear in the segment table.
|
|
82
|
+
* The maximum number of 255 segments (255 bytes each) sets the maximum possible physical page size at 65307 bytes or just under 64kB (thus we know that a header corrupted so as destroy sizing/alignment information will not cause a runaway bitstream.
|
|
83
|
+
* We'll read in the page according to the corrupted size information that's guaranteed to be a reasonable size regardless, notice the checksum mismatch, drop sync and then look for recapture).
|
|
84
|
+
*/
|
|
85
|
+
2,
|
|
86
|
+
// followed by the segment_table field
|
|
87
|
+
// offset of the comments table
|
|
88
|
+
vorbisInfo.length,
|
|
89
|
+
// offset of the codebooks table
|
|
90
|
+
vorbisComments.length,
|
|
91
|
+
// followed by the three Vorbis header packets,
|
|
92
|
+
// respectively the identification header,
|
|
93
|
+
...vorbisInfo,
|
|
94
|
+
// the comments header,
|
|
95
|
+
...vorbisComments,
|
|
96
|
+
// and the setup header, in this order, as described in section 4.2 of [VORBIS].
|
|
97
|
+
...vorbisBooks,
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
return vorbisDescription;
|
|
101
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type {Track} from '../../get-tracks';
|
|
2
|
+
import {getTracksSegment} from '../../traversal';
|
|
3
|
+
import {getTrack} from './get-track';
|
|
4
|
+
import type {MainSegment} from './segments/main';
|
|
5
|
+
|
|
6
|
+
export const getTracksFromMatroska = (
|
|
7
|
+
segment: MainSegment,
|
|
8
|
+
timescale: number,
|
|
9
|
+
): Track[] => {
|
|
10
|
+
const tracksSegment = getTracksSegment(segment);
|
|
11
|
+
if (!tracksSegment) {
|
|
12
|
+
throw new Error('No tracks segment');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const tracks: Track[] = [];
|
|
16
|
+
|
|
17
|
+
for (const trackEntrySegment of tracksSegment.children) {
|
|
18
|
+
if (trackEntrySegment.type === 'crc32-segment') {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (trackEntrySegment.type !== 'track-entry-segment') {
|
|
23
|
+
throw new Error('Expected track entry segment');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const track = getTrack({
|
|
27
|
+
track: trackEntrySegment,
|
|
28
|
+
timescale,
|
|
29
|
+
});
|
|
30
|
+
if (track) {
|
|
31
|
+
tracks.push(track);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return tracks;
|
|
36
|
+
};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {getArrayBufferIterator} from '../../buffer-iterator';
|
|
2
|
+
import type {AudioTrack, VideoTrack} from '../../get-tracks';
|
|
3
|
+
import {getHvc1CodecString} from '../../make-hvc1-codec-strings';
|
|
4
|
+
import {
|
|
5
|
+
getBitDepth,
|
|
6
|
+
getCodecSegment,
|
|
7
|
+
getDisplayHeightSegment,
|
|
8
|
+
getDisplayWidthSegment,
|
|
9
|
+
getHeightSegment,
|
|
10
|
+
getNumberOfChannels,
|
|
11
|
+
getPrivateData,
|
|
12
|
+
getSampleRate,
|
|
13
|
+
getTrackId,
|
|
14
|
+
getTrackTypeSegment,
|
|
15
|
+
getWidthSegment,
|
|
16
|
+
} from '../../traversal';
|
|
17
|
+
import {parseAv1PrivateData} from './av1-codec-private';
|
|
18
|
+
import {getAudioDescription} from './description';
|
|
19
|
+
import type {CodecSegment, TrackEntrySegment} from './segments/track-entry';
|
|
20
|
+
|
|
21
|
+
const getDescription = (track: TrackEntrySegment): undefined | Uint8Array => {
|
|
22
|
+
const codec = getCodecSegment(track);
|
|
23
|
+
if (!codec) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (codec.codec === 'V_MPEG4/ISO/AVC' || codec.codec === 'V_MPEGH/ISO/HEVC') {
|
|
28
|
+
const priv = getPrivateData(track);
|
|
29
|
+
if (priv) {
|
|
30
|
+
return priv;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return undefined;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const getMatroskaVideoCodecString = ({
|
|
38
|
+
track,
|
|
39
|
+
codecSegment: codec,
|
|
40
|
+
}: {
|
|
41
|
+
track: TrackEntrySegment;
|
|
42
|
+
codecSegment: CodecSegment;
|
|
43
|
+
}): string | null => {
|
|
44
|
+
if (codec.codec === 'V_VP8') {
|
|
45
|
+
return 'vp8';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (codec.codec === 'V_VP9') {
|
|
49
|
+
const priv = getPrivateData(track);
|
|
50
|
+
if (priv) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
'@remotion/media-parser cannot handle the private data for VP9. Do you have an example file you could send so we can implement it?',
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return 'vp09.00.10.08';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (codec.codec === 'V_MPEG4/ISO/AVC') {
|
|
60
|
+
const priv = getPrivateData(track);
|
|
61
|
+
if (priv) {
|
|
62
|
+
return `avc1.${priv[1].toString(16).padStart(2, '0')}${priv[2].toString(16).padStart(2, '0')}${priv[3].toString(16).padStart(2, '0')}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
throw new Error('Could not find a CodecPrivate field in TrackEntry');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (codec.codec === 'V_AV1') {
|
|
69
|
+
const priv = getPrivateData(track);
|
|
70
|
+
|
|
71
|
+
if (!priv) {
|
|
72
|
+
throw new Error('Expected private data in AV1 track');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return parseAv1PrivateData(priv, null);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (codec.codec === 'V_MPEGH/ISO/HEVC') {
|
|
79
|
+
const priv = getPrivateData(track);
|
|
80
|
+
const iterator = getArrayBufferIterator(priv as Uint8Array);
|
|
81
|
+
|
|
82
|
+
return 'hvc1.' + getHvc1CodecString(iterator);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
throw new Error(`Unknown codec: ${codec.codec}`);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const getMatroskaAudioCodecString = (track: TrackEntrySegment): string => {
|
|
89
|
+
const codec = getCodecSegment(track);
|
|
90
|
+
if (!codec) {
|
|
91
|
+
throw new Error('Expected codec segment');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (codec.codec === 'A_OPUS') {
|
|
95
|
+
return 'opus';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (codec.codec === 'A_VORBIS') {
|
|
99
|
+
return 'vorbis';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (codec.codec === 'A_PCM/INT/LIT') {
|
|
103
|
+
// https://github.com/ietf-wg-cellar/matroska-specification/issues/142#issuecomment-330004950
|
|
104
|
+
// Audio samples MUST be considered as signed values, except if the audio bit depth is 8 which MUST be interpreted as unsigned values.
|
|
105
|
+
|
|
106
|
+
const bitDepth = getBitDepth(track);
|
|
107
|
+
if (bitDepth === null) {
|
|
108
|
+
throw new Error('Expected bit depth');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (bitDepth === 8) {
|
|
112
|
+
return 'pcm-u8';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return 'pcm-s' + bitDepth;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (codec.codec === 'A_AAC') {
|
|
119
|
+
const priv = getPrivateData(track);
|
|
120
|
+
|
|
121
|
+
const iterator = getArrayBufferIterator(priv as Uint8Array);
|
|
122
|
+
|
|
123
|
+
iterator.startReadingBits();
|
|
124
|
+
/**
|
|
125
|
+
* ChatGPT
|
|
126
|
+
* ▪ The first 5 bits represent the AOT.
|
|
127
|
+
▪ Common values:
|
|
128
|
+
◦ 1 for AAC Main
|
|
129
|
+
◦ 2 for AAC LC (Low Complexity)
|
|
130
|
+
◦ 3 for AAC SSR (Scalable Sample Rate)
|
|
131
|
+
◦ 4 for AAC LTP (Long Term Prediction)
|
|
132
|
+
◦ 5 for SBR (Spectral Band Replication)
|
|
133
|
+
◦ 29 for HE-AAC (which uses SBR with AAC LC)
|
|
134
|
+
*/
|
|
135
|
+
/**
|
|
136
|
+
* Fully qualified codec:
|
|
137
|
+
* This codec has multiple possible codec strings:
|
|
138
|
+
"mp4a.40.2" — MPEG-4 AAC LC
|
|
139
|
+
"mp4a.40.02" — MPEG-4 AAC LC, leading 0 for Aud-OTI compatibility
|
|
140
|
+
"mp4a.40.5" — MPEG-4 HE-AAC v1 (AAC LC + SBR)
|
|
141
|
+
"mp4a.40.05" — MPEG-4 HE-AAC v1 (AAC LC + SBR), leading 0 for Aud-OTI compatibility
|
|
142
|
+
"mp4a.40.29" — MPEG-4 HE-AAC v2 (AAC LC + SBR + PS)
|
|
143
|
+
"mp4a.67" — MPEG-2 AAC LC
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
const profile = iterator.getBits(5);
|
|
147
|
+
iterator.stopReadingBits();
|
|
148
|
+
iterator.destroy();
|
|
149
|
+
|
|
150
|
+
return `mp4a.40.${profile.toString().padStart(2, '0')}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (codec.codec === 'A_MPEG/L3') {
|
|
154
|
+
return 'mp3';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
throw new Error(`Unknown codec: ${codec.codec}`);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const getTrack = ({
|
|
161
|
+
timescale,
|
|
162
|
+
track,
|
|
163
|
+
}: {
|
|
164
|
+
timescale: number;
|
|
165
|
+
track: TrackEntrySegment;
|
|
166
|
+
}): VideoTrack | AudioTrack | null => {
|
|
167
|
+
const trackType = getTrackTypeSegment(track);
|
|
168
|
+
|
|
169
|
+
if (!trackType) {
|
|
170
|
+
throw new Error('Expected track type segment');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const trackId = getTrackId(track);
|
|
174
|
+
|
|
175
|
+
if (trackType.trackType === 'video') {
|
|
176
|
+
const width = getWidthSegment(track);
|
|
177
|
+
|
|
178
|
+
if (width === null) {
|
|
179
|
+
throw new Error('Expected width segment');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const height = getHeightSegment(track);
|
|
183
|
+
|
|
184
|
+
if (height === null) {
|
|
185
|
+
throw new Error('Expected height segment');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const displayHeight = getDisplayHeightSegment(track);
|
|
189
|
+
const displayWidth = getDisplayWidthSegment(track);
|
|
190
|
+
|
|
191
|
+
const codec = getCodecSegment(track);
|
|
192
|
+
if (!codec) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const codecString = getMatroskaVideoCodecString({
|
|
197
|
+
track,
|
|
198
|
+
codecSegment: codec,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (!codecString) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
type: 'video',
|
|
207
|
+
trackId,
|
|
208
|
+
codec: codecString,
|
|
209
|
+
description: getDescription(track),
|
|
210
|
+
height: displayHeight ? displayHeight.displayHeight : height.height,
|
|
211
|
+
width: displayWidth ? displayWidth.displayWidth : width.width,
|
|
212
|
+
sampleAspectRatio: {
|
|
213
|
+
numerator: 1,
|
|
214
|
+
denominator: 1,
|
|
215
|
+
},
|
|
216
|
+
timescale,
|
|
217
|
+
samplePositions: [],
|
|
218
|
+
codedHeight: height.height,
|
|
219
|
+
codedWidth: width.width,
|
|
220
|
+
displayAspectHeight: displayHeight
|
|
221
|
+
? displayHeight.displayHeight
|
|
222
|
+
: height.height,
|
|
223
|
+
displayAspectWidth: displayWidth
|
|
224
|
+
? displayWidth.displayWidth
|
|
225
|
+
: width.width,
|
|
226
|
+
rotation: 0,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (trackType.trackType === 'audio') {
|
|
231
|
+
const sampleRate = getSampleRate(track);
|
|
232
|
+
const numberOfChannels = getNumberOfChannels(track);
|
|
233
|
+
if (sampleRate === null) {
|
|
234
|
+
throw new Error('Could not find sample rate or number of channels');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
type: 'audio',
|
|
239
|
+
trackId,
|
|
240
|
+
codec: getMatroskaAudioCodecString(track),
|
|
241
|
+
samplePositions: null,
|
|
242
|
+
timescale,
|
|
243
|
+
numberOfChannels,
|
|
244
|
+
sampleRate,
|
|
245
|
+
description: getAudioDescription(track),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return null;
|
|
250
|
+
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type {BufferIterator} from '../../buffer-iterator';
|
|
2
2
|
import type {ParseResult} from '../../parse-result';
|
|
3
|
+
import type {ParserContext} from '../../parser-context';
|
|
3
4
|
import {expectSegment} from './segments';
|
|
4
5
|
|
|
5
6
|
// Parsing according to https://darkcoding.net/software/reading-mediarecorders-webm-opus-output/
|
|
6
|
-
export const parseWebm = (
|
|
7
|
+
export const parseWebm = (
|
|
8
|
+
counter: BufferIterator,
|
|
9
|
+
parserContext: ParserContext,
|
|
10
|
+
): Promise<ParseResult> => {
|
|
7
11
|
counter.discard(4);
|
|
8
12
|
const length = counter.getVint();
|
|
9
13
|
|
|
@@ -14,5 +18,5 @@ export const parseWebm = (counter: BufferIterator): ParseResult => {
|
|
|
14
18
|
// Discard header for now
|
|
15
19
|
counter.discard(length);
|
|
16
20
|
|
|
17
|
-
return
|
|
21
|
+
return expectSegment(counter, parserContext);
|
|
18
22
|
};
|