@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.
Files changed (213) hide show
  1. package/buffer.js +2 -0
  2. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +1 -1
  3. package/dist/boxes/iso-base-media/make-track.js +14 -2
  4. package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
  5. package/dist/boxes/iso-base-media/mdat/mdat.js +8 -3
  6. package/dist/boxes/iso-base-media/moov/moov.d.ts +2 -1
  7. package/dist/boxes/iso-base-media/moov/moov.js +2 -1
  8. package/dist/boxes/iso-base-media/process-box.d.ts +6 -3
  9. package/dist/boxes/iso-base-media/process-box.js +20 -5
  10. package/dist/boxes/iso-base-media/stsd/avcc.d.ts +1 -1
  11. package/dist/boxes/iso-base-media/stsd/avcc.js +2 -2
  12. package/dist/boxes/iso-base-media/stsd/ctts.js +2 -5
  13. package/dist/boxes/iso-base-media/stsd/hvcc.d.ts +1 -1
  14. package/dist/boxes/iso-base-media/stsd/hvcc.js +2 -2
  15. package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
  16. package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
  17. package/dist/boxes/iso-base-media/stsd/samples.d.ts +4 -2
  18. package/dist/boxes/iso-base-media/stsd/samples.js +69 -11
  19. package/dist/boxes/iso-base-media/stsd/stsd.d.ts +2 -1
  20. package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
  21. package/dist/boxes/iso-base-media/trak/trak.d.ts +2 -1
  22. package/dist/boxes/iso-base-media/trak/trak.js +2 -1
  23. package/dist/boxes/iso-base-media/traversal.d.ts +44 -0
  24. package/dist/boxes/iso-base-media/traversal.js +211 -0
  25. package/dist/boxes/webm/color.d.ts +4 -0
  26. package/dist/boxes/webm/color.js +120 -0
  27. package/dist/boxes/webm/description.js +1 -1
  28. package/dist/boxes/webm/get-ready-tracks.js +3 -3
  29. package/dist/boxes/webm/get-sample-from-block.js +1 -1
  30. package/dist/boxes/webm/get-track.js +16 -1
  31. package/dist/boxes/webm/make-track.d.ts +9 -0
  32. package/dist/boxes/webm/make-track.js +260 -0
  33. package/dist/boxes/webm/parse-ebml.js +2 -2
  34. package/dist/boxes/webm/segments/all-segments.d.ts +36 -3
  35. package/dist/boxes/webm/segments/all-segments.js +34 -6
  36. package/dist/boxes/webm/traversal.d.ts +26 -1
  37. package/dist/boxes/webm/traversal.js +214 -1
  38. package/dist/create/cluster-segment.js +0 -2
  39. package/dist/create/cluster.d.ts +10 -2
  40. package/dist/create/cluster.js +16 -10
  41. package/dist/create/create-media.d.ts +4 -2
  42. package/dist/create/create-media.js +76 -14
  43. package/dist/create/cues.d.ts +0 -0
  44. package/dist/create/cues.js +1 -0
  45. package/dist/create/make-duration-with-padding.d.ts +1 -1
  46. package/dist/create/make-duration-with-padding.js +3 -3
  47. package/dist/create/matroska-cues.d.ts +6 -0
  48. package/dist/create/matroska-cues.js +50 -0
  49. package/dist/create/matroska-info.js +1 -1
  50. package/dist/create/matroska-seek.d.ts +6 -0
  51. package/dist/create/matroska-seek.js +32 -0
  52. package/dist/create/matroska-segment.d.ts +1 -0
  53. package/dist/create/matroska-segment.js +3 -2
  54. package/dist/create/matroska-trackentry.d.ts +9 -14
  55. package/dist/create/matroska-trackentry.js +79 -94
  56. package/dist/emit-available-info.d.ts +12 -0
  57. package/dist/emit-available-info.js +133 -0
  58. package/dist/esm/buffer.mjs +57 -0
  59. package/dist/esm/from-fetch.mjs +72 -0
  60. package/dist/esm/from-node.mjs +48 -0
  61. package/dist/esm/from-web-file.mjs +48 -0
  62. package/dist/esm/index.mjs +6689 -0
  63. package/dist/esm/web-fs.mjs +67 -0
  64. package/dist/get-audio-codec.d.ts +5 -5
  65. package/dist/get-audio-codec.js +41 -57
  66. package/dist/get-container.d.ts +4 -0
  67. package/dist/get-container.js +26 -0
  68. package/dist/get-duration.js +1 -1
  69. package/dist/get-fps.js +1 -1
  70. package/dist/get-sample-aspect-ratio.d.ts +1 -1
  71. package/dist/get-sample-aspect-ratio.js +19 -19
  72. package/dist/get-tracks.d.ts +13 -0
  73. package/dist/get-tracks.js +8 -8
  74. package/dist/get-video-codec.d.ts +5 -2
  75. package/dist/get-video-codec.js +111 -21
  76. package/dist/has-all-info.d.ts +2 -2
  77. package/dist/has-all-info.js +23 -9
  78. package/dist/index.d.ts +3 -1
  79. package/dist/options.d.ts +97 -30
  80. package/dist/parse-media.js +43 -62
  81. package/dist/parse-video.d.ts +2 -1
  82. package/dist/parse-video.js +3 -1
  83. package/dist/parser-state.js +1 -2
  84. package/dist/readers/from-fetch.js +24 -4
  85. package/dist/readers/from-node.js +13 -3
  86. package/dist/readers/from-web-file.js +14 -2
  87. package/dist/readers/reader.d.ts +6 -1
  88. package/dist/samples-from-moof.js +1 -1
  89. package/dist/traversal.d.ts +0 -21
  90. package/dist/traversal.js +1 -158
  91. package/dist/truthy.d.ts +3 -0
  92. package/dist/truthy.js +7 -0
  93. package/dist/writers/buffer.d.ts +2 -0
  94. package/dist/writers/buffer.js +58 -0
  95. package/dist/writers/web-fs.d.ts +1 -0
  96. package/dist/writers/web-fs.js +42 -18
  97. package/dist/writers/writer.d.ts +4 -2
  98. package/fetch.js +2 -0
  99. package/node.js +2 -0
  100. package/package.json +43 -8
  101. package/web-file.js +2 -0
  102. package/web-fs.js +2 -0
  103. package/.eslintrc +0 -8
  104. package/input.webm +0 -0
  105. package/src/add-new-matroska-tracks.ts +0 -23
  106. package/src/boxes/iso-base-media/base-type.ts +0 -4
  107. package/src/boxes/iso-base-media/esds/decoder-specific-config.ts +0 -68
  108. package/src/boxes/iso-base-media/esds/esds-descriptors.ts +0 -135
  109. package/src/boxes/iso-base-media/esds/esds.ts +0 -49
  110. package/src/boxes/iso-base-media/ftyp.ts +0 -39
  111. package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +0 -69
  112. package/src/boxes/iso-base-media/make-track.ts +0 -116
  113. package/src/boxes/iso-base-media/mdat/mdat.ts +0 -140
  114. package/src/boxes/iso-base-media/mdhd.ts +0 -59
  115. package/src/boxes/iso-base-media/moov/moov.ts +0 -43
  116. package/src/boxes/iso-base-media/mvhd.ts +0 -114
  117. package/src/boxes/iso-base-media/process-box.ts +0 -748
  118. package/src/boxes/iso-base-media/stsd/av1c.ts +0 -19
  119. package/src/boxes/iso-base-media/stsd/avcc.ts +0 -36
  120. package/src/boxes/iso-base-media/stsd/colr.ts +0 -49
  121. package/src/boxes/iso-base-media/stsd/ctts.ts +0 -64
  122. package/src/boxes/iso-base-media/stsd/hvcc.ts +0 -32
  123. package/src/boxes/iso-base-media/stsd/keys.ts +0 -27
  124. package/src/boxes/iso-base-media/stsd/mebx.ts +0 -54
  125. package/src/boxes/iso-base-media/stsd/pasp.ts +0 -32
  126. package/src/boxes/iso-base-media/stsd/samples.ts +0 -359
  127. package/src/boxes/iso-base-media/stsd/stco.ts +0 -52
  128. package/src/boxes/iso-base-media/stsd/stsc.ts +0 -61
  129. package/src/boxes/iso-base-media/stsd/stsd.ts +0 -55
  130. package/src/boxes/iso-base-media/stsd/stss.ts +0 -47
  131. package/src/boxes/iso-base-media/stsd/stsz.ts +0 -75
  132. package/src/boxes/iso-base-media/stsd/stts.ts +0 -62
  133. package/src/boxes/iso-base-media/tfdt.ts +0 -37
  134. package/src/boxes/iso-base-media/tfhd.ts +0 -66
  135. package/src/boxes/iso-base-media/tkhd.ts +0 -150
  136. package/src/boxes/iso-base-media/to-date.ts +0 -9
  137. package/src/boxes/iso-base-media/trak/trak.ts +0 -43
  138. package/src/boxes/iso-base-media/trun.ts +0 -74
  139. package/src/boxes/iso-base-media/void-box.ts +0 -4
  140. package/src/boxes/webm/allowed-partial-segments.ts +0 -1
  141. package/src/boxes/webm/av1-codec-private.ts +0 -113
  142. package/src/boxes/webm/description.ts +0 -104
  143. package/src/boxes/webm/ebml.ts +0 -98
  144. package/src/boxes/webm/get-ready-tracks.ts +0 -36
  145. package/src/boxes/webm/get-sample-from-block.ts +0 -125
  146. package/src/boxes/webm/get-track.ts +0 -257
  147. package/src/boxes/webm/make-header.ts +0 -253
  148. package/src/boxes/webm/parse-ebml.ts +0 -259
  149. package/src/boxes/webm/parse-webm-header.ts +0 -18
  150. package/src/boxes/webm/segments/all-segments.ts +0 -888
  151. package/src/boxes/webm/segments/block-simple-block-flags.ts +0 -52
  152. package/src/boxes/webm/segments/parse-children.ts +0 -144
  153. package/src/boxes/webm/segments/track-entry.ts +0 -38
  154. package/src/boxes/webm/segments.ts +0 -147
  155. package/src/boxes/webm/traversal.ts +0 -45
  156. package/src/buffer-iterator.ts +0 -555
  157. package/src/create/cluster-segment.ts +0 -62
  158. package/src/create/cluster.ts +0 -64
  159. package/src/create/create-media.ts +0 -136
  160. package/src/create/make-duration-with-padding.ts +0 -15
  161. package/src/create/matroska-header.ts +0 -63
  162. package/src/create/matroska-info.ts +0 -30
  163. package/src/create/matroska-segment.ts +0 -10
  164. package/src/create/matroska-trackentry.ts +0 -325
  165. package/src/create/timescale.ts +0 -1
  166. package/src/get-audio-codec.ts +0 -270
  167. package/src/get-dimensions.ts +0 -47
  168. package/src/get-duration.ts +0 -103
  169. package/src/get-fps.ts +0 -113
  170. package/src/get-sample-aspect-ratio.ts +0 -204
  171. package/src/get-sample-positions.ts +0 -93
  172. package/src/get-tracks.ts +0 -147
  173. package/src/get-video-codec.ts +0 -117
  174. package/src/has-all-info.ts +0 -81
  175. package/src/index.ts +0 -18
  176. package/src/make-hvc1-codec-strings.ts +0 -55
  177. package/src/options.ts +0 -118
  178. package/src/parse-media.ts +0 -183
  179. package/src/parse-result.ts +0 -79
  180. package/src/parse-video.ts +0 -83
  181. package/src/parser-context.ts +0 -10
  182. package/src/parser-state.ts +0 -178
  183. package/src/readers/from-fetch.ts +0 -90
  184. package/src/readers/from-node.ts +0 -51
  185. package/src/readers/from-web-file.ts +0 -49
  186. package/src/readers/reader.ts +0 -15
  187. package/src/samples-from-moof.ts +0 -102
  188. package/src/test/aspect-ratio.test.ts +0 -42
  189. package/src/test/av1.test.ts +0 -108
  190. package/src/test/create-matroska.test.ts +0 -287
  191. package/src/test/duration.test.ts +0 -18
  192. package/src/test/keys.test.ts +0 -47
  193. package/src/test/matroska.test.ts +0 -463
  194. package/src/test/mvhd.test.ts +0 -94
  195. package/src/test/parse-esds.test.ts +0 -98
  196. package/src/test/parse-stco.test.ts +0 -61
  197. package/src/test/parse-stsc.test.ts +0 -104
  198. package/src/test/parse-stsz.test.ts +0 -57
  199. package/src/test/parse-stts.test.ts +0 -38
  200. package/src/test/parse-video.test.ts +0 -101
  201. package/src/test/parse-webm.test.ts +0 -17
  202. package/src/test/samples-from-moof.test.ts +0 -2496
  203. package/src/test/stream-local.test.ts +0 -743
  204. package/src/test/stream-remote.test.ts +0 -59
  205. package/src/test/stream-samples.test.ts +0 -181
  206. package/src/test/stsd.test.ts +0 -265
  207. package/src/test/tkhd.test.ts +0 -87
  208. package/src/traversal.ts +0 -528
  209. package/src/webcodec-sample-types.ts +0 -29
  210. package/src/writers/web-fs.ts +0 -50
  211. package/src/writers/writer.ts +0 -12
  212. package/tsconfig.json +0 -14
  213. package/tsconfig.tsbuildinfo +0 -1
@@ -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
- };
@@ -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
- };
@@ -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
- };